summaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorm.hayes <m.hayes@138bc75d-0d04-0410-961f-82ee72b054a4>2001-01-11 09:13:02 +0000
committerm.hayes <m.hayes@138bc75d-0d04-0410-961f-82ee72b054a4>2001-01-11 09:13:02 +0000
commit4cef0eda798ae8098f062d6aca234e98120c608c (patch)
tree26948d17a5ada6ec1335c582ada8ab1d0353f991 /gcc
parentb90ec5a5b5bd60620e7361ec3f5237ae76f18154 (diff)
downloadgcc-4cef0eda798ae8098f062d6aca234e98120c608c.tar.gz
* flow.c (flow_call_edges_add): New.
* basic_block.h (flow_call_edges_add): New. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@38899 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog5
-rw-r--r--gcc/basic-block.h1
-rw-r--r--gcc/flow.c69
3 files changed, 75 insertions, 0 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 7b0099a5a10..35f1fe0f090 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,8 @@
+2001-01-11 Michael Hayes <mhayes@redhat.com>
+
+ * flow.c (flow_call_edges_add): New.
+ * basic_block.h (flow_call_edges_add): New.
+
2001-01-11 J"orn Rennecke <amylaar@redhat.com>
* reload1.c (move2add_note_store): Update reg_set_luid even if
diff --git a/gcc/basic-block.h b/gcc/basic-block.h
index c48a54701b3..b0175464b3a 100644
--- a/gcc/basic-block.h
+++ b/gcc/basic-block.h
@@ -249,6 +249,7 @@ extern void commit_edge_insertions PARAMS ((void));
extern void remove_fake_edges PARAMS ((void));
extern void add_noreturn_fake_exit_edges PARAMS ((void));
extern void connect_infinite_loops_to_exit PARAMS ((void));
+extern int flow_call_edges_add PARAMS ((sbitmap));
extern rtx flow_delete_insn PARAMS ((rtx));
extern void flow_delete_insn_chain PARAMS ((rtx, rtx));
extern void make_edge PARAMS ((sbitmap *, basic_block,
diff --git a/gcc/flow.c b/gcc/flow.c
index faed23fdd0c..862d40f5214 100644
--- a/gcc/flow.c
+++ b/gcc/flow.c
@@ -2011,6 +2011,75 @@ commit_edge_insertions ()
bb = BASIC_BLOCK (i);
}
}
+
+/* Add fake edges to the function exit for any non constant calls in
+ the bitmap of blocks specified by BLOCKS or to the whole CFG if
+ BLOCKS is zero. Return the nuber of blocks that were split. */
+
+int
+flow_call_edges_add (blocks)
+ sbitmap blocks;
+{
+ int i;
+ int blocks_split = 0;
+ int bb_num = 0;
+ basic_block *bbs;
+
+ /* Map bb indicies into basic block pointers since split_block
+ will renumber the basic blocks. */
+
+ bbs = xmalloc (n_basic_blocks * sizeof (*bbs));
+
+ if (! blocks)
+ {
+ for (i = 0; i < n_basic_blocks; i++)
+ bbs[bb_num++] = BASIC_BLOCK (i);
+ }
+ else
+ {
+ EXECUTE_IF_SET_IN_SBITMAP (blocks, 0, i,
+ {
+ bbs[bb_num++] = BASIC_BLOCK (i);
+ });
+ }
+
+
+ /* Now add fake edges to the function exit for any non constant
+ calls since there is no way that we can determine if they will
+ return or not... */
+
+ for (i = 0; i < bb_num; i++)
+ {
+ basic_block bb = bbs[i];
+ rtx insn;
+ rtx prev_insn;
+
+ for (insn = bb->end; ; insn = prev_insn)
+ {
+ prev_insn = PREV_INSN (insn);
+ if (GET_CODE (insn) == CALL_INSN && ! CONST_CALL_P (insn))
+ {
+ edge e;
+
+ /* Note that the following may create a new basic block
+ and renumber the existing basic blocks. */
+ e = split_block (bb, insn);
+ if (e)
+ blocks_split++;
+
+ make_edge (NULL, bb, EXIT_BLOCK_PTR, EDGE_FAKE);
+ }
+ if (insn == bb->head)
+ break;
+ }
+ }
+
+ if (blocks_split)
+ verify_flow_info ();
+
+ free (bbs);
+ return blocks_split;
+}
/* Delete all unreachable basic blocks. */