aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDale Johannesen <dalej@apple.com>2005-11-17 18:49:19 +0000
committerDale Johannesen <dalej@apple.com>2005-11-17 18:49:19 +0000
commit59e8a5806f455d94fd9b07fddcac760069a0e779 (patch)
treeac51a98f0eed62ef92a164bbf6a61fddf4be5eea
parentc059b0017c5653028a20e3617cbff1f1c0a102d1 (diff)
2005-11-17 Dale Johannesen <dalej@apple.com>apple/gcc-5249
Radar 4321079 * global.c (remove_invalidated_death_notes): New. * reload1.c (reload): Call it. git-svn-id: https://gcc.gnu.org/svn/gcc/branches/apple-200511-release-branch@107129 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/ChangeLog.apple-ppc6
-rw-r--r--gcc/global.c50
-rw-r--r--gcc/reload1.c8
3 files changed, 64 insertions, 0 deletions
diff --git a/gcc/ChangeLog.apple-ppc b/gcc/ChangeLog.apple-ppc
index 3164be8e83a..b6b83cad73c 100644
--- a/gcc/ChangeLog.apple-ppc
+++ b/gcc/ChangeLog.apple-ppc
@@ -1,3 +1,9 @@
+2005-11-17 Dale Johannesen <dalej@apple.com>
+
+ Radar 4321079
+ * global.c (remove_invalidated_death_notes): New.
+ * reload1.c (reload): Call it.
+
2005-11-15 Dale Johannesen <dalej@apple.com>
* expmed.c (store_bit_field): Add offset unconditionally for
diff --git a/gcc/global.c b/gcc/global.c
index cedebf0ca4d..592b90bbc75 100644
--- a/gcc/global.c
+++ b/gcc/global.c
@@ -1967,6 +1967,56 @@ find_tied_stack_pseudo (int r)
});
return 0;
}
+
+/* Callback for reload. We just altered all the rtx pseudo nodes to contain
+ the hard regs assigned by global allocation. In the case where the same
+ hard reg was assigned to two pseudos tied by pseudo_preferences but with
+ overlapping live ranges, REG_DEAD notes referring to the common hard reg
+ may now be invalid. Remove them. (The algorithm is overly conservative,
+ removing all notes for registers tied by pseudo_preferences without
+ checking that there actually is a live range overlap.) */
+
+void remove_invalidated_death_notes (rtx);
+void remove_invalidated_death_notes (rtx first)
+{
+ rtx insn;
+ int regno, orig_regno, i, j;
+ rtx r, *pnote, *next_pnote;
+ for (insn = first; insn; insn = NEXT_INSN (insn))
+ if (INSN_P (insn))
+ {
+ for (pnote = &REG_NOTES (insn); *pnote; pnote = next_pnote)
+ {
+ next_pnote = &XEXP (*pnote, 1);
+
+ if (REG_NOTE_KIND (*pnote) == REG_DEAD)
+ {
+ r = XEXP (*pnote, 0);
+ if (!REG_P (r))
+ continue;
+ regno = REGNO (r);
+ orig_regno = ORIGINAL_REGNO (r);
+ if (orig_regno < FIRST_PSEUDO_REGISTER || regno >= FIRST_PSEUDO_REGISTER)
+ continue;
+ if (regno == orig_regno)
+ continue;
+ i = reg_allocno[orig_regno];
+ EXECUTE_IF_SET_IN_ALLOCNO_SET(pseudo_preferences + i * allocno_row_words, j,
+ {
+ if (i != j
+ && !CONFLICTP(i, j)
+ && reg_renumber[allocno[j].reg] == regno)
+ {
+ *pnote = *next_pnote;
+ next_pnote = pnote;
+ goto next_note;
+ }
+ });
+ }
+ next_note:;
+ }
+ }
+}
/* APPLE LOCAL end 4321079 */
/* Indicate that hard register number FROM was eliminated and replaced with
diff --git a/gcc/reload1.c b/gcc/reload1.c
index 74958c06c1e..df56b3c2e7e 100644
--- a/gcc/reload1.c
+++ b/gcc/reload1.c
@@ -830,6 +830,14 @@ reload (rtx first, int global)
for (i = LAST_VIRTUAL_REGISTER + 1; i < max_regno; i++)
alter_reg (i, -1);
+ /* APPLE LOCAL begin 4321079 */
+ if (from_global)
+ {
+ extern void remove_invalidated_death_notes (rtx);
+ remove_invalidated_death_notes (first);
+ }
+ /* APPLE LOCAL end 4321079 */
+
/* If we have some registers we think can be eliminated, scan all insns to
see if there is an insn that sets one of these registers to something
other than itself plus a constant. If so, the register cannot be