From 7078ab7324aef0ad04b4a79a514f2c1d59b73fe5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Steinbrink?= Date: Thu, 25 Jul 2013 17:03:46 +0200 Subject: [PATCH] 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. --- src/librustc/middle/trans/controlflow.rs | 32 +++++++++++------------- 1 file changed, 14 insertions(+), 18 deletions(-) diff --git a/src/librustc/middle/trans/controlflow.rs b/src/librustc/middle/trans/controlflow.rs index a00cd94ad54ef..8c87766bbbe1f 100644 --- a/src/librustc/middle/trans/controlflow.rs +++ b/src/librustc/middle/trans/controlflow.rs @@ -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, @@ -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])) } _ => { @@ -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); @@ -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)) } }