@@ -133,6 +133,33 @@ pub fn inline(sess: &Session, module: &mut Module) -> super::Result<()> {
133
133
. map ( Ok )
134
134
. collect ( ) ;
135
135
136
+
137
+ let mut mem2reg_pointer_to_pointee = FxHashMap :: default ( ) ;
138
+ let mut mem2reg_constants = FxHashMap :: default ( ) ;
139
+ {
140
+ let mut u32 = None ;
141
+ for inst in & module. types_global_values {
142
+ match inst. class . opcode {
143
+ Op :: TypePointer => {
144
+ mem2reg_pointer_to_pointee
145
+ . insert ( inst. result_id . unwrap ( ) , inst. operands [ 1 ] . unwrap_id_ref ( ) ) ;
146
+ }
147
+ Op :: TypeInt
148
+ if inst. operands [ 0 ] . unwrap_literal_bit32 ( ) == 32
149
+ && inst. operands [ 1 ] . unwrap_literal_bit32 ( ) == 0 =>
150
+ {
151
+ assert ! ( u32 . is_none( ) ) ;
152
+ u32 = Some ( inst. result_id . unwrap ( ) ) ;
153
+ }
154
+ Op :: Constant if u32. is_some ( ) && inst. result_type == u32 => {
155
+ let value = inst. operands [ 0 ] . unwrap_literal_bit32 ( ) ;
156
+ mem2reg_constants. insert ( inst. result_id . unwrap ( ) , value) ;
157
+ }
158
+ _ => { }
159
+ }
160
+ }
161
+ }
162
+
136
163
// Inline functions in post-order (aka inside-out aka bottom-up) - that is,
137
164
// callees are processed before their callers, to avoid duplicating work.
138
165
for func_idx in call_graph. post_order ( ) {
@@ -145,6 +172,19 @@ pub fn inline(sess: &Session, module: &mut Module) -> super::Result<()> {
145
172
}
146
173
. remove_duplicate_debuginfo_in_function ( & mut function) ;
147
174
175
+ {
176
+ super :: simple_passes:: block_ordering_pass ( & mut function) ;
177
+ // Note: mem2reg requires functions to be in RPO order (i.e. block_ordering_pass)
178
+ super :: mem2reg:: mem2reg (
179
+ inliner. header ,
180
+ & mut module. types_global_values ,
181
+ & mem2reg_pointer_to_pointee,
182
+ & mem2reg_constants,
183
+ & mut function,
184
+ ) ;
185
+ super :: destructure_composites:: destructure_composites ( & mut function) ;
186
+ }
187
+
148
188
functions[ func_idx] = Ok ( function) ;
149
189
}
150
190
0 commit comments