aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJan Hubicka <jh@suse.cz>2002-03-06 18:16:22 +0100
committerJan Hubicka <hubicka@gcc.gnu.org>2002-03-06 17:16:22 +0000
commitfe477d8b5bc4d62f7592f5468a3c070ec47c0c95 (patch)
treea698c1b9825f69cafe0e368fa6287c770f99ca9b
parent2041cde4558a50795877fe1fb7f8e49c4c9a94c5 (diff)
downloadgcc-fe477d8b5bc4d62f7592f5468a3c070ec47c0c95.zip
gcc-fe477d8b5bc4d62f7592f5468a3c070ec47c0c95.tar.gz
gcc-fe477d8b5bc4d62f7592f5468a3c070ec47c0c95.tar.bz2
cfgcleanup.c (mentions_nonequal_regs): New function.
* cfgcleanup.c (mentions_nonequal_regs): New function. (thread_jump): Use it. * toplev.c (rest_of_compilation): Run jump threading after liveness. From-SVN: r50361
-rw-r--r--gcc/ChangeLog7
-rw-r--r--gcc/cfgcleanup.c32
-rw-r--r--gcc/toplev.c3
3 files changed, 41 insertions, 1 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 30c3e07..3b89fa4 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,10 @@
+Wed Mar 6 18:14:43 CET 2002 Jan Hubicka <jh@suse.cz>
+
+ * cfgcleanup.c (mentions_nonequal_regs): New function.
+ (thread_jump): Use it.
+ * toplev.c (rest_of_compilation): Run jump threading after
+ liveness.
+
2002-03-06 Jakub Jelinek <jakub@redhat.com>
* ssa-ccp.c (ssa_ccp_substitute_constants): Backout 2002-03-05
diff --git a/gcc/cfgcleanup.c b/gcc/cfgcleanup.c
index a4dccbe..bce4153 100644
--- a/gcc/cfgcleanup.c
+++ b/gcc/cfgcleanup.c
@@ -89,6 +89,7 @@ static edge thread_jump PARAMS ((int, edge, basic_block));
static bool mark_effect PARAMS ((rtx, bitmap));
static void notice_new_block PARAMS ((basic_block));
static void update_forwarder_flag PARAMS ((basic_block));
+static int mentions_nonequal_regs PARAMS ((rtx *, void *));
/* Set flags for newly created block. */
@@ -235,6 +236,32 @@ mark_effect (exp, nonequal)
return false;
}
}
+
+/* Return nonzero if X is an register set in regset DATA.
+ Called via for_each_rtx. */
+static int
+mentions_nonequal_regs (x, data)
+ rtx *x;
+ void *data;
+{
+ regset nonequal = (regset) data;
+ if (REG_P (*x))
+ {
+ int regno;
+
+ regno = REGNO (*x);
+ if (REGNO_REG_SET_P (nonequal, regno))
+ return 1;
+ if (regno < FIRST_PSEUDO_REGISTER)
+ {
+ int n = HARD_REGNO_NREGS (regno, GET_MODE (*x));
+ while (--n > 0)
+ if (REGNO_REG_SET_P (nonequal, regno + n))
+ return 1;
+ }
+ }
+ return 0;
+}
/* Attempt to prove that the basic block B will have no side effects and
allways continues in the same edge if reached via E. Return the edge
if exist, NULL otherwise. */
@@ -338,6 +365,11 @@ thread_jump (mode, e, b)
if (failed)
goto failed_exit;
+ /* cond2 must not mention any register that is not equal to the
+ former block. */
+ if (for_each_rtx (&cond2, mentions_nonequal_regs, nonequal))
+ goto failed_exit;
+
/* In case liveness information is available, we need to prove equivalence
only of the live values. */
if (mode & CLEANUP_UPDATE_LIFE)
diff --git a/gcc/toplev.c b/gcc/toplev.c
index f97db60..5cd2e44 100644
--- a/gcc/toplev.c
+++ b/gcc/toplev.c
@@ -3019,7 +3019,8 @@ rest_of_compilation (decl)
#endif
life_analysis (insns, rtl_dump_file, PROP_FINAL);
if (optimize)
- cleanup_cfg (CLEANUP_EXPENSIVE | CLEANUP_UPDATE_LIFE);
+ cleanup_cfg ((optimize ? CLEANUP_EXPENSIVE : 0)
+ | (flag_thread_jumps ? CLEANUP_THREADING : 0));
timevar_pop (TV_FLOW);
no_new_pseudos = 1;