]> git.lizzy.rs Git - rust.git/blob - compiler/rustc_codegen_cranelift/src/abi/comments.rs
Auto merge of #106938 - GuillaumeGomez:normalize-projection-field-ty, r=oli-obk
[rust.git] / compiler / rustc_codegen_cranelift / src / abi / comments.rs
1 //! Annotate the clif ir with comments describing how arguments are passed into the current function
2 //! and where all locals are stored.
3
4 use std::borrow::Cow;
5
6 use rustc_middle::mir;
7 use rustc_target::abi::call::PassMode;
8
9 use cranelift_codegen::entity::EntityRef;
10
11 use crate::prelude::*;
12
13 pub(super) fn add_args_header_comment(fx: &mut FunctionCx<'_, '_, '_>) {
14     if fx.clif_comments.enabled() {
15         fx.add_global_comment(
16             "kind  loc.idx   param    pass mode                            ty".to_string(),
17         );
18     }
19 }
20
21 pub(super) fn add_arg_comment<'tcx>(
22     fx: &mut FunctionCx<'_, '_, 'tcx>,
23     kind: &str,
24     local: Option<mir::Local>,
25     local_field: Option<usize>,
26     params: &[Value],
27     arg_abi_mode: &PassMode,
28     arg_layout: TyAndLayout<'tcx>,
29 ) {
30     if !fx.clif_comments.enabled() {
31         return;
32     }
33
34     let local = if let Some(local) = local {
35         Cow::Owned(format!("{:?}", local))
36     } else {
37         Cow::Borrowed("???")
38     };
39     let local_field = if let Some(local_field) = local_field {
40         Cow::Owned(format!(".{}", local_field))
41     } else {
42         Cow::Borrowed("")
43     };
44
45     let params = match params {
46         [] => Cow::Borrowed("-"),
47         [param] => Cow::Owned(format!("= {:?}", param)),
48         [param_a, param_b] => Cow::Owned(format!("= {:?},{:?}", param_a, param_b)),
49         params => Cow::Owned(format!(
50             "= {}",
51             params.iter().map(ToString::to_string).collect::<Vec<_>>().join(",")
52         )),
53     };
54
55     let pass_mode = format!("{:?}", arg_abi_mode);
56     fx.add_global_comment(format!(
57         "{kind:5}{local:>3}{local_field:<5} {params:10} {pass_mode:36} {ty:?}",
58         kind = kind,
59         local = local,
60         local_field = local_field,
61         params = params,
62         pass_mode = pass_mode,
63         ty = arg_layout.ty,
64     ));
65 }
66
67 pub(super) fn add_locals_header_comment(fx: &mut FunctionCx<'_, '_, '_>) {
68     if fx.clif_comments.enabled() {
69         fx.add_global_comment(String::new());
70         fx.add_global_comment(
71             "kind  local ty                              size align (abi,pref)".to_string(),
72         );
73     }
74 }
75
76 pub(super) fn add_local_place_comments<'tcx>(
77     fx: &mut FunctionCx<'_, '_, 'tcx>,
78     place: CPlace<'tcx>,
79     local: Local,
80 ) {
81     if !fx.clif_comments.enabled() {
82         return;
83     }
84     let TyAndLayout { ty, layout } = place.layout();
85     let rustc_target::abi::LayoutS {
86         size,
87         align,
88         abi: _,
89         variants: _,
90         fields: _,
91         largest_niche: _,
92     } = layout.0.0;
93
94     let (kind, extra) = match *place.inner() {
95         CPlaceInner::Var(place_local, var) => {
96             assert_eq!(local, place_local);
97             ("ssa", Cow::Owned(format!(",var={}", var.index())))
98         }
99         CPlaceInner::VarPair(place_local, var1, var2) => {
100             assert_eq!(local, place_local);
101             ("ssa", Cow::Owned(format!(",var=({}, {})", var1.index(), var2.index())))
102         }
103         CPlaceInner::VarLane(_local, _var, _lane) => unreachable!(),
104         CPlaceInner::Addr(ptr, meta) => {
105             let meta = if let Some(meta) = meta {
106                 Cow::Owned(format!(",meta={}", meta))
107             } else {
108                 Cow::Borrowed("")
109             };
110             match ptr.debug_base_and_offset() {
111                 (crate::pointer::PointerBase::Addr(addr), offset) => {
112                     ("reuse", format!("storage={}{}{}", addr, offset, meta).into())
113                 }
114                 (crate::pointer::PointerBase::Stack(stack_slot), offset) => {
115                     ("stack", format!("storage={}{}{}", stack_slot, offset, meta).into())
116                 }
117                 (crate::pointer::PointerBase::Dangling(align), offset) => {
118                     ("zst", format!("align={},offset={}", align.bytes(), offset).into())
119                 }
120             }
121         }
122     };
123
124     fx.add_global_comment(format!(
125         "{:<5} {:5} {:30} {:4}b {}, {}{}{}",
126         kind,
127         format!("{:?}", local),
128         format!("{:?}", ty),
129         size.bytes(),
130         align.abi.bytes(),
131         align.pref.bytes(),
132         if extra.is_empty() { "" } else { "              " },
133         extra,
134     ));
135 }