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