aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authorLuc Van Oostenryck <luc.vanoostenryck@gmail.com>2020-01-03 02:37:50 +0100
committerLuc Van Oostenryck <luc.vanoostenryck@gmail.com>2020-11-15 20:34:31 +0100
commitf4d847fc84d4378eaf5bf8f6fad96f959eb4f40b (patch)
tree9b704eaca07e20630da52f02be11593cd528d479
parent8f1047988b881f5d8c43c60ed7f651b74952a4a5 (diff)
downloadsparse-f4d847fc84d4378eaf5bf8f6fad96f959eb4f40b.tar.gz
cfg: extract merge_bb() from pack_basic_blocks()
Extract merge_bb() from pack_basic_blocks() in order to reuse this part of the code in other simplification/finer grained version of pack_basic_blocks(). Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
-rw-r--r--flow.c58
1 files changed, 35 insertions, 23 deletions
diff --git a/flow.c b/flow.c
index ef8d04e5..9ae8612a 100644
--- a/flow.c
+++ b/flow.c
@@ -723,13 +723,46 @@ void vrfy_flow(struct entrypoint *ep)
assert(!entry);
}
+///
+// merge two BBs
+// @top: the first BB to be merged
+// @bot: the second BB to be merged
+static int merge_bb(struct basic_block *top, struct basic_block *bot)
+{
+ struct instruction *insn;
+ struct basic_block *bb;
+
+ if (top == bot)
+ return 0;
+
+ top->children = bot->children;
+ bot->children = NULL;
+ bot->parents = NULL;
+
+ FOR_EACH_PTR(top->children, bb) {
+ replace_bb_in_list(&bb->parents, bot, top, 1);
+ } END_FOR_EACH_PTR(bb);
+
+ kill_instruction(delete_last_instruction(&top->insns));
+ FOR_EACH_PTR(bot->insns, insn) {
+ if (!insn->bb)
+ continue;
+ assert(insn->bb == bot);
+ insn->bb = top;
+ add_instruction(&top->insns, insn);
+ } END_FOR_EACH_PTR(insn);
+ bot->insns = NULL;
+ bot->ep = NULL;
+ return REPEAT_CFG_CLEANUP;
+}
+
void pack_basic_blocks(struct entrypoint *ep)
{
struct basic_block *bb;
/* See if we can merge a bb into another one.. */
FOR_EACH_PTR(ep->bbs, bb) {
- struct instruction *first, *insn;
+ struct instruction *first;
struct basic_block *parent, *child, *last;
if (!bb_reachable(bb))
@@ -786,28 +819,7 @@ out:
goto no_merge;
} END_FOR_EACH_PTR(child);
- /*
- * Merge the two.
- */
- repeat_phase |= REPEAT_CFG_CLEANUP;
-
- parent->children = bb->children;
- bb->children = NULL;
- bb->parents = NULL;
-
- FOR_EACH_PTR(parent->children, child) {
- replace_bb_in_list(&child->parents, bb, parent, 0);
- } END_FOR_EACH_PTR(child);
-
- kill_instruction(delete_last_instruction(&parent->insns));
- FOR_EACH_PTR(bb->insns, insn) {
- if (!insn->bb)
- continue;
- assert(insn->bb == bb);
- insn->bb = parent;
- add_instruction(&parent->insns, insn);
- } END_FOR_EACH_PTR(insn);
- bb->insns = NULL;
+ repeat_phase |= merge_bb(parent, bb);
no_merge:
/* nothing to do */;