Skip to content

Commit a6d2b01

Browse files
committed
---
yaml --- r: 905 b: refs/heads/master c: 0578978 h: refs/heads/master i: 903: a3ecbb4 v: v3
1 parent 7d8efc6 commit a6d2b01

File tree

2 files changed

+65
-44
lines changed

2 files changed

+65
-44
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
---
2-
refs/heads/master: 2ff0662eaef0af2a7a0173e5da53fe271c217e38
2+
refs/heads/master: 057897849526de884f2996423475f7aaeb3395e2

trunk/src/comp/middle/trans.rs

Lines changed: 64 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -584,18 +584,15 @@ impure fn trans_binary(@block_ctxt cx, ast.binop op,
584584
auto rhs_cx = new_sub_block_ctxt(cx, "rhs");
585585
auto rhs_res = trans_expr(rhs_cx, b);
586586

587-
auto next_cx = new_sub_block_ctxt(cx, "next");
588-
rhs_res.bcx.build.Br(next_cx.llbb);
587+
auto lhs_false_cx = new_sub_block_ctxt(cx, "lhs false");
588+
auto lhs_false_res = res(lhs_false_cx, C_bool(false));
589589

590590
lhs_res.bcx.build.CondBr(lhs_res.val,
591591
rhs_cx.llbb,
592-
next_cx.llbb);
593-
auto phi = next_cx.build.Phi(T_bool(),
594-
vec(lhs_res.val,
595-
rhs_res.val),
596-
vec(lhs_res.bcx.llbb,
597-
rhs_res.bcx.llbb));
598-
ret res(next_cx, phi);
592+
lhs_false_cx.llbb);
593+
594+
ret join_results(cx, T_bool(),
595+
vec(lhs_false_res, rhs_res));
599596
}
600597

601598
case (ast.or) {
@@ -605,18 +602,15 @@ impure fn trans_binary(@block_ctxt cx, ast.binop op,
605602
auto rhs_cx = new_sub_block_ctxt(cx, "rhs");
606603
auto rhs_res = trans_expr(rhs_cx, b);
607604

608-
auto next_cx = new_sub_block_ctxt(cx, "next");
609-
rhs_res.bcx.build.Br(next_cx.llbb);
605+
auto lhs_true_cx = new_sub_block_ctxt(cx, "lhs true");
606+
auto lhs_true_res = res(lhs_true_cx, C_bool(true));
610607

611608
lhs_res.bcx.build.CondBr(lhs_res.val,
612-
next_cx.llbb,
609+
lhs_true_cx.llbb,
613610
rhs_cx.llbb);
614-
auto phi = next_cx.build.Phi(T_bool(),
615-
vec(lhs_res.val,
616-
rhs_res.val),
617-
vec(lhs_res.bcx.llbb,
618-
rhs_res.bcx.llbb));
619-
ret res(next_cx, phi);
611+
612+
ret join_results(cx, T_bool(),
613+
vec(lhs_true_res, rhs_res));
620614
}
621615
}
622616

@@ -722,6 +716,48 @@ impure fn trans_binary(@block_ctxt cx, ast.binop op,
722716
fail;
723717
}
724718

719+
fn join_results(@block_ctxt parent_cx,
720+
TypeRef t,
721+
vec[result] ins)
722+
-> result {
723+
724+
let vec[result] live = vec();
725+
let vec[ValueRef] vals = vec();
726+
let vec[BasicBlockRef] bbs = vec();
727+
728+
for (result r in ins) {
729+
if (! is_terminated(r.bcx)) {
730+
live += r;
731+
vals += r.val;
732+
bbs += r.bcx.llbb;
733+
}
734+
}
735+
736+
alt (_vec.len[result](live)) {
737+
case (0u) {
738+
// No incoming edges are live, so we're in dead-code-land.
739+
// Arbitrarily pick the first dead edge, since the caller
740+
// is just going to propagate it outward.
741+
check (_vec.len[result](ins) >= 1u);
742+
ret ins.(0);
743+
}
744+
745+
case (1u) {
746+
// Only one incoming edge is live, so we just feed that block
747+
// onward.
748+
ret live.(0);
749+
}
750+
}
751+
752+
// We have >1 incoming edges. Make a join block and br+phi them into it.
753+
auto join_cx = new_sub_block_ctxt(parent_cx, "join");
754+
for (result r in live) {
755+
r.bcx.build.Br(join_cx.llbb);
756+
}
757+
auto phi = join_cx.build.Phi(t, vals, bbs);
758+
ret res(join_cx, phi);
759+
}
760+
725761
impure fn trans_if(@block_ctxt cx, &ast.expr cond,
726762
&ast.block thn, &option.t[ast.block] els) -> result {
727763

@@ -730,37 +766,22 @@ impure fn trans_if(@block_ctxt cx, &ast.expr cond,
730766
auto then_cx = new_sub_block_ctxt(cx, "then");
731767
auto then_res = trans_block(then_cx, thn);
732768

733-
auto next_cx = new_sub_block_ctxt(cx, "next");
734-
then_res.bcx.build.Br(next_cx.llbb);
735-
auto phi;
769+
auto else_cx = new_sub_block_ctxt(cx, "else");
770+
auto else_res = res(else_cx, C_nil());
736771

737772
alt (els) {
738773
case (some[ast.block](?eblk)) {
739-
auto else_cx = new_sub_block_ctxt(cx, "else");
740-
auto else_res = trans_block(else_cx, eblk);
741-
cond_res.bcx.build.CondBr(cond_res.val,
742-
then_cx.llbb,
743-
else_cx.llbb);
744-
else_res.bcx.build.Br(next_cx.llbb);
745-
phi = next_cx.build.Phi(T_nil(),
746-
vec(then_res.val,
747-
else_res.val),
748-
vec(then_res.bcx.llbb,
749-
else_res.bcx.llbb));
750-
}
751-
752-
case (_) {
753-
cond_res.bcx.build.CondBr(cond_res.val,
754-
then_cx.llbb,
755-
next_cx.llbb);
756-
phi = next_cx.build.Phi(T_nil(),
757-
vec(then_res.val, C_nil()),
758-
vec(then_res.bcx.llbb,
759-
cond_res.bcx.llbb));
774+
else_res = trans_block(else_cx, eblk);
760775
}
761776
}
762777

763-
ret res(next_cx, phi);
778+
cond_res.bcx.build.CondBr(cond_res.val,
779+
then_res.bcx.llbb,
780+
else_res.bcx.llbb);
781+
782+
// FIXME: use inferred type when available.
783+
ret join_results(cx, T_nil(),
784+
vec(then_res, else_res));
764785
}
765786

766787
impure fn trans_while(@block_ctxt cx, &ast.expr cond,

0 commit comments

Comments
 (0)