v8
V8 is Google’s open source high-performance JavaScript and WebAssembly engine, written in C++.
Loading...
Searching...
No Matches
graph-reducer.h
Go to the documentation of this file.
1// Copyright 2014 the V8 project authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef V8_COMPILER_GRAPH_REDUCER_H_
6#define V8_COMPILER_GRAPH_REDUCER_H_
7
13
14namespace v8 {
15namespace internal {
16
17class TickCounter;
18
19namespace compiler {
20
21class TFGraph;
22class JSHeapBroker;
23class Node;
24class ObserveNodeManager;
25
26// NodeIds are identifying numbers for nodes that can be used to index auxiliary
27// out-of-line data associated with each node.
28using NodeId = uint32_t;
29
30// Possible outcomes for decisions.
31enum class Decision : uint8_t { kUnknown, kTrue, kFalse };
32
33// Represents the result of trying to reduce a node in the graph.
34class Reduction final {
35 public:
37
38 Node* replacement() const { return replacement_; }
39 bool Changed() const { return replacement() != nullptr; }
41 if (next.Changed()) return next;
42 return *this;
43 }
44
45 private:
47};
48
49
50// A reducer can reduce or simplify a given node based on its operator and
51// inputs. This class functions as an extension point for the graph reducer for
52// language-specific reductions (e.g. reduction based on types or constant
53// folding of low-level operators) can be integrated into the graph reduction
54// phase.
56 public:
57 virtual ~Reducer() = default;
58
59 // Only used for tracing, when using the --trace_turbo_reduction flag.
60 virtual const char* reducer_name() const = 0;
61
62 // Try to reduce a node if possible.
63 Reduction Reduce(Node* node, ObserveNodeManager* observe_node_manager);
64
65 // Invoked by the {GraphReducer} when all nodes are done. Can be used to
66 // do additional reductions at the end, which in turn can cause a new round
67 // of reductions.
68 virtual void Finalize();
69
70 // Helper functions for subclasses to produce reductions for a node.
71 static Reduction NoChange() { return Reduction(); }
72 static Reduction Replace(Node* node) { return Reduction(node); }
73 static Reduction Changed(Node* node) { return Reduction(node); }
74
75 private:
76 virtual Reduction Reduce(Node* node) = 0;
77};
78
79
80// An advanced reducer can also edit the graphs by changing and replacing nodes
81// other than the one currently being reduced.
82class AdvancedReducer : public Reducer {
83 public:
84 // Observe the actions of this reducer.
85 class Editor {
86 public:
87 virtual ~Editor() = default;
88
89 // Replace {node} with {replacement}.
90 virtual void Replace(Node* node, Node* replacement) = 0;
91 virtual void Replace(Node* node, Node* replacement, NodeId max_id) = 0;
92 // Revisit the {node} again later.
93 virtual void Revisit(Node* node) = 0;
94 // Replace value uses of {node} with {value} and effect uses of {node} with
95 // {effect}. If {effect == nullptr}, then use the effect input to {node}.
96 // All control uses will be relaxed assuming {node} cannot throw.
97 virtual void ReplaceWithValue(Node* node, Node* value, Node* effect,
98 Node* control) = 0;
99 };
100
101 explicit AdvancedReducer(Editor* editor) : editor_(editor) {}
102
103 protected:
104 // Helper functions for subclasses to produce reductions for a node.
105 static Reduction Replace(Node* node) { return Reducer::Replace(node); }
106
107 // Helper functions for subclasses to edit the graph.
108 void Replace(Node* node, Node* replacement) {
110 editor_->Replace(node, replacement);
111 }
112 void Replace(Node* node, Node* replacement, NodeId max_id) {
113 return editor_->Replace(node, replacement, max_id);
114 }
115 void Revisit(Node* node) {
117 editor_->Revisit(node);
118 }
119 void ReplaceWithValue(Node* node, Node* value, Node* effect = nullptr,
120 Node* control = nullptr) {
122 editor_->ReplaceWithValue(node, value, effect, control);
123 }
124
125 // Relax the effects of {node} by immediately replacing effect and control
126 // uses of {node} with the effect and control input to {node}.
127 // TODO(turbofan): replace the effect input to {node} with {graph->start()}.
129 ReplaceWithValue(node, node, nullptr, nullptr);
130 }
131
132 // Relax the control uses of {node} by immediately replacing them with the
133 // either the given {control} node, or the control input to {node}.
134 void RelaxControls(Node* node, Node* control = nullptr) {
135 ReplaceWithValue(node, node, node, control);
136 }
137
139 Node* node) {
140 NodeProperties::MergeControlToEnd(graph, common, node);
141 Revisit(graph->end());
142 }
143
144 private:
146};
147
148
149// Performs an iterative reduction of a node graph.
151 : public NON_EXPORTED_BASE(AdvancedReducer::Editor) {
152 public:
153 GraphReducer(Zone* zone, TFGraph* graph, TickCounter* tick_counter,
154 JSHeapBroker* broker, Node* dead = nullptr,
155 ObserveNodeManager* observe_node_manager = nullptr);
156 ~GraphReducer() override;
157
158 GraphReducer(const GraphReducer&) = delete;
160
161 TFGraph* graph() const { return graph_; }
162
163 void AddReducer(Reducer* reducer);
164
165 // Reduce a single node.
166 void ReduceNode(Node* const);
167 // Reduce the whole graph.
168 void ReduceGraph();
169
170 private:
171 enum class State : uint8_t;
172 struct NodeState {
175 };
176
177 // Reduce a single node.
178 Reduction Reduce(Node* const);
179 // Reduce the node on top of the stack.
180 void ReduceTop();
181
182 // Replace {node} with {replacement}.
183 void Replace(Node* node, Node* replacement) final;
184
185 // Replace value uses of {node} with {value} and effect uses of {node} with
186 // {effect}. If {effect == nullptr}, then use the effect input to {node}. All
187 // control uses will be relaxed assuming {node} cannot throw.
188 void ReplaceWithValue(Node* node, Node* value, Node* effect,
189 Node* control) final;
190
191 // Replace all uses of {node} with {replacement} if the id of {replacement} is
192 // less than or equal to {max_id}. Otherwise, replace all uses of {node} whose
193 // id is less than or equal to {max_id} with the {replacement}.
194 void Replace(Node* node, Node* replacement, NodeId max_id) final;
195
196 // Node stack operations.
197 void Pop();
198 void Push(Node* node);
199
200 // Revisit queue operations.
201 bool Recurse(Node* node);
202 void Revisit(Node* node) final;
203
205 Node* const dead_;
213};
214
215} // namespace compiler
216} // namespace internal
217} // namespace v8
218
219#endif // V8_COMPILER_GRAPH_REDUCER_H_
virtual void Replace(Node *node, Node *replacement, NodeId max_id)=0
virtual void ReplaceWithValue(Node *node, Node *value, Node *effect, Node *control)=0
virtual void Replace(Node *node, Node *replacement)=0
void ReplaceWithValue(Node *node, Node *value, Node *effect=nullptr, Node *control=nullptr)
void Replace(Node *node, Node *replacement)
void MergeControlToEnd(TFGraph *graph, CommonOperatorBuilder *common, Node *node)
static Reduction Replace(Node *node)
void RelaxControls(Node *node, Node *control=nullptr)
void Replace(Node *node, Node *replacement, NodeId max_id)
ObserveNodeManager *const observe_node_manager_
GraphReducer & operator=(const GraphReducer &)=delete
ZoneVector< Reducer * > reducers_
GraphReducer(const GraphReducer &)=delete
static void MergeControlToEnd(TFGraph *graph, CommonOperatorBuilder *common, Node *node)
virtual const char * reducer_name() const =0
static Reduction Replace(Node *node)
static Reduction Changed(Node *node)
virtual Reduction Reduce(Node *node)=0
Reduction(Node *replacement=nullptr)
Reduction FollowedBy(Reduction next) const
JSHeapBroker * broker
#define NON_EXPORTED_BASE(code)
#define DCHECK_NOT_NULL(val)
Definition logging.h:492
#define V8_EXPORT_PRIVATE
Definition macros.h:460
TFGraph * graph_