aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJeffrey A Law <law@cygnus.com>1998-10-27 23:19:31 +0000
committerJeff Law <law@gcc.gnu.org>1998-10-27 16:19:31 -0700
commit0304f7877c4c65d129ea00cc2964a0998b9031ce (patch)
treec70a7a8b1e67a64ee37c4cbef242efc253b9a280 /gcc
parentbd09c530b225d9d838c63842e605aafe12a817e3 (diff)
downloadgcc-0304f7877c4c65d129ea00cc2964a0998b9031ce.zip
gcc-0304f7877c4c65d129ea00cc2964a0998b9031ce.tar.gz
gcc-0304f7877c4c65d129ea00cc2964a0998b9031ce.tar.bz2
final.c (cleanup_subreg_operands): New function.
* final.c (cleanup_subreg_operands): New function. (final_scan_insn): Use it. (alter_subreg): Clear the "used" field when we turn a SUBREG into a REG. * reload1.c (reload): Delete CLOBBER insns and also cleanup SUBREG operands when reload has finished. * reload.h (cleanup_subreg_operands): Declare.. * flow.c (life_analysis_1): No longer delete CLOBBER insns after reload. Handled in reload itself. Should fix sh, sparc and probably other problems with post-reload life pass and scheduling interactions. From-SVN: r23377
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog12
-rw-r--r--gcc/final.c64
-rw-r--r--gcc/flow.c17
-rw-r--r--gcc/reload.h3
-rw-r--r--gcc/reload1.c12
5 files changed, 70 insertions, 38 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 4cab3de..23af102 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,15 @@
+Wed Oct 28 00:10:35 1998 Jeffrey A Law (law@cygnus.com)
+
+ * final.c (cleanup_subreg_operands): New function.
+ (final_scan_insn): Use it.
+ (alter_subreg): Clear the "used" field when we turn a SUBREG into
+ a REG.
+ * reload1.c (reload): Delete CLOBBER insns and also cleanup SUBREG
+ operands when reload has finished.
+ * reload.h (cleanup_subreg_operands): Declare..
+ * flow.c (life_analysis_1): No longer delete CLOBBER insns after
+ reload. Handled in reload itself.
+
Tue Oct 27 23:32:34 1998 Bernd Schmidt <crux@pool.informatik.rwth-aachen.de>
* reload.h (struct insn_chain): Add need_operand_change element.
diff --git a/gcc/final.c b/gcc/final.c
index 5b7874e..4c19c84 100644
--- a/gcc/final.c
+++ b/gcc/final.c
@@ -2844,23 +2844,7 @@ final_scan_insn (insn, file, optimize, prescan, nopeepholes)
insn_code_number = recog_memoized (insn);
insn_extract (insn);
- for (i = 0; i < insn_n_operands[insn_code_number]; i++)
- {
- if (GET_CODE (recog_operand[i]) == SUBREG)
- recog_operand[i] = alter_subreg (recog_operand[i]);
- else if (GET_CODE (recog_operand[i]) == PLUS
- || GET_CODE (recog_operand[i]) == MULT)
- recog_operand[i] = walk_alter_subreg (recog_operand[i]);
- }
-
- for (i = 0; i < insn_n_dups[insn_code_number]; i++)
- {
- if (GET_CODE (*recog_dup_loc[i]) == SUBREG)
- *recog_dup_loc[i] = alter_subreg (*recog_dup_loc[i]);
- else if (GET_CODE (*recog_dup_loc[i]) == PLUS
- || GET_CODE (*recog_dup_loc[i]) == MULT)
- *recog_dup_loc[i] = walk_alter_subreg (*recog_dup_loc[i]);
- }
+ cleanup_subreg_operands (insn);
#ifdef REGISTER_CONSTRAINTS
if (! constrain_operands (insn_code_number, 1))
@@ -3039,6 +3023,49 @@ output_source_line (file, insn)
}
}
+
+/* For each operand in INSN, simplify (subreg (reg)) so that it refers
+ directly to the desired hard register. */
+void
+cleanup_subreg_operands (insn)
+ rtx insn;
+{
+ int insn_code_number, i;
+
+ /* Ignore things we can not handle. */
+ if (GET_RTX_CLASS (GET_CODE (insn)) != 'i'
+ || GET_CODE (PATTERN (insn)) == USE
+ || GET_CODE (PATTERN (insn)) == ADDR_VEC
+ || GET_CODE (PATTERN (insn)) == ADDR_DIFF_VEC
+ || asm_noperands (PATTERN (insn)) >= 0)
+ return;
+
+ /* Try to recognize the instruction.
+ If successful, verify that the operands satisfy the
+ constraints for the instruction. Crash if they don't,
+ since `reload' should have changed them so that they do. */
+
+ insn_code_number = recog_memoized (insn);
+ insn_extract (insn);
+ for (i = 0; i < insn_n_operands[insn_code_number]; i++)
+ {
+ if (GET_CODE (recog_operand[i]) == SUBREG)
+ recog_operand[i] = alter_subreg (recog_operand[i]);
+ else if (GET_CODE (recog_operand[i]) == PLUS
+ || GET_CODE (recog_operand[i]) == MULT)
+ recog_operand[i] = walk_alter_subreg (recog_operand[i]);
+ }
+
+ for (i = 0; i < insn_n_dups[insn_code_number]; i++)
+ {
+ if (GET_CODE (*recog_dup_loc[i]) == SUBREG)
+ *recog_dup_loc[i] = alter_subreg (*recog_dup_loc[i]);
+ else if (GET_CODE (*recog_dup_loc[i]) == PLUS
+ || GET_CODE (*recog_dup_loc[i]) == MULT)
+ *recog_dup_loc[i] = walk_alter_subreg (*recog_dup_loc[i]);
+ }
+}
+
/* If X is a SUBREG, replace it with a REG or a MEM,
based on the thing it is a subreg of. */
@@ -3072,6 +3099,9 @@ alter_subreg (x)
#else
REGNO (x) = REGNO (y) + SUBREG_WORD (x);
#endif
+ /* This field has a different meaning for REGs and SUBREGs. Make sure
+ to clear it! */
+ x->used = 0;
}
else if (GET_CODE (y) == MEM)
{
diff --git a/gcc/flow.c b/gcc/flow.c
index 3fecc85..51af041 100644
--- a/gcc/flow.c
+++ b/gcc/flow.c
@@ -1358,23 +1358,6 @@ life_analysis_1 (f, nregs)
if (reload_completed)
bcopy (regs_ever_live, save_regs_ever_live, (sizeof (regs_ever_live)));
- /* Also remove all CLOBBER insns after reload. They can cause us to think
- a value is dead when it really is not dead. */
- if (reload_completed)
- {
- rtx insn;
-
- for (insn = f; insn; insn = NEXT_INSN (insn))
- {
- if (GET_CODE (insn) == INSN
- && GET_CODE (PATTERN (insn)) == CLOBBER)
- {
- PUT_CODE (insn, NOTE);
- NOTE_LINE_NUMBER (insn) = NOTE_INSN_DELETED;
- NOTE_SOURCE_FILE (insn) = 0;
- }
- }
- }
bzero (regs_ever_live, sizeof regs_ever_live);
/* Allocate and zero out many data structures
diff --git a/gcc/reload.h b/gcc/reload.h
index 5606a4e..968d312 100644
--- a/gcc/reload.h
+++ b/gcc/reload.h
@@ -339,3 +339,6 @@ extern void setup_save_areas PROTO((void));
/* Find the places where hard regs are live across calls and save them. */
extern void save_call_clobbered_regs PROTO((void));
+
+/* Replace (subreg (reg)) with the appropriate (reg) for any operands. */
+extern void cleanup_subreg_operands PROTO ((rtx));
diff --git a/gcc/reload1.c b/gcc/reload1.c
index ae0eb77..7e702d3 100644
--- a/gcc/reload1.c
+++ b/gcc/reload1.c
@@ -1037,16 +1037,17 @@ reload (first, global, dumpfile)
}
/* Make a pass over all the insns and delete all USEs which we inserted
- only to tag a REG_EQUAL note on them. Also remove all REG_DEAD and
- REG_UNUSED notes. */
+ only to tag a REG_EQUAL note on them. Remove all REG_DEAD and REG_UNUSED
+ notes. Delete all CLOBBER insns and simplify (subreg (reg)) operands. */
for (insn = first; insn; insn = NEXT_INSN (insn))
if (GET_RTX_CLASS (GET_CODE (insn)) == 'i')
{
rtx *pnote;
- if (GET_CODE (PATTERN (insn)) == USE
- && find_reg_note (insn, REG_EQUAL, NULL_RTX))
+ if ((GET_CODE (PATTERN (insn)) == USE
+ && find_reg_note (insn, REG_EQUAL, NULL_RTX))
+ || GET_CODE (PATTERN (insn)) == CLOBBER)
{
PUT_CODE (insn, NOTE);
NOTE_SOURCE_FILE (insn) = 0;
@@ -1063,6 +1064,9 @@ reload (first, global, dumpfile)
else
pnote = &XEXP (*pnote, 1);
}
+
+ /* And simplify (subreg (reg)) if it appears as an operand. */
+ cleanup_subreg_operands (insn);
}
/* If we are doing stack checking, give a warning if this function's