1
Fork 0

Auto merge of #83663 - AngelicosPhosphoros:simplify_binary_and_to_get_better_asm, r=nagisa

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)
This commit is contained in:
bors 2021-04-02 00:48:31 +00:00
commit d1065e6cef
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 } => {