[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:
Tobias Tebbi 2018-12-13 13:22:17 +01:00 committed by Commit Bot
parent a176aec77f
commit bc9704e030
7 changed files with 95 additions and 31 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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_;
};