Commit 59346569 authored by Benedikt Meurer's avatar Benedikt Meurer

[turbofan] Smartify the GraphReducer.

Don't use the generic algorithm, but instead start going into the
direction of ControlReducer, using a stack plus a revisit queue to
not miss any more possibilities for reductions anymore.

TEST=cctest,unittests
R=dcarney@chromium.org

Committed: https://chromium.googlesource.com/v8/v8/+/f047507370634155113d78685372630a230613cf

Committed: https://chromium.googlesource.com/v8/v8/+/6e148989a4227a5290a7f8ca72c71f5740870afe

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

Cr-Commit-Position: refs/heads/master@{#25377}
parent 2eaca10e
...@@ -12,79 +12,189 @@ namespace v8 { ...@@ -12,79 +12,189 @@ namespace v8 {
namespace internal { namespace internal {
namespace compiler { namespace compiler {
GraphReducer::GraphReducer(Graph* graph) enum class GraphReducer::State : uint8_t {
: graph_(graph), reducers_(graph->zone()) {} kUnvisited,
kRevisit,
kOnStack,
kVisited
};
GraphReducer::GraphReducer(Graph* graph, Zone* zone)
: graph_(graph),
reducers_(zone),
revisit_(zone),
stack_(zone),
state_(zone) {}
static bool NodeIdIsLessThan(const Node* node, NodeId id) { void GraphReducer::AddReducer(Reducer* reducer) {
return node->id() < id; reducers_.push_back(reducer);
} }
void GraphReducer::ReduceNode(Node* node) { void GraphReducer::ReduceNode(Node* node) {
static const unsigned kMaxAttempts = 16; DCHECK(stack_.empty());
bool reduce = true; DCHECK(revisit_.empty());
for (unsigned attempts = 0; attempts <= kMaxAttempts; ++attempts) { std::fill(state_.begin(), state_.end(), State::kUnvisited);
if (!reduce) return; Push(node);
reduce = false; // Assume we don't need to rerun any reducers. for (;;) {
int before = graph_->NodeCount(); DCHECK(!stack_.empty() ||
for (ZoneVector<Reducer*>::iterator i = reducers_.begin(); std::find(state_.begin(), state_.end(), State::kOnStack) ==
i != reducers_.end(); ++i) { state_.end());
if (!stack_.empty()) {
// Process the node on the top of the stack, potentially pushing more or
// popping the node off the stack.
ReduceTop();
} else if (!revisit_.empty()) {
// If the stack becomes empty, revisit any nodes in the revisit queue.
Node* const node = revisit_.top();
revisit_.pop();
if (state_[node->id()] == State::kRevisit) {
// state can change while in queue.
Push(node);
}
} else {
break;
}
}
DCHECK(std::find(state_.begin(), state_.end(), State::kOnStack) ==
state_.end());
DCHECK(revisit_.empty());
DCHECK(stack_.empty());
}
void GraphReducer::ReduceGraph() { ReduceNode(graph()->end()); }
Reduction GraphReducer::Reduce(Node* const node) {
auto skip = reducers_.end();
for (auto i = reducers_.begin(); i != reducers_.end();) {
if (i != skip) {
Reduction reduction = (*i)->Reduce(node); Reduction reduction = (*i)->Reduce(node);
Node* replacement = reduction.replacement(); if (!reduction.Changed()) {
if (replacement == NULL) {
// No change from this reducer. // No change from this reducer.
} else if (replacement == node) { } else if (reduction.replacement() == node) {
// {replacement == node} represents an in-place reduction. // {replacement} == {node} represents an in-place reduction. Rerun
// Rerun all the reducers for this node, as now there may be more // all the other reducers for this node, as now there may be more
// opportunities for reduction. // opportunities for reduction.
reduce = true; skip = i;
break; i = reducers_.begin();
continue;
} else { } else {
if (node == graph_->start()) graph_->SetStart(replacement); // {node} was replaced by another node.
if (node == graph_->end()) graph_->SetEnd(replacement); return reduction;
// If {node} was replaced by an old node, unlink {node} and assume that }
// {replacement} was already reduced and finish. }
if (replacement->id() < before) { ++i;
node->ReplaceUses(replacement); }
node->Kill(); if (skip == reducers_.end()) {
return; // No change from any reducer.
} return Reducer::NoChange();
// Otherwise, {node} was replaced by a new node. Replace all old uses of }
// At least one reducer did some in-place reduction.
return Reducer::Changed(node);
}
void GraphReducer::ReduceTop() {
Node* const node = Top();
if (node->IsDead()) return Pop(); // Node was killed while on stack.
// Recurse on an input if necessary.
for (auto const input : node->inputs()) {
if (input != node && Recurse(input)) return;
}
// Remember the node count before reduction.
const int node_count = graph()->NodeCount();
// All inputs should be visited or on stack. Apply reductions to node.
Reduction reduction = Reduce(node);
// After reducing the node, pop it off the stack.
Pop();
// If there was a reduction, revisit the uses and reduce the replacement.
if (reduction.Changed()) {
for (Node* const use : node->uses()) {
// Don't revisit this node if it refers to itself.
if (use != node) Revisit(use);
}
Node* const replacement = reduction.replacement();
if (replacement != node) {
if (node == graph()->start()) graph()->SetStart(replacement);
if (node == graph()->end()) graph()->SetEnd(replacement);
// If {node} was replaced by an old node, unlink {node} and assume that
// {replacement} was already reduced and finish.
if (replacement->id() < node_count) {
node->ReplaceUses(replacement);
node->Kill();
} else {
// Otherwise {node} was replaced by a new node. Replace all old uses of
// {node} with {replacement}. New nodes created by this reduction can // {node} with {replacement}. New nodes created by this reduction can
// use {node}. // use {node}.
node->ReplaceUsesIf( node->ReplaceUsesIf([node_count](Node* const node) {
std::bind2nd(std::ptr_fun(&NodeIdIsLessThan), before), replacement); return node->id() < node_count;
},
replacement);
// Unlink {node} if it's no longer used. // Unlink {node} if it's no longer used.
if (node->uses().empty()) { if (node->uses().empty()) {
node->Kill(); node->Kill();
} }
// Rerun all the reductions on the {replacement}.
node = replacement; // If there was a replacement, reduce it after popping {node}.
reduce = true; Recurse(replacement);
break;
} }
} }
} }
} }
// A helper class to reuse the node traversal algorithm. void GraphReducer::Pop() {
struct GraphReducerVisitor FINAL : public NullNodeVisitor { Node* const node = Top();
explicit GraphReducerVisitor(GraphReducer* reducer) : reducer_(reducer) {} state_[node->id()] = State::kVisited;
void Post(Node* node) { reducer_->ReduceNode(node); } stack_.pop();
GraphReducer* reducer_; }
};
void GraphReducer::ReduceGraph() { void GraphReducer::Push(Node* const node) {
GraphReducerVisitor visitor(this); size_t const id = static_cast<size_t>(node->id());
// Perform a post-order reduction of all nodes starting from the end. if (id >= state_.size()) state_.resize(id + 1);
graph()->VisitNodeInputsFromEnd(&visitor); DCHECK(id < state_.size());
DCHECK(state_[id] != State::kOnStack);
state_[id] = State::kOnStack;
stack_.push(node);
} }
// TODO(titzer): partial graph reductions. Node* GraphReducer::Top() const {
DCHECK(!stack_.empty());
Node* const node = stack_.top();
size_t const id = static_cast<size_t>(node->id());
DCHECK(id < state_.size());
DCHECK(state_[id] == State::kOnStack);
USE(id);
return node;
}
bool GraphReducer::Recurse(Node* const node) {
size_t const id = static_cast<size_t>(node->id());
if (id < state_.size() && state_[id] > State::kRevisit) return false;
Push(node);
return true;
}
void GraphReducer::Revisit(Node* const node) {
size_t const id = static_cast<size_t>(node->id());
if (id < state_.size() && state_[id] == State::kVisited) {
state_[id] = State::kRevisit;
revisit_.push(node);
}
}
} // namespace compiler } // namespace compiler
} // namespace internal } // namespace internal
......
...@@ -55,20 +55,39 @@ class Reducer { ...@@ -55,20 +55,39 @@ class Reducer {
// Performs an iterative reduction of a node graph. // Performs an iterative reduction of a node graph.
class GraphReducer FINAL { class GraphReducer FINAL {
public: public:
explicit GraphReducer(Graph* graph); GraphReducer(Graph* graph, Zone* zone);
Graph* graph() const { return graph_; } Graph* graph() const { return graph_; }
void AddReducer(Reducer* reducer) { reducers_.push_back(reducer); } void AddReducer(Reducer* reducer);
// Reduce a single node. // Reduce a single node.
void ReduceNode(Node* node); void ReduceNode(Node* const);
// Reduce the whole graph. // Reduce the whole graph.
void ReduceGraph(); void ReduceGraph();
private: private:
enum class State : uint8_t;
// Reduce a single node.
Reduction Reduce(Node* const);
// Reduce the node on top of the stack.
void ReduceTop();
// Node stack operations.
void Pop();
void Push(Node* const);
Node* Top() const;
// Revisit queue operations.
bool Recurse(Node* const);
void Revisit(Node* const);
Graph* graph_; Graph* graph_;
ZoneVector<Reducer*> reducers_; ZoneVector<Reducer*> reducers_;
ZoneStack<Node*> revisit_;
ZoneStack<Node*> stack_;
ZoneDeque<State> state_;
DISALLOW_COPY_AND_ASSIGN(GraphReducer); DISALLOW_COPY_AND_ASSIGN(GraphReducer);
}; };
......
...@@ -382,7 +382,7 @@ struct TypedLoweringPhase { ...@@ -382,7 +382,7 @@ struct TypedLoweringPhase {
ValueNumberingReducer vn_reducer(data->graph_zone()); ValueNumberingReducer vn_reducer(data->graph_zone());
JSTypedLowering lowering(data->jsgraph()); JSTypedLowering lowering(data->jsgraph());
SimplifiedOperatorReducer simple_reducer(data->jsgraph()); SimplifiedOperatorReducer simple_reducer(data->jsgraph());
GraphReducer graph_reducer(data->graph()); GraphReducer graph_reducer(data->graph(), temp_zone);
graph_reducer.AddReducer(&vn_reducer); graph_reducer.AddReducer(&vn_reducer);
graph_reducer.AddReducer(&lowering); graph_reducer.AddReducer(&lowering);
graph_reducer.AddReducer(&simple_reducer); graph_reducer.AddReducer(&simple_reducer);
...@@ -401,7 +401,7 @@ struct SimplifiedLoweringPhase { ...@@ -401,7 +401,7 @@ struct SimplifiedLoweringPhase {
lowering.LowerAllNodes(); lowering.LowerAllNodes();
ValueNumberingReducer vn_reducer(data->graph_zone()); ValueNumberingReducer vn_reducer(data->graph_zone());
SimplifiedOperatorReducer simple_reducer(data->jsgraph()); SimplifiedOperatorReducer simple_reducer(data->jsgraph());
GraphReducer graph_reducer(data->graph()); GraphReducer graph_reducer(data->graph(), temp_zone);
graph_reducer.AddReducer(&vn_reducer); graph_reducer.AddReducer(&vn_reducer);
graph_reducer.AddReducer(&simple_reducer); graph_reducer.AddReducer(&simple_reducer);
graph_reducer.ReduceGraph(); graph_reducer.ReduceGraph();
...@@ -420,7 +420,7 @@ struct ChangeLoweringPhase { ...@@ -420,7 +420,7 @@ struct ChangeLoweringPhase {
SimplifiedOperatorReducer simple_reducer(data->jsgraph()); SimplifiedOperatorReducer simple_reducer(data->jsgraph());
ChangeLowering lowering(data->jsgraph(), &linkage); ChangeLowering lowering(data->jsgraph(), &linkage);
MachineOperatorReducer mach_reducer(data->jsgraph()); MachineOperatorReducer mach_reducer(data->jsgraph());
GraphReducer graph_reducer(data->graph()); GraphReducer graph_reducer(data->graph(), temp_zone);
// TODO(titzer): Figure out if we should run all reducers at once here. // TODO(titzer): Figure out if we should run all reducers at once here.
graph_reducer.AddReducer(&vn_reducer); graph_reducer.AddReducer(&vn_reducer);
graph_reducer.AddReducer(&simple_reducer); graph_reducer.AddReducer(&simple_reducer);
...@@ -458,7 +458,7 @@ struct GenericLoweringPhase { ...@@ -458,7 +458,7 @@ struct GenericLoweringPhase {
SourcePosition::Unknown()); SourcePosition::Unknown());
JSGenericLowering generic(data->info(), data->jsgraph()); JSGenericLowering generic(data->info(), data->jsgraph());
SelectLowering select(data->jsgraph()->graph(), data->jsgraph()->common()); SelectLowering select(data->jsgraph()->graph(), data->jsgraph()->common());
GraphReducer graph_reducer(data->graph()); GraphReducer graph_reducer(data->graph(), temp_zone);
graph_reducer.AddReducer(&generic); graph_reducer.AddReducer(&generic);
graph_reducer.AddReducer(&select); graph_reducer.AddReducer(&select);
graph_reducer.ReduceGraph(); graph_reducer.ReduceGraph();
......
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
#include <deque> #include <deque>
#include <queue> #include <queue>
#include <stack>
#include <vector> #include <vector>
#include "src/zone-allocator.h" #include "src/zone-allocator.h"
...@@ -36,29 +37,45 @@ class ZoneVector : public std::vector<T, zone_allocator<T> > { ...@@ -36,29 +37,45 @@ class ZoneVector : public std::vector<T, zone_allocator<T> > {
} }
}; };
// A wrapper subclass std::deque to make it easy to construct one // A wrapper subclass std::deque to make it easy to construct one
// that uses a zone allocator. // that uses a zone allocator.
template <typename T> template <typename T>
class ZoneDeque : public std::deque<T, zone_allocator<T> > { class ZoneDeque : public std::deque<T, zone_allocator<T> > {
public: public:
// Constructs an empty deque.
explicit ZoneDeque(Zone* zone) explicit ZoneDeque(Zone* zone)
: std::deque<T, zone_allocator<T> >(zone_allocator<T>(zone)) {} : std::deque<T, zone_allocator<T> >(zone_allocator<T>(zone)) {}
}; };
// A wrapper subclass for std::queue to make it easy to construct one // A wrapper subclass for std::queue to make it easy to construct one
// that uses a zone allocator. // that uses a zone allocator.
template <typename T> template <typename T>
class ZoneQueue : public std::queue<T, std::deque<T, zone_allocator<T> > > { class ZoneQueue : public std::queue<T, ZoneDeque<T>> {
public: public:
// Constructs an empty queue. // Constructs an empty queue.
explicit ZoneQueue(Zone* zone) explicit ZoneQueue(Zone* zone)
: std::queue<T, std::deque<T, zone_allocator<T> > >( : std::queue<T, ZoneDeque<T>>(ZoneDeque<T>(zone)) {}
std::deque<T, zone_allocator<T> >(zone_allocator<T>(zone))) {}
}; };
// A wrapper subclass for std::stack to make it easy to construct one that uses
// a zone allocator.
template <typename T>
class ZoneStack : public std::stack<T, ZoneDeque<T>> {
public:
// Constructs an empty stack.
explicit ZoneStack(Zone* zone)
: std::stack<T, ZoneDeque<T>>(ZoneDeque<T>(zone)) {}
};
// Typedefs to shorten commonly used vectors. // Typedefs to shorten commonly used vectors.
typedef ZoneVector<bool> BoolVector; typedef ZoneVector<bool> BoolVector;
typedef ZoneVector<int> IntVector; typedef ZoneVector<int> IntVector;
} } // namespace v8::internal
} // namespace internal
} // namespace v8
#endif // V8_ZONE_CONTAINERS_H_ #endif // V8_ZONE_CONTAINERS_H_
...@@ -129,7 +129,7 @@ class ChangesLoweringTester : public GraphBuilderTester<ReturnType> { ...@@ -129,7 +129,7 @@ class ChangesLoweringTester : public GraphBuilderTester<ReturnType> {
Linkage linkage(this->zone(), &info); Linkage linkage(this->zone(), &info);
ChangeLowering change_lowering(&jsgraph, &linkage); ChangeLowering change_lowering(&jsgraph, &linkage);
SelectLowering select_lowering(this->graph(), this->common()); SelectLowering select_lowering(this->graph(), this->common());
GraphReducer reducer(this->graph()); GraphReducer reducer(this->graph(), this->zone());
reducer.AddReducer(&change_lowering); reducer.AddReducer(&change_lowering);
reducer.AddReducer(&select_lowering); reducer.AddReducer(&select_lowering);
reducer.ReduceNode(change); reducer.ReduceNode(change);
......
...@@ -202,7 +202,7 @@ TEST(ReduceGraphFromEnd1) { ...@@ -202,7 +202,7 @@ TEST(ReduceGraphFromEnd1) {
Node* end = graph.NewNode(&OPA1, n1); Node* end = graph.NewNode(&OPA1, n1);
graph.SetEnd(end); graph.SetEnd(end);
GraphReducer reducer(&graph); GraphReducer reducer(&graph, graph.zone());
ReducerRecorder recorder(graph.zone()); ReducerRecorder recorder(graph.zone());
reducer.AddReducer(&recorder); reducer.AddReducer(&recorder);
reducer.ReduceGraph(); reducer.ReduceGraph();
...@@ -220,7 +220,7 @@ TEST(ReduceGraphFromEnd2) { ...@@ -220,7 +220,7 @@ TEST(ReduceGraphFromEnd2) {
Node* end = graph.NewNode(&OPA2, n2, n3); Node* end = graph.NewNode(&OPA2, n2, n3);
graph.SetEnd(end); graph.SetEnd(end);
GraphReducer reducer(&graph); GraphReducer reducer(&graph, graph.zone());
ReducerRecorder recorder(graph.zone()); ReducerRecorder recorder(graph.zone());
reducer.AddReducer(&recorder); reducer.AddReducer(&recorder);
reducer.ReduceGraph(); reducer.ReduceGraph();
...@@ -238,7 +238,7 @@ TEST(ReduceInPlace1) { ...@@ -238,7 +238,7 @@ TEST(ReduceInPlace1) {
Node* end = graph.NewNode(&OPA1, n1); Node* end = graph.NewNode(&OPA1, n1);
graph.SetEnd(end); graph.SetEnd(end);
GraphReducer reducer(&graph); GraphReducer reducer(&graph, graph.zone());
InPlaceABReducer r; InPlaceABReducer r;
reducer.AddReducer(&r); reducer.AddReducer(&r);
...@@ -263,7 +263,7 @@ TEST(ReduceInPlace2) { ...@@ -263,7 +263,7 @@ TEST(ReduceInPlace2) {
Node* end = graph.NewNode(&OPA2, n2, n3); Node* end = graph.NewNode(&OPA2, n2, n3);
graph.SetEnd(end); graph.SetEnd(end);
GraphReducer reducer(&graph); GraphReducer reducer(&graph, graph.zone());
InPlaceABReducer r; InPlaceABReducer r;
reducer.AddReducer(&r); reducer.AddReducer(&r);
...@@ -293,7 +293,7 @@ TEST(ReduceNew1) { ...@@ -293,7 +293,7 @@ TEST(ReduceNew1) {
Node* end = graph.NewNode(&OPA2, n2, n3); Node* end = graph.NewNode(&OPA2, n2, n3);
graph.SetEnd(end); graph.SetEnd(end);
GraphReducer reducer(&graph); GraphReducer reducer(&graph, graph.zone());
NewABReducer r(&graph); NewABReducer r(&graph);
reducer.AddReducer(&r); reducer.AddReducer(&r);
...@@ -330,7 +330,7 @@ TEST(Wrapping1) { ...@@ -330,7 +330,7 @@ TEST(Wrapping1) {
graph.SetEnd(end); graph.SetEnd(end);
CHECK_EQ(1, graph.NodeCount()); CHECK_EQ(1, graph.NodeCount());
GraphReducer reducer(&graph); GraphReducer reducer(&graph, graph.zone());
A0Wrapper r(&graph); A0Wrapper r(&graph);
reducer.AddReducer(&r); reducer.AddReducer(&r);
...@@ -352,7 +352,7 @@ TEST(Wrapping2) { ...@@ -352,7 +352,7 @@ TEST(Wrapping2) {
graph.SetEnd(end); graph.SetEnd(end);
CHECK_EQ(1, graph.NodeCount()); CHECK_EQ(1, graph.NodeCount());
GraphReducer reducer(&graph); GraphReducer reducer(&graph, graph.zone());
B0Wrapper r(&graph); B0Wrapper r(&graph);
reducer.AddReducer(&r); reducer.AddReducer(&r);
...@@ -379,7 +379,7 @@ TEST(Forwarding1) { ...@@ -379,7 +379,7 @@ TEST(Forwarding1) {
Node* end = graph.NewNode(&OPA1, n1); Node* end = graph.NewNode(&OPA1, n1);
graph.SetEnd(end); graph.SetEnd(end);
GraphReducer reducer(&graph); GraphReducer reducer(&graph, graph.zone());
A1Forwarder r; A1Forwarder r;
reducer.AddReducer(&r); reducer.AddReducer(&r);
...@@ -403,7 +403,7 @@ TEST(Forwarding2) { ...@@ -403,7 +403,7 @@ TEST(Forwarding2) {
Node* end = graph.NewNode(&OPA2, n2, n3); Node* end = graph.NewNode(&OPA2, n2, n3);
graph.SetEnd(end); graph.SetEnd(end);
GraphReducer reducer(&graph); GraphReducer reducer(&graph, graph.zone());
A1Forwarder r; A1Forwarder r;
reducer.AddReducer(&r); reducer.AddReducer(&r);
...@@ -434,7 +434,7 @@ TEST(Forwarding3) { ...@@ -434,7 +434,7 @@ TEST(Forwarding3) {
} }
graph.SetEnd(end); graph.SetEnd(end);
GraphReducer reducer(&graph); GraphReducer reducer(&graph, graph.zone());
A1Forwarder r; A1Forwarder r;
reducer.AddReducer(&r); reducer.AddReducer(&r);
...@@ -458,7 +458,7 @@ TEST(ReduceForward1) { ...@@ -458,7 +458,7 @@ TEST(ReduceForward1) {
Node* end = graph.NewNode(&OPA2, n2, n3); Node* end = graph.NewNode(&OPA2, n2, n3);
graph.SetEnd(end); graph.SetEnd(end);
GraphReducer reducer(&graph); GraphReducer reducer(&graph, graph.zone());
InPlaceABReducer r; InPlaceABReducer r;
B1Forwarder f; B1Forwarder f;
reducer.AddReducer(&r); reducer.AddReducer(&r);
...@@ -501,7 +501,7 @@ TEST(Sorter1) { ...@@ -501,7 +501,7 @@ TEST(Sorter1) {
graph.SetEnd(end); graph.SetEnd(end);
GraphReducer reducer(&graph); GraphReducer reducer(&graph, graph.zone());
reducer.AddReducer(&r); reducer.AddReducer(&r);
int before = graph.NodeCount(); int before = graph.NodeCount();
...@@ -560,7 +560,7 @@ TEST(SortForwardReduce) { ...@@ -560,7 +560,7 @@ TEST(SortForwardReduce) {
GenDAG(&graph, p3, p2, p1); GenDAG(&graph, p3, p2, p1);
GraphReducer reducer(&graph); GraphReducer reducer(&graph, graph.zone());
AB2Sorter r1; AB2Sorter r1;
A1Forwarder r2; A1Forwarder r2;
InPlaceABReducer r3; InPlaceABReducer r3;
...@@ -599,7 +599,7 @@ TEST(Order) { ...@@ -599,7 +599,7 @@ TEST(Order) {
Node* end = graph.NewNode(&OPA1, n1); Node* end = graph.NewNode(&OPA1, n1);
graph.SetEnd(end); graph.SetEnd(end);
GraphReducer reducer(&graph); GraphReducer reducer(&graph, graph.zone());
InPlaceABReducer abr; InPlaceABReducer abr;
InPlaceBCReducer bcr; InPlaceBCReducer bcr;
if (i == 0) { if (i == 0) {
......
...@@ -63,7 +63,7 @@ class SimplifiedLoweringTester : public GraphBuilderTester<ReturnType> { ...@@ -63,7 +63,7 @@ class SimplifiedLoweringTester : public GraphBuilderTester<ReturnType> {
Linkage linkage( Linkage linkage(
zone, Linkage::GetSimplifiedCDescriptor(zone, this->machine_sig_)); zone, Linkage::GetSimplifiedCDescriptor(zone, this->machine_sig_));
ChangeLowering lowering(&jsgraph, &linkage); ChangeLowering lowering(&jsgraph, &linkage);
GraphReducer reducer(this->graph()); GraphReducer reducer(this->graph(), this->zone());
reducer.AddReducer(&lowering); reducer.AddReducer(&lowering);
reducer.ReduceGraph(); reducer.ReduceGraph();
Verifier::Run(this->graph()); Verifier::Run(this->graph());
......
...@@ -55,20 +55,20 @@ class GraphReducerTest : public TestWithZone { ...@@ -55,20 +55,20 @@ class GraphReducerTest : public TestWithZone {
protected: protected:
void ReduceNode(Node* node, Reducer* r) { void ReduceNode(Node* node, Reducer* r) {
GraphReducer reducer(graph()); GraphReducer reducer(graph(), zone());
reducer.AddReducer(r); reducer.AddReducer(r);
reducer.ReduceNode(node); reducer.ReduceNode(node);
} }
void ReduceNode(Node* node, Reducer* r1, Reducer* r2) { void ReduceNode(Node* node, Reducer* r1, Reducer* r2) {
GraphReducer reducer(graph()); GraphReducer reducer(graph(), zone());
reducer.AddReducer(r1); reducer.AddReducer(r1);
reducer.AddReducer(r2); reducer.AddReducer(r2);
reducer.ReduceNode(node); reducer.ReduceNode(node);
} }
void ReduceNode(Node* node, Reducer* r1, Reducer* r2, Reducer* r3) { void ReduceNode(Node* node, Reducer* r1, Reducer* r2, Reducer* r3) {
GraphReducer reducer(graph()); GraphReducer reducer(graph(), zone());
reducer.AddReducer(r1); reducer.AddReducer(r1);
reducer.AddReducer(r2); reducer.AddReducer(r2);
reducer.AddReducer(r3); reducer.AddReducer(r3);
...@@ -87,6 +87,7 @@ TEST_F(GraphReducerTest, NodeIsDeadAfterReplace) { ...@@ -87,6 +87,7 @@ TEST_F(GraphReducerTest, NodeIsDeadAfterReplace) {
Node* node0 = graph()->NewNode(&OP0); Node* node0 = graph()->NewNode(&OP0);
Node* node1 = graph()->NewNode(&OP1, node0); Node* node1 = graph()->NewNode(&OP1, node0);
Node* node2 = graph()->NewNode(&OP1, node0); Node* node2 = graph()->NewNode(&OP1, node0);
EXPECT_CALL(r, Reduce(node0)).WillOnce(Return(Reducer::NoChange()));
EXPECT_CALL(r, Reduce(node1)).WillOnce(Return(Reducer::Replace(node2))); EXPECT_CALL(r, Reduce(node1)).WillOnce(Return(Reducer::Replace(node2)));
ReduceNode(node1, &r); ReduceNode(node1, &r);
EXPECT_FALSE(node0->IsDead()); EXPECT_FALSE(node0->IsDead());
...@@ -114,7 +115,6 @@ TEST_F(GraphReducerTest, ReduceAgainAfterChanged) { ...@@ -114,7 +115,6 @@ TEST_F(GraphReducerTest, ReduceAgainAfterChanged) {
Return(Reducer::Changed(node0))); Return(Reducer::Changed(node0)));
EXPECT_CALL(r1, Reduce(node0)).InSequence(s1); EXPECT_CALL(r1, Reduce(node0)).InSequence(s1);
EXPECT_CALL(r2, Reduce(node0)).InSequence(s2); EXPECT_CALL(r2, Reduce(node0)).InSequence(s2);
EXPECT_CALL(r3, Reduce(node0)).InSequence(s3);
ReduceNode(node0, &r1, &r2, &r3); ReduceNode(node0, &r1, &r2, &r3);
} }
......
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