aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linearize.c
diff options
authorLuc Van Oostenryck <luc.vanoostenryck@gmail.com>2018-08-03 18:46:10 +0200
committerLuc Van Oostenryck <luc.vanoostenryck@gmail.com>2018-08-06 08:50:52 +0200
commit5fccf5f5a85d01ca21d06675216345a182555cce (patch)
tree2ff8f6a5e810588c4797f204a2fb04d65b0ce7a2 /linearize.c
parentc47f18c7699d0a9fbb8b8adbd2c3bf177214beb4 (diff)
downloadsparse-dev-5fccf5f5a85d01ca21d06675216345a182555cce.tar.gz
simplify linearize_logical()
The linearized code for logical expressions looks like: .Lc ... condition 1 ... cbr %c, .L1, .L2 .L1 %phisrc %phi1 <- $1 br .Lm .L2 ... condition 2 ... %phisrc %phi2 <- %r br .Lm .Lm %phi %r <- %phi1, %phi2 But .L1 can easily be merged with .Lc: .Lc ... condition 1 ... %phisrc %phi1 <- $1 cbr %c, .Lm, .L2 .L2 ... condition 2 ... %phisrc %phi2 <- %r br .Lm .Lm %phi %r <- %phi1, %phi2 Do this simplification which: * creates less basic blocks & branches * do at linearization time a simplification not done later. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
Diffstat (limited to 'linearize.c')
-rw-r--r--linearize.c41
1 files changed, 14 insertions, 27 deletions
diff --git a/linearize.c b/linearize.c
index 3dfe45c0..eeef0ba7 100644
--- a/linearize.c
+++ b/linearize.c
@@ -1644,48 +1644,35 @@ static pseudo_t linearize_conditional(struct entrypoint *ep, struct expression *
static pseudo_t linearize_logical(struct entrypoint *ep, struct expression *expr)
{
- struct basic_block *merge;
+ struct basic_block *other, *merge;
pseudo_t phi1, phi2;
if (!ep->active || !expr->left || !expr->right)
return VOID;
- if (expr->op == SPECIAL_LOGICAL_OR) {
- struct expression *expr_false = expr->right;
- struct basic_block *bb_true = alloc_basic_block(ep, expr->pos);
- struct basic_block *bb_false = alloc_basic_block(ep, expr_false->pos);
- pseudo_t src1, src2;
+ other = alloc_basic_block(ep, expr->right->pos);
+ merge = alloc_basic_block(ep, expr->pos);
- merge = alloc_basic_block(ep, expr->pos);
- linearize_cond_branch(ep, expr->left, bb_true, bb_false);
+ if (expr->op == SPECIAL_LOGICAL_OR) {
+ pseudo_t src2;
- set_activeblock(ep, bb_true);
- src1 = value_pseudo(1);
- phi1 = alloc_phi(ep->active, src1, expr->ctype);
- add_goto(ep, merge);
+ phi1 = alloc_phi(ep->active, value_pseudo(1), expr->ctype);
+ linearize_cond_branch(ep, expr->left, merge, other);
- set_activeblock(ep, bb_false);
- src2 = linearize_expression_to_bool(ep, expr_false);
+ set_activeblock(ep, other);
+ src2 = linearize_expression_to_bool(ep, expr->right);
src2 = cast_pseudo(ep, src2, &bool_ctype, expr->ctype);
phi2 = alloc_phi(ep->active, src2, expr->ctype);
} else {
- struct expression *expr_true = expr->right;
- struct basic_block *bb_true = alloc_basic_block(ep, expr_true->pos);
- struct basic_block *bb_false = alloc_basic_block(ep, expr->pos);
- pseudo_t src1, src2;
+ pseudo_t src1;
- merge = alloc_basic_block(ep, expr->pos);
- linearize_cond_branch(ep, expr->left, bb_true, bb_false);
+ phi2 = alloc_phi(ep->active, value_pseudo(0), expr->ctype);
+ linearize_cond_branch(ep, expr->left, other, merge);
- set_activeblock(ep, bb_true);
- src1 = linearize_expression_to_bool(ep, expr_true);
+ set_activeblock(ep, other);
+ src1 = linearize_expression_to_bool(ep, expr->right);
src1 = cast_pseudo(ep, src1, &bool_ctype, expr->ctype);
phi1 = alloc_phi(ep->active, src1, expr->ctype);
- add_goto(ep, merge);
-
- set_activeblock(ep, bb_false);
- src2 = value_pseudo(0);
- phi2 = alloc_phi(ep->active, src2, expr->ctype);
}
set_activeblock(ep, merge);