Skip to content

Commit

Permalink
Generate branchless code when "if" can be evaluated at compile time
Browse files Browse the repository at this point in the history
We already avoid the conditional branch, but still have an
unconditional branch in the generated code. Remove it.
  • Loading branch information
dotdash committed Jul 25, 2013
1 parent e0685e2 commit 7078ab7
Showing 1 changed file with 14 additions and 18 deletions.
32 changes: 14 additions & 18 deletions src/librustc/middle/trans/controlflow.rs
Expand Up @@ -74,20 +74,18 @@ pub fn trans_if(bcx: @mut Block,
if is_const(cond_val) && !is_undef(cond_val) {
if const_to_uint(cond_val) == 1 {
// if true { .. } [else { .. }]
let then_bcx_in = scope_block(bcx, thn.info(), "if_true_then");
let then_bcx_out = trans_block(then_bcx_in, thn, dest);
let then_bcx_out = trans_block_cleanups(then_bcx_out,
block_cleanups(then_bcx_in));
Br(bcx, then_bcx_in.llbb);
return then_bcx_out;
return do with_scope(bcx, thn.info(), "if_true_then") |bcx| {
let bcx_out = trans_block(bcx, thn, dest);
trans_block_cleanups(bcx_out, block_cleanups(bcx))
}
} else {
match els {
// if false { .. } else { .. }
Some(elexpr) => {
let (else_bcx_in, else_bcx_out) =
trans_if_else(bcx, elexpr, dest, "if_false_else");
Br(bcx, else_bcx_in.llbb);
return else_bcx_out;
return do with_scope(bcx, elexpr.info(), "if_false_then") |bcx| {
let bcx_out = trans_if_else(bcx, elexpr, dest);
trans_block_cleanups(bcx_out, block_cleanups(bcx))
}
}
// if false { .. }
None => return bcx,
Expand All @@ -107,7 +105,8 @@ pub fn trans_if(bcx: @mut Block,
// 'else' context
let (else_bcx_in, next_bcx) = match els {
Some(elexpr) => {
let (else_bcx_in, else_bcx_out) = trans_if_else(bcx, elexpr, dest, "else");
let else_bcx_in = scope_block(bcx, elexpr.info(), "else");
let else_bcx_out = trans_if_else(else_bcx_in, elexpr, dest);
(else_bcx_in, join_blocks(bcx, [then_bcx_out, else_bcx_out]))
}
_ => {
Expand All @@ -125,9 +124,8 @@ pub fn trans_if(bcx: @mut Block,
return next_bcx;

// trans `else [ if { .. } ... | { .. } ]`
fn trans_if_else(bcx: @mut Block, elexpr: @ast::expr,
dest: expr::Dest, scope_name: &str) -> (@mut Block, @mut Block) {
let else_bcx_in = scope_block(bcx, elexpr.info(), scope_name);
fn trans_if_else(else_bcx_in: @mut Block, elexpr: @ast::expr,
dest: expr::Dest) -> @mut Block {
let else_bcx_out = match elexpr.node {
ast::expr_if(_, _, _) => {
let elseif_blk = ast_util::block_from_expr(elexpr);
Expand All @@ -137,11 +135,9 @@ pub fn trans_if(bcx: @mut Block,
trans_block(else_bcx_in, blk, dest)
}
// would be nice to have a constraint on ifs
_ => bcx.tcx().sess.bug("strange alternative in if")
_ => else_bcx_in.tcx().sess.bug("strange alternative in if")
};
let else_bcx_out = trans_block_cleanups(else_bcx_out,
block_cleanups(else_bcx_in));
(else_bcx_in, else_bcx_out)
trans_block_cleanups(else_bcx_out, block_cleanups(else_bcx_in))
}
}

Expand Down

5 comments on commit 7078ab7

@bors
Copy link
Contributor

@bors bors commented on 7078ab7 Jul 26, 2013

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

saw approval from huonw
at dotdash@7078ab7

@bors
Copy link
Contributor

@bors bors commented on 7078ab7 Jul 26, 2013

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

merging dotdash/rust/const_if_else = 7078ab7 into auto

@bors
Copy link
Contributor

@bors bors commented on 7078ab7 Jul 26, 2013

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

dotdash/rust/const_if_else = 7078ab7 merged ok, testing candidate = 544ef6c

@bors
Copy link
Contributor

@bors bors commented on 7078ab7 Jul 26, 2013

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fast-forwarding master to auto = 544ef6c

Please sign in to comment.