diff options
| author | Luc Van Oostenryck <luc.vanoostenryck@gmail.com> | 2018-08-03 18:46:10 +0200 |
|---|---|---|
| committer | Luc Van Oostenryck <luc.vanoostenryck@gmail.com> | 2018-08-06 08:50:52 +0200 |
| commit | 5fccf5f5a85d01ca21d06675216345a182555cce (patch) | |
| tree | 2ff8f6a5e810588c4797f204a2fb04d65b0ce7a2 /linearize.c | |
| parent | c47f18c7699d0a9fbb8b8adbd2c3bf177214beb4 (diff) | |
| download | sparse-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.c | 41 |
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); |
