This is the mail archive of the gcc-help@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]

Question for an expert in the cse optimisation pass of the compiler


I am working on a port of gcc to a new platform and have encountered a problem
in the cse optimisation phase.  Unfortunately, because it is an unsupported
platform I am not able to supply code to demonstrate, but what I really need
to know is a non-specific thing: why the compiler in general makes an
assumption about its ability to amend an insn without validating it.

I am working in 2.95.2, but the 3.0 cse sources look essentially unchanged.

The problem is that the compiler is generating an illegal insn.  It
specifically does this in cse_insn () at the point where the comments state
"Canonicalize sources and addresses of destinations." The same logic is
repeated in canon_reg (). The compiler believes it can replace a register with
another without validating the new insn if both the new and old registers are
hard, or both pseudo (but not mixed - in this case it will validate the new
insn). In my example this assumption is incorrect, so the problem is either
that this assumption should not be made, or that assumption depends on
something else which is failing (and that might become more obvious when I know
why the assumption is made).

If it helps, here is a description of what cse does in my example.  The
relevant insns are shown here, with registers notated as R0 (a hard register)
and V0 and V1 (pseudos).  There are a couple of unrelated insns between these.

1: set reg:SI R0 const_int 0
2: set reg/v:HI V0 const_int 0
3: set reg:SI V1 sign_extend:SI (reg/v:HI V0)
4: set reg:SI R0 reg:SI V1

What happens during the cse phase is this:

1: set reg:SI R0 const_int 0
   The statement is unchanged but R0 is given REG_QTY 176

2: set reg/v:HI V0 const_int 0
   Because R0 contains const_int 0 and can be addressed in HI mode, the
   statement becomes
   set reg/v:HI V0 reg:HI R0 (with a REG_EQUAL note that it is 0)
   V0 is also given REG_QTY 176 (despite being of a different mode).

3: set reg:SI V1 sign_extend:SI (reg/v:HI V0)
   This time the compiler prefers to eliminate the sign_extend and replaces
   the source register with its known value, giving
   set reg:SI V1 const_int 0 (again with a REG_EQUAL note)
   V1 is also given REG_QTY 176.

4: set reg:SI R0 reg:SI V1
   Here the compiler fails.  It believes it can replace reg:SI V1 with
   reg/v:HI V0 because these have the same REG_QTY. It doesn't check the
   validity of the new insn because these are both pseudo registers.  As a
   result you get
   set reg:SI R0 reg/v:HI V0
   which is unrecongnised. If the compiler checked the validity of this (and
   rejected it) it would then go on to replace the source with reg:SI RO, and
   eliminate the insn.

Many thanks in advance for your help!

-- 
Regards,
Richard.
Home: 4 Broadmeadow End, Thatcham, Berkshire, RG18 4ED.
Tel.: (01635) 872625.


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