diff options
| author | Mazdak Farrokhzad <twingoow@gmail.com> | 2018-12-23 23:09:03 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2018-12-23 23:09:03 +0100 |
| commit | 6ce5ecbc2a6c7e323f8194229327c179cb7d976d (patch) | |
| tree | 770a573fdc2777f7148b64ad30d59b82fce53631 | |
| parent | 84bc34e70e2be9a0d4087ba030f7153fcf003ee9 (diff) | |
| parent | e38e954a0d249f88d0a55504f70d6055e865a931 (diff) | |
| download | rust-6ce5ecbc2a6c7e323f8194229327c179cb7d976d.tar.gz rust-6ce5ecbc2a6c7e323f8194229327c179cb7d976d.zip | |
Rollup merge of #56917 - sinkuu:mir_build_logicop, r=davidtwco
Simplify MIR generation for logical operations Reduces one block and one branch from MIR generated for a logical operator.
| -rw-r--r-- | src/librustc_mir/build/expr/into.rs | 53 |
1 files changed, 23 insertions, 30 deletions
diff --git a/src/librustc_mir/build/expr/into.rs b/src/librustc_mir/build/expr/into.rs index 146bf538306..64defaf78a4 100644 --- a/src/librustc_mir/build/expr/into.rs +++ b/src/librustc_mir/build/expr/into.rs @@ -126,18 +126,17 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { ExprKind::LogicalOp { op, lhs, rhs } => { // And: // - // [block: If(lhs)] -true-> [else_block: If(rhs)] -true-> [true_block] - // | | (false) - // +----------false-----------+------------------> [false_block] + // [block: If(lhs)] -true-> [else_block: dest = (rhs)] + // | (false) + // [shortcurcuit_block: dest = false] // // Or: // - // [block: If(lhs)] -false-> [else_block: If(rhs)] -true-> [true_block] - // | (true) | (false) - // [true_block] [false_block] + // [block: If(lhs)] -false-> [else_block: dest = (rhs)] + // | (true) + // [shortcurcuit_block: dest = true] - let (true_block, false_block, mut else_block, join_block) = ( - this.cfg.start_new_block(), + let (shortcircuit_block, mut else_block, join_block) = ( this.cfg.start_new_block(), this.cfg.start_new_block(), this.cfg.start_new_block(), @@ -145,47 +144,41 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { let lhs = unpack!(block = this.as_local_operand(block, lhs)); let blocks = match op { - LogicalOp::And => (else_block, false_block), - LogicalOp::Or => (true_block, else_block), + LogicalOp::And => (else_block, shortcircuit_block), + LogicalOp::Or => (shortcircuit_block, else_block), }; let term = TerminatorKind::if_(this.hir.tcx(), lhs, blocks.0, blocks.1); this.cfg.terminate(block, source_info, term); - let rhs = unpack!(else_block = this.as_local_operand(else_block, rhs)); - let term = TerminatorKind::if_(this.hir.tcx(), rhs, true_block, false_block); - this.cfg.terminate(else_block, source_info, term); - this.cfg.push_assign_constant( - true_block, + shortcircuit_block, source_info, destination, Constant { span: expr_span, ty: this.hir.bool_ty(), user_ty: None, - literal: this.hir.true_literal(), + literal: match op { + LogicalOp::And => this.hir.false_literal(), + LogicalOp::Or => this.hir.true_literal(), + }, }, ); - - this.cfg.push_assign_constant( - false_block, + this.cfg.terminate( + shortcircuit_block, source_info, - destination, - Constant { - span: expr_span, - ty: this.hir.bool_ty(), - user_ty: None, - literal: this.hir.false_literal(), - }, + TerminatorKind::Goto { target: join_block }, ); - this.cfg.terminate( - true_block, + let rhs = unpack!(else_block = this.as_local_operand(else_block, rhs)); + this.cfg.push_assign( + else_block, source_info, - TerminatorKind::Goto { target: join_block }, + destination, + Rvalue::Use(rhs), ); this.cfg.terminate( - false_block, + else_block, source_info, TerminatorKind::Goto { target: join_block }, ); |
