Skip to content

Commit

Permalink
rustc: selectively trans branches for if <literal-bool>.
Browse files Browse the repository at this point in the history
That is, the `b` branch in `if true { a } else { b }` will not be
trans'd, and that expression will be exactly the same as `a`. This
means that, for example, macros conditionally expanding to `if false
{ .. }` (like debug!) will not waste time in LLVM (or trans).
  • Loading branch information
huonw committed Jul 16, 2013
1 parent e252277 commit 4797dd4
Showing 1 changed file with 55 additions and 17 deletions.
72 changes: 55 additions & 17 deletions src/librustc/middle/trans/controlflow.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,38 @@ pub fn trans_if(bcx: block,
let _indenter = indenter();

let _icx = push_ctxt("trans_if");

match cond.node {
// `if true` and `if false` can be trans'd more efficiently,
// by dropping branches that are known to be impossible.
ast::expr_lit(@ref l) => match l.node {
ast::lit_bool(true) => {
// 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;
}
ast::lit_bool(false) => {
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;
}
// if false { .. }
None => return bcx,
}
}
_ => {}
},
_ => {}
}

let Result {bcx, val: cond_val} =
expr::trans_to_datum(bcx, cond).to_result();

Expand All @@ -80,22 +112,8 @@ pub fn trans_if(bcx: block,
// 'else' context
let (else_bcx_in, next_bcx) = match els {
Some(elexpr) => {
let else_bcx_in = scope_block(bcx, els.info(), "else");
let else_bcx_out = match elexpr.node {
ast::expr_if(_, _, _) => {
let elseif_blk = ast_util::block_from_expr(elexpr);
trans_block(else_bcx_in, &elseif_blk, dest)
}
ast::expr_block(ref blk) => {
trans_block(else_bcx_in, blk, dest)
}
// would be nice to have a constraint on ifs
_ => bcx.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, join_blocks(bcx, [then_bcx_out, else_bcx_out]))
let (else_bcx_in, else_bcx_out) = trans_if_else(bcx, elexpr, dest, "else");
(else_bcx_in, join_blocks(bcx, [then_bcx_out, else_bcx_out]))
}
_ => {
let next_bcx = sub_block(bcx, "next");
Expand All @@ -109,7 +127,27 @@ pub fn trans_if(bcx: block,
then_bcx_in.to_str(), else_bcx_in.to_str());

CondBr(bcx, cond_val, then_bcx_in.llbb, else_bcx_in.llbb);
next_bcx
return next_bcx;

// trans `else [ if { .. } ... | { .. } ]`
fn trans_if_else(bcx: block, elexpr: @ast::expr,
dest: expr::Dest, scope_name: &str) -> (block, block) {
let else_bcx_in = scope_block(bcx, elexpr.info(), scope_name);
let else_bcx_out = match elexpr.node {
ast::expr_if(_, _, _) => {
let elseif_blk = ast_util::block_from_expr(elexpr);
trans_block(else_bcx_in, &elseif_blk, dest)
}
ast::expr_block(ref blk) => {
trans_block(else_bcx_in, blk, dest)
}
// would be nice to have a constraint on ifs
_ => bcx.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)
}
}

pub fn join_blocks(parent_bcx: block, in_cxs: &[block]) -> block {
Expand Down

5 comments on commit 4797dd4

@bors
Copy link
Contributor

@bors bors commented on 4797dd4 Jul 16, 2013

Choose a reason for hiding this comment

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

saw approval from graydon
at huonw@4797dd4

@bors
Copy link
Contributor

@bors bors commented on 4797dd4 Jul 16, 2013

Choose a reason for hiding this comment

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

merging huonw/rust/cond-debug = 4797dd4 into auto

@bors
Copy link
Contributor

@bors bors commented on 4797dd4 Jul 16, 2013

Choose a reason for hiding this comment

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

huonw/rust/cond-debug = 4797dd4 merged ok, testing candidate = ad212ec

@bors
Copy link
Contributor

@bors bors commented on 4797dd4 Jul 16, 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 = ad212ec

Please sign in to comment.