]> git.lizzy.rs Git - rust.git/commitdiff
Simplify MIR generation for logical ops
authorShotaro Yamada <sinkuu@sinkuu.xyz>
Mon, 17 Dec 2018 06:57:38 +0000 (15:57 +0900)
committerShotaro Yamada <sinkuu@sinkuu.xyz>
Mon, 17 Dec 2018 13:16:13 +0000 (22:16 +0900)
src/librustc_mir/build/expr/into.rs

index 0e7305e076edeb3f39f3de319b5b8c3787aaa99d..a26b0055a048cac9fc5b913bb104f1e532e0b29f 100644 (file)
@@ -126,18 +126,17 @@ pub fn into_expr(
             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 @@ pub fn into_expr(
 
                 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 },
                 );