aboutsummaryrefslogtreecommitdiff
path: root/gcc/alias.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/alias.c')
-rw-r--r--gcc/alias.c18
1 files changed, 17 insertions, 1 deletions
diff --git a/gcc/alias.c b/gcc/alias.c
index 4c7965d..5fa15cb 100644
--- a/gcc/alias.c
+++ b/gcc/alias.c
@@ -3191,12 +3191,21 @@ init_alias_target (void)
&& targetm.hard_regno_mode_ok (i, Pmode))
static_reg_base_value[i] = arg_base_value;
+ /* RTL code is required to be consistent about whether it uses the
+ stack pointer, the frame pointer or the argument pointer to
+ access a given area of the frame. We can therefore use the
+ base address to distinguish between the different areas. */
static_reg_base_value[STACK_POINTER_REGNUM]
= unique_base_value (UNIQUE_BASE_VALUE_SP);
static_reg_base_value[ARG_POINTER_REGNUM]
= unique_base_value (UNIQUE_BASE_VALUE_ARGP);
static_reg_base_value[FRAME_POINTER_REGNUM]
= unique_base_value (UNIQUE_BASE_VALUE_FP);
+
+ /* The above rules extend post-reload, with eliminations applying
+ consistently to each of the three pointers. Cope with cases in
+ which the frame pointer is eliminated to the hard frame pointer
+ rather than the stack pointer. */
if (!HARD_FRAME_POINTER_IS_FRAME_POINTER)
static_reg_base_value[HARD_FRAME_POINTER_REGNUM]
= unique_base_value (UNIQUE_BASE_VALUE_HFP);
@@ -3329,7 +3338,14 @@ init_alias_analysis (void)
/* Initialize the alias information for this pass. */
for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
- if (static_reg_base_value[i])
+ if (static_reg_base_value[i]
+ /* Don't treat the hard frame pointer as special if we
+ eliminated the frame pointer to the stack pointer instead. */
+ && !(i == HARD_FRAME_POINTER_REGNUM
+ && reload_completed
+ && !frame_pointer_needed
+ && targetm.can_eliminate (FRAME_POINTER_REGNUM,
+ STACK_POINTER_REGNUM)))
{
new_reg_base_value[i] = static_reg_base_value[i];
bitmap_set_bit (reg_seen, i);