1
Fork 0

Simplify logical operations CFG

This is basically same commit as e38e954a0d which was reverted later in 676953fde9
In both cases, this changes weren't benchmarked.
e38e954a0d leads to missed optimization described in [this issue](https://github.com/rust-lang/rust/issues/62993)
676953fde9 leads to missed optimization described in [this issue](https://github.com/rust-lang/rust/issues/83623)

Also it changes some src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump* files automatically.
This commit is contained in:
AngelicosPhosphoros 2021-03-30 00:19:10 +03:00
parent cc4103089f
commit 4464cc2256
8 changed files with 360 additions and 325 deletions

View file

@ -111,18 +111,17 @@ impl<'a, 'tcx> Builder<'a, '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(),
@ -130,41 +129,31 @@ impl<'a, 'tcx> Builder<'a, '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.tcx, lhs, blocks.0, blocks.1);
this.cfg.terminate(block, source_info, term);
this.cfg.push_assign_constant(
shortcircuit_block,
source_info,
destination,
Constant {
span: expr_span,
user_ty: None,
literal: match op {
LogicalOp::And => ty::Const::from_bool(this.tcx, false).into(),
LogicalOp::Or => ty::Const::from_bool(this.tcx, true).into(),
},
},
);
this.cfg.goto(shortcircuit_block, source_info, join_block);
let rhs = unpack!(else_block = this.as_local_operand(else_block, rhs));
let term = TerminatorKind::if_(this.tcx, rhs, true_block, false_block);
this.cfg.terminate(else_block, source_info, term);
this.cfg.push_assign(else_block, source_info, destination, Rvalue::Use(rhs));
this.cfg.goto(else_block, source_info, join_block);
this.cfg.push_assign_constant(
true_block,
source_info,
destination,
Constant {
span: expr_span,
user_ty: None,
literal: ty::Const::from_bool(this.tcx, true).into(),
},
);
this.cfg.push_assign_constant(
false_block,
source_info,
destination,
Constant {
span: expr_span,
user_ty: None,
literal: ty::Const::from_bool(this.tcx, false).into(),
},
);
// Link up both branches:
this.cfg.goto(true_block, source_info, join_block);
this.cfg.goto(false_block, source_info, join_block);
join_block.unit()
}
ExprKind::Loop { body } => {