aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorRichard Henderson <rth@cygnus.com>2000-04-07 02:22:10 -0700
committerRichard Henderson <rth@gcc.gnu.org>2000-04-07 02:22:10 -0700
commitdc108b7a752864a4d586d5c30325030b42d6c395 (patch)
treee9ce53be6b335cccddd6f48585704963508842b5 /gcc
parent1e143002cbb4f70c6cfe87bd4cab1bd3aa539184 (diff)
downloadgcc-dc108b7a752864a4d586d5c30325030b42d6c395.zip
gcc-dc108b7a752864a4d586d5c30325030b42d6c395.tar.gz
gcc-dc108b7a752864a4d586d5c30325030b42d6c395.tar.bz2
basic-block.h (merge_blocks_nomove): Declare.
* basic-block.h (merge_blocks_nomove): Declare. (tidy_fallthru_edge): Declare. * flow.c (merge_blocks_nomove): Document as merging into previous blocks. Remove cruft from between blocks; remove all edges out of A. (tidy_fallthru_edge): Export. From-SVN: r32994
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog8
-rw-r--r--gcc/basic-block.h4
-rw-r--r--gcc/flow.c196
3 files changed, 115 insertions, 93 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 5b69106..04b2004 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,11 @@
+2000-04-07 Richard Henderson <rth@cygnus.com>
+
+ * basic-block.h (merge_blocks_nomove): Declare.
+ (tidy_fallthru_edge): Declare.
+ * flow.c (merge_blocks_nomove): Document as merging into previous
+ blocks. Remove cruft from between blocks; remove all edges out of A.
+ (tidy_fallthru_edge): Export.
+
2000-04-06 Alex Samuel <samuel@codesourcery.com>
* ssa.c (compute_conservative_reg_partition): Declare with
diff --git a/gcc/basic-block.h b/gcc/basic-block.h
index 5fa6226..e59c16e 100644
--- a/gcc/basic-block.h
+++ b/gcc/basic-block.h
@@ -231,7 +231,9 @@ extern void make_edge PARAMS ((sbitmap *, basic_block,
basic_block, int));
extern void remove_edge PARAMS ((edge));
extern void create_basic_block PARAMS ((int, rtx, rtx, rtx));
-
+extern void merge_blocks_nomove PARAMS ((basic_block, basic_block));
+extern void tidy_fallthru_edge PARAMS ((edge, basic_block,
+ basic_block));
/* Structure to hold information for each natural loop. */
struct loop
diff --git a/gcc/flow.c b/gcc/flow.c
index dc50d17..4dc9624 100644
--- a/gcc/flow.c
+++ b/gcc/flow.c
@@ -302,10 +302,8 @@ static int merge_blocks_move_predecessor_nojumps PARAMS ((basic_block,
basic_block));
static int merge_blocks_move_successor_nojumps PARAMS ((basic_block,
basic_block));
-static void merge_blocks_nomove PARAMS ((basic_block, basic_block));
static int merge_blocks PARAMS ((edge,basic_block,basic_block));
static void try_merge_blocks PARAMS ((void));
-static void tidy_fallthru_edge PARAMS ((edge,basic_block,basic_block));
static void tidy_fallthru_edges PARAMS ((void));
static int verify_wide_reg_1 PARAMS ((rtx *, void *));
static void verify_wide_reg PARAMS ((int, rtx, rtx));
@@ -2032,6 +2030,109 @@ can_delete_label_p (label)
return 1;
}
+/* Blocks A and B are to be merged into a single block A. The insns
+ are already contiguous, hence `nomove'. */
+
+void
+merge_blocks_nomove (a, b)
+ basic_block a, b;
+{
+ edge e;
+ rtx b_head, b_end, a_end;
+ rtx del_first = NULL_RTX, del_last = NULL_RTX;
+ int b_empty = 0;
+
+ /* If there was a CODE_LABEL beginning B, delete it. */
+ b_head = b->head;
+ b_end = b->end;
+ if (GET_CODE (b_head) == CODE_LABEL)
+ {
+ /* Detect basic blocks with nothing but a label. This can happen
+ in particular at the end of a function. */
+ if (b_head == b_end)
+ b_empty = 1;
+ del_first = del_last = b_head;
+ b_head = NEXT_INSN (b_head);
+ }
+
+ /* Delete the basic block note. */
+ if (GET_CODE (b_head) == NOTE
+ && NOTE_LINE_NUMBER (b_head) == NOTE_INSN_BASIC_BLOCK)
+ {
+ if (b_head == b_end)
+ b_empty = 1;
+ if (! del_last)
+ del_first = b_head;
+ del_last = b_head;
+ b_head = NEXT_INSN (b_head);
+ }
+
+ /* If there was a jump out of A, delete it. */
+ a_end = a->end;
+ if (GET_CODE (a_end) == JUMP_INSN)
+ {
+ rtx prev;
+
+ prev = prev_nonnote_insn (a_end);
+ if (!prev)
+ prev = a->head;
+
+ del_first = a_end;
+
+#ifdef HAVE_cc0
+ /* If this was a conditional jump, we need to also delete
+ the insn that set cc0. */
+ if (prev && sets_cc0_p (prev))
+ {
+ rtx tmp = prev;
+ prev = prev_nonnote_insn (prev);
+ if (!prev)
+ prev = a->head;
+ del_first = tmp;
+ }
+#endif
+
+ a_end = prev;
+ }
+
+ /* Delete everything marked above as well as crap that might be
+ hanging out between the two blocks. */
+ flow_delete_insn_chain (del_first, del_last);
+
+ /* Normally there should only be one successor of A and that is B, but
+ partway though the merge of blocks for conditional_execution we'll
+ be merging a TEST block with THEN and ELSE successors. Free the
+ whole lot of them and hope the caller knows what they're doing. */
+ while (a->succ)
+ remove_edge (a->succ);
+
+ /* Adjust the edges out of B for the new owner. */
+ for (e = b->succ; e ; e = e->succ_next)
+ e->src = a;
+ a->succ = b->succ;
+
+ /* B hasn't quite yet ceased to exist. Attempt to prevent mishap. */
+ b->pred = b->succ = NULL;
+
+ /* Reassociate the insns of B with A. */
+ if (!b_empty)
+ {
+ if (basic_block_for_insn)
+ {
+ BLOCK_FOR_INSN (b_head) = a;
+ while (b_head != b_end)
+ {
+ b_head = NEXT_INSN (b_head);
+ BLOCK_FOR_INSN (b_head) = a;
+ }
+ }
+ a_end = b_end;
+ }
+ a->end = a_end;
+
+ expunge_block (b);
+}
+
/* Blocks A and B are to be merged into a single block. A has no incoming
fallthru edge, so it can be moved before B without adding or modifying
any jumps (aside from the jump from A to B). */
@@ -2145,95 +2246,6 @@ merge_blocks_move_successor_nojumps (a, b)
return 1;
}
-/* Blocks A and B are to be merged into a single block. The insns
- are already contiguous, hence `nomove'. */
-
-static void
-merge_blocks_nomove (a, b)
- basic_block a, b;
-{
- edge e;
- rtx b_head, b_end, a_end;
- int b_empty = 0;
-
- /* If there was a CODE_LABEL beginning B, delete it. */
- b_head = b->head;
- b_end = b->end;
- if (GET_CODE (b_head) == CODE_LABEL)
- {
- /* Detect basic blocks with nothing but a label. This can happen
- in particular at the end of a function. */
- if (b_head == b_end)
- b_empty = 1;
- b_head = flow_delete_insn (b_head);
- }
-
- /* Delete the basic block note. */
- if (GET_CODE (b_head) == NOTE
- && NOTE_LINE_NUMBER (b_head) == NOTE_INSN_BASIC_BLOCK)
- {
- if (b_head == b_end)
- b_empty = 1;
- b_head = flow_delete_insn (b_head);
- }
-
- /* If there was a jump out of A, delete it. */
- a_end = a->end;
- if (GET_CODE (a_end) == JUMP_INSN)
- {
- rtx prev;
-
- prev = prev_nonnote_insn (a_end);
- if (!prev)
- prev = a->head;
-
-#ifdef HAVE_cc0
- /* If this was a conditional jump, we need to also delete
- the insn that set cc0. */
-
- if (prev && sets_cc0_p (prev))
- {
- rtx tmp = prev;
- prev = prev_nonnote_insn (prev);
- if (!prev)
- prev = a->head;
- flow_delete_insn (tmp);
- }
-#endif
-
- /* Note that a->head != a->end, since we should have at least a
- bb note plus the jump, so prev != insn. */
- flow_delete_insn (a_end);
- a_end = prev;
- }
-
- /* By definition, there should only be one successor of A, and that is
- B. Free that edge struct. */
- n_edges--;
- free (a->succ);
-
- /* Adjust the edges out of B for the new owner. */
- for (e = b->succ; e ; e = e->succ_next)
- e->src = a;
- a->succ = b->succ;
-
- /* Reassociate the insns of B with A. */
- if (!b_empty)
- {
- BLOCK_FOR_INSN (b_head) = a;
- while (b_head != b_end)
- {
- b_head = NEXT_INSN (b_head);
- BLOCK_FOR_INSN (b_head) = a;
- }
- a_end = b_head;
- }
- a->end = a_end;
-
- /* Compact the basic block array. */
- expunge_block (b);
-}
-
/* Attempt to merge basic blocks that are potentially non-adjacent.
Return true iff the attempt succeeded. */
@@ -2366,7 +2378,7 @@ try_merge_blocks ()
/* The given edge should potentially be a fallthru edge. If that is in
fact true, delete the jump and barriers that are in the way. */
-static void
+void
tidy_fallthru_edge (e, b, c)
edge e;
basic_block b, c;