[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:
Ross McIlroy 2019-10-01 16:49:41 +01:00 committed by Commit Bot
parent 647f6568e6
commit f61780c432
4 changed files with 62 additions and 65 deletions

View File

@ -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());
}

View File

@ -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());

View File

@ -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

View File

@ -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