Commit e02f5611 authored by Tobias Tebbi's avatar Tobias Tebbi Committed by Commit Bot

[turbofan] trim effect chain nodes when they have no side-effect

Bug: 
Change-Id: Ic1b6dc6fcd8bfc4f0c3dbb101a38106aa3596a12
Reviewed-on: https://chromium-review.googlesource.com/863886
Commit-Queue: Tobias Tebbi <tebbi@chromium.org>
Reviewed-by: 's avatarJaroslav Sevcik <jarin@chromium.org>
Cr-Commit-Position: refs/heads/master@{#50588}
parent b80a698d
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
#include "src/compiler/graph-trimmer.h" #include "src/compiler/graph-trimmer.h"
#include "src/compiler/graph.h" #include "src/compiler/graph.h"
#include "src/compiler/node-properties.h"
namespace v8 { namespace v8 {
namespace internal { namespace internal {
...@@ -18,6 +19,18 @@ GraphTrimmer::GraphTrimmer(Zone* zone, Graph* graph) ...@@ -18,6 +19,18 @@ GraphTrimmer::GraphTrimmer(Zone* zone, Graph* graph)
GraphTrimmer::~GraphTrimmer() {} GraphTrimmer::~GraphTrimmer() {}
namespace {
bool IsSideEffectFree(const Operator* op) {
switch (op->opcode()) {
case IrOpcode::kLoad:
case IrOpcode::kLoadElement:
case IrOpcode::kLoadField:
return true;
default:
return false;
}
}
} // namespace
void GraphTrimmer::TrimGraph() { void GraphTrimmer::TrimGraph() {
// Mark end node as live. // Mark end node as live.
...@@ -25,8 +38,44 @@ void GraphTrimmer::TrimGraph() { ...@@ -25,8 +38,44 @@ void GraphTrimmer::TrimGraph() {
// Compute transitive closure of live nodes. // Compute transitive closure of live nodes.
for (size_t i = 0; i < live_.size(); ++i) { for (size_t i = 0; i < live_.size(); ++i) {
Node* const live = live_[i]; Node* const live = live_[i];
for (Node* const input : live->inputs()) MarkAsLive(input); for (Edge edge : live->input_edges()) {
Node* input = edge.to();
if (NodeProperties::IsEffectEdge(edge)) {
while (IsSideEffectFree(input->op())) {
// Side-effect free effect chain nodes can be removed from the effect
// chain when only their effect output is used. So we ignore the
// effect chain use when determining liveness.
DCHECK_EQ(1, input->op()->EffectInputCount());
input = NodeProperties::GetEffectInput(input);
}
}
MarkAsLive(input);
}
}
// Remove unused side-effect-free nodes from the effect chain.
// These are exactly the nodes we skipped before and that don't have value
// uses. This has to be done before we remove dead->live edges because we need
// to read the effect predecessor from the dead effect chain node.
for (Node* const live : live_) {
DCHECK(IsLive(live));
for (Edge edge : live->input_edges()) {
Node* input = edge.to();
if (NodeProperties::IsEffectEdge(edge)) {
Node* new_input = input;
while (!IsLive(new_input)) {
DCHECK(IsSideEffectFree(new_input->op()));
if (FLAG_trace_turbo_trimming) {
OFStream os(stdout);
os << "DeadEffectChainNode: " << *new_input << std::endl;
}
new_input = NodeProperties::GetEffectInput(new_input);
} }
if (new_input != input) edge.UpdateTo(new_input);
}
}
}
// Remove dead->live edges. // Remove dead->live edges.
for (Node* const live : live_) { for (Node* const live : live_) {
DCHECK(IsLive(live)); DCHECK(IsLive(live));
......
...@@ -15,7 +15,6 @@ namespace compiler { ...@@ -15,7 +15,6 @@ namespace compiler {
// Forward declarations. // Forward declarations.
class Graph; class Graph;
// Trims dead nodes from the node graph. // Trims dead nodes from the node graph.
class V8_EXPORT_PRIVATE GraphTrimmer final { class V8_EXPORT_PRIVATE GraphTrimmer final {
public: public:
......
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