aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/example.c
diff options
authorLuc Van Oostenryck <luc.vanoostenryck@gmail.com>2017-02-28 14:30:27 +0100
committerChristopher Li <sparse@chrisli.org>2017-03-06 08:45:58 +0800
commit86bcec7afa667010d6f38f11a09ada960fd20dbf (patch)
tree6fc9aaf9aeaf631b2507deeeb9c7546acfd3b3a4 /example.c
parent522773d089700cce5551860aea3cb93f40b5f3a4 (diff)
downloadsparse-dev-86bcec7afa667010d6f38f11a09ada960fd20dbf.tar.gz
split OP_BR between unconditional & conditional: OP_CBR
OP_BR instructions exist in two flavours, relatively much differentiated: conditional & non-conditional. One has an operand (and thus its usage need to be cared for, must be handled in liveness analysis, ..) the other has not; one has two BB target, the other only one. There is essentially no places in the code where both flavours are handled the same. Sometimes they both must be handled but each with their specificities but in most cases only one of them is concerned and we need to filter out the other one. In both cases it means that we need to check what kind we're dealing with. There is already a problem with this because there is several ways to test which kind an OP_BR is and they are not exactly equivalent: 1) testing if insn->cond is NULL 2) testing if one of insn->bb_true or ->bb_false is NULL. There exist also an helper (is_branch_goto()) which does the second tests but which is never used. It appears that the first test should not be used because in some cases an conditional OP_BR is changed into a non-conditional one by (amongst others things) setting it's ->cond to VOID. We should thus always use the seconds test (which need two compares with NULL). This could be corrected in several ways (like changing all the places wheer the first test is used, use the helper everywhere or never set ->cond to VOID) but the simplest is to simply split them in two separated instructions: OP_BR & OP_CBR, especailly given the fact that in most cases the OP_BR was first selected by a switch (opcode). Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com> Signed-off-by: Christopher Li <sparse@chrisli.org>
Diffstat (limited to 'example.c')
-rw-r--r--example.c2
1 files changed, 2 insertions, 0 deletions
diff --git a/example.c b/example.c
index 24444c6c..691e0f97 100644
--- a/example.c
+++ b/example.c
@@ -23,6 +23,7 @@ static const char *opcodes[] = {
/* Terminator */
[OP_RET] = "ret",
[OP_BR] = "br",
+ [OP_CBR] = "cbr",
[OP_SWITCH] = "switch",
[OP_INVOKE] = "invoke",
[OP_COMPUTEDGOTO] = "jmp *",
@@ -1428,6 +1429,7 @@ static void generate_one_insn(struct instruction *insn, struct bb_state *state)
break;
case OP_BR:
+ case OP_CBR:
generate_branch(state, insn);
break;