Skip to content

Commit 7078ab7

Browse files
committed
Generate branchless code when "if" can be evaluated at compile time
We already avoid the conditional branch, but still have an unconditional branch in the generated code. Remove it.
1 parent e0685e2 commit 7078ab7

File tree

1 file changed

+14
-18
lines changed

1 file changed

+14
-18
lines changed

src/librustc/middle/trans/controlflow.rs

+14-18
Original file line numberDiff line numberDiff line change
@@ -74,20 +74,18 @@ pub fn trans_if(bcx: @mut Block,
7474
if is_const(cond_val) && !is_undef(cond_val) {
7575
if const_to_uint(cond_val) == 1 {
7676
// 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;
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))
80+
}
8381
} else {
8482
match els {
8583
// if false { .. } else { .. }
8684
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;
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))
88+
}
9189
}
9290
// if false { .. }
9391
None => return bcx,
@@ -107,7 +105,8 @@ pub fn trans_if(bcx: @mut Block,
107105
// 'else' context
108106
let (else_bcx_in, next_bcx) = match els {
109107
Some(elexpr) => {
110-
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);
111110
(else_bcx_in, join_blocks(bcx, [then_bcx_out, else_bcx_out]))
112111
}
113112
_ => {
@@ -125,9 +124,8 @@ pub fn trans_if(bcx: @mut Block,
125124
return next_bcx;
126125

127126
// trans `else [ if { .. } ... | { .. } ]`
128-
fn trans_if_else(bcx: @mut Block, elexpr: @ast::expr,
129-
dest: expr::Dest, scope_name: &str) -> (@mut Block, @mut Block) {
130-
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 {
131129
let else_bcx_out = match elexpr.node {
132130
ast::expr_if(_, _, _) => {
133131
let elseif_blk = ast_util::block_from_expr(elexpr);
@@ -137,11 +135,9 @@ pub fn trans_if(bcx: @mut Block,
137135
trans_block(else_bcx_in, blk, dest)
138136
}
139137
// would be nice to have a constraint on ifs
140-
_ => bcx.tcx().sess.bug("strange alternative in if")
138+
_ => else_bcx_in.tcx().sess.bug("strange alternative in if")
141139
};
142-
let else_bcx_out = trans_block_cleanups(else_bcx_out,
143-
block_cleanups(else_bcx_in));
144-
(else_bcx_in, else_bcx_out)
140+
trans_block_cleanups(else_bcx_out, block_cleanups(else_bcx_in))
145141
}
146142
}
147143

0 commit comments

Comments
 (0)