about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMazdak Farrokhzad <twingoow@gmail.com>2018-12-23 23:09:03 +0100
committerGitHub <noreply@github.com>2018-12-23 23:09:03 +0100
commit6ce5ecbc2a6c7e323f8194229327c179cb7d976d (patch)
tree770a573fdc2777f7148b64ad30d59b82fce53631
parent84bc34e70e2be9a0d4087ba030f7153fcf003ee9 (diff)
parente38e954a0d249f88d0a55504f70d6055e865a931 (diff)
downloadrust-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.rs53
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 },
                 );