[PATCH 08/13] let insert_branch() return a status

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



insert_branch() modifies the CFG and the usage of pseudos so these
changes must be, in a way or another, notify to the upper layers.
Currently this is done by setting 'repeat_phase' in the function
itself.

Let this function to also report the changes via its return value
since this is usually useful for the caller to know and tend to
leaner code too.

Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@xxxxxxxxx>
---
 flow.c     |  7 +++++--
 flow.h     |  2 +-
 simplify.c | 21 +++++++--------------
 3 files changed, 13 insertions(+), 17 deletions(-)

diff --git a/flow.c b/flow.c
index 1f4b4ff08151..38e0ccade722 100644
--- a/flow.c
+++ b/flow.c
@@ -711,10 +711,11 @@ void vrfy_flow(struct entrypoint *ep)
 
 ///
 // change a switch or a conditional branch into a branch
-void insert_branch(struct instruction *insn, struct basic_block *target)
+int insert_branch(struct instruction *insn, struct basic_block *target)
 {
 	struct basic_block *bb = insn->bb;
 	struct basic_block *child;
+	int changed = REPEAT_CSE;
 
 	kill_use(&insn->cond);
 	insn->bb_true = target;
@@ -730,9 +731,11 @@ void insert_branch(struct instruction *insn, struct basic_block *target)
 		}
 		DELETE_CURRENT_PTR(child);
 		remove_bb_from_list(&child->parents, bb, 1);
+		changed |= REPEAT_CFG_CLEANUP;
 	} END_FOR_EACH_PTR(child);
 	PACK_PTR_LIST(&bb->children);
-	repeat_phase |= REPEAT_CFG_CLEANUP;
+	repeat_phase |= changed;
+	return changed;
 }
 
 static int retarget_parents(struct basic_block *bb, struct basic_block *target)
diff --git a/flow.h b/flow.h
index f9213306dfd6..cad1de7723d5 100644
--- a/flow.h
+++ b/flow.h
@@ -18,7 +18,7 @@ extern void simplify_symbol_usage(struct entrypoint *ep);
 extern void simplify_memops(struct entrypoint *ep);
 extern void pack_basic_blocks(struct entrypoint *ep);
 extern int simplify_cfg_early(struct entrypoint *ep);
-extern void insert_branch(struct instruction *insn, struct basic_block *target);
+extern int insert_branch(struct instruction *insn, struct basic_block *target);
 
 extern void convert_instruction_target(struct instruction *insn, pseudo_t src);
 extern void remove_dead_insns(struct entrypoint *);
diff --git a/simplify.c b/simplify.c
index 930c0fa7e83f..0bc201e84313 100644
--- a/simplify.c
+++ b/simplify.c
@@ -2440,10 +2440,8 @@ static int simplify_branch(struct instruction *insn)
 	pseudo_t cond = insn->cond;
 
 	/* Constant conditional */
-	if (constant(cond)) {
-		insert_branch(insn, cond->value ? insn->bb_true : insn->bb_false);
-		return REPEAT_CSE;
-	}
+	if (constant(cond))
+		return insert_branch(insn, cond->value ? insn->bb_true : insn->bb_false);
 
 	/* Same target? */
 	if (insn->bb_true == insn->bb_false) {
@@ -2472,14 +2470,10 @@ static int simplify_branch(struct instruction *insn)
 			if (constant(def->src2) && constant(def->src3)) {
 				long long val1 = def->src2->value;
 				long long val2 = def->src3->value;
-				if (!val1 && !val2) {
-					insert_branch(insn, insn->bb_false);
-					return REPEAT_CSE;
-				}
-				if (val1 && val2) {
-					insert_branch(insn, insn->bb_true);
-					return REPEAT_CSE;
-				}
+				if (!val1 && !val2)
+					return insert_branch(insn, insn->bb_false);
+				if (val1 && val2)
+					return insert_branch(insn, insn->bb_true);
 				if (val2) {
 					struct basic_block *tmp = insn->bb_true;
 					insn->bb_true = insn->bb_false;
@@ -2515,8 +2509,7 @@ static int simplify_switch(struct instruction *insn)
 	return 0;
 
 found:
-	insert_branch(insn, jmp->target);
-	return REPEAT_CSE;
+	return insert_branch(insn, jmp->target);
 }
 
 static struct basic_block *is_label(pseudo_t pseudo)
-- 
2.31.0




[Index of Archives]     [Newbies FAQ]     [LKML]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Trinity Fuzzer Tool]

  Powered by Linux