I have some broken code, compiled from Java source. It looks like:
D.843 = &java.text.Collator.class$$; _Jv_InitClass (D.843); D.845 = &_CD_java_text_Collator; is being turned into: D.843 = &java.text.Collator.class$$; D.845 = &_CD_java_text_Collator; _Jv_InitClass (D.843); i.e. the memory reference is moved to before the call to _Jv_InitClass. To get to my question: I presume that loop2 is supposed to be able to move loads across calls, but it can only do so if the memory is unreachable from the callee. But how does loop2 know if the memory is reachable? Is there a full data flow graph computed, or does it depend one the scope of the memory decl? Thanks, Andrew. in the loop2_invariant dump we have: (call_insn 31 30 33 3 /home/aph/gcc/classpath-098-merge-branch/libjava/java/text/Collator.java:304 (call (mem:QI (symbol_ref:DI ("_Jv_InitClass") [flags 0x41] <function_decl 0x7f3030515800 _Jv_InitClass>) [0 S1 A8]) (const_int 0 [0x0])) 646 {*call_0} (expr_list:REG_DEAD (reg:DI 5 di) (nil)) (expr_list:REG_DEP_TRUE (use (reg:DI 5 di)) (nil))) (insn 33 31 35 3 /home/aph/gcc/classpath-098-merge-branch/libjava/java/text/Collator.java:305 (set (reg/f:DI 95 [ #ref#8#1 ]) (mem/s/u/f/j:DI (const:DI (plus:DI (symbol_ref:DI ("_CD_java_text_Collator") [flags 0x2] <var_decl 0x7f30305eaa00 _CD_java_text_Collator>) (const_int 16 [0x10]))) [0 _CD_java_text_Collator+16 S8 A64])) 89 {*movdi_1_rex64} (nil)) i.e. the call is followed by the load. In the loop2_done dump we have: (insn 33 354 51 2 /home/aph/gcc/classpath-098-merge-branch/libjava/java/text/Collator.java:305 (set (reg/f:DI 162 [ #ref#8#1 ]) (mem/s/u/f/j:DI (const:DI (plus:DI (symbol_ref:DI ("_CD_java_text_Collator") [flags 0x2] <var_decl 0x7f30305eaa00 _CD_java_text_Collator>) (const_int 16 [0x10]))) [0 _CD_java_text_Collator+16 S8 A64])) 89 {*movdi_1_rex64} (nil)) ... (call_insn 31 30 360 3 /home/aph/gcc/classpath-098-merge-branch/libjava/java/text/Collator.java:304 (call (mem:QI (symbol_ref:DI ("_Jv_InitClass") [flags 0x41] <function_decl 0x7f3030515800 _Jv_InitClass>) [0 S1 A8]) (const_int 0 [0x0])) 646 {*call_0} (expr_list:REG_DEAD (reg:DI 5 di) (nil)) (expr_list:REG_DEP_TRUE (use (reg:DI 5 di)) (nil))) i.e. the memory load has been moved before the call.