summaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authoramylaar <amylaar@138bc75d-0d04-0410-961f-82ee72b054a4>2005-03-02 22:02:32 +0000
committeramylaar <amylaar@138bc75d-0d04-0410-961f-82ee72b054a4>2005-03-02 22:02:32 +0000
commit82880dfd5cfbedf5fd319d079e242d61b95fc57f (patch)
tree2e930d7443fe4dbacbd3f498df67cff02962fe05 /gcc
parentf664da299a9f3b7eed0b9c9659419126aa836b97 (diff)
downloadgcc-82880dfd5cfbedf5fd319d079e242d61b95fc57f.tar.gz
* recog.c (verify_changes, confirm_change_group): New functions,
broken out of apply_change_group. (apply_change_group): Use them. * recog.h (verify_change, confirm_change_group): Declare. * rtl.h (redirect_jump_2): Declare. * jump.c (redirect_exp, invert_exp): Delete. (invert_exp_1): Take second parameter. Return value. Changed caller. (redirect_jump_2): New function, broken out of redirect_jump. (redirect_jump): Use redirect_jump_1 and redirect_jump_2. (invert_jump): Use invert_jump_1 and redirect_jump_2. * ifcvt.c (dead_or_predicable): Use redirect_jump_2. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@95813 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog14
-rw-r--r--gcc/ifcvt.c8
-rw-r--r--gcc/jump.c135
-rw-r--r--gcc/recog.c46
-rw-r--r--gcc/recog.h2
-rw-r--r--gcc/rtl.h1
6 files changed, 93 insertions, 113 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index b545f960e88..8e4d6dc15a6 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,17 @@
+2005-03-02 J"orn Rennecke <joern.rennecke@st.com>
+
+ * recog.c (verify_changes, confirm_change_group): New functions,
+ broken out of apply_change_group.
+ (apply_change_group): Use them.
+ * recog.h (verify_change, confirm_change_group): Declare.
+ * rtl.h (redirect_jump_2): Declare.
+ * jump.c (redirect_exp, invert_exp): Delete.
+ (invert_exp_1): Take second parameter. Return value. Changed caller.
+ (redirect_jump_2): New function, broken out of redirect_jump.
+ (redirect_jump): Use redirect_jump_1 and redirect_jump_2.
+ (invert_jump): Use invert_jump_1 and redirect_jump_2.
+ * ifcvt.c (dead_or_predicable): Use redirect_jump_2.
+
2005-03-02 Geoffrey Keating <geoffk@apple.com>
* varasm.c (named_section): Use xstrdup rather than doing it by
diff --git a/gcc/ifcvt.c b/gcc/ifcvt.c
index eb597d13f1f..996e8cd4364 100644
--- a/gcc/ifcvt.c
+++ b/gcc/ifcvt.c
@@ -3258,13 +3258,7 @@ dead_or_predicable (basic_block test_bb, basic_block merge_bb,
if (other_bb != new_dest)
{
- if (old_dest)
- LABEL_NUSES (old_dest) -= 1;
- if (new_label)
- LABEL_NUSES (new_label) += 1;
- JUMP_LABEL (jump) = new_label;
- if (reversep)
- invert_br_probabilities (jump);
+ redirect_jump_2 (jump, old_dest, new_label, -1, reversep);
redirect_edge_succ (BRANCH_EDGE (test_bb), new_dest);
if (reversep)
diff --git a/gcc/jump.c b/gcc/jump.c
index 85c1f6b2d75..4af8b5a5a10 100644
--- a/gcc/jump.c
+++ b/gcc/jump.c
@@ -67,9 +67,7 @@ static void init_label_info (rtx);
static void mark_all_labels (rtx);
static void delete_computation (rtx);
static void redirect_exp_1 (rtx *, rtx, rtx, rtx);
-static int redirect_exp (rtx, rtx, rtx);
-static void invert_exp_1 (rtx);
-static int invert_exp (rtx);
+static int invert_exp_1 (rtx, rtx);
static int returnjump_p_1 (rtx *, void *);
static void delete_prior_computation (rtx, rtx);
@@ -1570,25 +1568,6 @@ redirect_exp_1 (rtx *loc, rtx olabel, rtx nlabel, rtx insn)
}
}
-/* Similar, but apply the change group and report success or failure. */
-
-static int
-redirect_exp (rtx olabel, rtx nlabel, rtx insn)
-{
- rtx *loc;
-
- if (GET_CODE (PATTERN (insn)) == PARALLEL)
- loc = &XVECEXP (PATTERN (insn), 0, 0);
- else
- loc = &PATTERN (insn);
-
- redirect_exp_1 (loc, olabel, nlabel, insn);
- if (num_validated_changes () == 0)
- return 0;
-
- return apply_change_group ();
-}
-
/* Make JUMP go to NLABEL instead of where it jumps now. Accrue
the modifications into the change group. Return false if we did
not see how to do that. */
@@ -1622,14 +1601,28 @@ int
redirect_jump (rtx jump, rtx nlabel, int delete_unused)
{
rtx olabel = JUMP_LABEL (jump);
- rtx note;
if (nlabel == olabel)
return 1;
- if (! redirect_exp (olabel, nlabel, jump))
+ if (! redirect_jump_1 (jump, nlabel) || ! apply_change_group ())
return 0;
+ redirect_jump_2 (jump, olabel, nlabel, delete_unused, 0);
+ return 1;
+}
+
+/* Fix up JUMP_LABEL and label ref counts after OLABEL has been replaced with
+ NLABEL in JUMP. If DELETE_UNUSED is non-negative, copy a
+ NOTE_INSN_FUNCTION_END found after OLABEL to the place after NLABEL.
+ If DELETE_UNUSED is positive, delete related insn to OLABEL if its ref
+ count has dropped to zero. */
+void
+redirect_jump_2 (rtx jump, rtx olabel, rtx nlabel, int delete_unused,
+ int invert)
+{
+ rtx note;
+
JUMP_LABEL (jump) = nlabel;
if (nlabel)
++LABEL_NUSES (nlabel);
@@ -1637,24 +1630,13 @@ redirect_jump (rtx jump, rtx nlabel, int delete_unused)
/* Update labels in any REG_EQUAL note. */
if ((note = find_reg_note (jump, REG_EQUAL, NULL_RTX)) != NULL_RTX)
{
- if (nlabel && olabel)
+ if (!nlabel || (invert && !invert_exp_1 (XEXP (note, 0), jump)))
+ remove_note (jump, note);
+ else
{
- rtx dest = XEXP (note, 0);
-
- if (GET_CODE (dest) == IF_THEN_ELSE)
- {
- if (GET_CODE (XEXP (dest, 1)) == LABEL_REF
- && XEXP (XEXP (dest, 1), 0) == olabel)
- XEXP (XEXP (dest, 1), 0) = nlabel;
- if (GET_CODE (XEXP (dest, 2)) == LABEL_REF
- && XEXP (XEXP (dest, 2), 0) == olabel)
- XEXP (XEXP (dest, 2), 0) = nlabel;
- }
- else
- remove_note (jump, note);
+ redirect_exp_1 (&XEXP (note, 0), olabel, nlabel, jump);
+ confirm_change_group ();
}
- else
- remove_note (jump, note);
}
/* If we're eliding the jump over exception cleanups at the end of a
@@ -1662,31 +1644,24 @@ redirect_jump (rtx jump, rtx nlabel, int delete_unused)
if (olabel && nlabel
&& NEXT_INSN (olabel)
&& NOTE_P (NEXT_INSN (olabel))
- && NOTE_LINE_NUMBER (NEXT_INSN (olabel)) == NOTE_INSN_FUNCTION_END)
+ && NOTE_LINE_NUMBER (NEXT_INSN (olabel)) == NOTE_INSN_FUNCTION_END
+ && delete_unused >= 0)
emit_note_after (NOTE_INSN_FUNCTION_END, nlabel);
- if (olabel && --LABEL_NUSES (olabel) == 0 && delete_unused
+ if (olabel && --LABEL_NUSES (olabel) == 0 && delete_unused > 0
/* Undefined labels will remain outside the insn stream. */
&& INSN_UID (olabel))
delete_related_insns (olabel);
-
- return 1;
+ if (invert)
+ invert_br_probabilities (jump);
}
-/* Invert the jump condition of rtx X contained in jump insn, INSN.
- Accrue the modifications into the change group. */
-
-static void
-invert_exp_1 (rtx insn)
+/* Invert the jump condition X contained in jump insn INSN. Accrue the
+ modifications into the change group. Return nonzero for success. */
+static int
+invert_exp_1 (rtx x, rtx insn)
{
- RTX_CODE code;
- rtx x = pc_set (insn);
-
- if (!x)
- abort ();
- x = SET_SRC (x);
-
- code = GET_CODE (x);
+ RTX_CODE code = GET_CODE (x);
if (code == IF_THEN_ELSE)
{
@@ -1708,30 +1683,16 @@ invert_exp_1 (rtx insn)
GET_MODE (comp), XEXP (comp, 0),
XEXP (comp, 1)),
1);
- return;
+ return 1;
}
tem = XEXP (x, 1);
validate_change (insn, &XEXP (x, 1), XEXP (x, 2), 1);
validate_change (insn, &XEXP (x, 2), tem, 1);
+ return 1;
}
else
- abort ();
-}
-
-/* Invert the jump condition of conditional jump insn, INSN.
-
- Return 1 if we can do so, 0 if we cannot find a way to do so that
- matches a pattern. */
-
-static int
-invert_exp (rtx insn)
-{
- invert_exp_1 (insn);
- if (num_validated_changes () == 0)
return 0;
-
- return apply_change_group ();
}
/* Invert the condition of the jump JUMP, and make it jump to label
@@ -1742,10 +1703,12 @@ invert_exp (rtx insn)
int
invert_jump_1 (rtx jump, rtx nlabel)
{
+ rtx x = pc_set (jump);
int ochanges;
ochanges = num_validated_changes ();
- invert_exp_1 (jump);
+ if (!x || !invert_exp_1 (SET_SRC (x), jump))
+ abort ();
if (num_validated_changes () == ochanges)
return 0;
@@ -1758,30 +1721,14 @@ invert_jump_1 (rtx jump, rtx nlabel)
int
invert_jump (rtx jump, rtx nlabel, int delete_unused)
{
- /* We have to either invert the condition and change the label or
- do neither. Either operation could fail. We first try to invert
- the jump. If that succeeds, we try changing the label. If that fails,
- we invert the jump back to what it was. */
-
- if (! invert_exp (jump))
- return 0;
+ rtx olabel = JUMP_LABEL (jump);
- if (redirect_jump (jump, nlabel, delete_unused))
+ if (invert_jump_1 (jump, nlabel) && apply_change_group ())
{
- /* Remove REG_EQUAL note if we have one. */
- rtx note = find_reg_note (jump, REG_EQUAL, NULL_RTX);
- if (note)
- remove_note (jump, note);
-
- invert_br_probabilities (jump);
-
+ redirect_jump_2 (jump, olabel, nlabel, delete_unused, 1);
return 1;
}
-
- if (! invert_exp (jump))
- /* This should just be putting it back the way it was. */
- abort ();
-
+ cancel_changes (0);
return 0;
}
diff --git a/gcc/recog.c b/gcc/recog.c
index 1c0e27e27b3..224df47cf8c 100644
--- a/gcc/recog.c
+++ b/gcc/recog.c
@@ -294,11 +294,11 @@ num_changes_pending (void)
return num_changes;
}
-/* Apply a group of changes previously issued with `validate_change'.
+/* Tentatively apply the changes numbered NUM and up.
Return 1 if all changes are valid, zero otherwise. */
int
-apply_change_group (void)
+verify_changes (int num)
{
int i;
rtx last_validated = NULL_RTX;
@@ -312,7 +312,7 @@ apply_change_group (void)
we also require that the operands meet the constraints for
the insn. */
- for (i = 0; i < num_changes; i++)
+ for (i = num; i < num_changes; i++)
{
rtx object = changes[i].object;
@@ -376,17 +376,38 @@ apply_change_group (void)
last_validated = object;
}
- if (i == num_changes)
- {
- basic_block bb;
+ return (i == num_changes);
+}
- for (i = 0; i < num_changes; i++)
- if (changes[i].object
- && INSN_P (changes[i].object)
- && (bb = BLOCK_FOR_INSN (changes[i].object)))
- bb->flags |= BB_DIRTY;
+/* A group of changes has previously been issued with validate_change and
+ verified with verify_changes. Update the BB_DIRTY flags of the affected
+ blocks, and clear num_changes. */
- num_changes = 0;
+void
+confirm_change_group (void)
+{
+ int i;
+ basic_block bb;
+
+ for (i = 0; i < num_changes; i++)
+ if (changes[i].object
+ && INSN_P (changes[i].object)
+ && (bb = BLOCK_FOR_INSN (changes[i].object)))
+ bb->flags |= BB_DIRTY;
+
+ num_changes = 0;
+}
+
+/* Apply a group of changes previously issued with `validate_change'.
+ If all changes are valid, call confirm_change_group and return 1,
+ otherwise, call cancel_changes and return 0. */
+
+int
+apply_change_group (void)
+{
+ if (verify_changes (0))
+ {
+ confirm_change_group ();
return 1;
}
else
@@ -396,6 +417,7 @@ apply_change_group (void)
}
}
+
/* Return the number of changes so far in the current group. */
int
diff --git a/gcc/recog.h b/gcc/recog.h
index 0c340cc35a0..d4ded6cccc0 100644
--- a/gcc/recog.h
+++ b/gcc/recog.h
@@ -75,6 +75,8 @@ extern int check_asm_operands (rtx);
extern int asm_operand_ok (rtx, const char *);
extern int validate_change (rtx, rtx *, rtx, int);
extern int insn_invalid_p (rtx);
+extern int verify_changes (int);
+extern void confirm_change_group (void);
extern int apply_change_group (void);
extern int num_validated_changes (void);
extern void cancel_changes (int);
diff --git a/gcc/rtl.h b/gcc/rtl.h
index 9042e03729f..1968c88d34f 100644
--- a/gcc/rtl.h
+++ b/gcc/rtl.h
@@ -1912,6 +1912,7 @@ extern int rtx_renumbered_equal_p (rtx, rtx);
extern int true_regnum (rtx);
extern unsigned int reg_or_subregno (rtx);
extern int redirect_jump_1 (rtx, rtx);
+extern void redirect_jump_2 (rtx, rtx, rtx, int, int);
extern int redirect_jump (rtx, rtx, int);
extern void rebuild_jump_labels (rtx);
extern enum rtx_code reversed_comparison_code (rtx, rtx);