Commit 9e9d1cb3 authored by bmeurer's avatar bmeurer Committed by Commit bot

[turbofan] Run inlining within the regular reducer fixpoint.

Introduce Reducer::Finalize, which get's called by the GraphReducer once
all reductions are done, and use this to implement full inlining as part
of the regular reducer fixpoint.

R=jarin@chromium.org
BUG=v8:4493
LOG=n

Review URL: https://codereview.chromium.org/1419373012

Cr-Commit-Position: refs/heads/master@{#31875}
parent d7166acd
......@@ -23,6 +23,9 @@ enum class GraphReducer::State : uint8_t {
};
void Reducer::Finalize() {}
GraphReducer::GraphReducer(Zone* zone, Graph* graph, Node* dead)
: graph_(graph),
dead_(dead),
......@@ -58,7 +61,11 @@ void GraphReducer::ReduceNode(Node* node) {
Push(node);
}
} else {
break;
// Run all finalizers.
for (Reducer* const reducer : reducers_) reducer->Finalize();
// Check if we have new nodes to revisit.
if (revisit_.empty()) break;
}
}
DCHECK(revisit_.empty());
......
......@@ -47,6 +47,11 @@ class Reducer {
// Try to reduce a node if possible.
virtual Reduction Reduce(Node* node) = 0;
// Invoked by the {GraphReducer} when all nodes are done. Can be used to
// do additional reductions at the end, which in turn can cause a new round
// of reductions.
virtual void Finalize();
// Helper functions for subclasses to produce reductions for a node.
static Reduction NoChange() { return Reduction(); }
static Reduction Replace(Node* node) { return Reduction(node); }
......
......@@ -5,7 +5,6 @@
#include "src/compiler/js-inlining-heuristic.h"
#include "src/compiler.h"
#include "src/compiler/dead-code-elimination.h" // TODO(mstarzinger): Remove!
#include "src/compiler/node-matchers.h"
#include "src/objects-inl.h"
......@@ -16,6 +15,10 @@ namespace compiler {
Reduction JSInliningHeuristic::Reduce(Node* node) {
if (node->opcode() != IrOpcode::kJSCallFunction) return NoChange();
// Check if we already saw that {node} before, and if so, just skip it.
if (seen_.find(node->id()) != seen_.end()) return NoChange();
seen_.insert(node->id());
Node* callee = node->InputAt(0);
HeapObjectMatcher match(callee);
if (!match.HasValue() || !match.Value()->IsJSFunction()) return NoChange();
......@@ -59,6 +62,14 @@ Reduction JSInliningHeuristic::Reduce(Node* node) {
if (info_->shared_info()->asm_function()) return NoChange();
if (function->shared()->asm_function()) return NoChange();
// Stop inlinining once the maximum allowed level is reached.
int level = 0;
for (Node* frame_state = NodeProperties::GetFrameStateInput(node, 1);
frame_state->opcode() == IrOpcode::kFrameState;
frame_state = NodeProperties::GetFrameStateInput(frame_state, 0)) {
if (++level > FLAG_max_inlining_levels) return NoChange();
}
// Gather feedback on how often this call site has been hit before.
CallFunctionParameters p = CallFunctionParametersOf(node->op());
int calls = -1; // Same default as CallICNexus::ExtractCallCount.
......@@ -77,24 +88,17 @@ Reduction JSInliningHeuristic::Reduce(Node* node) {
}
void JSInliningHeuristic::ProcessCandidates() {
if (candidates_.empty()) return; // Nothing to do without candidates.
void JSInliningHeuristic::Finalize() {
if (FLAG_trace_turbo_inlining) PrintCandidates();
int cumulative_count = 0;
for (const Candidate& candidate : candidates_) {
if (cumulative_count > FLAG_max_inlined_nodes_cumulative) break;
while (!candidates_.empty()) {
if (cumulative_count_ > FLAG_max_inlined_nodes_cumulative) break;
auto i = candidates_.begin();
Candidate const& candidate = *i;
inliner_.ReduceJSCallFunction(candidate.node, candidate.function);
cumulative_count += candidate.function->shared()->ast_node_count();
cumulative_count_ += candidate.function->shared()->ast_node_count();
candidates_.erase(i);
}
// TODO(mstarzinger): Temporary workaround to eliminate dead control from the
// graph being introduced by the inliner. Make this part of the pipeline.
GraphReducer graph_reducer(local_zone_, jsgraph_->graph(), jsgraph_->Dead());
DeadCodeElimination dead_code_elimination(&graph_reducer, jsgraph_->graph(),
jsgraph_->common());
graph_reducer.AddReducer(&dead_code_elimination);
graph_reducer.ReduceGraph();
}
......
......@@ -18,17 +18,16 @@ class JSInliningHeuristic final : public AdvancedReducer {
CompilationInfo* info, JSGraph* jsgraph)
: AdvancedReducer(editor),
mode_(mode),
local_zone_(local_zone),
jsgraph_(jsgraph),
inliner_(editor, local_zone, info, jsgraph),
candidates_(local_zone),
seen_(local_zone),
info_(info) {}
Reduction Reduce(Node* node) final;
// Processes the list of candidates gathered while the reducer was running,
// and inlines call sites that the heuristic determines to be important.
void ProcessCandidates();
void Finalize() final;
private:
struct Candidate {
......@@ -49,11 +48,11 @@ class JSInliningHeuristic final : public AdvancedReducer {
void PrintCandidates();
Mode const mode_;
Zone* local_zone_;
JSGraph* jsgraph_;
JSInliner inliner_;
Candidates candidates_;
ZoneSet<NodeId> seen_;
CompilationInfo* info_;
int cumulative_count_ = 0;
};
} // namespace compiler
......
......@@ -554,7 +554,6 @@ struct InliningPhase {
AddReducer(data, &graph_reducer, &context_specialization);
AddReducer(data, &graph_reducer, &inlining);
graph_reducer.ReduceGraph();
inlining.ProcessCandidates();
}
};
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment