aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linearize.c
diff options
authorChristopher Li <sparse@chrisli.org>2004-04-18 23:13:25 -0700
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-04-07 21:01:37 -0700
commit62e541910017e5015eb1a84d7a1f600e8fe08a98 (patch)
tree688b7abb2fb1b8d013332aec856f65ad40291512 /linearize.c
parent86c405cf6f27615237545997afc9ee2cf815022c (diff)
downloadsparse-dev-62e541910017e5015eb1a84d7a1f600e8fe08a98.tar.gz
[PATCH] linearize conditional expressions
- add conditional expression linearization - fix a silly typo. It seems that most of the expression and statement work is done. The initialize expression is still missing, which looks very complicated.
Diffstat (limited to 'linearize.c')
-rw-r--r--linearize.c45
1 files changed, 27 insertions, 18 deletions
diff --git a/linearize.c b/linearize.c
index 6638a81a..563970df 100644
--- a/linearize.c
+++ b/linearize.c
@@ -500,42 +500,47 @@ static pseudo_t linearize_logical_branch(struct entrypoint *ep, struct expressio
pseudo_t linearize_cond_branch(struct entrypoint *ep, struct expression *expr, struct basic_block *bb_true, struct basic_block *bb_false);
-static pseudo_t linearize_logical(struct entrypoint *ep, struct expression *expr)
+static pseudo_t linearize_conditional(struct entrypoint *ep, struct expression *expr,
+ struct expression *cond, struct expression *expr_true,
+ struct expression *expr_false)
{
pseudo_t src1, src2, target;
struct basic_block *bb_true = alloc_basic_block();
struct basic_block *bb_false = alloc_basic_block();
struct basic_block *merge = alloc_basic_block();
- struct basic_block *first = bb_true;
- struct basic_block *second = bb_false;
-
- if (expr->op == SPECIAL_LOGICAL_OR) {
- first = bb_false;
- second = bb_true;
- }
- linearize_cond_branch(ep, expr->left, bb_true, bb_false);
+ linearize_cond_branch(ep, cond, bb_true, bb_false);
- set_activeblock(ep, first);
- src1 = linearize_expression(ep, expr->right);
- add_goto(ep, merge);
-
- set_activeblock(ep, second);
- src2 = add_setval(ep, expr->ctype, alloc_const_expression(expr->pos, expr->op == SPECIAL_LOGICAL_OR));
+ set_activeblock(ep, bb_true);
+ src1 = linearize_expression(ep, expr_true);
+ bb_true = ep->active;
+ add_goto(ep, merge);
+ set_activeblock(ep, bb_false);
+ src2 = linearize_expression(ep, expr_false);
+ bb_false = ep->active;
set_activeblock(ep, merge);
if (bb_reachable(bb_true) && bb_reachable(bb_false)) {
struct instruction *phi_node = alloc_instruction(OP_PHI, expr->ctype);
- add_phi(&phi_node->phi_list, alloc_phi(first, src1));
- add_phi(&phi_node->phi_list, alloc_phi(second, src2));
+ add_phi(&phi_node->phi_list, alloc_phi(bb_true, src1));
+ add_phi(&phi_node->phi_list, alloc_phi(bb_false, src2));
phi_node->target = target = alloc_pseudo();
add_one_insn(ep, expr->pos, phi_node);
set_activeblock(ep, alloc_basic_block());
return target;
}
- return bb_reachable(first) ? src1 : src2;
+ return bb_reachable(bb_true) ? src1 : src2;
+}
+
+static pseudo_t linearize_logical(struct entrypoint *ep, struct expression *expr)
+{
+ struct expression *shortcut;
+
+ shortcut = alloc_const_expression(expr->pos, expr->op == SPECIAL_LOGICAL_OR);
+ shortcut->ctype = expr->ctype;
+ return linearize_conditional(ep, expr, expr->left, shortcut, expr->right);
}
static pseudo_t linearize_compare(struct entrypoint *ep, struct expression *expr)
@@ -645,6 +650,10 @@ pseudo_t linearize_expression(struct entrypoint *ep, struct expression *expr)
case EXPR_COMPARE:
return linearize_compare(ep, expr);
+ case EXPR_CONDITIONAL:
+ return linearize_conditional(ep, expr, expr->conditional,
+ expr->cond_true, expr->cond_false);
+
case EXPR_COMMA: {
linearize_expression(ep, expr->left);
return linearize_expression(ep, expr->right);