about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorBjörn Steinbrink <bsteinbr@gmail.com>2013-07-25 17:03:46 +0200
committerBjörn Steinbrink <bsteinbr@gmail.com>2013-07-25 17:03:46 +0200
commit7078ab7324aef0ad04b4a79a514f2c1d59b73fe5 (patch)
treee7984ac2611d1f69a3aa666aef95118662e51632 /src
parente0685e22a3a7a5735f635bd28bdcb5084dd5be34 (diff)
downloadrust-7078ab7324aef0ad04b4a79a514f2c1d59b73fe5.tar.gz
rust-7078ab7324aef0ad04b4a79a514f2c1d59b73fe5.zip
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.
Diffstat (limited to 'src')
-rw-r--r--src/librustc/middle/trans/controlflow.rs32
1 files changed, 14 insertions, 18 deletions
diff --git a/src/librustc/middle/trans/controlflow.rs b/src/librustc/middle/trans/controlflow.rs
index a00cd94ad54..8c87766bbbe 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))
     }
 }