@@ -133,6 +133,33 @@ pub fn inline(sess: &Session, module: &mut Module) -> super::Result<()> {
133133 . map ( Ok )
134134 . collect ( ) ;
135135
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+
136163 // Inline functions in post-order (aka inside-out aka bottom-up) - that is,
137164 // callees are processed before their callers, to avoid duplicating work.
138165 for func_idx in call_graph. post_order ( ) {
@@ -145,6 +172,19 @@ pub fn inline(sess: &Session, module: &mut Module) -> super::Result<()> {
145172 }
146173 . remove_duplicate_debuginfo_in_function ( & mut function) ;
147174
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+
148188 functions[ func_idx] = Ok ( function) ;
149189 }
150190
0 commit comments