[TurboProp] Remove the second schedule for TurboProp.

This rearranges the TurboProp pipeline to avoid the need for a second
schedule of the graph. To do this, it moves the final schedule creation
before effect-control-linearization (which used a temporary schedule
previously, and with TurboFan). It then enables the block updater in the
graph assembler for effect control linearization and does select and
memory lowering in a new ScheduledMachineLowering phase to maintain
this existing schedule during these lowering passes.

BUG=v8:9684

Change-Id: I6a7790b010f8b152dd01d85aa95ee5d4f99087a5
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1847351
Commit-Queue: Ross McIlroy <rmcilroy@chromium.org>
Reviewed-by: Tobias Tebbi <tebbi@chromium.org>
Reviewed-by: Georg Neis <neis@chromium.org>
Cr-Commit-Position: refs/heads/master@{#64537}
This commit is contained in:
Ross McIlroy 2019-10-23 16:36:21 +01:00 committed by Commit Bot
parent e0c1ca5a30
commit 22fd955507
15 changed files with 292 additions and 115 deletions

View File

@ -1828,6 +1828,8 @@ v8_compiler_sources = [
"src/compiler/representation-change.h",
"src/compiler/schedule.cc",
"src/compiler/schedule.h",
"src/compiler/scheduled-machine-lowering.cc",
"src/compiler/scheduled-machine-lowering.h",
"src/compiler/scheduler.cc",
"src/compiler/scheduler.h",
"src/compiler/select-lowering.cc",

View File

@ -34,14 +34,17 @@ class EffectControlLinearizer {
Zone* temp_zone,
SourcePositionTable* source_positions,
NodeOriginTable* node_origins,
MaskArrayIndexEnable mask_array_index)
MaskArrayIndexEnable mask_array_index,
MaintainSchedule maintain_schedule)
: js_graph_(js_graph),
schedule_(schedule),
temp_zone_(temp_zone),
mask_array_index_(mask_array_index),
maintain_schedule_(maintain_schedule),
source_positions_(source_positions),
node_origins_(node_origins),
graph_assembler_(js_graph, temp_zone),
graph_assembler_(js_graph, temp_zone,
should_maintain_schedule() ? schedule : nullptr),
frame_state_zapper_(nullptr) {}
void Run();
@ -253,6 +256,10 @@ class EffectControlLinearizer {
void TransitionElementsTo(Node* node, Node* array, ElementsKind from,
ElementsKind to);
bool should_maintain_schedule() const {
return maintain_schedule_ == MaintainSchedule::kMaintain;
}
Factory* factory() const { return isolate()->factory(); }
Isolate* isolate() const { return jsgraph()->isolate(); }
JSGraph* jsgraph() const { return js_graph_; }
@ -270,6 +277,7 @@ class EffectControlLinearizer {
Schedule* schedule_;
Zone* temp_zone_;
MaskArrayIndexEnable mask_array_index_;
MaintainSchedule maintain_schedule_;
RegionObservability region_observability_ = RegionObservability::kObservable;
SourcePositionTable* source_positions_;
NodeOriginTable* node_origins_;
@ -544,6 +552,8 @@ void EffectControlLinearizer::Run() {
ZoneVector<BasicBlock*> pending_block_controls(temp_zone());
NodeVector inputs_buffer(temp_zone());
// TODO(rmcilroy) We should not depend on having rpo_order on schedule, and
// instead just do our own RPO walk here.
for (BasicBlock* block : *(schedule()->rpo_order())) {
gasm()->Reset(block);
@ -704,7 +714,8 @@ void EffectControlLinearizer::Run() {
break;
}
if (block->control() == BasicBlock::kBranch) {
if (!should_maintain_schedule() &&
block->control() == BasicBlock::kBranch) {
TryCloneBranch(block->control_input(), block, temp_zone(), graph(),
common(), &block_effects, source_positions_,
node_origins_);
@ -732,6 +743,7 @@ void EffectControlLinearizer::Run() {
UpdateEffectPhi(pending_effect_phi.effect_phi, pending_effect_phi.block,
&block_effects);
}
schedule_->rpo_order()->clear();
}
@ -757,6 +769,13 @@ void EffectControlLinearizer::ProcessNode(Node* node, Node** frame_state) {
source_positions_->GetSourcePosition(node));
NodeOriginTable::Scope origin_scope(node_origins_, "process node", node);
// If basic block is unreachable after this point, update the node's effect
// and control inputs to mark it as dead, but don't process further.
if (gasm()->current_effect() == jsgraph()->Dead()) {
UpdateEffectControlForNode(node);
return;
}
// If the node needs to be wired into the effect/control chain, do this
// here. Pass current frame state for lowering to eager deoptimization.
if (TryWireInStateEffect(node, *frame_state)) {
@ -6053,10 +6072,11 @@ Node* EffectControlLinearizer::LowerDateNow(Node* node) {
void LinearizeEffectControl(JSGraph* graph, Schedule* schedule, Zone* temp_zone,
SourcePositionTable* source_positions,
NodeOriginTable* node_origins,
MaskArrayIndexEnable mask_array_index) {
MaskArrayIndexEnable mask_array_index,
MaintainSchedule maintain_schedule) {
EffectControlLinearizer linearizer(graph, schedule, temp_zone,
source_positions, node_origins,
mask_array_index);
mask_array_index, maintain_schedule);
linearizer.Run();
}

View File

@ -24,10 +24,12 @@ class SourcePositionTable;
enum class MaskArrayIndexEnable { kDoNotMaskArrayIndex, kMaskArrayIndex };
enum class MaintainSchedule { kMaintain, kDiscard };
V8_EXPORT_PRIVATE void LinearizeEffectControl(
JSGraph* graph, Schedule* schedule, Zone* temp_zone,
SourcePositionTable* source_positions, NodeOriginTable* node_origins,
MaskArrayIndexEnable mask_array_index);
MaskArrayIndexEnable mask_array_index, MaintainSchedule maintain_schedule);
} // namespace compiler
} // namespace internal

View File

@ -261,11 +261,16 @@ void GraphAssembler::BasicBlockUpdater::AddThrow(Node* node) {
}
schedule_->AddThrow(current_block_, node);
// Clear original successors and update the original control and control input
// to the throw, since this block is now connected directly to end().
saved_successors_.clear();
// Clear original successors and replace the block's original control and
// control input to the throw, since this block is now connected directly to
// the end.
if (original_control_input_ != nullptr) {
NodeProperties::ReplaceUses(original_control_input_, node, nullptr, node);
original_control_input_->Kill();
}
original_control_input_ = node;
original_control_ = BasicBlock::kThrow;
saved_successors_.clear();
}
void GraphAssembler::BasicBlockUpdater::UpdateSuccessors(BasicBlock* block) {
@ -317,19 +322,14 @@ BasicBlock* GraphAssembler::BasicBlockUpdater::Finalize(BasicBlock* original) {
return block;
}
GraphAssembler::GraphAssembler(JSGraph* jsgraph, Zone* zone)
GraphAssembler::GraphAssembler(JSGraph* jsgraph, Zone* zone, Schedule* schedule)
: temp_zone_(zone),
jsgraph_(jsgraph),
current_effect_(nullptr),
current_control_(nullptr),
block_updater_(nullptr) {}
GraphAssembler::GraphAssembler(JSGraph* jsgraph, Schedule* schedule, Zone* zone)
: temp_zone_(zone),
jsgraph_(jsgraph),
current_effect_(nullptr),
current_control_(nullptr),
block_updater_(new BasicBlockUpdater(schedule, jsgraph->graph(), zone)) {}
block_updater_(schedule != nullptr ? new BasicBlockUpdater(
schedule, jsgraph->graph(), zone)
: nullptr) {}
GraphAssembler::~GraphAssembler() = default;
@ -660,7 +660,15 @@ void GraphAssembler::GotoIfBasicBlock(BasicBlock* block, Node* branch,
BasicBlock* GraphAssembler::FinalizeCurrentBlock(BasicBlock* block) {
if (block_updater_) {
return block_updater_->Finalize(block);
block = block_updater_->Finalize(block);
if (current_control_ == jsgraph()->Dead()) {
// If the block's end is unreachable, then reset current effect and
// control to that of the block's throw control node.
DCHECK(block->control() == BasicBlock::kThrow);
Node* throw_node = block->control_input();
current_control_ = NodeProperties::GetControlInput(throw_node);
current_effect_ = NodeProperties::GetEffectInput(throw_node);
}
}
return block;
}

View File

@ -167,11 +167,9 @@ class GraphAssemblerLabel {
class GraphAssembler {
public:
// Constructs a GraphAssembler that operates on an unscheduled graph.
GraphAssembler(JSGraph* jsgraph, Zone* zone);
// Constructs a GraphAssembler that operates on a scheduled graph, updating
// the schedule in the process.
GraphAssembler(JSGraph* jsgraph, Schedule* schedule, Zone* zone);
// Constructs a GraphAssembler. If {schedule} is not null, the graph assembler
// will maintain the schedule as it updates blocks.
GraphAssembler(JSGraph* jsgraph, Zone* zone, Schedule* schedule = nullptr);
~GraphAssembler();
void Reset(BasicBlock* block);

View File

@ -44,13 +44,17 @@ class MemoryLowering::AllocationGroup final : public ZoneObject {
};
MemoryLowering::MemoryLowering(JSGraph* jsgraph, Zone* zone,
GraphAssembler* graph_assembler,
PoisoningMitigationLevel poisoning_level,
AllocationFolding allocation_folding,
WriteBarrierAssertFailedCallback callback,
const char* function_debug_name)
: jsgraph_(jsgraph),
: isolate_(jsgraph->isolate()),
zone_(zone),
graph_assembler_(jsgraph, zone),
graph_zone_(jsgraph->graph()->zone()),
common_(jsgraph->common()),
machine_(jsgraph->machine()),
graph_assembler_(graph_assembler),
allocation_folding_(allocation_folding),
poisoning_level_(poisoning_level),
write_barrier_assert_failed_(callback),
@ -195,7 +199,7 @@ Reduction MemoryLowering::ReduceAllocateRaw(
if (!allocate_operator_.is_set()) {
auto descriptor = AllocateDescriptor{};
auto call_descriptor = Linkage::GetStubCallDescriptor(
graph()->zone(), descriptor, descriptor.GetStackParameterCount(),
graph_zone(), descriptor, descriptor.GetStackParameterCount(),
CallDescriptor::kCanUseRoots, Operator::kNoThrow);
allocate_operator_.set(common()->Call(call_descriptor));
}
@ -256,7 +260,7 @@ Reduction MemoryLowering::ReduceAllocateRaw(
if (!allocate_operator_.is_set()) {
auto descriptor = AllocateDescriptor{};
auto call_descriptor = Linkage::GetStubCallDescriptor(
graph()->zone(), descriptor, descriptor.GetStackParameterCount(),
graph_zone(), descriptor, descriptor.GetStackParameterCount(),
CallDescriptor::kCanUseRoots, Operator::kNoThrow);
allocate_operator_.set(common()->Call(call_descriptor));
}
@ -275,22 +279,6 @@ Reduction MemoryLowering::ReduceAllocateRaw(
}
}
// Replace all effect uses of {node} with the {effect} and replace
// all value uses of {node} with the {value}.
for (Edge edge : node->use_edges()) {
if (NodeProperties::IsEffectEdge(edge)) {
edge.UpdateTo(effect);
} else if (NodeProperties::IsValueEdge(edge)) {
edge.UpdateTo(value);
} else {
DCHECK(NodeProperties::IsControlEdge(edge));
edge.UpdateTo(control);
}
}
// Kill the {node} to make sure we don't leave dangling dead uses.
node->Kill();
return Replace(value);
}
@ -318,8 +306,8 @@ Reduction MemoryLowering::ReduceLoadElement(Node* node) {
Reduction MemoryLowering::ReduceLoadField(Node* node) {
DCHECK_EQ(IrOpcode::kLoadField, node->opcode());
FieldAccess const& access = FieldAccessOf(node->op());
Node* offset = jsgraph()->IntPtrConstant(access.offset - access.tag());
node->InsertInput(graph()->zone(), 1, offset);
Node* offset = __ IntPtrConstant(access.offset - access.tag());
node->InsertInput(graph_zone(), 1, offset);
MachineType type = access.machine_type;
if (NeedsPoisoning(access.load_sensitivity)) {
NodeProperties::ChangeOp(node, machine()->PoisonedLoad(type));
@ -367,8 +355,8 @@ Reduction MemoryLowering::ReduceStoreField(Node* node,
Node* value = node->InputAt(1);
WriteBarrierKind write_barrier_kind = ComputeWriteBarrierKind(
node, object, value, state, access.write_barrier_kind);
Node* offset = jsgraph()->IntPtrConstant(access.offset - access.tag());
node->InsertInput(graph()->zone(), 1, offset);
Node* offset = __ IntPtrConstant(access.offset - access.tag());
node->InsertInput(graph_zone(), 1, offset);
NodeProperties::ChangeOp(
node, machine()->Store(StoreRepresentation(
access.machine_type.representation(), write_barrier_kind)));
@ -534,18 +522,6 @@ bool MemoryLowering::AllocationState::IsYoungGenerationAllocation() const {
return group() && group()->IsYoungGenerationAllocation();
}
Graph* MemoryLowering::graph() const { return jsgraph()->graph(); }
Isolate* MemoryLowering::isolate() const { return jsgraph()->isolate(); }
CommonOperatorBuilder* MemoryLowering::common() const {
return jsgraph()->common();
}
MachineOperatorBuilder* MemoryLowering::machine() const {
return jsgraph()->machine();
}
} // namespace compiler
} // namespace internal
} // namespace v8

View File

@ -71,7 +71,8 @@ class MemoryLowering final : public Reducer {
Node* node, Node* object, const char* name, Zone* temp_zone)>;
MemoryLowering(
JSGraph* jsgraph, Zone* zone, PoisoningMitigationLevel poisoning_level,
JSGraph* jsgraph, Zone* zone, GraphAssembler* graph_assembler,
PoisoningMitigationLevel poisoning_level,
AllocationFolding allocation_folding =
AllocationFolding::kDontAllocationFolding,
WriteBarrierAssertFailedCallback callback = [](Node*, Node*, const char*,
@ -110,17 +111,20 @@ class MemoryLowering final : public Reducer {
bool NeedsPoisoning(LoadSensitivity load_sensitivity) const;
Graph* graph() const;
Isolate* isolate() const;
Isolate* isolate() const { return isolate_; }
Zone* zone() const { return zone_; }
JSGraph* jsgraph() const { return jsgraph_; }
CommonOperatorBuilder* common() const;
MachineOperatorBuilder* machine() const;
GraphAssembler* gasm() { return &graph_assembler_; }
Zone* graph_zone() const { return graph_zone_; }
CommonOperatorBuilder* common() const { return common_; }
MachineOperatorBuilder* machine() const { return machine_; }
GraphAssembler* gasm() const { return graph_assembler_; }
SetOncePointer<const Operator> allocate_operator_;
JSGraph* const jsgraph_;
Isolate* isolate_;
Zone* zone_;
GraphAssembler graph_assembler_;
Zone* graph_zone_;
CommonOperatorBuilder* common_;
MachineOperatorBuilder* machine_;
GraphAssembler* graph_assembler_;
AllocationFolding allocation_folding_;
PoisoningMitigationLevel poisoning_level_;
WriteBarrierAssertFailedCallback write_barrier_assert_failed_;

View File

@ -185,8 +185,10 @@ MemoryOptimizer::MemoryOptimizer(
JSGraph* jsgraph, Zone* zone, PoisoningMitigationLevel poisoning_level,
MemoryLowering::AllocationFolding allocation_folding,
const char* function_debug_name, TickCounter* tick_counter)
: memory_lowering_(jsgraph, zone, poisoning_level, allocation_folding,
WriteBarrierAssertFailed, function_debug_name),
: graph_assembler_(jsgraph, zone),
memory_lowering_(jsgraph, zone, &graph_assembler_, poisoning_level,
allocation_folding, WriteBarrierAssertFailed,
function_debug_name),
jsgraph_(jsgraph),
empty_state_(AllocationState::Empty(zone)),
pending_(zone),
@ -311,8 +313,17 @@ void MemoryOptimizer::VisitAllocateRaw(Node* node,
}
}
memory_lowering()->ReduceAllocateRaw(
Reduction reduction = memory_lowering()->ReduceAllocateRaw(
node, allocation_type, allocation.allow_large_objects(), &state);
CHECK(reduction.Changed() && reduction.replacement() != node);
// Replace all uses of node and kill the node to make sure we don't leave
// dangling dead uses.
NodeProperties::ReplaceUses(node, reduction.replacement(),
graph_assembler_.current_effect(),
graph_assembler_.current_control());
node->Kill();
EnqueueUses(state->effect(), state);
}

View File

@ -5,6 +5,7 @@
#ifndef V8_COMPILER_MEMORY_OPTIMIZER_H_
#define V8_COMPILER_MEMORY_OPTIMIZER_H_
#include "src/compiler/graph-assembler.h"
#include "src/compiler/memory-lowering.h"
#include "src/zone/zone-containers.h"
@ -78,6 +79,7 @@ class MemoryOptimizer final {
JSGraph* jsgraph() const { return jsgraph_; }
Zone* zone() const { return zone_; }
GraphAssembler graph_assembler_;
MemoryLowering memory_lowering_;
JSGraph* jsgraph_;
AllocationState const* const empty_state_;

View File

@ -65,6 +65,7 @@
#include "src/compiler/pipeline-statistics.h"
#include "src/compiler/redundancy-elimination.h"
#include "src/compiler/schedule.h"
#include "src/compiler/scheduled-machine-lowering.h"
#include "src/compiler/scheduler.h"
#include "src/compiler/select-lowering.h"
#include "src/compiler/serializer-for-background-compilation.h"
@ -1645,7 +1646,7 @@ struct EffectControlLinearizationPhase {
// - introduce effect phis and rewire effects to get SSA again.
LinearizeEffectControl(data->jsgraph(), schedule, temp_zone,
data->source_positions(), data->node_origins(),
mask_array_index);
mask_array_index, MaintainSchedule::kDiscard);
}
{
// The {EffectControlLinearizer} might leave {Dead} nodes behind, so we
@ -1759,7 +1760,8 @@ struct LateOptimizationPhase {
CommonOperatorReducer common_reducer(&graph_reducer, data->graph(),
data->broker(), data->common(),
data->machine(), temp_zone);
SelectLowering select_lowering(data->jsgraph(), temp_zone);
GraphAssembler graph_assembler(data->jsgraph(), temp_zone);
SelectLowering select_lowering(&graph_assembler, data->graph());
// TODO(v8:7703, solanes): go back to using #if guards once
// FLAG_turbo_decompression_elimination gets removed.
DecompressionElimination decompression_elimination(
@ -1806,20 +1808,48 @@ struct DecompressionOptimizationPhase {
}
};
struct MidTierMachineLoweringPhase {
static const char* phase_name() { return "V8.TFMidTierMachineLoweringPhase"; }
struct ScheduledEffectControlLinearizationPhase {
static const char* phase_name() {
return "V8.TFScheduledEffectControlLinearizationPhase";
}
void Run(PipelineData* data, Zone* temp_zone) {
GraphReducer graph_reducer(temp_zone, data->graph(),
&data->info()->tick_counter(),
data->jsgraph()->Dead());
SelectLowering select_lowering(data->jsgraph(), temp_zone);
MemoryLowering memory_lowering(data->jsgraph(), temp_zone,
data->info()->GetPoisoningMitigationLevel());
MaskArrayIndexEnable mask_array_index =
(data->info()->GetPoisoningMitigationLevel() !=
PoisoningMitigationLevel::kDontPoison)
? MaskArrayIndexEnable::kMaskArrayIndex
: MaskArrayIndexEnable::kDoNotMaskArrayIndex;
// Post-pass for wiring the control/effects
// - connect allocating representation changes into the control&effect
// chains and lower them,
// - get rid of the region markers,
// - introduce effect phis and rewire effects to get SSA again.
LinearizeEffectControl(data->jsgraph(), data->schedule(), temp_zone,
data->source_positions(), data->node_origins(),
mask_array_index, MaintainSchedule::kMaintain);
AddReducer(data, &graph_reducer, &memory_lowering);
AddReducer(data, &graph_reducer, &select_lowering);
graph_reducer.ReduceGraph();
// TODO(rmcilroy) Avoid having to rebuild rpo_order on schedule each time.
Scheduler::ComputeSpecialRPO(temp_zone, data->schedule());
TraceSchedule(data->info(), data, data->schedule(),
"effect linearization schedule");
}
};
struct ScheduledMachineLoweringPhase {
static const char* phase_name() {
return "V8.TFScheduledMachineLoweringPhase";
}
void Run(PipelineData* data, Zone* temp_zone) {
ScheduledMachineLowering machine_lowering(
data->jsgraph(), data->schedule(), temp_zone, data->source_positions(),
data->node_origins(), data->info()->GetPoisoningMitigationLevel());
machine_lowering.Run();
// TODO(rmcilroy) Avoid having to rebuild rpo_order on schedule each time.
Scheduler::ComputeSpecialRPO(temp_zone, data->schedule());
TraceSchedule(data->info(), data, data->schedule(),
"machine lowered schedule");
}
};
@ -2498,19 +2528,20 @@ bool PipelineImpl::OptimizeGraphForMidTier(Linkage* linkage) {
data->BeginPhaseKind("V8.TFBlockBuilding");
Run<EffectControlLinearizationPhase>();
RunPrintAndVerify(EffectControlLinearizationPhase::phase_name(), true);
ComputeScheduledGraph();
Run<MidTierMachineLoweringPhase>();
RunPrintAndVerify(MidTierMachineLoweringPhase::phase_name(), true);
Run<ScheduledEffectControlLinearizationPhase>();
RunPrintAndVerify(ScheduledEffectControlLinearizationPhase::phase_name(),
true);
Run<ScheduledMachineLoweringPhase>();
RunPrintAndVerify(ScheduledMachineLoweringPhase::phase_name(), true);
data->source_positions()->RemoveDecorator();
if (data->info()->trace_turbo_json_enabled()) {
data->node_origins()->RemoveDecorator();
}
ComputeScheduledGraph();
return SelectInstructions(linkage);
}

View File

@ -0,0 +1,69 @@
// Copyright 2019 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "src/compiler/scheduled-machine-lowering.h"
#include "src/compiler/compiler-source-position-table.h"
#include "src/compiler/js-graph.h"
#include "src/compiler/node-origin-table.h"
#include "src/compiler/node-properties.h"
#include "src/compiler/schedule.h"
namespace v8 {
namespace internal {
namespace compiler {
ScheduledMachineLowering::ScheduledMachineLowering(
JSGraph* js_graph, Schedule* schedule, Zone* temp_zone,
SourcePositionTable* source_positions, NodeOriginTable* node_origins,
PoisoningMitigationLevel poison_level)
: schedule_(schedule),
graph_assembler_(js_graph, temp_zone, schedule),
select_lowering_(&graph_assembler_, js_graph->graph()),
memory_lowering_(js_graph, temp_zone, &graph_assembler_, poison_level),
reducers_({&select_lowering_, &memory_lowering_}, temp_zone),
source_positions_(source_positions),
node_origins_(node_origins) {}
void ScheduledMachineLowering::Run() {
// TODO(rmcilroy) We should not depend on having rpo_order on schedule, and
// instead just do our own RPO walk here.
for (BasicBlock* block : *(schedule()->rpo_order())) {
BasicBlock::iterator instr = block->begin();
BasicBlock::iterator end_instr = block->end();
gasm()->Reset(block);
for (; instr != end_instr; instr++) {
Node* node = *instr;
Reduction reduction;
for (auto reducer : reducers_) {
reduction = reducer->Reduce(node);
if (reduction.Changed()) break;
}
if (reduction.Changed()) {
Node* replacement = reduction.replacement();
if (replacement != node) {
// Replace all uses of node and kill the node to make sure we don't
// leave dangling dead uses.
NodeProperties::ReplaceUses(node, replacement,
gasm()->current_effect(),
gasm()->current_control());
node->Kill();
} else {
gasm()->AddNode(replacement);
}
} else {
gasm()->AddNode(node);
}
}
gasm()->FinalizeCurrentBlock(block);
}
schedule_->rpo_order()->clear();
}
} // namespace compiler
} // namespace internal
} // namespace v8

View File

@ -0,0 +1,51 @@
// Copyright 2019 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef V8_COMPILER_SCHEDULED_MACHINE_LOWERING_H_
#define V8_COMPILER_SCHEDULED_MACHINE_LOWERING_H_
#include "src/compiler/graph-assembler.h"
#include "src/compiler/memory-lowering.h"
#include "src/compiler/select-lowering.h"
namespace v8 {
namespace internal {
namespace compiler {
class NodeOriginTable;
class Schedule;
class SourcePositionTable;
// Performs machine lowering on an already scheduled graph.
class ScheduledMachineLowering final {
public:
ScheduledMachineLowering(JSGraph* js_graph, Schedule* schedule,
Zone* temp_zone,
SourcePositionTable* source_positions,
NodeOriginTable* node_origins,
PoisoningMitigationLevel poison_level);
~ScheduledMachineLowering() = default;
void Run();
private:
bool LowerNode(Node* node);
GraphAssembler* gasm() { return &graph_assembler_; }
Schedule* schedule() { return schedule_; }
Schedule* schedule_;
GraphAssembler graph_assembler_;
SelectLowering select_lowering_;
MemoryLowering memory_lowering_;
ZoneVector<Reducer*> reducers_;
SourcePositionTable* source_positions_;
NodeOriginTable* node_origins_;
};
} // namespace compiler
} // namespace internal
} // namespace v8
#endif // V8_COMPILER_SCHEDULED_MACHINE_LOWERING_H_

View File

@ -6,27 +6,28 @@
#include "src/compiler/common-operator.h"
#include "src/compiler/diamond.h"
#include "src/compiler/graph-assembler.h"
#include "src/compiler/graph.h"
#include "src/compiler/node.h"
#include "src/compiler/node-properties.h"
#include "src/compiler/node.h"
namespace v8 {
namespace internal {
namespace compiler {
SelectLowering::SelectLowering(JSGraph* jsgraph, Zone* zone)
: graph_assembler_(jsgraph, zone), start_(jsgraph->graph()->start()) {}
SelectLowering::SelectLowering(GraphAssembler* graph_assembler, Graph* graph)
: graph_assembler_(graph_assembler), start_(graph->start()) {}
SelectLowering::~SelectLowering() = default;
Reduction SelectLowering::Reduce(Node* node) {
if (node->opcode() != IrOpcode::kSelect) return NoChange();
return Changed(LowerSelect(node));
return LowerSelect(node);
}
#define __ gasm()->
Node* SelectLowering::LowerSelect(Node* node) {
Reduction SelectLowering::LowerSelect(Node* node) {
SelectParameters const p = SelectParametersOf(node->op());
Node* condition = node->InputAt(0);
@ -41,7 +42,7 @@ Node* SelectLowering::LowerSelect(Node* node) {
__ Goto(&done, vfalse);
__ Bind(&done);
return done.PhiAt(0);
return Changed(done.PhiAt(0));
}
#undef __

View File

@ -5,30 +5,32 @@
#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 GraphAssembler;
// Lowers Select nodes to diamonds.
class SelectLowering final : public Reducer {
public:
SelectLowering(JSGraph* jsgraph, Zone* zone);
SelectLowering(GraphAssembler* graph_assembler, Graph* graph);
~SelectLowering() override;
const char* reducer_name() const override { return "SelectLowering"; }
Reduction Reduce(Node* node) override;
Node* LowerSelect(Node* node);
private:
GraphAssembler* gasm() { return &graph_assembler_; }
Node* start() { return start_; }
Reduction LowerSelect(Node* node);
GraphAssembler graph_assembler_;
GraphAssembler* gasm() const { return graph_assembler_; }
Node* start() const { return start_; }
GraphAssembler* graph_assembler_;
Node* start_;
};

View File

@ -85,9 +85,9 @@ TEST_F(EffectControlLinearizerTest, SimpleLoad) {
schedule.AddReturn(start, ret);
// Run the state effect introducer.
LinearizeEffectControl(jsgraph(), &schedule, zone(), source_positions(),
node_origins(),
MaskArrayIndexEnable::kDoNotMaskArrayIndex);
LinearizeEffectControl(
jsgraph(), &schedule, zone(), source_positions(), node_origins(),
MaskArrayIndexEnable::kDoNotMaskArrayIndex, MaintainSchedule::kDiscard);
EXPECT_THAT(load,
IsLoadField(AccessBuilder::ForHeapNumberValue(), heap_number,
@ -147,9 +147,9 @@ TEST_F(EffectControlLinearizerTest, DiamondLoad) {
schedule.AddReturn(mblock, ret);
// Run the state effect introducer.
LinearizeEffectControl(jsgraph(), &schedule, zone(), source_positions(),
node_origins(),
MaskArrayIndexEnable::kDoNotMaskArrayIndex);
LinearizeEffectControl(
jsgraph(), &schedule, zone(), source_positions(), node_origins(),
MaskArrayIndexEnable::kDoNotMaskArrayIndex, MaintainSchedule::kDiscard);
// The effect input to the return should be an effect phi with the
// newly introduced effectful change operators.
@ -214,9 +214,9 @@ TEST_F(EffectControlLinearizerTest, LoopLoad) {
schedule.AddReturn(rblock, ret);
// Run the state effect introducer.
LinearizeEffectControl(jsgraph(), &schedule, zone(), source_positions(),
node_origins(),
MaskArrayIndexEnable::kDoNotMaskArrayIndex);
LinearizeEffectControl(
jsgraph(), &schedule, zone(), source_positions(), node_origins(),
MaskArrayIndexEnable::kDoNotMaskArrayIndex, MaintainSchedule::kDiscard);
ASSERT_THAT(ret, IsReturn(load, load, if_true));
EXPECT_THAT(load, IsLoadField(AccessBuilder::ForHeapNumberValue(),
@ -277,9 +277,9 @@ TEST_F(EffectControlLinearizerTest, CloneBranch) {
schedule.AddNode(mblock, merge);
schedule.AddNode(mblock, graph()->end());
LinearizeEffectControl(jsgraph(), &schedule, zone(), source_positions(),
node_origins(),
MaskArrayIndexEnable::kDoNotMaskArrayIndex);
LinearizeEffectControl(
jsgraph(), &schedule, zone(), source_positions(), node_origins(),
MaskArrayIndexEnable::kDoNotMaskArrayIndex, MaintainSchedule::kDiscard);
Capture<Node *> branch1_capture, branch2_capture;
EXPECT_THAT(