ruka_mir/browser_graph/
formatting.rs1use cranelift_entity::EntityRef;
2
3use crate::naming::FunctionNames;
4use crate::{
5 LocalKind, MirAggregateArg, MirArgMode, MirBlock, MirFunction, MirLocalId, MirLocalRepr,
6 MirOwnershipMode, MirTerminator,
7};
8
9pub(super) fn format_block_summary(
11 function: &MirFunction,
12 block_index: usize,
13 block: &MirBlock,
14 function_names: &FunctionNames,
15) -> String {
16 let mut parts = Vec::new();
17 if function.entry.index() == block_index {
18 parts.push("entry".to_owned());
19 }
20 if !block.params.is_empty() {
21 parts.push(format!(
22 "params {}",
23 format_local_list(&block.params, function_names)
24 ));
25 }
26 parts.push(format!("{} instr", block.instrs.len()));
27 parts.push(format_terminator_kind(&block.terminator));
28 parts.join(" | ")
29}
30
31pub(super) fn format_terminator_kind(term: &MirTerminator) -> String {
33 match term {
34 MirTerminator::Jump { target, .. } => format!("jump -> b{}", target.index()),
35 MirTerminator::Branch {
36 then_target,
37 else_target,
38 ..
39 } => format!(
40 "branch -> b{}/b{}",
41 then_target.index(),
42 else_target.index()
43 ),
44 MirTerminator::Return { .. } => "return".to_owned(),
45 }
46}
47
48pub(super) fn format_jump_edge_label(
50 args: &[MirLocalId],
51 function_names: &FunctionNames,
52) -> Option<String> {
53 if args.is_empty() {
54 None
55 } else {
56 Some(format!(
57 "jump [{}]",
58 format_local_list(args, function_names)
59 ))
60 }
61}
62
63pub(super) fn format_terminator(term: &MirTerminator, function_names: &FunctionNames) -> String {
65 match term {
66 MirTerminator::Jump { target, args } => {
67 format!(
68 "jump b{}({})",
69 target.index(),
70 format_local_list(args, function_names)
71 )
72 }
73 MirTerminator::Branch {
74 cond,
75 then_target,
76 else_target,
77 ..
78 } => format!(
79 "branch {} ? b{} : b{}",
80 format_local(*cond, function_names),
81 then_target.index(),
82 else_target.index()
83 ),
84 MirTerminator::Return { value } => {
85 format!("return {}", format_local(*value, function_names))
86 }
87 }
88}
89
90pub(super) fn format_local(local: MirLocalId, function_names: &FunctionNames) -> String {
92 function_names.local_ident(local).to_owned()
93}
94
95pub(super) fn format_local_list(locals: &[MirLocalId], function_names: &FunctionNames) -> String {
97 if locals.is_empty() {
98 "-".to_string()
99 } else {
100 locals
101 .iter()
102 .map(|local| format_local(*local, function_names))
103 .collect::<Vec<_>>()
104 .join(", ")
105 }
106}
107
108pub(super) fn format_edge_label(
110 prefix: &str,
111 args: &[MirLocalId],
112 function_names: &FunctionNames,
113) -> String {
114 if args.is_empty() {
115 prefix.to_string()
116 } else {
117 format!("{prefix} [{}]", format_local_list(args, function_names))
118 }
119}
120
121pub(super) fn format_function_params(
123 function: &MirFunction,
124 function_names: &FunctionNames,
125) -> String {
126 if function.params.is_empty() {
127 return "-".to_owned();
128 }
129
130 function
131 .params
132 .iter()
133 .zip(function.param_modes.iter())
134 .map(|(local, mode)| {
135 format!(
136 "{}:{}:{}",
137 function_names.local_ident(*local),
138 format_param_mode(*mode),
139 format_local_repr(function.locals[*local].repr),
140 )
141 })
142 .collect::<Vec<_>>()
143 .join(", ")
144}
145
146pub(super) fn format_param_mode(mode: MirOwnershipMode) -> &'static str {
148 match mode {
149 MirOwnershipMode::View => "view",
150 MirOwnershipMode::MutBorrow => "mut-borrow",
151 MirOwnershipMode::Owned => "owned",
152 }
153}
154
155pub(super) fn format_local_kind(kind: LocalKind) -> &'static str {
157 match kind {
158 LocalKind::Param => "param",
159 LocalKind::Binding => "binding",
160 LocalKind::Temp => "temp",
161 }
162}
163
164pub(super) fn format_local_repr(repr: MirLocalRepr) -> &'static str {
166 match repr {
167 MirLocalRepr::Value => "value",
168 MirLocalRepr::SharedPlace => "shared-place",
169 MirLocalRepr::MutablePlace => "mutable-place",
170 }
171}
172
173pub(super) fn format_aggregate_arg(
175 arg: &MirAggregateArg,
176 function_names: &FunctionNames,
177) -> String {
178 format!(
179 "{} {}",
180 format_call_arg_mode(arg.mode),
181 format_local(arg.local, function_names)
182 )
183}
184
185pub(super) fn format_call_arg_mode(mode: MirArgMode) -> &'static str {
187 match mode {
188 MirArgMode::Borrowed => "borrowed",
189 MirArgMode::MutableBorrow => "mutable-borrow",
190 MirArgMode::OwnedMove => "owned-move",
191 MirArgMode::OwnedCopy => "owned-copy",
192 }
193}