Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(179)

Unified Diff: src/compiler/arm64/instruction-selector-arm64.cc

Issue 1721103003: [turbofan] Introduce DeoptimizeIf And DeoptimizeUnless common operators. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Add comments Created 4 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/compiler/arm/instruction-selector-arm.cc ('k') | src/compiler/branch-elimination.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/compiler/arm64/instruction-selector-arm64.cc
diff --git a/src/compiler/arm64/instruction-selector-arm64.cc b/src/compiler/arm64/instruction-selector-arm64.cc
index 26a289613483065ac8dab4ccf3561743d4a26656..557fe864615429f2f208c2acc71ba9139f684eae 100644
--- a/src/compiler/arm64/instruction-selector-arm64.cc
+++ b/src/compiler/arm64/instruction-selector-arm64.cc
@@ -289,8 +289,13 @@ void VisitBinop(InstructionSelector* selector, Node* node,
DCHECK_GE(arraysize(inputs), input_count);
DCHECK_GE(arraysize(outputs), output_count);
- selector->Emit(cont->Encode(opcode), output_count, outputs, input_count,
- inputs);
+ opcode = cont->Encode(opcode);
+ if (cont->IsDeoptimize()) {
+ selector->EmitDeoptimize(opcode, output_count, outputs, input_count, inputs,
+ cont->frame_state());
+ } else {
+ selector->Emit(opcode, output_count, outputs, input_count, inputs);
+ }
}
@@ -1674,6 +1679,9 @@ void VisitCompare(InstructionSelector* selector, InstructionCode opcode,
if (cont->IsBranch()) {
selector->Emit(opcode, g.NoOutput(), left, right,
g.Label(cont->true_block()), g.Label(cont->false_block()));
+ } else if (cont->IsDeoptimize()) {
+ selector->EmitDeoptimize(opcode, g.NoOutput(), left, right,
+ cont->frame_state());
} else {
DCHECK(cont->IsSet());
selector->Emit(opcode, g.DefineAsRegister(cont->result()), left, right);
@@ -1789,85 +1797,72 @@ void VisitFloat64Compare(InstructionSelector* selector, Node* node,
}
}
-} // namespace
-
-
-void InstructionSelector::VisitBranch(Node* branch, BasicBlock* tbranch,
- BasicBlock* fbranch) {
- OperandGenerator g(this);
- Node* user = branch;
- Node* value = branch->InputAt(0);
-
- FlagsContinuation cont(kNotEqual, tbranch, fbranch);
-
- // Try to combine with comparisons against 0 by simply inverting the branch.
- while (CanCover(user, value) && value->opcode() == IrOpcode::kWord32Equal) {
- Int32BinopMatcher m(value);
- if (m.right().Is(0)) {
- user = value;
- value = m.left().node();
- cont.Negate();
- } else {
- break;
- }
- }
-
- // Try to combine the branch with a comparison.
- if (CanCover(user, value)) {
+void VisitWordCompareZero(InstructionSelector* selector, Node* user,
+ Node* value, FlagsContinuation* cont) {
+ Arm64OperandGenerator g(selector);
+ while (selector->CanCover(user, value)) {
switch (value->opcode()) {
- case IrOpcode::kWord32Equal:
- cont.OverwriteAndNegateIfEqual(kEqual);
- return VisitWord32Compare(this, value, &cont);
+ case IrOpcode::kWord32Equal: {
+ Int32BinopMatcher m(value);
+ if (m.right().Is(0)) {
+ user = value;
+ value = m.left().node();
+ cont->Negate();
+ continue;
+ }
+ cont->OverwriteAndNegateIfEqual(kEqual);
+ return VisitWord32Compare(selector, value, cont);
+ }
case IrOpcode::kInt32LessThan:
- cont.OverwriteAndNegateIfEqual(kSignedLessThan);
- return VisitWord32Compare(this, value, &cont);
+ cont->OverwriteAndNegateIfEqual(kSignedLessThan);
+ return VisitWord32Compare(selector, value, cont);
case IrOpcode::kInt32LessThanOrEqual:
- cont.OverwriteAndNegateIfEqual(kSignedLessThanOrEqual);
- return VisitWord32Compare(this, value, &cont);
+ cont->OverwriteAndNegateIfEqual(kSignedLessThanOrEqual);
+ return VisitWord32Compare(selector, value, cont);
case IrOpcode::kUint32LessThan:
- cont.OverwriteAndNegateIfEqual(kUnsignedLessThan);
- return VisitWord32Compare(this, value, &cont);
+ cont->OverwriteAndNegateIfEqual(kUnsignedLessThan);
+ return VisitWord32Compare(selector, value, cont);
case IrOpcode::kUint32LessThanOrEqual:
- cont.OverwriteAndNegateIfEqual(kUnsignedLessThanOrEqual);
- return VisitWord32Compare(this, value, &cont);
+ cont->OverwriteAndNegateIfEqual(kUnsignedLessThanOrEqual);
+ return VisitWord32Compare(selector, value, cont);
case IrOpcode::kWord64Equal:
- cont.OverwriteAndNegateIfEqual(kEqual);
- return VisitWordCompare(this, value, kArm64Cmp, &cont, false,
+ cont->OverwriteAndNegateIfEqual(kEqual);
+ return VisitWordCompare(selector, value, kArm64Cmp, cont, false,
kArithmeticImm);
case IrOpcode::kInt64LessThan:
- cont.OverwriteAndNegateIfEqual(kSignedLessThan);
- return VisitWordCompare(this, value, kArm64Cmp, &cont, false,
+ cont->OverwriteAndNegateIfEqual(kSignedLessThan);
+ return VisitWordCompare(selector, value, kArm64Cmp, cont, false,
kArithmeticImm);
case IrOpcode::kInt64LessThanOrEqual:
- cont.OverwriteAndNegateIfEqual(kSignedLessThanOrEqual);
- return VisitWordCompare(this, value, kArm64Cmp, &cont, false,
+ cont->OverwriteAndNegateIfEqual(kSignedLessThanOrEqual);
+ return VisitWordCompare(selector, value, kArm64Cmp, cont, false,
kArithmeticImm);
case IrOpcode::kUint64LessThan:
- cont.OverwriteAndNegateIfEqual(kUnsignedLessThan);
- return VisitWordCompare(this, value, kArm64Cmp, &cont, false,
+ cont->OverwriteAndNegateIfEqual(kUnsignedLessThan);
+ return VisitWordCompare(selector, value, kArm64Cmp, cont, false,
kArithmeticImm);
case IrOpcode::kUint64LessThanOrEqual:
- cont.OverwriteAndNegateIfEqual(kUnsignedLessThanOrEqual);
- return VisitWordCompare(this, value, kArm64Cmp, &cont, false,
+ cont->OverwriteAndNegateIfEqual(kUnsignedLessThanOrEqual);
+ return VisitWordCompare(selector, value, kArm64Cmp, cont, false,
kArithmeticImm);
case IrOpcode::kFloat32Equal:
- cont.OverwriteAndNegateIfEqual(kEqual);
- return VisitFloat32Compare(this, value, &cont);
+ cont->OverwriteAndNegateIfEqual(kEqual);
+ return VisitFloat32Compare(selector, value, cont);
case IrOpcode::kFloat32LessThan:
- cont.OverwriteAndNegateIfEqual(kFloatLessThan);
- return VisitFloat32Compare(this, value, &cont);
+ cont->OverwriteAndNegateIfEqual(kFloatLessThan);
+ return VisitFloat32Compare(selector, value, cont);
case IrOpcode::kFloat32LessThanOrEqual:
- cont.OverwriteAndNegateIfEqual(kFloatLessThanOrEqual);
- return VisitFloat32Compare(this, value, &cont);
+ cont->OverwriteAndNegateIfEqual(kFloatLessThanOrEqual);
+ return VisitFloat32Compare(selector, value, cont);
case IrOpcode::kFloat64Equal:
- cont.OverwriteAndNegateIfEqual(kEqual);
- return VisitFloat64Compare(this, value, &cont);
+ cont->OverwriteAndNegateIfEqual(kEqual);
+ return VisitFloat64Compare(selector, value, cont);
case IrOpcode::kFloat64LessThan:
- cont.OverwriteAndNegateIfEqual(kFloatLessThan);
- return VisitFloat64Compare(this, value, &cont);
+ cont->OverwriteAndNegateIfEqual(kFloatLessThan);
+ return VisitFloat64Compare(selector, value, cont);
case IrOpcode::kFloat64LessThanOrEqual:
- cont.OverwriteAndNegateIfEqual(kFloatLessThanOrEqual);
- return VisitFloat64Compare(this, value, &cont);
+ cont->OverwriteAndNegateIfEqual(kFloatLessThanOrEqual);
+ return VisitFloat64Compare(selector, value, cont);
case IrOpcode::kProjection:
// Check if this is the overflow output projection of an
// <Operation>WithOverflow node.
@@ -1879,24 +1874,24 @@ void InstructionSelector::VisitBranch(Node* branch, BasicBlock* tbranch,
// *AFTER* this branch).
Node* const node = value->InputAt(0);
Node* const result = NodeProperties::FindProjection(node, 0);
- if (result == nullptr || IsDefined(result)) {
+ if (result == nullptr || selector->IsDefined(result)) {
switch (node->opcode()) {
case IrOpcode::kInt32AddWithOverflow:
- cont.OverwriteAndNegateIfEqual(kOverflow);
- return VisitBinop<Int32BinopMatcher>(this, node, kArm64Add32,
- kArithmeticImm, &cont);
+ cont->OverwriteAndNegateIfEqual(kOverflow);
+ return VisitBinop<Int32BinopMatcher>(
+ selector, node, kArm64Add32, kArithmeticImm, cont);
case IrOpcode::kInt32SubWithOverflow:
- cont.OverwriteAndNegateIfEqual(kOverflow);
- return VisitBinop<Int32BinopMatcher>(this, node, kArm64Sub32,
- kArithmeticImm, &cont);
+ cont->OverwriteAndNegateIfEqual(kOverflow);
+ return VisitBinop<Int32BinopMatcher>(
+ selector, node, kArm64Sub32, kArithmeticImm, cont);
case IrOpcode::kInt64AddWithOverflow:
- cont.OverwriteAndNegateIfEqual(kOverflow);
- return VisitBinop<Int64BinopMatcher>(this, node, kArm64Add,
- kArithmeticImm, &cont);
+ cont->OverwriteAndNegateIfEqual(kOverflow);
+ return VisitBinop<Int64BinopMatcher>(selector, node, kArm64Add,
+ kArithmeticImm, cont);
case IrOpcode::kInt64SubWithOverflow:
- cont.OverwriteAndNegateIfEqual(kOverflow);
- return VisitBinop<Int64BinopMatcher>(this, node, kArm64Sub,
- kArithmeticImm, &cont);
+ cont->OverwriteAndNegateIfEqual(kOverflow);
+ return VisitBinop<Int64BinopMatcher>(selector, node, kArm64Sub,
+ kArithmeticImm, cont);
default:
break;
}
@@ -1904,55 +1899,84 @@ void InstructionSelector::VisitBranch(Node* branch, BasicBlock* tbranch,
}
break;
case IrOpcode::kInt32Add:
- return VisitWordCompare(this, value, kArm64Cmn32, &cont, true,
+ return VisitWordCompare(selector, value, kArm64Cmn32, cont, true,
kArithmeticImm);
case IrOpcode::kInt32Sub:
- return VisitWord32Compare(this, value, &cont);
+ return VisitWord32Compare(selector, value, cont);
case IrOpcode::kWord32And: {
Int32BinopMatcher m(value);
- if (m.right().HasValue() &&
+ if (cont->IsBranch() && m.right().HasValue() &&
(base::bits::CountPopulation32(m.right().Value()) == 1)) {
// If the mask has only one bit set, we can use tbz/tbnz.
- DCHECK((cont.condition() == kEqual) ||
- (cont.condition() == kNotEqual));
- Emit(cont.Encode(kArm64TestAndBranch32), g.NoOutput(),
- g.UseRegister(m.left().node()),
- g.TempImmediate(
- base::bits::CountTrailingZeros32(m.right().Value())),
- g.Label(cont.true_block()), g.Label(cont.false_block()));
+ DCHECK((cont->condition() == kEqual) ||
+ (cont->condition() == kNotEqual));
+ selector->Emit(
+ cont->Encode(kArm64TestAndBranch32), g.NoOutput(),
+ g.UseRegister(m.left().node()),
+ g.TempImmediate(
+ base::bits::CountTrailingZeros32(m.right().Value())),
+ g.Label(cont->true_block()), g.Label(cont->false_block()));
return;
}
- return VisitWordCompare(this, value, kArm64Tst32, &cont, true,
+ return VisitWordCompare(selector, value, kArm64Tst32, cont, true,
kLogical32Imm);
}
case IrOpcode::kWord64And: {
Int64BinopMatcher m(value);
- if (m.right().HasValue() &&
+ if (cont->IsBranch() && m.right().HasValue() &&
(base::bits::CountPopulation64(m.right().Value()) == 1)) {
// If the mask has only one bit set, we can use tbz/tbnz.
- DCHECK((cont.condition() == kEqual) ||
- (cont.condition() == kNotEqual));
- Emit(cont.Encode(kArm64TestAndBranch), g.NoOutput(),
- g.UseRegister(m.left().node()),
- g.TempImmediate(
- base::bits::CountTrailingZeros64(m.right().Value())),
- g.Label(cont.true_block()), g.Label(cont.false_block()));
+ DCHECK((cont->condition() == kEqual) ||
+ (cont->condition() == kNotEqual));
+ selector->Emit(
+ cont->Encode(kArm64TestAndBranch), g.NoOutput(),
+ g.UseRegister(m.left().node()),
+ g.TempImmediate(
+ base::bits::CountTrailingZeros64(m.right().Value())),
+ g.Label(cont->true_block()), g.Label(cont->false_block()));
return;
}
- return VisitWordCompare(this, value, kArm64Tst, &cont, true,
+ return VisitWordCompare(selector, value, kArm64Tst, cont, true,
kLogical64Imm);
}
default:
break;
}
+ break;
}
// Branch could not be combined with a compare, compare against 0 and branch.
- Emit(cont.Encode(kArm64CompareAndBranch32), g.NoOutput(),
- g.UseRegister(value), g.Label(cont.true_block()),
- g.Label(cont.false_block()));
+ if (cont->IsBranch()) {
+ selector->Emit(cont->Encode(kArm64CompareAndBranch32), g.NoOutput(),
+ g.UseRegister(value), g.Label(cont->true_block()),
+ g.Label(cont->false_block()));
+ } else {
+ DCHECK(cont->IsDeoptimize());
+ selector->EmitDeoptimize(cont->Encode(kArm64Tst32), g.NoOutput(),
+ g.UseRegister(value), g.UseRegister(value),
+ cont->frame_state());
+ }
+}
+
+} // namespace
+
+void InstructionSelector::VisitBranch(Node* branch, BasicBlock* tbranch,
+ BasicBlock* fbranch) {
+ FlagsContinuation cont(kNotEqual, tbranch, fbranch);
+ VisitWordCompareZero(this, branch, branch->InputAt(0), &cont);
+}
+
+void InstructionSelector::VisitDeoptimizeIf(Node* node) {
+ FlagsContinuation cont =
+ FlagsContinuation::ForDeoptimize(kNotEqual, node->InputAt(1));
+ VisitWordCompareZero(this, node, node->InputAt(0), &cont);
}
+void InstructionSelector::VisitDeoptimizeUnless(Node* node) {
+ FlagsContinuation cont =
+ FlagsContinuation::ForDeoptimize(kEqual, node->InputAt(1));
+ VisitWordCompareZero(this, node, node->InputAt(0), &cont);
+}
void InstructionSelector::VisitSwitch(Node* node, const SwitchInfo& sw) {
Arm64OperandGenerator g(this);
@@ -1984,7 +2008,7 @@ void InstructionSelector::VisitSwitch(Node* node, const SwitchInfo& sw) {
void InstructionSelector::VisitWord32Equal(Node* const node) {
Node* const user = node;
- FlagsContinuation cont(kEqual, node);
+ FlagsContinuation cont = FlagsContinuation::ForSet(kEqual, node);
Int32BinopMatcher m(user);
if (m.right().Is(0)) {
Node* const value = m.left().node();
@@ -2018,32 +2042,34 @@ void InstructionSelector::VisitWord32Equal(Node* const node) {
void InstructionSelector::VisitInt32LessThan(Node* node) {
- FlagsContinuation cont(kSignedLessThan, node);
+ FlagsContinuation cont = FlagsContinuation::ForSet(kSignedLessThan, node);
VisitWord32Compare(this, node, &cont);
}
void InstructionSelector::VisitInt32LessThanOrEqual(Node* node) {
- FlagsContinuation cont(kSignedLessThanOrEqual, node);
+ FlagsContinuation cont =
+ FlagsContinuation::ForSet(kSignedLessThanOrEqual, node);
VisitWord32Compare(this, node, &cont);
}
void InstructionSelector::VisitUint32LessThan(Node* node) {
- FlagsContinuation cont(kUnsignedLessThan, node);
+ FlagsContinuation cont = FlagsContinuation::ForSet(kUnsignedLessThan, node);
VisitWord32Compare(this, node, &cont);
}
void InstructionSelector::VisitUint32LessThanOrEqual(Node* node) {
- FlagsContinuation cont(kUnsignedLessThanOrEqual, node);
+ FlagsContinuation cont =
+ FlagsContinuation::ForSet(kUnsignedLessThanOrEqual, node);
VisitWord32Compare(this, node, &cont);
}
void InstructionSelector::VisitWord64Equal(Node* const node) {
Node* const user = node;
- FlagsContinuation cont(kEqual, node);
+ FlagsContinuation cont = FlagsContinuation::ForSet(kEqual, node);
Int64BinopMatcher m(user);
if (m.right().Is(0)) {
Node* const value = m.left().node();
@@ -2064,7 +2090,7 @@ void InstructionSelector::VisitWord64Equal(Node* const node) {
void InstructionSelector::VisitInt32AddWithOverflow(Node* node) {
if (Node* ovf = NodeProperties::FindProjection(node, 1)) {
- FlagsContinuation cont(kOverflow, ovf);
+ FlagsContinuation cont = FlagsContinuation::ForSet(kOverflow, ovf);
return VisitBinop<Int32BinopMatcher>(this, node, kArm64Add32,
kArithmeticImm, &cont);
}
@@ -2075,7 +2101,7 @@ void InstructionSelector::VisitInt32AddWithOverflow(Node* node) {
void InstructionSelector::VisitInt32SubWithOverflow(Node* node) {
if (Node* ovf = NodeProperties::FindProjection(node, 1)) {
- FlagsContinuation cont(kOverflow, ovf);
+ FlagsContinuation cont = FlagsContinuation::ForSet(kOverflow, ovf);
return VisitBinop<Int32BinopMatcher>(this, node, kArm64Sub32,
kArithmeticImm, &cont);
}
@@ -2086,7 +2112,7 @@ void InstructionSelector::VisitInt32SubWithOverflow(Node* node) {
void InstructionSelector::VisitInt64AddWithOverflow(Node* node) {
if (Node* ovf = NodeProperties::FindProjection(node, 1)) {
- FlagsContinuation cont(kOverflow, ovf);
+ FlagsContinuation cont = FlagsContinuation::ForSet(kOverflow, ovf);
return VisitBinop<Int64BinopMatcher>(this, node, kArm64Add, kArithmeticImm,
&cont);
}
@@ -2097,7 +2123,7 @@ void InstructionSelector::VisitInt64AddWithOverflow(Node* node) {
void InstructionSelector::VisitInt64SubWithOverflow(Node* node) {
if (Node* ovf = NodeProperties::FindProjection(node, 1)) {
- FlagsContinuation cont(kOverflow, ovf);
+ FlagsContinuation cont = FlagsContinuation::ForSet(kOverflow, ovf);
return VisitBinop<Int64BinopMatcher>(this, node, kArm64Sub, kArithmeticImm,
&cont);
}
@@ -2107,61 +2133,65 @@ void InstructionSelector::VisitInt64SubWithOverflow(Node* node) {
void InstructionSelector::VisitInt64LessThan(Node* node) {
- FlagsContinuation cont(kSignedLessThan, node);
+ FlagsContinuation cont = FlagsContinuation::ForSet(kSignedLessThan, node);
VisitWordCompare(this, node, kArm64Cmp, &cont, false, kArithmeticImm);
}
void InstructionSelector::VisitInt64LessThanOrEqual(Node* node) {
- FlagsContinuation cont(kSignedLessThanOrEqual, node);
+ FlagsContinuation cont =
+ FlagsContinuation::ForSet(kSignedLessThanOrEqual, node);
VisitWordCompare(this, node, kArm64Cmp, &cont, false, kArithmeticImm);
}
void InstructionSelector::VisitUint64LessThan(Node* node) {
- FlagsContinuation cont(kUnsignedLessThan, node);
+ FlagsContinuation cont = FlagsContinuation::ForSet(kUnsignedLessThan, node);
VisitWordCompare(this, node, kArm64Cmp, &cont, false, kArithmeticImm);
}
void InstructionSelector::VisitUint64LessThanOrEqual(Node* node) {
- FlagsContinuation cont(kUnsignedLessThanOrEqual, node);
+ FlagsContinuation cont =
+ FlagsContinuation::ForSet(kUnsignedLessThanOrEqual, node);
VisitWordCompare(this, node, kArm64Cmp, &cont, false, kArithmeticImm);
}
void InstructionSelector::VisitFloat32Equal(Node* node) {
- FlagsContinuation cont(kEqual, node);
+ FlagsContinuation cont = FlagsContinuation::ForSet(kEqual, node);
VisitFloat32Compare(this, node, &cont);
}
void InstructionSelector::VisitFloat32LessThan(Node* node) {
- FlagsContinuation cont(kFloatLessThan, node);
+ FlagsContinuation cont = FlagsContinuation::ForSet(kFloatLessThan, node);
VisitFloat32Compare(this, node, &cont);
}
void InstructionSelector::VisitFloat32LessThanOrEqual(Node* node) {
- FlagsContinuation cont(kFloatLessThanOrEqual, node);
+ FlagsContinuation cont =
+ FlagsContinuation::ForSet(kFloatLessThanOrEqual, node);
VisitFloat32Compare(this, node, &cont);
}
void InstructionSelector::VisitFloat64Equal(Node* node) {
- FlagsContinuation cont(kEqual, node);
+ FlagsContinuation cont = FlagsContinuation::ForSet(kEqual, node);
VisitFloat64Compare(this, node, &cont);
}
void InstructionSelector::VisitFloat64LessThan(Node* node) {
- FlagsContinuation cont(kFloatLessThan, node);
+ FlagsContinuation cont = FlagsContinuation::ForSet(kFloatLessThan, node);
VisitFloat64Compare(this, node, &cont);
}
void InstructionSelector::VisitFloat64LessThanOrEqual(Node* node) {
- FlagsContinuation cont(kFloatLessThanOrEqual, node);
+ FlagsContinuation cont =
+ FlagsContinuation::ForSet(kFloatLessThanOrEqual, node);
VisitFloat64Compare(this, node, &cont);
}
« no previous file with comments | « src/compiler/arm/instruction-selector-arm.cc ('k') | src/compiler/branch-elimination.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698