summaryrefslogtreecommitdiff
path: root/gcc/cse.c
diff options
context:
space:
mode:
authorAndreas Krebbel <krebbel1@de.ibm.com>2004-11-16 11:38:11 +0000
committerUlrich Weigand <uweigand@gcc.gnu.org>2004-11-16 11:38:11 +0000
commitfc188d37b37726535ea6fd8c546987e691fd2ae1 (patch)
treeddaa587ca7451dcfa811939156a099ec3f17328a /gcc/cse.c
parentbe06f47bc163661477f50bf46e103314f1c24498 (diff)
downloadgcc-fc188d37b37726535ea6fd8c546987e691fd2ae1.tar.gz
cse.c (struct change_cc_mode_args): New structure.
2004-11-16 Andreas Krebbel <krebbel1@de.ibm.com> * gcc/cse.c (struct change_cc_mode_args): New structure. (cse_change_cc_mode_insn): New function. (cse_change_cc_mode): Use validate_change to perfom changes. (cse_change_cc_mode_insns, cse_condition_code_reg): Call cse_change_cc_mode_insn. From-SVN: r90728
Diffstat (limited to 'gcc/cse.c')
-rw-r--r--gcc/cse.c56
1 files changed, 44 insertions, 12 deletions
diff --git a/gcc/cse.c b/gcc/cse.c
index 914f19682ba..67bb822909f 100644
--- a/gcc/cse.c
+++ b/gcc/cse.c
@@ -263,6 +263,14 @@ struct qty_table_elem
/* The table of all qtys, indexed by qty number. */
static struct qty_table_elem *qty_table;
+/* Structure used to pass arguments via for_each_rtx to function
+ cse_change_cc_mode. */
+struct change_cc_mode_args
+{
+ rtx insn;
+ rtx newreg;
+};
+
#ifdef HAVE_cc0
/* For machines that have a CC0, we do not record its value in the hash
table since its use is guaranteed to be the insn immediately following
@@ -653,6 +661,7 @@ static bool insn_live_p (rtx, int *);
static bool set_live_p (rtx, rtx, int *);
static bool dead_libcall_p (rtx, int *);
static int cse_change_cc_mode (rtx *, void *);
+static void cse_change_cc_mode_insn (rtx, rtx);
static void cse_change_cc_mode_insns (rtx, rtx, rtx);
static enum machine_mode cse_cc_succs (basic_block, rtx, rtx, bool);
@@ -7303,20 +7312,47 @@ delete_trivially_dead_insns (rtx insns, int nreg)
static int
cse_change_cc_mode (rtx *loc, void *data)
{
- rtx newreg = (rtx) data;
+ struct change_cc_mode_args* args = (struct change_cc_mode_args*)data;
if (*loc
&& REG_P (*loc)
- && REGNO (*loc) == REGNO (newreg)
- && GET_MODE (*loc) != GET_MODE (newreg))
+ && REGNO (*loc) == REGNO (args->newreg)
+ && GET_MODE (*loc) != GET_MODE (args->newreg))
{
- *loc = newreg;
+ validate_change (args->insn, loc, args->newreg, 1);
+
return -1;
}
return 0;
}
/* Change the mode of any reference to the register REGNO (NEWREG) to
+ GET_MODE (NEWREG) in INSN. */
+
+static void
+cse_change_cc_mode_insn (rtx insn, rtx newreg)
+{
+ struct change_cc_mode_args args;
+ int success;
+
+ if (!INSN_P (insn))
+ return;
+
+ args.insn = insn;
+ args.newreg = newreg;
+
+ for_each_rtx (&PATTERN (insn), cse_change_cc_mode, &args);
+ for_each_rtx (&REG_NOTES (insn), cse_change_cc_mode, &args);
+
+ /* If the following assertion was triggered, there is most probably
+ something wrong with the cc_modes_compatible back end function.
+ CC modes only can be considered compatible if the insn - with the mode
+ replaced by any of the compatible modes - can still be recognized. */
+ success = apply_change_group ();
+ gcc_assert (success);
+}
+
+/* Change the mode of any reference to the register REGNO (NEWREG) to
GET_MODE (NEWREG), starting at START. Stop before END. Stop at
any instruction which modifies NEWREG. */
@@ -7333,8 +7369,7 @@ cse_change_cc_mode_insns (rtx start, rtx end, rtx newreg)
if (reg_set_p (newreg, insn))
return;
- for_each_rtx (&PATTERN (insn), cse_change_cc_mode, newreg);
- for_each_rtx (&REG_NOTES (insn), cse_change_cc_mode, newreg);
+ cse_change_cc_mode_insn (insn, newreg);
}
}
@@ -7443,6 +7478,8 @@ cse_cc_succs (basic_block bb, rtx cc_reg, rtx cc_src, bool can_change_mode)
{
gcc_assert (can_change_mode);
mode = comp_mode;
+
+ /* The modified insn will be re-recognized later. */
PUT_MODE (cc_src, mode);
}
}
@@ -7622,12 +7659,7 @@ cse_condition_code_reg (void)
{
rtx newreg = gen_rtx_REG (mode, REGNO (cc_reg));
- /* Change the mode of CC_REG in CC_SRC_INSN to
- GET_MODE (NEWREG). */
- for_each_rtx (&PATTERN (cc_src_insn), cse_change_cc_mode,
- newreg);
- for_each_rtx (&REG_NOTES (cc_src_insn), cse_change_cc_mode,
- newreg);
+ cse_change_cc_mode_insn (cc_src_insn, newreg);
/* Do the same in the following insns that use the
current value of CC_REG within BB. */