OLD | NEW |
1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #ifndef V8_COMPILER_GRAPH_BUILDER_H_ | 5 #ifndef V8_COMPILER_GRAPH_BUILDER_H_ |
6 #define V8_COMPILER_GRAPH_BUILDER_H_ | 6 #define V8_COMPILER_GRAPH_BUILDER_H_ |
7 | 7 |
8 #include "src/v8.h" | 8 #include "src/v8.h" |
9 | 9 |
10 #include "src/allocation.h" | 10 #include "src/allocation.h" |
11 #include "src/compiler/common-operator.h" | 11 #include "src/compiler/common-operator.h" |
12 #include "src/compiler/graph.h" | 12 #include "src/compiler/graph.h" |
13 #include "src/compiler/node.h" | 13 #include "src/compiler/node.h" |
14 #include "src/unique.h" | 14 #include "src/unique.h" |
15 | 15 |
16 namespace v8 { | 16 namespace v8 { |
17 namespace internal { | 17 namespace internal { |
18 | |
19 class BitVector; | |
20 | |
21 namespace compiler { | 18 namespace compiler { |
22 | 19 |
23 class Node; | |
24 | |
25 // A common base class for anything that creates nodes in a graph. | 20 // A common base class for anything that creates nodes in a graph. |
26 class GraphBuilder { | 21 class GraphBuilder { |
27 public: | 22 public: |
28 GraphBuilder(Isolate* isolate, Graph* graph) | 23 GraphBuilder(Isolate* isolate, Graph* graph) |
29 : isolate_(isolate), graph_(graph) {} | 24 : isolate_(isolate), graph_(graph) {} |
30 virtual ~GraphBuilder() {} | 25 virtual ~GraphBuilder() {} |
31 | 26 |
32 Node* NewNode(const Operator* op, bool incomplete = false) { | 27 Node* NewNode(const Operator* op, bool incomplete = false) { |
33 return MakeNode(op, 0, static_cast<Node**>(NULL), incomplete); | 28 return MakeNode(op, 0, static_cast<Node**>(NULL), incomplete); |
34 } | 29 } |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
75 protected: | 70 protected: |
76 // Base implementation used by all factory methods. | 71 // Base implementation used by all factory methods. |
77 virtual Node* MakeNode(const Operator* op, int value_input_count, | 72 virtual Node* MakeNode(const Operator* op, int value_input_count, |
78 Node** value_inputs, bool incomplete) = 0; | 73 Node** value_inputs, bool incomplete) = 0; |
79 | 74 |
80 private: | 75 private: |
81 Isolate* isolate_; | 76 Isolate* isolate_; |
82 Graph* graph_; | 77 Graph* graph_; |
83 }; | 78 }; |
84 | 79 |
85 | |
86 // The StructuredGraphBuilder produces a high-level IR graph. It is used as the | |
87 // base class for concrete implementations (e.g the AstGraphBuilder or the | |
88 // StubGraphBuilder). | |
89 class StructuredGraphBuilder : public GraphBuilder { | |
90 public: | |
91 StructuredGraphBuilder(Isolate* isolate, Zone* zone, Graph* graph, | |
92 CommonOperatorBuilder* common); | |
93 ~StructuredGraphBuilder() OVERRIDE {} | |
94 | |
95 // Creates a new Phi node having {count} input values. | |
96 Node* NewPhi(int count, Node* input, Node* control); | |
97 Node* NewEffectPhi(int count, Node* input, Node* control); | |
98 | |
99 // Helpers for merging control, effect or value dependencies. | |
100 Node* MergeControl(Node* control, Node* other); | |
101 Node* MergeEffect(Node* value, Node* other, Node* control); | |
102 Node* MergeValue(Node* value, Node* other, Node* control); | |
103 | |
104 // Helpers to create new control nodes. | |
105 Node* NewIfTrue() { return NewNode(common()->IfTrue()); } | |
106 Node* NewIfFalse() { return NewNode(common()->IfFalse()); } | |
107 Node* NewMerge() { return NewNode(common()->Merge(1), true); } | |
108 Node* NewLoop() { return NewNode(common()->Loop(1), true); } | |
109 Node* NewBranch(Node* condition, BranchHint hint = BranchHint::kNone) { | |
110 return NewNode(common()->Branch(hint), condition); | |
111 } | |
112 | |
113 protected: | |
114 class Environment; | |
115 friend class Environment; | |
116 friend class ControlBuilder; | |
117 | |
118 // The following method creates a new node having the specified operator and | |
119 // ensures effect and control dependencies are wired up. The dependencies | |
120 // tracked by the environment might be mutated. | |
121 Node* MakeNode(const Operator* op, int value_input_count, Node** value_inputs, | |
122 bool incomplete) FINAL; | |
123 | |
124 Environment* environment() const { return environment_; } | |
125 void set_environment(Environment* env) { environment_ = env; } | |
126 | |
127 Node* current_context() const { return current_context_; } | |
128 void set_current_context(Node* context) { current_context_ = context; } | |
129 | |
130 Node* exit_control() const { return exit_control_; } | |
131 void set_exit_control(Node* node) { exit_control_ = node; } | |
132 | |
133 Node* dead_control(); | |
134 | |
135 Zone* graph_zone() const { return graph()->zone(); } | |
136 Zone* local_zone() const { return local_zone_; } | |
137 CommonOperatorBuilder* common() const { return common_; } | |
138 | |
139 // Helper to wrap a Handle<T> into a Unique<T>. | |
140 template <class T> | |
141 Unique<T> MakeUnique(Handle<T> object) { | |
142 return Unique<T>::CreateUninitialized(object); | |
143 } | |
144 | |
145 // Support for control flow builders. The concrete type of the environment | |
146 // depends on the graph builder, but environments themselves are not virtual. | |
147 virtual Environment* CopyEnvironment(Environment* env); | |
148 | |
149 // Helper to indicate a node exits the function body. | |
150 void UpdateControlDependencyToLeaveFunction(Node* exit); | |
151 | |
152 private: | |
153 CommonOperatorBuilder* common_; | |
154 Environment* environment_; | |
155 | |
156 // Zone local to the builder for data not leaking into the graph. | |
157 Zone* local_zone_; | |
158 | |
159 // Temporary storage for building node input lists. | |
160 int input_buffer_size_; | |
161 Node** input_buffer_; | |
162 | |
163 // Node representing the control dependency for dead code. | |
164 SetOncePointer<Node> dead_control_; | |
165 | |
166 // Node representing the current context within the function body. | |
167 Node* current_context_; | |
168 | |
169 // Merge of all control nodes that exit the function body. | |
170 Node* exit_control_; | |
171 | |
172 // Growth increment for the temporary buffer used to construct input lists to | |
173 // new nodes. | |
174 static const int kInputBufferSizeIncrement = 64; | |
175 | |
176 Node** EnsureInputBufferSize(int size); | |
177 | |
178 DISALLOW_COPY_AND_ASSIGN(StructuredGraphBuilder); | |
179 }; | |
180 | |
181 | |
182 // The abstract execution environment contains static knowledge about | |
183 // execution state at arbitrary control-flow points. It allows for | |
184 // simulation of the control-flow at compile time. | |
185 class StructuredGraphBuilder::Environment : public ZoneObject { | |
186 public: | |
187 Environment(StructuredGraphBuilder* builder, Node* control_dependency); | |
188 Environment(const Environment& copy); | |
189 | |
190 // Control dependency tracked by this environment. | |
191 Node* GetControlDependency() { return control_dependency_; } | |
192 void UpdateControlDependency(Node* dependency) { | |
193 control_dependency_ = dependency; | |
194 } | |
195 | |
196 // Effect dependency tracked by this environment. | |
197 Node* GetEffectDependency() { return effect_dependency_; } | |
198 void UpdateEffectDependency(Node* dependency) { | |
199 effect_dependency_ = dependency; | |
200 } | |
201 | |
202 // Mark this environment as being unreachable. | |
203 void MarkAsUnreachable() { | |
204 UpdateControlDependency(builder()->dead_control()); | |
205 } | |
206 bool IsMarkedAsUnreachable() { | |
207 return GetControlDependency()->opcode() == IrOpcode::kDead; | |
208 } | |
209 | |
210 // Merge another environment into this one. | |
211 void Merge(Environment* other); | |
212 | |
213 // Copies this environment at a control-flow split point. | |
214 Environment* CopyForConditional() { return builder()->CopyEnvironment(this); } | |
215 | |
216 // Copies this environment to a potentially unreachable control-flow point. | |
217 Environment* CopyAsUnreachable() { | |
218 Environment* env = builder()->CopyEnvironment(this); | |
219 env->MarkAsUnreachable(); | |
220 return env; | |
221 } | |
222 | |
223 // Copies this environment at a loop header control-flow point. | |
224 Environment* CopyForLoop(BitVector* assigned, bool is_osr = false) { | |
225 PrepareForLoop(assigned, is_osr); | |
226 return builder()->CopyEnvironment(this); | |
227 } | |
228 | |
229 Node* GetContext() { return builder_->current_context(); } | |
230 | |
231 protected: | |
232 Zone* zone() const { return builder_->local_zone(); } | |
233 Graph* graph() const { return builder_->graph(); } | |
234 StructuredGraphBuilder* builder() const { return builder_; } | |
235 CommonOperatorBuilder* common() { return builder_->common(); } | |
236 NodeVector* values() { return &values_; } | |
237 | |
238 // Prepare environment to be used as loop header. | |
239 void PrepareForLoop(BitVector* assigned, bool is_osr = false); | |
240 | |
241 private: | |
242 StructuredGraphBuilder* builder_; | |
243 Node* control_dependency_; | |
244 Node* effect_dependency_; | |
245 NodeVector values_; | |
246 }; | |
247 } | 80 } |
248 } | 81 } |
249 } // namespace v8::internal::compiler | 82 } // namespace v8::internal::compiler |
250 | 83 |
251 #endif // V8_COMPILER_GRAPH_BUILDER_H__ | 84 #endif // V8_COMPILER_GRAPH_BUILDER_H__ |
OLD | NEW |