This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
new-regalloc vs alpha
- To: Daniel Berlin <dberlin at redhat dot com>
- Subject: new-regalloc vs alpha
- From: Richard Henderson <rth at redhat dot com>
- Date: Tue, 30 Jan 2001 04:28:04 -0800
- Cc: gcc-patches at gcc dot gnu dot org
I've run into two problems so far trying this on alphaev6-linux.
One, you should never try to allocate fixed registers, even if they
are in the proper register class. Fixed with attachment one.
Two, reload has a sort of phase ordering problem with local-alloc.
I'm not sure how this doesn't show up with current code. The
sequence of events is
* The code around line 1140 in update_equiv_regs decides to re-emit the
set of a reg near it's (only) use, we lose the memoized INSN_CODE
that we'd had before.
* The allocator chooses a hard reg that is not valid for that insn.
* reload calls alter_reg for each pseudo, which updates the REGNO
of each pseudo, which means the bogus hard reg is reflected in
the insn.
* eliminate_regs_in_insn calls recog_memoized, which fails. We abort.
The quickest way around this that I saw is to have update_equiv_regs
copy the insn code while re-emitting the instruction.
I've not committed either of these patches.
You may wish to examine this case further (_fixunsdfsi), as the
allocation is particularly bletcherous, and results in quite a
few bogus fp->int and int->fp copies.
r~
* new-regalloc.c (assign_regs): Don't consider fixed regs.
Index: new-regalloc.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/new-regalloc.c,v
retrieving revision 1.1.2.6
diff -c -p -d -r1.1.2.6 new-regalloc.c
*** new-regalloc.c 2001/01/30 04:52:49 1.1.2.6
--- new-regalloc.c 2001/01/30 11:34:41
*************** void assign_regs()
*** 1322,1327 ****
--- 1322,1328 ----
VARRAY_POP(selectStack);
COPY_HARD_REG_SET(okColors, reg_class_contents[reg_preferred_class(currReg)]);
IOR_HARD_REG_SET(okColors, reg_class_contents[reg_alternate_class(currReg)]);
+ AND_COMPL_HARD_REG_SET (okColors, fixed_reg_set);
EXECUTE_IF_SET_IN_SBITMAP(regInfo[currReg]->adjList, 0, entry,
{
* local-alloc.c (update_equiv_regs): Copy INSN_CODE when
re-emitting an equivalence.
Index: local-alloc.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/local-alloc.c,v
retrieving revision 1.77
diff -u -p -r1.77 local-alloc.c
--- local-alloc.c 2001/01/01 17:20:08 1.77
+++ local-alloc.c 2001/01/30 12:03:56
@@ -1141,8 +1141,15 @@ update_equiv_regs ()
rtx new_insn;
new_insn = emit_insn_before (PATTERN (equiv_insn), insn);
- REG_NOTES (PREV_INSN (insn)) = REG_NOTES (equiv_insn);
+ REG_NOTES (new_insn) = REG_NOTES (equiv_insn);
REG_NOTES (equiv_insn) = 0;
+
+ /* ??? We may not recognize this insn before
+ eliminate_regs_in_insn, which is called after
+ alter_regs. And if the allocators have chosen
+ a bum register class, recognition will at that
+ point fail, and we will abort. */
+ INSN_CODE (new_insn) = INSN_CODE (equiv_insn);
PUT_CODE (equiv_insn, NOTE);
NOTE_LINE_NUMBER (equiv_insn) = NOTE_INSN_DELETED;
_fixunsdfsi.i.bz2