Commit f61780c4 authored by Ross McIlroy's avatar Ross McIlroy Committed by Commit Bot

[TurboProp] Use GraphAssembler for all Select and Effect-Control lowerings.

TurboProp will not reschedule after effect-control linearization, so
the graph-assembler will be used to modify the schedule as new nodes
are added. To enable this, ensure we use the graph assembler for all
node creation from effect-control linearization onwards.

BUG=v8:9684

Change-Id: I2be3f5d2a3f2cbee44c72bb397e9bd1d9ac7de05
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1832166
Auto-Submit: Ross McIlroy <rmcilroy@chromium.org>
Commit-Queue: Georg Neis <neis@chromium.org>
Reviewed-by: 's avatarGeorg Neis <neis@chromium.org>
Cr-Commit-Position: refs/heads/master@{#64072}
parent 647f6568
...@@ -252,6 +252,7 @@ class EffectControlLinearizer { ...@@ -252,6 +252,7 @@ class EffectControlLinearizer {
Node* SmiShiftBitsConstant(); Node* SmiShiftBitsConstant();
void TransitionElementsTo(Node* node, Node* array, ElementsKind from, void TransitionElementsTo(Node* node, Node* array, ElementsKind from,
ElementsKind to); ElementsKind to);
void ConnectUnreachableToEnd(Node* effect, Node* control);
Factory* factory() const { return isolate()->factory(); } Factory* factory() const { return isolate()->factory(); }
Isolate* isolate() const { return jsgraph()->isolate(); } Isolate* isolate() const { return jsgraph()->isolate(); }
...@@ -313,19 +314,8 @@ struct PendingEffectPhi { ...@@ -313,19 +314,8 @@ struct PendingEffectPhi {
: effect_phi(effect_phi), block(block) {} : effect_phi(effect_phi), block(block) {}
}; };
void ConnectUnreachableToEnd(Node* effect, Node* control, JSGraph* jsgraph) {
Graph* graph = jsgraph->graph();
CommonOperatorBuilder* common = jsgraph->common();
if (effect->opcode() == IrOpcode::kDead) return;
if (effect->opcode() != IrOpcode::kUnreachable) {
effect = graph->NewNode(common->Unreachable(), effect, control);
}
Node* throw_node = graph->NewNode(common->Throw(), effect, control);
NodeProperties::MergeControlToEnd(graph, common, throw_node);
}
void UpdateEffectPhi(Node* node, BasicBlock* block, void UpdateEffectPhi(Node* node, BasicBlock* block,
BlockEffectControlMap* block_effects, JSGraph* jsgraph) { BlockEffectControlMap* block_effects) {
// Update all inputs to an effect phi with the effects from the given // Update all inputs to an effect phi with the effects from the given
// block->effect map. // block->effect map.
DCHECK_EQ(IrOpcode::kEffectPhi, node->opcode()); DCHECK_EQ(IrOpcode::kEffectPhi, node->opcode());
...@@ -612,7 +602,7 @@ void EffectControlLinearizer::Run() { ...@@ -612,7 +602,7 @@ void EffectControlLinearizer::Run() {
// record the effect phi for later processing. // record the effect phi for later processing.
pending_effect_phis.push_back(PendingEffectPhi(effect_phi, block)); pending_effect_phis.push_back(PendingEffectPhi(effect_phi, block));
} else { } else {
UpdateEffectPhi(effect_phi, block, &block_effects, jsgraph()); UpdateEffectPhi(effect_phi, block, &block_effects);
} }
} }
...@@ -654,7 +644,7 @@ void EffectControlLinearizer::Run() { ...@@ -654,7 +644,7 @@ void EffectControlLinearizer::Run() {
if (control->opcode() == IrOpcode::kLoop) { if (control->opcode() == IrOpcode::kLoop) {
pending_effect_phis.push_back(PendingEffectPhi(effect, block)); pending_effect_phis.push_back(PendingEffectPhi(effect, block));
} else { } else {
UpdateEffectPhi(effect, block, &block_effects, jsgraph()); UpdateEffectPhi(effect, block, &block_effects);
} }
} else if (control->opcode() == IrOpcode::kIfException) { } else if (control->opcode() == IrOpcode::kIfException) {
// The IfException is connected into the effect chain, so we need // The IfException is connected into the effect chain, so we need
...@@ -739,7 +729,7 @@ void EffectControlLinearizer::Run() { ...@@ -739,7 +729,7 @@ void EffectControlLinearizer::Run() {
// during the first pass (because they could have incoming back edges). // during the first pass (because they could have incoming back edges).
for (const PendingEffectPhi& pending_effect_phi : pending_effect_phis) { for (const PendingEffectPhi& pending_effect_phi : pending_effect_phis) {
UpdateEffectPhi(pending_effect_phi.effect_phi, pending_effect_phi.block, UpdateEffectPhi(pending_effect_phi.effect_phi, pending_effect_phi.block,
&block_effects, jsgraph()); &block_effects);
} }
} }
...@@ -833,7 +823,7 @@ void EffectControlLinearizer::ProcessNode(Node* node, Node** frame_state, ...@@ -833,7 +823,7 @@ void EffectControlLinearizer::ProcessNode(Node* node, Node** frame_state,
// Break the effect chain on {Unreachable} and reconnect to the graph end. // Break the effect chain on {Unreachable} and reconnect to the graph end.
// Mark the following code for deletion by connecting to the {Dead} node. // Mark the following code for deletion by connecting to the {Dead} node.
if (node->opcode() == IrOpcode::kUnreachable) { if (node->opcode() == IrOpcode::kUnreachable) {
ConnectUnreachableToEnd(*effect, *control, jsgraph()); ConnectUnreachableToEnd(*effect, *control);
*effect = *control = jsgraph()->Dead(); *effect = *control = jsgraph()->Dead();
} }
} }
...@@ -1339,6 +1329,13 @@ bool EffectControlLinearizer::TryWireInStateEffect(Node* node, ...@@ -1339,6 +1329,13 @@ bool EffectControlLinearizer::TryWireInStateEffect(Node* node,
return true; return true;
} }
void EffectControlLinearizer::ConnectUnreachableToEnd(Node* effect,
Node* control) {
DCHECK_EQ(effect->opcode(), IrOpcode::kUnreachable);
Node* throw_node = graph()->NewNode(common()->Throw(), effect, control);
NodeProperties::MergeControlToEnd(graph(), common(), throw_node);
}
#define __ gasm()-> #define __ gasm()->
Node* EffectControlLinearizer::LowerChangeFloat64ToTagged(Node* node) { Node* EffectControlLinearizer::LowerChangeFloat64ToTagged(Node* node) {
...@@ -2042,9 +2039,8 @@ Node* EffectControlLinearizer::LowerStringConcat(Node* node) { ...@@ -2042,9 +2039,8 @@ Node* EffectControlLinearizer::LowerStringConcat(Node* node) {
callable.descriptor().GetStackParameterCount(), CallDescriptor::kNoFlags, callable.descriptor().GetStackParameterCount(), CallDescriptor::kNoFlags,
Operator::kNoDeopt | Operator::kNoWrite | Operator::kNoThrow); Operator::kNoDeopt | Operator::kNoWrite | Operator::kNoThrow);
Node* value = Node* value = __ Call(call_descriptor, __ HeapConstant(callable.code()), lhs,
__ Call(call_descriptor, jsgraph()->HeapConstant(callable.code()), lhs, rhs, __ NoContextConstant());
rhs, __ NoContextConstant());
return value; return value;
} }
...@@ -2126,8 +2122,7 @@ Node* EffectControlLinearizer::LowerCheckedInt32Div(Node* node, ...@@ -2126,8 +2122,7 @@ Node* EffectControlLinearizer::LowerCheckedInt32Div(Node* node,
// Check if {lhs} is kMinInt and {rhs} is -1, in which case we'd have // Check if {lhs} is kMinInt and {rhs} is -1, in which case we'd have
// to return -kMinInt, which is not representable as Word32. // to return -kMinInt, which is not representable as Word32.
Node* check_lhs_minint = graph()->NewNode(machine()->Word32Equal(), lhs, Node* check_lhs_minint = __ Word32Equal(lhs, __ Int32Constant(kMinInt));
__ Int32Constant(kMinInt));
__ Branch(check_lhs_minint, &if_lhs_minint, &if_lhs_notminint); __ Branch(check_lhs_minint, &if_lhs_minint, &if_lhs_notminint);
__ Bind(&if_lhs_minint); __ Bind(&if_lhs_minint);
...@@ -2774,7 +2769,7 @@ Node* EffectControlLinearizer::LowerChangeUint64ToBigInt(Node* node) { ...@@ -2774,7 +2769,7 @@ Node* EffectControlLinearizer::LowerChangeUint64ToBigInt(Node* node) {
DCHECK(machine()->Is64()); DCHECK(machine()->Is64());
Node* value = node->InputAt(0); Node* value = node->InputAt(0);
Node* map = jsgraph()->HeapConstant(factory()->bigint_map()); Node* map = __ HeapConstant(factory()->bigint_map());
// BigInts with value 0 must be of size 0 (canonical form). // BigInts with value 0 must be of size 0 (canonical form).
auto if_zerodigits = __ MakeLabel(); auto if_zerodigits = __ MakeLabel();
auto if_onedigit = __ MakeLabel(); auto if_onedigit = __ MakeLabel();
...@@ -3559,7 +3554,7 @@ Node* EffectControlLinearizer::LowerNewDoubleElements(Node* node) { ...@@ -3559,7 +3554,7 @@ Node* EffectControlLinearizer::LowerNewDoubleElements(Node* node) {
auto done = __ MakeLabel(MachineRepresentation::kTaggedPointer); auto done = __ MakeLabel(MachineRepresentation::kTaggedPointer);
Node* zero_length = __ IntPtrEqual(length, __ IntPtrConstant(0)); Node* zero_length = __ IntPtrEqual(length, __ IntPtrConstant(0));
__ GotoIf(zero_length, &done, __ GotoIf(zero_length, &done,
jsgraph()->HeapConstant(factory()->empty_fixed_array())); __ HeapConstant(factory()->empty_fixed_array()));
// Compute the effective size of the backing store. // Compute the effective size of the backing store.
Node* size = __ IntAdd(__ WordShl(length, __ IntPtrConstant(kDoubleSizeLog2)), Node* size = __ IntAdd(__ WordShl(length, __ IntPtrConstant(kDoubleSizeLog2)),
...@@ -3607,7 +3602,7 @@ Node* EffectControlLinearizer::LowerNewSmiOrObjectElements(Node* node) { ...@@ -3607,7 +3602,7 @@ Node* EffectControlLinearizer::LowerNewSmiOrObjectElements(Node* node) {
auto done = __ MakeLabel(MachineRepresentation::kTaggedPointer); auto done = __ MakeLabel(MachineRepresentation::kTaggedPointer);
Node* zero_length = __ IntPtrEqual(length, __ IntPtrConstant(0)); Node* zero_length = __ IntPtrEqual(length, __ IntPtrConstant(0));
__ GotoIf(zero_length, &done, __ GotoIf(zero_length, &done,
jsgraph()->HeapConstant(factory()->empty_fixed_array())); __ HeapConstant(factory()->empty_fixed_array()));
// Compute the effective size of the backing store. // Compute the effective size of the backing store.
Node* size = __ IntAdd(__ WordShl(length, __ IntPtrConstant(kTaggedSizeLog2)), Node* size = __ IntAdd(__ WordShl(length, __ IntPtrConstant(kTaggedSizeLog2)),
...@@ -3689,10 +3684,9 @@ Node* EffectControlLinearizer::LowerNewConsString(Node* node) { ...@@ -3689,10 +3684,9 @@ Node* EffectControlLinearizer::LowerNewConsString(Node* node) {
__ Branch(__ Word32Equal(encoding, __ Int32Constant(kTwoByteStringTag)), __ Branch(__ Word32Equal(encoding, __ Int32Constant(kTwoByteStringTag)),
&if_twobyte, &if_onebyte); &if_twobyte, &if_onebyte);
__ Bind(&if_onebyte); __ Bind(&if_onebyte);
__ Goto(&done, __ Goto(&done, __ HeapConstant(factory()->cons_one_byte_string_map()));
jsgraph()->HeapConstant(factory()->cons_one_byte_string_map()));
__ Bind(&if_twobyte); __ Bind(&if_twobyte);
__ Goto(&done, jsgraph()->HeapConstant(factory()->cons_string_map())); __ Goto(&done, __ HeapConstant(factory()->cons_string_map()));
__ Bind(&done); __ Bind(&done);
Node* result_map = done.PhiAt(0); Node* result_map = done.PhiAt(0);
...@@ -4305,9 +4299,8 @@ Node* EffectControlLinearizer::LowerBigIntAdd(Node* node, Node* frame_state) { ...@@ -4305,9 +4299,8 @@ Node* EffectControlLinearizer::LowerBigIntAdd(Node* node, Node* frame_state) {
graph()->zone(), callable.descriptor(), graph()->zone(), callable.descriptor(),
callable.descriptor().GetStackParameterCount(), CallDescriptor::kNoFlags, callable.descriptor().GetStackParameterCount(), CallDescriptor::kNoFlags,
Operator::kFoldable | Operator::kNoThrow); Operator::kFoldable | Operator::kNoThrow);
Node* value = Node* value = __ Call(call_descriptor, __ HeapConstant(callable.code()), lhs,
__ Call(call_descriptor, jsgraph()->HeapConstant(callable.code()), lhs, rhs, __ NoContextConstant());
rhs, __ NoContextConstant());
// Check for exception sentinel: Smi is returned to signal BigIntTooBig. // Check for exception sentinel: Smi is returned to signal BigIntTooBig.
__ DeoptimizeIf(DeoptimizeReason::kBigIntTooBig, FeedbackSource{}, __ DeoptimizeIf(DeoptimizeReason::kBigIntTooBig, FeedbackSource{},
...@@ -4323,9 +4316,8 @@ Node* EffectControlLinearizer::LowerBigIntNegate(Node* node) { ...@@ -4323,9 +4316,8 @@ Node* EffectControlLinearizer::LowerBigIntNegate(Node* node) {
graph()->zone(), callable.descriptor(), graph()->zone(), callable.descriptor(),
callable.descriptor().GetStackParameterCount(), CallDescriptor::kNoFlags, callable.descriptor().GetStackParameterCount(), CallDescriptor::kNoFlags,
Operator::kFoldable | Operator::kNoThrow); Operator::kFoldable | Operator::kNoThrow);
Node* value = Node* value = __ Call(call_descriptor, __ HeapConstant(callable.code()),
__ Call(call_descriptor, jsgraph()->HeapConstant(callable.code()), node->InputAt(0), __ NoContextConstant());
node->InputAt(0), __ NoContextConstant());
return value; return value;
} }
...@@ -4879,9 +4871,8 @@ Node* EffectControlLinearizer::LowerLoadFieldByIndex(Node* node) { ...@@ -4879,9 +4871,8 @@ Node* EffectControlLinearizer::LowerLoadFieldByIndex(Node* node) {
// to copy anything anyway. // to copy anything anyway.
__ GotoIf(ObjectIsSmi(field), &done, field); __ GotoIf(ObjectIsSmi(field), &done, field);
Node* field_map = __ LoadField(AccessBuilder::ForMap(), field); Node* field_map = __ LoadField(AccessBuilder::ForMap(), field);
__ GotoIfNot( __ GotoIfNot(__ TaggedEqual(field_map, __ HeapNumberMapConstant()), &done,
__ TaggedEqual(field_map, jsgraph()->HeapNumberMapConstant()), &done, field);
field);
Node* value = __ LoadField(AccessBuilder::ForHeapNumberValue(), field); Node* value = __ LoadField(AccessBuilder::ForHeapNumberValue(), field);
__ Goto(&done_double, value); __ Goto(&done_double, value);
...@@ -5478,7 +5469,7 @@ void EffectControlLinearizer::LowerRuntimeAbort(Node* node) { ...@@ -5478,7 +5469,7 @@ void EffectControlLinearizer::LowerRuntimeAbort(Node* node) {
auto call_descriptor = Linkage::GetRuntimeCallDescriptor( auto call_descriptor = Linkage::GetRuntimeCallDescriptor(
graph()->zone(), id, 1, properties, CallDescriptor::kNoFlags); graph()->zone(), id, 1, properties, CallDescriptor::kNoFlags);
__ Call(call_descriptor, __ CEntryStubConstant(1), __ Call(call_descriptor, __ CEntryStubConstant(1),
jsgraph()->SmiConstant(static_cast<int>(reason)), __ SmiConstant(static_cast<int>(reason)),
__ ExternalConstant(ExternalReference::Create(id)), __ ExternalConstant(ExternalReference::Create(id)),
__ Int32Constant(1), __ NoContextConstant()); __ Int32Constant(1), __ NoContextConstant());
} }
......
...@@ -1758,8 +1758,7 @@ struct LateOptimizationPhase { ...@@ -1758,8 +1758,7 @@ struct LateOptimizationPhase {
CommonOperatorReducer common_reducer(&graph_reducer, data->graph(), CommonOperatorReducer common_reducer(&graph_reducer, data->graph(),
data->broker(), data->common(), data->broker(), data->common(),
data->machine(), temp_zone); data->machine(), temp_zone);
SelectLowering select_lowering(data->jsgraph()->graph(), SelectLowering select_lowering(data->jsgraph(), temp_zone);
data->jsgraph()->common());
#ifdef V8_COMPRESS_POINTERS #ifdef V8_COMPRESS_POINTERS
DecompressionElimination decompression_elimination( DecompressionElimination decompression_elimination(
&graph_reducer, data->graph(), data->machine(), data->common()); &graph_reducer, data->graph(), data->machine(), data->common());
...@@ -1798,8 +1797,7 @@ struct MidTierMachineLoweringPhase { ...@@ -1798,8 +1797,7 @@ struct MidTierMachineLoweringPhase {
GraphReducer graph_reducer(temp_zone, data->graph(), GraphReducer graph_reducer(temp_zone, data->graph(),
&data->info()->tick_counter(), &data->info()->tick_counter(),
data->jsgraph()->Dead()); data->jsgraph()->Dead());
SelectLowering select_lowering(data->jsgraph()->graph(), SelectLowering select_lowering(data->jsgraph(), temp_zone);
data->jsgraph()->common());
MemoryLowering memory_lowering(data->jsgraph(), temp_zone, MemoryLowering memory_lowering(data->jsgraph(), temp_zone,
data->info()->GetPoisoningMitigationLevel()); data->info()->GetPoisoningMitigationLevel());
......
...@@ -14,29 +14,39 @@ namespace v8 { ...@@ -14,29 +14,39 @@ namespace v8 {
namespace internal { namespace internal {
namespace compiler { namespace compiler {
SelectLowering::SelectLowering(Graph* graph, CommonOperatorBuilder* common) SelectLowering::SelectLowering(JSGraph* jsgraph, Zone* zone)
: common_(common), graph_(graph) {} : graph_assembler_(jsgraph, nullptr, nullptr, zone),
start_(jsgraph->graph()->start()) {}
SelectLowering::~SelectLowering() = default; SelectLowering::~SelectLowering() = default;
Reduction SelectLowering::Reduce(Node* node) { Reduction SelectLowering::Reduce(Node* node) {
if (node->opcode() != IrOpcode::kSelect) return NoChange(); if (node->opcode() != IrOpcode::kSelect) return NoChange();
return Changed(LowerSelect(node));
}
#define __ gasm()->
Node* SelectLowering::LowerSelect(Node* node) {
SelectParameters const p = SelectParametersOf(node->op()); SelectParameters const p = SelectParametersOf(node->op());
Node* cond = node->InputAt(0); Node* condition = node->InputAt(0);
Node* vthen = node->InputAt(1); Node* vtrue = node->InputAt(1);
Node* velse = node->InputAt(2); Node* vfalse = node->InputAt(2);
// Create a diamond and a phi. gasm()->Reset(start(), start());
Diamond d(graph(), common(), cond, p.hint());
node->ReplaceInput(0, vthen); auto done = __ MakeLabel(p.representation());
node->ReplaceInput(1, velse);
node->ReplaceInput(2, d.merge); __ GotoIf(condition, &done, vtrue);
NodeProperties::ChangeOp(node, common()->Phi(p.representation(), 2)); __ Goto(&done, vfalse);
return Changed(node); __ Bind(&done);
return done.PhiAt(0);
} }
#undef __
} // namespace compiler } // namespace compiler
} // namespace internal } // namespace internal
} // namespace v8 } // namespace v8
...@@ -5,33 +5,31 @@ ...@@ -5,33 +5,31 @@
#ifndef V8_COMPILER_SELECT_LOWERING_H_ #ifndef V8_COMPILER_SELECT_LOWERING_H_
#define V8_COMPILER_SELECT_LOWERING_H_ #define V8_COMPILER_SELECT_LOWERING_H_
#include "src/compiler/graph-assembler.h"
#include "src/compiler/graph-reducer.h" #include "src/compiler/graph-reducer.h"
namespace v8 { namespace v8 {
namespace internal { namespace internal {
namespace compiler { namespace compiler {
// Forward declarations.
class CommonOperatorBuilder;
class Graph;
// Lowers Select nodes to diamonds. // Lowers Select nodes to diamonds.
class SelectLowering final : public Reducer { class SelectLowering final : public Reducer {
public: public:
SelectLowering(Graph* graph, CommonOperatorBuilder* common); SelectLowering(JSGraph* jsgraph, Zone* zone);
~SelectLowering() override; ~SelectLowering() override;
const char* reducer_name() const override { return "SelectLowering"; } const char* reducer_name() const override { return "SelectLowering"; }
Reduction Reduce(Node* node) override; Reduction Reduce(Node* node) override;
Node* LowerSelect(Node* node);
private: private:
CommonOperatorBuilder* common() const { return common_; } GraphAssembler* gasm() { return &graph_assembler_; }
Graph* graph() const { return graph_; } Node* start() { return start_; }
CommonOperatorBuilder* common_; GraphAssembler graph_assembler_;
Graph* graph_; Node* start_;
}; };
} // namespace compiler } // namespace compiler
......
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