[csa] enable basic Turbofan machine graph optimizations
This enables Turbofan's machine graph constant folding and branch reduction on CSA/Torque code. Bug: v8:7793 Change-Id: I5ada63d0c6d920e5f900b8e9255d884c799a9c1e Reviewed-on: https://chromium-review.googlesource.com/c/1373785 Commit-Queue: Tobias Tebbi <tebbi@chromium.org> Reviewed-by: Jaroslav Sevcik <jarin@chromium.org> Cr-Commit-Position: refs/heads/master@{#58219}
This commit is contained in:
parent
a176aec77f
commit
bc9704e030
@ -65,7 +65,8 @@ Reduction DeadCodeElimination::Reduce(Node* node) {
|
||||
case IrOpcode::kDeoptimize:
|
||||
case IrOpcode::kReturn:
|
||||
case IrOpcode::kTerminate:
|
||||
return ReduceDeoptimizeOrReturnOrTerminate(node);
|
||||
case IrOpcode::kTailCall:
|
||||
return ReduceDeoptimizeOrReturnOrTerminateOrTailCall(node);
|
||||
case IrOpcode::kThrow:
|
||||
return PropagateDeadControl(node);
|
||||
case IrOpcode::kBranch:
|
||||
@ -281,10 +282,12 @@ Reduction DeadCodeElimination::ReduceEffectNode(Node* node) {
|
||||
return NoChange();
|
||||
}
|
||||
|
||||
Reduction DeadCodeElimination::ReduceDeoptimizeOrReturnOrTerminate(Node* node) {
|
||||
Reduction DeadCodeElimination::ReduceDeoptimizeOrReturnOrTerminateOrTailCall(
|
||||
Node* node) {
|
||||
DCHECK(node->opcode() == IrOpcode::kDeoptimize ||
|
||||
node->opcode() == IrOpcode::kReturn ||
|
||||
node->opcode() == IrOpcode::kTerminate);
|
||||
node->opcode() == IrOpcode::kTerminate ||
|
||||
node->opcode() == IrOpcode::kTailCall);
|
||||
Reduction reduction = PropagateDeadControl(node);
|
||||
if (reduction.Changed()) return reduction;
|
||||
if (FindDeadInput(node) != nullptr) {
|
||||
|
@ -56,7 +56,7 @@ class V8_EXPORT_PRIVATE DeadCodeElimination final
|
||||
Reduction ReducePureNode(Node* node);
|
||||
Reduction ReduceUnreachableOrIfException(Node* node);
|
||||
Reduction ReduceEffectNode(Node* node);
|
||||
Reduction ReduceDeoptimizeOrReturnOrTerminate(Node* node);
|
||||
Reduction ReduceDeoptimizeOrReturnOrTerminateOrTailCall(Node* node);
|
||||
Reduction ReduceBranchOrSwitch(Node* node);
|
||||
|
||||
Reduction RemoveLoopExit(Node* node);
|
||||
|
@ -18,9 +18,12 @@ namespace v8 {
|
||||
namespace internal {
|
||||
namespace compiler {
|
||||
|
||||
MachineOperatorReducer::MachineOperatorReducer(MachineGraph* mcgraph,
|
||||
MachineOperatorReducer::MachineOperatorReducer(Editor* editor,
|
||||
MachineGraph* mcgraph,
|
||||
bool allow_signalling_nan)
|
||||
: mcgraph_(mcgraph), allow_signalling_nan_(allow_signalling_nan) {}
|
||||
: AdvancedReducer(editor),
|
||||
mcgraph_(mcgraph),
|
||||
allow_signalling_nan_(allow_signalling_nan) {}
|
||||
|
||||
MachineOperatorReducer::~MachineOperatorReducer() = default;
|
||||
|
||||
@ -702,6 +705,14 @@ Reduction MachineOperatorReducer::Reduce(Node* node) {
|
||||
return ReduceFloat64Compare(node);
|
||||
case IrOpcode::kFloat64RoundDown:
|
||||
return ReduceFloat64RoundDown(node);
|
||||
case IrOpcode::kBitcastTaggedToWord: {
|
||||
NodeMatcher m(node->InputAt(0));
|
||||
if (m.IsBitcastWordToTaggedSigned()) {
|
||||
RelaxEffectsAndControls(node);
|
||||
return Replace(m.InputAt(0));
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -21,9 +21,9 @@ class MachineGraph;
|
||||
// Performs constant folding and strength reduction on nodes that have
|
||||
// machine operators.
|
||||
class V8_EXPORT_PRIVATE MachineOperatorReducer final
|
||||
: public NON_EXPORTED_BASE(Reducer) {
|
||||
: public NON_EXPORTED_BASE(AdvancedReducer) {
|
||||
public:
|
||||
explicit MachineOperatorReducer(MachineGraph* mcgraph,
|
||||
explicit MachineOperatorReducer(Editor* editor, MachineGraph* mcgraph,
|
||||
bool allow_signalling_nan = true);
|
||||
~MachineOperatorReducer() override;
|
||||
|
||||
|
@ -168,7 +168,7 @@ class PipelineData {
|
||||
register_allocation_zone_(register_allocation_zone_scope_.zone()),
|
||||
assembler_options_(assembler_options) {}
|
||||
|
||||
// For machine graph testing entry point.
|
||||
// For CodeStubAssembler and machine graph testing entry point.
|
||||
PipelineData(ZoneStats* zone_stats, OptimizedCompilationInfo* info,
|
||||
Isolate* isolate, Graph* graph, Schedule* schedule,
|
||||
SourcePositionTable* source_positions,
|
||||
@ -180,6 +180,7 @@ class PipelineData {
|
||||
debug_name_(info_->GetDebugName()),
|
||||
zone_stats_(zone_stats),
|
||||
graph_zone_scope_(zone_stats_, ZONE_NAME),
|
||||
graph_zone_(graph_zone_scope_.zone()),
|
||||
graph_(graph),
|
||||
source_positions_(source_positions),
|
||||
node_origins_(node_origins),
|
||||
@ -191,7 +192,17 @@ class PipelineData {
|
||||
register_allocation_zone_scope_(zone_stats_, ZONE_NAME),
|
||||
register_allocation_zone_(register_allocation_zone_scope_.zone()),
|
||||
jump_optimization_info_(jump_opt),
|
||||
assembler_options_(assembler_options) {}
|
||||
assembler_options_(assembler_options) {
|
||||
simplified_ = new (graph_zone_) SimplifiedOperatorBuilder(graph_zone_);
|
||||
machine_ = new (graph_zone_) MachineOperatorBuilder(
|
||||
graph_zone_, MachineType::PointerRepresentation(),
|
||||
InstructionSelector::SupportedMachineOperatorFlags(),
|
||||
InstructionSelector::AlignmentRequirements());
|
||||
common_ = new (graph_zone_) CommonOperatorBuilder(graph_zone_);
|
||||
javascript_ = new (graph_zone_) JSOperatorBuilder(graph_zone_);
|
||||
jsgraph_ = new (graph_zone_)
|
||||
JSGraph(isolate_, graph_, common_, javascript_, simplified_, machine_);
|
||||
}
|
||||
|
||||
// For register allocation testing entry point.
|
||||
PipelineData(ZoneStats* zone_stats, OptimizedCompilationInfo* info,
|
||||
@ -1303,7 +1314,7 @@ struct EarlyOptimizationPhase {
|
||||
data->broker());
|
||||
RedundancyElimination redundancy_elimination(&graph_reducer, temp_zone);
|
||||
ValueNumberingReducer value_numbering(temp_zone, data->graph()->zone());
|
||||
MachineOperatorReducer machine_reducer(data->jsgraph());
|
||||
MachineOperatorReducer machine_reducer(&graph_reducer, data->jsgraph());
|
||||
CommonOperatorReducer common_reducer(&graph_reducer, data->graph(),
|
||||
data->broker(), data->common(),
|
||||
data->machine(), temp_zone);
|
||||
@ -1467,7 +1478,7 @@ struct LateOptimizationPhase {
|
||||
DeadCodeElimination dead_code_elimination(&graph_reducer, data->graph(),
|
||||
data->common(), temp_zone);
|
||||
ValueNumberingReducer value_numbering(temp_zone, data->graph()->zone());
|
||||
MachineOperatorReducer machine_reducer(data->jsgraph());
|
||||
MachineOperatorReducer machine_reducer(&graph_reducer, data->jsgraph());
|
||||
CommonOperatorReducer common_reducer(&graph_reducer, data->graph(),
|
||||
data->broker(), data->common(),
|
||||
data->machine(), temp_zone);
|
||||
@ -1483,6 +1494,28 @@ struct LateOptimizationPhase {
|
||||
}
|
||||
};
|
||||
|
||||
struct CsaOptimizationPhase {
|
||||
static const char* phase_name() { return "csa optimization"; }
|
||||
|
||||
void Run(PipelineData* data, Zone* temp_zone) {
|
||||
GraphReducer graph_reducer(temp_zone, data->graph(),
|
||||
data->jsgraph()->Dead());
|
||||
BranchElimination branch_condition_elimination(&graph_reducer,
|
||||
data->jsgraph(), temp_zone);
|
||||
DeadCodeElimination dead_code_elimination(&graph_reducer, data->graph(),
|
||||
data->common(), temp_zone);
|
||||
MachineOperatorReducer machine_reducer(&graph_reducer, data->jsgraph());
|
||||
CommonOperatorReducer common_reducer(&graph_reducer, data->graph(),
|
||||
data->broker(), data->common(),
|
||||
data->machine(), temp_zone);
|
||||
AddReducer(data, &graph_reducer, &branch_condition_elimination);
|
||||
AddReducer(data, &graph_reducer, &dead_code_elimination);
|
||||
AddReducer(data, &graph_reducer, &machine_reducer);
|
||||
AddReducer(data, &graph_reducer, &common_reducer);
|
||||
graph_reducer.ReduceGraph();
|
||||
}
|
||||
};
|
||||
|
||||
struct EarlyGraphTrimmingPhase {
|
||||
static const char* phase_name() { return "early trimming"; }
|
||||
void Run(PipelineData* data, Zone* temp_zone) {
|
||||
@ -2035,12 +2068,13 @@ MaybeHandle<Code> Pipeline::GenerateCodeForCodeStub(
|
||||
// Construct a pipeline for scheduling and code generation.
|
||||
ZoneStats zone_stats(isolate->allocator());
|
||||
NodeOriginTable node_origins(graph);
|
||||
SourcePositionTable source_positions(graph);
|
||||
JumpOptimizationInfo jump_opt;
|
||||
bool should_optimize_jumps =
|
||||
isolate->serializer_enabled() && FLAG_turbo_rewrite_far_jumps;
|
||||
PipelineData data(&zone_stats, &info, isolate, graph, nullptr, nullptr,
|
||||
&node_origins, should_optimize_jumps ? &jump_opt : nullptr,
|
||||
options);
|
||||
PipelineData data(&zone_stats, &info, isolate, graph, nullptr,
|
||||
&source_positions, &node_origins,
|
||||
should_optimize_jumps ? &jump_opt : nullptr, options);
|
||||
data.set_verify_graph(FLAG_verify_csa);
|
||||
std::unique_ptr<PipelineStatistics> pipeline_statistics;
|
||||
if (FLAG_turbo_stats || FLAG_turbo_stats_nvp) {
|
||||
@ -2067,6 +2101,9 @@ MaybeHandle<Code> Pipeline::GenerateCodeForCodeStub(
|
||||
pipeline.Run<PrintGraphPhase>("Machine");
|
||||
}
|
||||
|
||||
pipeline.Run<CsaOptimizationPhase>();
|
||||
pipeline.RunPrintAndVerify(CsaOptimizationPhase::phase_name(), true);
|
||||
|
||||
pipeline.Run<VerifyGraphPhase>(true);
|
||||
pipeline.ComputeScheduledGraph();
|
||||
DCHECK_NOT_NULL(data.schedule());
|
||||
@ -2075,8 +2112,9 @@ MaybeHandle<Code> Pipeline::GenerateCodeForCodeStub(
|
||||
// repeat it for jump optimization. The first run has to happen on a temporary
|
||||
// pipeline to avoid deletion of zones on the main pipeline.
|
||||
PipelineData second_data(&zone_stats, &info, isolate, data.graph(),
|
||||
data.schedule(), nullptr, &node_origins,
|
||||
data.jump_optimization_info(), options);
|
||||
data.schedule(), data.source_positions(),
|
||||
data.node_origins(), data.jump_optimization_info(),
|
||||
options);
|
||||
second_data.set_verify_graph(FLAG_verify_csa);
|
||||
PipelineImpl second_pipeline(&second_data);
|
||||
Handle<Code> code =
|
||||
@ -2345,7 +2383,7 @@ wasm::WasmCode* Pipeline::GenerateCodeForWasmFunction(
|
||||
data.common(), scope.zone());
|
||||
ValueNumberingReducer value_numbering(scope.zone(), data.graph()->zone());
|
||||
const bool allow_signalling_nan = is_asm_js;
|
||||
MachineOperatorReducer machine_reducer(data.mcgraph(),
|
||||
MachineOperatorReducer machine_reducer(&graph_reducer, data.mcgraph(),
|
||||
allow_signalling_nan);
|
||||
CommonOperatorReducer common_reducer(&graph_reducer, data.graph(),
|
||||
data.broker(), data.common(),
|
||||
|
@ -85,7 +85,8 @@ class ReducerTester : public HandleAndZoneScope {
|
||||
graph(main_zone()),
|
||||
javascript(main_zone()),
|
||||
jsgraph(isolate, &graph, &common, &javascript, nullptr, &machine),
|
||||
maxuint32(Constant<int32_t>(kMaxUInt32)) {
|
||||
maxuint32(Constant<int32_t>(kMaxUInt32)),
|
||||
graph_reducer(main_zone(), &graph, jsgraph.Dead()) {
|
||||
Node* s = graph.NewNode(common.Start(num_parameters));
|
||||
graph.SetStart(s);
|
||||
}
|
||||
@ -99,6 +100,7 @@ class ReducerTester : public HandleAndZoneScope {
|
||||
JSOperatorBuilder javascript;
|
||||
JSGraph jsgraph;
|
||||
Node* maxuint32;
|
||||
GraphReducer graph_reducer;
|
||||
|
||||
template <typename T>
|
||||
Node* Constant(volatile T value) {
|
||||
@ -123,7 +125,7 @@ class ReducerTester : public HandleAndZoneScope {
|
||||
void CheckFoldBinop(volatile T expect, Node* a, Node* b) {
|
||||
CHECK(binop);
|
||||
Node* n = CreateBinopNode(a, b);
|
||||
MachineOperatorReducer reducer(&jsgraph);
|
||||
MachineOperatorReducer reducer(&graph_reducer, &jsgraph);
|
||||
Reduction reduction = reducer.Reduce(n);
|
||||
CHECK(reduction.Changed());
|
||||
CHECK_NE(n, reduction.replacement());
|
||||
@ -143,7 +145,7 @@ class ReducerTester : public HandleAndZoneScope {
|
||||
void CheckBinop(Node* expect, Node* a, Node* b) {
|
||||
CHECK(binop);
|
||||
Node* n = CreateBinopNode(a, b);
|
||||
MachineOperatorReducer reducer(&jsgraph);
|
||||
MachineOperatorReducer reducer(&graph_reducer, &jsgraph);
|
||||
Reduction reduction = reducer.Reduce(n);
|
||||
CHECK(reduction.Changed());
|
||||
CHECK_EQ(expect, reduction.replacement());
|
||||
@ -155,7 +157,7 @@ class ReducerTester : public HandleAndZoneScope {
|
||||
Node* right) {
|
||||
CHECK(binop);
|
||||
Node* n = CreateBinopNode(left, right);
|
||||
MachineOperatorReducer reducer(&jsgraph);
|
||||
MachineOperatorReducer reducer(&graph_reducer, &jsgraph);
|
||||
Reduction reduction = reducer.Reduce(n);
|
||||
CHECK(reduction.Changed());
|
||||
CHECK_EQ(binop, reduction.replacement()->op());
|
||||
@ -170,7 +172,7 @@ class ReducerTester : public HandleAndZoneScope {
|
||||
Node* right_expect, Node* left, Node* right) {
|
||||
CHECK(binop);
|
||||
Node* n = CreateBinopNode(left, right);
|
||||
MachineOperatorReducer reducer(&jsgraph);
|
||||
MachineOperatorReducer reducer(&graph_reducer, &jsgraph);
|
||||
Reduction r = reducer.Reduce(n);
|
||||
CHECK(r.Changed());
|
||||
CHECK_EQ(op_expect->opcode(), r.replacement()->op()->opcode());
|
||||
@ -185,7 +187,7 @@ class ReducerTester : public HandleAndZoneScope {
|
||||
volatile T right_expect, Node* left, Node* right) {
|
||||
CHECK(binop);
|
||||
Node* n = CreateBinopNode(left, right);
|
||||
MachineOperatorReducer reducer(&jsgraph);
|
||||
MachineOperatorReducer reducer(&graph_reducer, &jsgraph);
|
||||
Reduction r = reducer.Reduce(n);
|
||||
CHECK(r.Changed());
|
||||
CHECK_EQ(op_expect->opcode(), r.replacement()->op()->opcode());
|
||||
@ -204,7 +206,7 @@ class ReducerTester : public HandleAndZoneScope {
|
||||
Node* k = Constant<T>(constant);
|
||||
{
|
||||
Node* n = CreateBinopNode(k, p);
|
||||
MachineOperatorReducer reducer(&jsgraph);
|
||||
MachineOperatorReducer reducer(&graph_reducer, &jsgraph);
|
||||
Reduction reduction = reducer.Reduce(n);
|
||||
CHECK(!reduction.Changed() || reduction.replacement() == n);
|
||||
CHECK_EQ(p, n->InputAt(0));
|
||||
@ -212,7 +214,7 @@ class ReducerTester : public HandleAndZoneScope {
|
||||
}
|
||||
{
|
||||
Node* n = CreateBinopNode(p, k);
|
||||
MachineOperatorReducer reducer(&jsgraph);
|
||||
MachineOperatorReducer reducer(&graph_reducer, &jsgraph);
|
||||
Reduction reduction = reducer.Reduce(n);
|
||||
CHECK(!reduction.Changed());
|
||||
CHECK_EQ(p, n->InputAt(0));
|
||||
@ -228,7 +230,7 @@ class ReducerTester : public HandleAndZoneScope {
|
||||
Node* p = Parameter();
|
||||
Node* k = Constant<T>(constant);
|
||||
Node* n = CreateBinopNode(k, p);
|
||||
MachineOperatorReducer reducer(&jsgraph);
|
||||
MachineOperatorReducer reducer(&graph_reducer, &jsgraph);
|
||||
Reduction reduction = reducer.Reduce(n);
|
||||
CHECK(!reduction.Changed());
|
||||
CHECK_EQ(k, n->InputAt(0));
|
||||
@ -823,7 +825,7 @@ TEST(ReduceLoadStore) {
|
||||
index, R.graph.start(), R.graph.start());
|
||||
|
||||
{
|
||||
MachineOperatorReducer reducer(&R.jsgraph);
|
||||
MachineOperatorReducer reducer(&R.graph_reducer, &R.jsgraph);
|
||||
Reduction reduction = reducer.Reduce(load);
|
||||
CHECK(!reduction.Changed()); // loads should not be reduced.
|
||||
}
|
||||
@ -833,7 +835,7 @@ TEST(ReduceLoadStore) {
|
||||
R.graph.NewNode(R.machine.Store(StoreRepresentation(
|
||||
MachineRepresentation::kWord32, kNoWriteBarrier)),
|
||||
base, index, load, load, R.graph.start());
|
||||
MachineOperatorReducer reducer(&R.jsgraph);
|
||||
MachineOperatorReducer reducer(&R.graph_reducer, &R.jsgraph);
|
||||
Reduction reduction = reducer.Reduce(store);
|
||||
CHECK(!reduction.Changed()); // stores should not be reduced.
|
||||
}
|
||||
|
@ -26,14 +26,20 @@ namespace compiler {
|
||||
class MachineOperatorReducerTest : public GraphTest {
|
||||
public:
|
||||
explicit MachineOperatorReducerTest(int num_parameters = 2)
|
||||
: GraphTest(num_parameters), machine_(zone()) {}
|
||||
: GraphTest(num_parameters),
|
||||
machine_(zone()),
|
||||
common_(zone()),
|
||||
javascript_(zone()),
|
||||
jsgraph_(isolate(), graph(), &common_, &javascript_, nullptr,
|
||||
&machine_),
|
||||
graph_reducer_(zone(), graph(), jsgraph_.Dead()) {}
|
||||
|
||||
protected:
|
||||
Reduction Reduce(Node* node) {
|
||||
JSOperatorBuilder javascript(zone());
|
||||
JSGraph jsgraph(isolate(), graph(), common(), &javascript, nullptr,
|
||||
&machine_);
|
||||
MachineOperatorReducer reducer(&jsgraph);
|
||||
MachineOperatorReducer reducer(&graph_reducer_, &jsgraph);
|
||||
return reducer.Reduce(node);
|
||||
}
|
||||
|
||||
@ -61,6 +67,10 @@ class MachineOperatorReducerTest : public GraphTest {
|
||||
|
||||
private:
|
||||
MachineOperatorBuilder machine_;
|
||||
CommonOperatorBuilder common_;
|
||||
JSOperatorBuilder javascript_;
|
||||
JSGraph jsgraph_;
|
||||
GraphReducer graph_reducer_;
|
||||
};
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user