On 10/16/07, David Miller <[EMAIL PROTECTED]> wrote: > From: "Seongbae Park (박성배, 朴成培)" <[EMAIL PROTECTED]> > Date: Tue, 16 Oct 2007 21:53:37 -0700 > > Annyoung haseyo, Park-sanseng-nim,
:) > > loop-invariant.cc uses ud-chain. > > So if there's something wrong with the chain, > > it could go nuts. > > Can you send me the rtl dump of loop2_invariant pass ? > > I have found the problem, and yes it has to do with the ud chains. > > Because global registers are only marked via df_invalidated_by_call, > they get the DF_REF_MAY_CLOBBER flag. > > This flag causes the dataflow problem solver to not add the global > register definitions to the generator set. Specifically I am > talking about the code in df_rd_bb_local_compute_process_def(), it > says: > > if (!(DF_REF_FLAGS (def) > & (DF_REF_MUST_CLOBBER | DF_REF_MAY_CLOBBER))) > bitmap_set_bit (bb_info->gen, DF_REF_ID (def)); > > Global registers don't get clobbered by calls, they are potentially > set as a side effect of calling them. And they are set to valid > values we might actually depend upon as inputs later. > > I tried a potential fix, which is to change df_insn_refs_record(), > such that it handles global registers instead like this: > > if (global_regs[i]) > df_ref_record (dflow, regno_reg_rtx[i], ®no_reg_rtx[i], > bb, insn, DF_REF_REG_DEF, 0, true); > > and this made the illegal loop-invariant transformation no longer > occur in my test case. Did you replace the DF_REF_REG_USE with DEF ? If so, that's not correct. We need to add DEF as well as USE: diff -r fd0f94fbe89d gcc/df-scan.c --- a/gcc/df-scan.c Wed Oct 10 03:32:43 2007 +0000 +++ b/gcc/df-scan.c Tue Oct 16 22:52:44 2007 -0700 @@ -3109,8 +3109,13 @@ df_get_call_refs (struct df_collection_r so they are recorded as used. */ for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) if (global_regs[i]) - df_ref_record (collection_rec, regno_reg_rtx[i], - NULL, bb, insn, DF_REF_REG_USE, flags); + { + df_ref_record (collection_rec, regno_reg_rtx[i], + NULL, bb, insn, DF_REF_REG_USE, flags); + df_ref_record (collection_rec, regno_reg_rtx[i], + NULL, bb, insn, DF_REF_REG_DEF, flags); + } + is_sibling_call = SIBLING_CALL_P (insn); EXECUTE_IF_SET_IN_BITMAP (df_invalidated_by_call, 0, ui, bi) Then, we'll need to change the df_invalidated_by_call loop not to add global_regs[] again (with MAY_CLOBBER bits). -- #pragma ident "Seongbae Park, compiler, http://seongbae.blogspot.com"