79 lines
2.4 KiB
Diff
79 lines
2.4 KiB
Diff
Index: gcc/global.c
|
|
===================================================================
|
|
RCS file: /cvs/gcc/gcc/gcc/global.c,v
|
|
retrieving revision 1.86.2.3
|
|
diff -u -p -r1.86.2.3 global.c
|
|
--- gcc/global.c 31 Jan 2004 12:46:03 -0000 1.86.2.3
|
|
+++ gcc/global.c 14 Feb 2005 08:02:59 -0000
|
|
@@ -131,10 +131,8 @@ struct allocno
|
|
|
|
HARD_REG_SET regs_someone_prefers;
|
|
|
|
-#ifdef STACK_REGS
|
|
/* Set to true if allocno can't be allocated in the stack register. */
|
|
- bool no_stack_reg;
|
|
-#endif
|
|
+ bool live_over_abnormal;
|
|
};
|
|
|
|
static struct allocno *allocno;
|
|
@@ -727,26 +725,37 @@ global_conflicts ()
|
|
scan the instruction that makes either X or Y become live. */
|
|
record_conflicts (block_start_allocnos, ax);
|
|
|
|
-#ifdef STACK_REGS
|
|
+ /* Pseudos can't go in stack regs at the start of a basic block that
|
|
+ is reached by an abnormal edge. Ditto for call clobbered regs,
|
|
+ because because caller-save, fixup_abnormal_edges, and possibly the
|
|
+ table driven EH machinery are not quite ready to handle such regs
|
|
+ live across such edges. */
|
|
{
|
|
- /* Pseudos can't go in stack regs at the start of a basic block
|
|
- that is reached by an abnormal edge. */
|
|
-
|
|
edge e;
|
|
for (e = b->pred; e ; e = e->pred_next)
|
|
if (e->flags & EDGE_ABNORMAL)
|
|
break;
|
|
+
|
|
if (e != NULL)
|
|
{
|
|
EXECUTE_IF_SET_IN_ALLOCNO_SET (allocnos_live, ax,
|
|
{
|
|
- allocno[ax].no_stack_reg = 1;
|
|
+ allocno[ax].live_over_abnormal = 1;
|
|
});
|
|
+#ifdef STACK_REGS
|
|
for (ax = FIRST_STACK_REG; ax <= LAST_STACK_REG; ax++)
|
|
record_one_conflict (ax);
|
|
+#endif
|
|
+
|
|
+ /* No need to record conflicts for call clobbered regs if we have
|
|
+ nonlocal labels around, as we don't ever try to allocate such
|
|
+ regs in this case. */
|
|
+ if (! current_function_has_nonlocal_label)
|
|
+ for (ax = 0; ax < FIRST_PSEUDO_REGISTER; ax ++)
|
|
+ if (call_used_regs [ax])
|
|
+ record_one_conflict (ax);
|
|
}
|
|
}
|
|
-#endif
|
|
}
|
|
|
|
insn = b->head;
|
|
@@ -1241,10 +1250,12 @@ find_reg (num, losers, alt_regs_p, accep
|
|
&& ! invalid_mode_change_p (regno, REGNO_REG_CLASS (regno),
|
|
mode)
|
|
#endif
|
|
+ && (!allocno[num].live_over_abnormal
|
|
+ || (!call_used_regs[regno]
|
|
#ifdef STACK_REGS
|
|
- && (!allocno[num].no_stack_reg
|
|
- || regno < FIRST_STACK_REG || regno > LAST_STACK_REG)
|
|
+ && (regno < FIRST_STACK_REG || regno > LAST_STACK_REG)
|
|
#endif
|
|
+ ))
|
|
)
|
|
{
|
|
/* We explicitly evaluate the divide results into temporary
|