Commit e1bed4f9 authored by mbrandy's avatar mbrandy Committed by Commit bot

PPC: [turbofan] Introduce DeoptimizeIf And DeoptimizeUnless common operators.

Port c129aa4d

Original commit message:
    These macro operators represent a conditional eager deoptimization exit
    without explicit branching, which greatly reduces overhead of both
    scheduling and register allocation, and thereby greatly reduces overall
    compilation time, esp. when there are a lot of eager deoptimization
    exits.

R=bmeurer@chromium.org, joransiu@ca.ibm.com, jyan@ca.ibm.com, michael_dawson@ca.ibm.com
BUG=

Review URL: https://codereview.chromium.org/1730383002

Cr-Commit-Position: refs/heads/master@{#34267}
parent 546ea6b8
...@@ -32,6 +32,7 @@ class PPCOperandConverter final : public InstructionOperandConverter { ...@@ -32,6 +32,7 @@ class PPCOperandConverter final : public InstructionOperandConverter {
RCBit OutputRCBit() const { RCBit OutputRCBit() const {
switch (instr_->flags_mode()) { switch (instr_->flags_mode()) {
case kFlags_branch: case kFlags_branch:
case kFlags_deoptimize:
case kFlags_set: case kFlags_set:
return SetRC; return SetRC;
case kFlags_none: case kFlags_none:
...@@ -1589,6 +1590,9 @@ void CodeGenerator::AssembleDeoptimizerCall( ...@@ -1589,6 +1590,9 @@ void CodeGenerator::AssembleDeoptimizerCall(
int deoptimization_id, Deoptimizer::BailoutType bailout_type) { int deoptimization_id, Deoptimizer::BailoutType bailout_type) {
Address deopt_entry = Deoptimizer::GetDeoptimizationEntry( Address deopt_entry = Deoptimizer::GetDeoptimizationEntry(
isolate(), deoptimization_id, bailout_type); isolate(), deoptimization_id, bailout_type);
// TODO(turbofan): We should be able to generate better code by sharing the
// actual final call site and just bl'ing to it here, similar to what we do
// in the lithium backend.
__ Call(deopt_entry, RelocInfo::RUNTIME_ENTRY); __ Call(deopt_entry, RelocInfo::RUNTIME_ENTRY);
} }
......
...@@ -144,8 +144,13 @@ void VisitBinop(InstructionSelector* selector, Node* node, ...@@ -144,8 +144,13 @@ void VisitBinop(InstructionSelector* selector, Node* node,
DCHECK_GE(arraysize(inputs), input_count); DCHECK_GE(arraysize(inputs), input_count);
DCHECK_GE(arraysize(outputs), output_count); DCHECK_GE(arraysize(outputs), output_count);
selector->Emit(cont->Encode(opcode), output_count, outputs, input_count, opcode = cont->Encode(opcode);
inputs); 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);
}
} }
...@@ -1264,7 +1269,7 @@ void InstructionSelector::VisitFloat64RoundTiesEven(Node* node) { ...@@ -1264,7 +1269,7 @@ void InstructionSelector::VisitFloat64RoundTiesEven(Node* node) {
void InstructionSelector::VisitInt32AddWithOverflow(Node* node) { void InstructionSelector::VisitInt32AddWithOverflow(Node* node) {
if (Node* ovf = NodeProperties::FindProjection(node, 1)) { if (Node* ovf = NodeProperties::FindProjection(node, 1)) {
FlagsContinuation cont(kOverflow, ovf); FlagsContinuation cont = FlagsContinuation::ForSet(kOverflow, ovf);
return VisitBinop<Int32BinopMatcher>(this, node, kPPC_AddWithOverflow32, return VisitBinop<Int32BinopMatcher>(this, node, kPPC_AddWithOverflow32,
kInt16Imm, &cont); kInt16Imm, &cont);
} }
...@@ -1276,7 +1281,7 @@ void InstructionSelector::VisitInt32AddWithOverflow(Node* node) { ...@@ -1276,7 +1281,7 @@ void InstructionSelector::VisitInt32AddWithOverflow(Node* node) {
void InstructionSelector::VisitInt32SubWithOverflow(Node* node) { void InstructionSelector::VisitInt32SubWithOverflow(Node* node) {
if (Node* ovf = NodeProperties::FindProjection(node, 1)) { if (Node* ovf = NodeProperties::FindProjection(node, 1)) {
FlagsContinuation cont(kOverflow, ovf); FlagsContinuation cont = FlagsContinuation::ForSet(kOverflow, ovf);
return VisitBinop<Int32BinopMatcher>(this, node, kPPC_SubWithOverflow32, return VisitBinop<Int32BinopMatcher>(this, node, kPPC_SubWithOverflow32,
kInt16Imm_Negate, &cont); kInt16Imm_Negate, &cont);
} }
...@@ -1289,7 +1294,7 @@ void InstructionSelector::VisitInt32SubWithOverflow(Node* node) { ...@@ -1289,7 +1294,7 @@ void InstructionSelector::VisitInt32SubWithOverflow(Node* node) {
#if V8_TARGET_ARCH_PPC64 #if V8_TARGET_ARCH_PPC64
void InstructionSelector::VisitInt64AddWithOverflow(Node* node) { void InstructionSelector::VisitInt64AddWithOverflow(Node* node) {
if (Node* ovf = NodeProperties::FindProjection(node, 1)) { if (Node* ovf = NodeProperties::FindProjection(node, 1)) {
FlagsContinuation cont(kOverflow, ovf); FlagsContinuation cont = FlagsContinuation::ForSet(kOverflow, ovf);
return VisitBinop<Int64BinopMatcher>(this, node, kPPC_Add, kInt16Imm, return VisitBinop<Int64BinopMatcher>(this, node, kPPC_Add, kInt16Imm,
&cont); &cont);
} }
...@@ -1300,7 +1305,7 @@ void InstructionSelector::VisitInt64AddWithOverflow(Node* node) { ...@@ -1300,7 +1305,7 @@ void InstructionSelector::VisitInt64AddWithOverflow(Node* node) {
void InstructionSelector::VisitInt64SubWithOverflow(Node* node) { void InstructionSelector::VisitInt64SubWithOverflow(Node* node) {
if (Node* ovf = NodeProperties::FindProjection(node, 1)) { if (Node* ovf = NodeProperties::FindProjection(node, 1)) {
FlagsContinuation cont(kOverflow, ovf); FlagsContinuation cont = FlagsContinuation::ForSet(kOverflow, ovf);
return VisitBinop<Int64BinopMatcher>(this, node, kPPC_Sub, kInt16Imm_Negate, return VisitBinop<Int64BinopMatcher>(this, node, kPPC_Sub, kInt16Imm_Negate,
&cont); &cont);
} }
...@@ -1336,6 +1341,9 @@ void VisitCompare(InstructionSelector* selector, InstructionCode opcode, ...@@ -1336,6 +1341,9 @@ void VisitCompare(InstructionSelector* selector, InstructionCode opcode,
if (cont->IsBranch()) { if (cont->IsBranch()) {
selector->Emit(opcode, g.NoOutput(), left, right, selector->Emit(opcode, g.NoOutput(), left, right,
g.Label(cont->true_block()), g.Label(cont->false_block())); 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 { } else {
DCHECK(cont->IsSet()); DCHECK(cont->IsSet());
selector->Emit(opcode, g.DefineAsRegister(cont->result()), left, right); selector->Emit(opcode, g.DefineAsRegister(cont->result()), left, right);
...@@ -1573,6 +1581,17 @@ void InstructionSelector::VisitBranch(Node* branch, BasicBlock* tbranch, ...@@ -1573,6 +1581,17 @@ void InstructionSelector::VisitBranch(Node* branch, BasicBlock* tbranch,
VisitWord32CompareZero(this, branch, branch->InputAt(0), &cont); VisitWord32CompareZero(this, branch, branch->InputAt(0), &cont);
} }
void InstructionSelector::VisitDeoptimizeIf(Node* node) {
FlagsContinuation cont =
FlagsContinuation::ForDeoptimize(kNotEqual, node->InputAt(1));
VisitWord32CompareZero(this, node, node->InputAt(0), &cont);
}
void InstructionSelector::VisitDeoptimizeUnless(Node* node) {
FlagsContinuation cont =
FlagsContinuation::ForDeoptimize(kEqual, node->InputAt(1));
VisitWord32CompareZero(this, node, node->InputAt(0), &cont);
}
void InstructionSelector::VisitSwitch(Node* node, const SwitchInfo& sw) { void InstructionSelector::VisitSwitch(Node* node, const SwitchInfo& sw) {
PPCOperandGenerator g(this); PPCOperandGenerator g(this);
...@@ -1603,7 +1622,7 @@ void InstructionSelector::VisitSwitch(Node* node, const SwitchInfo& sw) { ...@@ -1603,7 +1622,7 @@ void InstructionSelector::VisitSwitch(Node* node, const SwitchInfo& sw) {
void InstructionSelector::VisitWord32Equal(Node* const node) { void InstructionSelector::VisitWord32Equal(Node* const node) {
FlagsContinuation cont(kEqual, node); FlagsContinuation cont = FlagsContinuation::ForSet(kEqual, node);
Int32BinopMatcher m(node); Int32BinopMatcher m(node);
if (m.right().Is(0)) { if (m.right().Is(0)) {
return VisitWord32CompareZero(this, m.node(), m.left().node(), &cont); return VisitWord32CompareZero(this, m.node(), m.left().node(), &cont);
...@@ -1613,32 +1632,34 @@ void InstructionSelector::VisitWord32Equal(Node* const node) { ...@@ -1613,32 +1632,34 @@ void InstructionSelector::VisitWord32Equal(Node* const node) {
void InstructionSelector::VisitInt32LessThan(Node* node) { void InstructionSelector::VisitInt32LessThan(Node* node) {
FlagsContinuation cont(kSignedLessThan, node); FlagsContinuation cont = FlagsContinuation::ForSet(kSignedLessThan, node);
VisitWord32Compare(this, node, &cont); VisitWord32Compare(this, node, &cont);
} }
void InstructionSelector::VisitInt32LessThanOrEqual(Node* node) { void InstructionSelector::VisitInt32LessThanOrEqual(Node* node) {
FlagsContinuation cont(kSignedLessThanOrEqual, node); FlagsContinuation cont =
FlagsContinuation::ForSet(kSignedLessThanOrEqual, node);
VisitWord32Compare(this, node, &cont); VisitWord32Compare(this, node, &cont);
} }
void InstructionSelector::VisitUint32LessThan(Node* node) { void InstructionSelector::VisitUint32LessThan(Node* node) {
FlagsContinuation cont(kUnsignedLessThan, node); FlagsContinuation cont = FlagsContinuation::ForSet(kUnsignedLessThan, node);
VisitWord32Compare(this, node, &cont); VisitWord32Compare(this, node, &cont);
} }
void InstructionSelector::VisitUint32LessThanOrEqual(Node* node) { void InstructionSelector::VisitUint32LessThanOrEqual(Node* node) {
FlagsContinuation cont(kUnsignedLessThanOrEqual, node); FlagsContinuation cont =
FlagsContinuation::ForSet(kUnsignedLessThanOrEqual, node);
VisitWord32Compare(this, node, &cont); VisitWord32Compare(this, node, &cont);
} }
#if V8_TARGET_ARCH_PPC64 #if V8_TARGET_ARCH_PPC64
void InstructionSelector::VisitWord64Equal(Node* const node) { void InstructionSelector::VisitWord64Equal(Node* const node) {
FlagsContinuation cont(kEqual, node); FlagsContinuation cont = FlagsContinuation::ForSet(kEqual, node);
Int64BinopMatcher m(node); Int64BinopMatcher m(node);
if (m.right().Is(0)) { if (m.right().Is(0)) {
return VisitWord64CompareZero(this, m.node(), m.left().node(), &cont); return VisitWord64CompareZero(this, m.node(), m.left().node(), &cont);
...@@ -1648,62 +1669,66 @@ void InstructionSelector::VisitWord64Equal(Node* const node) { ...@@ -1648,62 +1669,66 @@ void InstructionSelector::VisitWord64Equal(Node* const node) {
void InstructionSelector::VisitInt64LessThan(Node* node) { void InstructionSelector::VisitInt64LessThan(Node* node) {
FlagsContinuation cont(kSignedLessThan, node); FlagsContinuation cont = FlagsContinuation::ForSet(kSignedLessThan, node);
VisitWord64Compare(this, node, &cont); VisitWord64Compare(this, node, &cont);
} }
void InstructionSelector::VisitInt64LessThanOrEqual(Node* node) { void InstructionSelector::VisitInt64LessThanOrEqual(Node* node) {
FlagsContinuation cont(kSignedLessThanOrEqual, node); FlagsContinuation cont =
FlagsContinuation::ForSet(kSignedLessThanOrEqual, node);
VisitWord64Compare(this, node, &cont); VisitWord64Compare(this, node, &cont);
} }
void InstructionSelector::VisitUint64LessThan(Node* node) { void InstructionSelector::VisitUint64LessThan(Node* node) {
FlagsContinuation cont(kUnsignedLessThan, node); FlagsContinuation cont = FlagsContinuation::ForSet(kUnsignedLessThan, node);
VisitWord64Compare(this, node, &cont); VisitWord64Compare(this, node, &cont);
} }
void InstructionSelector::VisitUint64LessThanOrEqual(Node* node) { void InstructionSelector::VisitUint64LessThanOrEqual(Node* node) {
FlagsContinuation cont(kUnsignedLessThanOrEqual, node); FlagsContinuation cont =
FlagsContinuation::ForSet(kUnsignedLessThanOrEqual, node);
VisitWord64Compare(this, node, &cont); VisitWord64Compare(this, node, &cont);
} }
#endif #endif
void InstructionSelector::VisitFloat32Equal(Node* node) { void InstructionSelector::VisitFloat32Equal(Node* node) {
FlagsContinuation cont(kEqual, node); FlagsContinuation cont = FlagsContinuation::ForSet(kEqual, node);
VisitFloat32Compare(this, node, &cont); VisitFloat32Compare(this, node, &cont);
} }
void InstructionSelector::VisitFloat32LessThan(Node* node) { void InstructionSelector::VisitFloat32LessThan(Node* node) {
FlagsContinuation cont(kUnsignedLessThan, node); FlagsContinuation cont = FlagsContinuation::ForSet(kUnsignedLessThan, node);
VisitFloat32Compare(this, node, &cont); VisitFloat32Compare(this, node, &cont);
} }
void InstructionSelector::VisitFloat32LessThanOrEqual(Node* node) { void InstructionSelector::VisitFloat32LessThanOrEqual(Node* node) {
FlagsContinuation cont(kUnsignedLessThanOrEqual, node); FlagsContinuation cont =
FlagsContinuation::ForSet(kUnsignedLessThanOrEqual, node);
VisitFloat32Compare(this, node, &cont); VisitFloat32Compare(this, node, &cont);
} }
void InstructionSelector::VisitFloat64Equal(Node* node) { void InstructionSelector::VisitFloat64Equal(Node* node) {
FlagsContinuation cont(kEqual, node); FlagsContinuation cont = FlagsContinuation::ForSet(kEqual, node);
VisitFloat64Compare(this, node, &cont); VisitFloat64Compare(this, node, &cont);
} }
void InstructionSelector::VisitFloat64LessThan(Node* node) { void InstructionSelector::VisitFloat64LessThan(Node* node) {
FlagsContinuation cont(kUnsignedLessThan, node); FlagsContinuation cont = FlagsContinuation::ForSet(kUnsignedLessThan, node);
VisitFloat64Compare(this, node, &cont); VisitFloat64Compare(this, node, &cont);
} }
void InstructionSelector::VisitFloat64LessThanOrEqual(Node* node) { void InstructionSelector::VisitFloat64LessThanOrEqual(Node* node) {
FlagsContinuation cont(kUnsignedLessThanOrEqual, node); FlagsContinuation cont =
FlagsContinuation::ForSet(kUnsignedLessThanOrEqual, node);
VisitFloat64Compare(this, node, &cont); VisitFloat64Compare(this, node, &cont);
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment