aboutsummaryrefslogtreecommitdiff
path: root/gcc/global.c
diff options
context:
space:
mode:
authorAlan Modra <amodra@bigpond.net.au>2003-12-06 12:22:31 +0000
committerAlan Modra <amodra@gcc.gnu.org>2003-12-06 22:52:31 +1030
commitdf2ef49bbf1d8e81db688fb49ddaf7e614b71961 (patch)
tree806d63a055d1e8b44cd4e930d2d4c903a4cfaee2 /gcc/global.c
parent929a3294725cb55f539bde39b50672cf24055c07 (diff)
downloadgcc-df2ef49bbf1d8e81db688fb49ddaf7e614b71961.zip
gcc-df2ef49bbf1d8e81db688fb49ddaf7e614b71961.tar.gz
gcc-df2ef49bbf1d8e81db688fb49ddaf7e614b71961.tar.bz2
re PR rtl-optimization/13169 (asm using r30 or r31 confuses global_alloc)
PR 13169 * basic-block.h (PROP_ASM_SCAN): Define. * final.c (regs_asm_clobbered): New array. * regs.h (regs_asm_clobbered): Declare. * flow.c (life_analysis): Init it. (mark_set_regs): Set PROP_ASM_SCAN for asms. (mark_set_1): Set regs_asm_clobbered. * global.c (global_alloc): Don't set eliminable_regset when regs_asm_clobbered. From-SVN: r74363
Diffstat (limited to 'gcc/global.c')
-rw-r--r--gcc/global.c40
1 files changed, 30 insertions, 10 deletions
diff --git a/gcc/global.c b/gcc/global.c
index c808e20..c337cd4 100644
--- a/gcc/global.c
+++ b/gcc/global.c
@@ -343,22 +343,42 @@ global_alloc (FILE *file)
#ifdef ELIMINABLE_REGS
for (i = 0; i < ARRAY_SIZE (eliminables); i++)
{
- SET_HARD_REG_BIT (eliminable_regset, eliminables[i].from);
+ bool cannot_elim
+ = (! CAN_ELIMINATE (eliminables[i].from, eliminables[i].to)
+ || (eliminables[i].to == STACK_POINTER_REGNUM && need_fp));
- if (! CAN_ELIMINATE (eliminables[i].from, eliminables[i].to)
- || (eliminables[i].to == STACK_POINTER_REGNUM && need_fp))
- SET_HARD_REG_BIT (no_global_alloc_regs, eliminables[i].from);
+ if (!regs_asm_clobbered[eliminables[i].from])
+ {
+ SET_HARD_REG_BIT (eliminable_regset, eliminables[i].from);
+
+ if (cannot_elim)
+ SET_HARD_REG_BIT (no_global_alloc_regs, eliminables[i].from);
+ }
+ else if (cannot_elim)
+ error ("%s cannot be used in asm here",
+ reg_names[eliminables[i].from]);
}
#if FRAME_POINTER_REGNUM != HARD_FRAME_POINTER_REGNUM
- SET_HARD_REG_BIT (eliminable_regset, HARD_FRAME_POINTER_REGNUM);
- if (need_fp)
- SET_HARD_REG_BIT (no_global_alloc_regs, HARD_FRAME_POINTER_REGNUM);
+ if (!regs_asm_clobbered[HARD_FRAME_POINTER_REGNUM])
+ {
+ SET_HARD_REG_BIT (eliminable_regset, HARD_FRAME_POINTER_REGNUM);
+ if (need_fp)
+ SET_HARD_REG_BIT (no_global_alloc_regs, HARD_FRAME_POINTER_REGNUM);
+ }
+ else if (need_fp)
+ error ("%s cannot be used in asm here",
+ reg_names[HARD_FRAME_POINTER_REGNUM]);
#endif
#else
- SET_HARD_REG_BIT (eliminable_regset, FRAME_POINTER_REGNUM);
- if (need_fp)
- SET_HARD_REG_BIT (no_global_alloc_regs, FRAME_POINTER_REGNUM);
+ if (!regs_asm_clobbered[FRAME_POINTER_REGNUM])
+ {
+ SET_HARD_REG_BIT (eliminable_regset, FRAME_POINTER_REGNUM);
+ if (need_fp)
+ SET_HARD_REG_BIT (no_global_alloc_regs, FRAME_POINTER_REGNUM);
+ }
+ else if (need_fp)
+ error ("%s cannot be used in asm here", reg_names[FRAME_POINTER_REGNUM]);
#endif
/* Track which registers have already been used. Start with registers