Skip to content

Commit e0685e2

Browse files
committed
Make omission of impossible if-else branches work with constants
Until now, we only optimized away impossible branches when there is a literal true/false in the code. But since the LLVM IR builder already does constant folding for us, we can trivially expand that to work with constants as well. Refs #7834
1 parent 75a0862 commit e0685e2

File tree

1 file changed

+26
-32
lines changed

1 file changed

+26
-32
lines changed

src/librustc/middle/trans/controlflow.rs

+26-32
Original file line numberDiff line numberDiff line change
@@ -65,44 +65,38 @@ pub fn trans_if(bcx: @mut Block,
6565

6666
let _icx = push_ctxt("trans_if");
6767

68-
match cond.node {
69-
// `if true` and `if false` can be trans'd more efficiently,
70-
// by dropping branches that are known to be impossible.
71-
ast::expr_lit(@ref l) => match l.node {
72-
ast::lit_bool(true) => {
73-
// if true { .. } [else { .. }]
74-
let then_bcx_in = scope_block(bcx, thn.info(), "if_true_then");
75-
let then_bcx_out = trans_block(then_bcx_in, thn, dest);
76-
let then_bcx_out = trans_block_cleanups(then_bcx_out,
77-
block_cleanups(then_bcx_in));
78-
Br(bcx, then_bcx_in.llbb);
79-
return then_bcx_out;
80-
}
81-
ast::lit_bool(false) => {
82-
match els {
83-
// if false { .. } else { .. }
84-
Some(elexpr) => {
85-
let (else_bcx_in, else_bcx_out) =
86-
trans_if_else(bcx, elexpr, dest, "if_false_else");
87-
Br(bcx, else_bcx_in.llbb);
88-
return else_bcx_out;
89-
}
90-
// if false { .. }
91-
None => return bcx,
68+
let Result {bcx, val: cond_val} =
69+
expr::trans_to_datum(bcx, cond).to_result();
70+
71+
let cond_val = bool_to_i1(bcx, cond_val);
72+
73+
// Drop branches that are known to be impossible
74+
if is_const(cond_val) && !is_undef(cond_val) {
75+
if const_to_uint(cond_val) == 1 {
76+
// if true { .. } [else { .. }]
77+
let then_bcx_in = scope_block(bcx, thn.info(), "if_true_then");
78+
let then_bcx_out = trans_block(then_bcx_in, thn, dest);
79+
let then_bcx_out = trans_block_cleanups(then_bcx_out,
80+
block_cleanups(then_bcx_in));
81+
Br(bcx, then_bcx_in.llbb);
82+
return then_bcx_out;
83+
} else {
84+
match els {
85+
// if false { .. } else { .. }
86+
Some(elexpr) => {
87+
let (else_bcx_in, else_bcx_out) =
88+
trans_if_else(bcx, elexpr, dest, "if_false_else");
89+
Br(bcx, else_bcx_in.llbb);
90+
return else_bcx_out;
9291
}
92+
// if false { .. }
93+
None => return bcx,
9394
}
94-
_ => {}
95-
},
96-
_ => {}
95+
}
9796
}
9897

99-
let Result {bcx, val: cond_val} =
100-
expr::trans_to_datum(bcx, cond).to_result();
101-
10298
let then_bcx_in = scope_block(bcx, thn.info(), "then");
10399

104-
let cond_val = bool_to_i1(bcx, cond_val);
105-
106100
let then_bcx_out = trans_block(then_bcx_in, thn, dest);
107101
let then_bcx_out = trans_block_cleanups(then_bcx_out,
108102
block_cleanups(then_bcx_in));

0 commit comments

Comments
 (0)