------- Comment #6 from wilson at gcc dot gnu dot org  2010-03-15 04:08 -------
I can reproduce the original problem with 28490 by changing the line in
ia64_legitimate_constant_p from
          return (addend & 0x3fff) == 0;
to
            return true;
and compiling the testcase with -O.  What happens is that in reload.c we see a
REG_EQUAL note with symbol+8 and put it in reg_equiv_constant because it is
accepted by LEGITIMATE_CONSTANT_P.  This then gets substituted into a SET_SRC. 
Except that this insn now requires a scratch register, and we are after reload,
so we end up aborting.

The traditional solution for this is to define LEGITIMATE_PIC_OPERAND_P so that
it rejects symbol+const when it would require a scratch register.  See the
sparc port for instance.  However, this works only if flag_pic is set.  IA-64
is PIC always, and we use flag_pic for shared libraries, so we can't just set
it.  Or at least, I'm not sure what will happen if we set it, and I don't want
to spend that much time looking into it.

Another traditional solution is to rewrite pic symbols in such a way that they
can't be recognized as constants anymore, for instance, by putting them inside
unspecs.  This is ugly, and I only mention it for completeness.  I don't
recommend fixing the problem this way.

It might be tempting to check for reload_in_progress, but unfortunately the
LEGITIMATE_CONSTANT_P check in reload1.c comes before reload_in_progress is
set, so that won't work.  And messing with reload isn't a good idea, so we
shouldn't try moving where reload_in_progress is set.

That leaves the currently_expanding_to_rtl solution.  We can accept any
constant if that var is true, and we use the current code if that var is false.
 I think this is the second best solution after the LEGITIMATE_PIC_OPERAND_P
solution.

I tried this, and found that it is an imperfect solution.  I don't get a core
dump for 28490, and I don't get a constant pool entry for the 42040 testcase. 
Unfortunately, I do now get a constant pool entry for the 28490 testcase. 
Because symbol+8 is no longer a LEGITIMATE_CONSTANT_P, reload decides to call
force_const_mem and put it in reg_equiv_memory_loc.  So this solution doesn't
completely eliminate the constant pool entries, but it will eliminate most of
them.

To eliminate all of them, we would have to get the LEGITIMATE_PIC_OPERAND_P
solution working.


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=42040

Reply via email to