This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Redundant Load Elimination in GCSE


Deleting "obviously dead" insns:

Recent changes that we're working on in gcse.c to improve PRE (see
"GCSE/PRE problem"
and "Redundant Load Elimination in GCSE")
have created redundant register-copy instructions (i.e.: an r211 = r232 rtx
followed
by another r211 = r232 rtx). These obviously dead copy instructions are not
cleared
by cse.c/delete_trivially_dead_insns() because it takes a minimal amount of
flow
information to see that the first is dead. So they remain, and create havoc
to the
loop unroller because it throws loop.c/basic_induction_var() off track. The
latter
is "smart" enough to catch the following (which delete_trivially_dead_insns
handles):

     /* If this sets a register to itself, we would repeat any previous
        biv increment if we applied this strategy blindly.  */
     if (rtx_equal_p (dest_reg, x))
       return 0;

but will repeat any previous biv increment if a pair of identical
register-copy is
encountered.


Adding the following ("delete_obviously_dead_insns") at the end of
cse.c/delete_trivially_dead_insns() is one way to fix/work around this
problem:

  for (insn = next_real_insn (insns); insn; insn = next_real_insn (insn))
    {
      rtx set = single_set (insn);
      if (set && GET_CODE (SET_DEST (set)) == REG)
        {
          rtx next_insn = NEXT_INSN (insn);
          if (next_insn && next_insn != NULL_RTX)
            {
              rtx next_set = single_set (next_insn);
              if (next_set && GET_CODE (SET_DEST (next_set)) == REG)
              {
                rtx reg1 = SET_DEST(set);
                rtx reg2 = SET_DEST(next_set);
                if ((REGNO(reg1) == REGNO(reg2)) && (REGNO(reg1) >=
FIRST_PSEUDO_REGISTER)
                  && !reg_overlap_mentioned_p(reg1, PATTERN (next_insn)))
                {
                  delete_insn_and_edges (insn);
                  ndead++;
                }
              }
            }
        }
    }

Anyway, this note comes to warn about the fragility of
loop.c/basic_induction_var().
Any suggestions or comments are welcome, before we submit a patch.

Mustafa and Ayal.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]