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]

Recovering REG_EXPR information after temporary expression replacement


A member of our team was working on some switch statement optimizations,
and ran into a situation that seems a little curious on the face of it.
Consider these two test variants:

------------------------------------------------------------------------
int
test_switch_1 (unsigned int *index, int i)
{
  switch (*index)
    {
    case 0:
      return i;
    case 1:
      return i+1;
    case 2:
      return i+2;
    default:
      return i+3;
    }
}
------------------------------------------------------------------------
int
test_switch_2 (unsigned int *index, int i)
{
  switch (*index)
    {
    case 0:
      return i;
    case 1:
      return i+1;
    case 2:
      return i+2;
    default:
      return *index+3;
    }
}
------------------------------------------------------------------------

For the second case we see the following from expand.  The key point is
that reg:SI 120 has a REG_EXPR of D.2004, which allows getting type
information from the original decl of D.2004:

------------------------------------------------------------------------
;; D.2004_3 = *index_2(D);

(insn 7 6 0 (set (reg:SI 120 [ D.2004 ])
        (mem:SI (reg/v/f:SI 123 [ index ]) [2 *index_2(D)+0 S4 A32]))
t2.i:4 -1
     (nil))

;; switch (D.2004_3) <default: <L3>, case 0: <L5>, case 1: <L1>, case 2:
<L2>>

(insn 8 7 9 (set (reg:CCUNS 125)
        (compare:CCUNS (reg:SI 120 [ D.2004 ])
            (const_int 1 [0x1]))) t2.i:4 -1
     (nil))
------------------------------------------------------------------------

However, for the first case, temporary expression replacement has
effectively removed the assignment to D.2004_3 (single local immediate
use permits replacement), so instead we see:

------------------------------------------------------------------------
;; switch (D.2004_3) <default: <L3>, case 0: <L5>, case 1: <L1>, case 2:
<L2>>

(insn 7 6 8 (set (reg:SI 124)
        (mem:SI (reg/v/f:SI 122 [ index ]) [2 *index_2(D)+0 S4 A32]))
t1.i:4 -1
     (nil))

(insn 8 7 9 (set (reg:CC 125)
        (compare:CC (reg:SI 124)
            (const_int 1 [0x1]))) t1.i:4 -1
     (nil))
------------------------------------------------------------------------

The REG_EXPR is missing for reg:SI 124, so the type information for
D.2004 can't be recovered.

I am not very familiar with all the ins and outs of expand, so it's not
clear to me whether this is necessary.  It seems to me that it would be
theoretically possible to attach the REG_EXPR data here when doing the
TER lookup while expanding the switch, but perhaps there are reasons why
that's difficult.

It would be a nice enhancement if the REG_EXPR could be preserved in
such cases.  Does anyone know if there's something that would prevent
this?

Thanks!

Bill


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