Skip to content

Commit 544ef6c

Browse files
committed
auto merge of #8041 : dotdash/rust/const_if_else, r=huonw
2 parents 15ab6fd + 7078ab7 commit 544ef6c

File tree

2 files changed

+34
-38
lines changed

2 files changed

+34
-38
lines changed

src/librustc/middle/trans/common.rs

+6
Original file line numberDiff line numberDiff line change
@@ -850,6 +850,12 @@ pub fn const_get_elt(cx: &CrateContext, v: ValueRef, us: &[c_uint])
850850
}
851851
}
852852

853+
pub fn is_const(v: ValueRef) -> bool {
854+
unsafe {
855+
llvm::LLVMIsConstant(v) == True
856+
}
857+
}
858+
853859
pub fn const_to_int(v: ValueRef) -> c_longlong {
854860
unsafe {
855861
llvm::LLVMConstIntGetSExtValue(v)

src/librustc/middle/trans/controlflow.rs

+28-38
Original file line numberDiff line numberDiff line change
@@ -65,44 +65,36 @@ 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;
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+
return do with_scope(bcx, thn.info(), "if_true_then") |bcx| {
78+
let bcx_out = trans_block(bcx, thn, dest);
79+
trans_block_cleanups(bcx_out, block_cleanups(bcx))
8080
}
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;
81+
} else {
82+
match els {
83+
// if false { .. } else { .. }
84+
Some(elexpr) => {
85+
return do with_scope(bcx, elexpr.info(), "if_false_then") |bcx| {
86+
let bcx_out = trans_if_else(bcx, elexpr, dest);
87+
trans_block_cleanups(bcx_out, block_cleanups(bcx))
8988
}
90-
// if false { .. }
91-
None => return bcx,
9289
}
90+
// if false { .. }
91+
None => return bcx,
9392
}
94-
_ => {}
95-
},
96-
_ => {}
93+
}
9794
}
9895

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

104-
let cond_val = bool_to_i1(bcx, cond_val);
105-
10698
let then_bcx_out = trans_block(then_bcx_in, thn, dest);
10799
let then_bcx_out = trans_block_cleanups(then_bcx_out,
108100
block_cleanups(then_bcx_in));
@@ -113,7 +105,8 @@ pub fn trans_if(bcx: @mut Block,
113105
// 'else' context
114106
let (else_bcx_in, next_bcx) = match els {
115107
Some(elexpr) => {
116-
let (else_bcx_in, else_bcx_out) = trans_if_else(bcx, elexpr, dest, "else");
108+
let else_bcx_in = scope_block(bcx, elexpr.info(), "else");
109+
let else_bcx_out = trans_if_else(else_bcx_in, elexpr, dest);
117110
(else_bcx_in, join_blocks(bcx, [then_bcx_out, else_bcx_out]))
118111
}
119112
_ => {
@@ -131,9 +124,8 @@ pub fn trans_if(bcx: @mut Block,
131124
return next_bcx;
132125

133126
// trans `else [ if { .. } ... | { .. } ]`
134-
fn trans_if_else(bcx: @mut Block, elexpr: @ast::expr,
135-
dest: expr::Dest, scope_name: &str) -> (@mut Block, @mut Block) {
136-
let else_bcx_in = scope_block(bcx, elexpr.info(), scope_name);
127+
fn trans_if_else(else_bcx_in: @mut Block, elexpr: @ast::expr,
128+
dest: expr::Dest) -> @mut Block {
137129
let else_bcx_out = match elexpr.node {
138130
ast::expr_if(_, _, _) => {
139131
let elseif_blk = ast_util::block_from_expr(elexpr);
@@ -143,11 +135,9 @@ pub fn trans_if(bcx: @mut Block,
143135
trans_block(else_bcx_in, blk, dest)
144136
}
145137
// would be nice to have a constraint on ifs
146-
_ => bcx.tcx().sess.bug("strange alternative in if")
138+
_ => else_bcx_in.tcx().sess.bug("strange alternative in if")
147139
};
148-
let else_bcx_out = trans_block_cleanups(else_bcx_out,
149-
block_cleanups(else_bcx_in));
150-
(else_bcx_in, else_bcx_out)
140+
trans_block_cleanups(else_bcx_out, block_cleanups(else_bcx_in))
151141
}
152142
}
153143

0 commit comments

Comments
 (0)