Index: src/compiler/graph-reducer.h |
diff --git a/src/compiler/graph-reducer.h b/src/compiler/graph-reducer.h |
index a6cc1f2d94b0b14974907cd37b83ac7d8d81a448..5f80e3af40d39808d1a628da5951de44b02c3156 100644 |
--- a/src/compiler/graph-reducer.h |
+++ b/src/compiler/graph-reducer.h |
@@ -17,13 +17,18 @@ class Graph; |
class Node; |
+// NodeIds are identifying numbers for nodes that can be used to index auxiliary |
+// out-of-line data associated with each node. |
+typedef int32_t NodeId; |
+ |
+ |
// Represents the result of trying to reduce a node in the graph. |
class Reduction final { |
public: |
- explicit Reduction(Node* replacement = NULL) : replacement_(replacement) {} |
+ explicit Reduction(Node* replacement = nullptr) : replacement_(replacement) {} |
Node* replacement() const { return replacement_; } |
- bool Changed() const { return replacement() != NULL; } |
+ bool Changed() const { return replacement() != nullptr; } |
private: |
Node* replacement_; |
@@ -37,26 +42,62 @@ class Reduction final { |
// phase. |
class Reducer { |
public: |
- Reducer() {} |
+ class Observer { |
titzer
2015/05/06 08:57:40
As discussed, if we could move this out of the bas
Benedikt Meurer
2015/05/06 09:10:32
Done as discussed. However I kept the Finish metho
|
+ public: |
+ Observer() {} |
+ virtual ~Observer() {} |
+ |
+ // Replace {node} with {replacement}. |
+ virtual void Replace(Node* node, Node* replacement) = 0; |
+ // Revisit the {node} again later. |
+ virtual void Revisit(Node* node) = 0; |
+ |
+ private: |
+ DISALLOW_COPY_AND_ASSIGN(Observer); |
+ }; |
+ |
+ Reducer() : observer_(nullptr) {} |
virtual ~Reducer() {} |
+ // Observe the actions of this reducer. |
+ Observer* observer() const { return observer_; } |
+ void set_observer(Observer* observer) { observer_ = observer; } |
+ |
// Try to reduce a node if possible. |
virtual Reduction Reduce(Node* node) = 0; |
+ // Ask this reducer to finish operation, returns {true} if the reducer is |
+ // done, while {false} indicates that the graph might need to be reduced |
+ // again. |
+ virtual bool Finish(); |
+ |
// Helper functions for subclasses to produce reductions for a node. |
static Reduction NoChange() { return Reduction(); } |
static Reduction Replace(Node* node) { return Reduction(node); } |
static Reduction Changed(Node* node) { return Reduction(node); } |
+ protected: |
+ void Replace(Node* node, Node* replacement) { |
+ DCHECK_NOT_NULL(observer_); |
+ observer_->Replace(node, replacement); |
+ } |
+ void Revisit(Node* node) { |
+ DCHECK_NOT_NULL(observer_); |
+ observer_->Revisit(node); |
+ } |
+ |
private: |
+ Observer* observer_; |
+ |
DISALLOW_COPY_AND_ASSIGN(Reducer); |
}; |
// Performs an iterative reduction of a node graph. |
-class GraphReducer final { |
+class GraphReducer final : public Reducer::Observer { |
public: |
GraphReducer(Graph* graph, Zone* zone); |
+ ~GraphReducer() final; |
Graph* graph() const { return graph_; } |
@@ -79,15 +120,30 @@ class GraphReducer final { |
// Reduce the node on top of the stack. |
void ReduceTop(); |
+ // Replace {node} with {replacement}. |
+ void Replace(Node* node, Node* replacement) final; |
+ // Replace {node} during reduction with {replacement}. If the {replacement} |
+ // is a node whose id is less than {max_id}, then replace all uses. |
+ // Otherwise, only replace edges whose user id is less than {max_id}. |
+ void Replace(Node* node, Node* replacement, NodeId max_id); |
+ |
// Node stack operations. |
void Pop(); |
void Push(Node* node); |
// Revisit queue operations. |
bool Recurse(Node* node); |
- void Revisit(Node* node); |
+ void Revisit(Node* node) final; |
+ |
+ // Finish the graph reduction. |
+ bool Finish() { |
+ for (Reducer* const reducer : reducers_) { |
+ if (!reducer->Finish()) return false; |
+ } |
+ return true; |
+ } |
- Graph* graph_; |
+ Graph* const graph_; |
NodeMarker<State> state_; |
ZoneVector<Reducer*> reducers_; |
ZoneStack<Node*> revisit_; |