Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(223)

Side by Side Diff: src/cfg.h

Issue 159701: Restructure to support recursive invocation of the CFG builder. Add... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: Created 11 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/arm/cfg-arm.cc ('k') | src/cfg.cc » ('j') | src/cfg.cc » ('J')
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2009 the V8 project authors. All rights reserved. 1 // Copyright 2009 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 15 matching lines...) Expand all
26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 27
28 #ifndef V8_CFG_H_ 28 #ifndef V8_CFG_H_
29 #define V8_CFG_H_ 29 #define V8_CFG_H_
30 30
31 #include "ast.h" 31 #include "ast.h"
32 32
33 namespace v8 { 33 namespace v8 {
34 namespace internal { 34 namespace internal {
35 35
36 class ExitNode;
37
38 // A convenient class to keep 'global' values when building a CFG. Since
39 // CFG construction can be invoked recursively, CFG globals are stacked.
40 class CfgGlobals BASE_EMBEDDED {
41 public:
42 explicit CfgGlobals(FunctionLiteral* fun);
43
44 ~CfgGlobals() { top_ = previous_; }
45
46 static CfgGlobals* current() {
47 ASSERT(top_ != NULL);
48 return top_;
49 }
50
51 FunctionLiteral* fun() { return global_fun_; }
52
53 ExitNode* exit() { return global_exit_; }
54
55 #ifdef DEBUG
56 int next_number() { return node_counter_++; }
57 #endif
58
59 private:
60 static CfgGlobals* top_;
61
62 // Function literal currently compiling.
63 FunctionLiteral* global_fun_;
64
65 // Shared global exit node for all returns from the same function.
66 ExitNode* global_exit_;
67
68 #ifdef DEBUG
69 // Used to number nodes when printing.
70 int node_counter_;
71 #endif
72
73 CfgGlobals* previous_;
74 };
75
76
36 // Values appear in instructions. They represent trivial source 77 // Values appear in instructions. They represent trivial source
37 // expressions: ones with no side effects and that do not require code to be 78 // expressions: ones with no side effects and that do not require code to be
38 // generated. 79 // generated.
39 class Value : public ZoneObject { 80 class Value : public ZoneObject {
40 public: 81 public:
41 virtual ~Value() {} 82 virtual ~Value() {}
42 83
43 virtual void ToRegister(MacroAssembler* masm, Register reg) = 0; 84 virtual void ToRegister(MacroAssembler* masm, Register reg) = 0;
44 85
45 #ifdef DEBUG 86 #ifdef DEBUG
(...skipping 13 matching lines...) Expand all
59 100
60 #ifdef DEBUG 101 #ifdef DEBUG
61 void Print(); 102 void Print();
62 #endif 103 #endif
63 104
64 private: 105 private:
65 Handle<Object> handle_; 106 Handle<Object> handle_;
66 }; 107 };
67 108
68 109
110 // Locations are values that can be stored into ('lvalues').
111 class Location : public Value {
112 public:
113 virtual ~Location() {}
114
115 virtual void ToRegister(MacroAssembler* masm, Register reg) = 0;
116
117 #ifdef DEBUG
118 virtual void Print() = 0;
119 #endif
120 };
121
122
123 // SlotLocations represent parameters and stack-allocated (i.e.,
124 // non-context) local variables.
125 class SlotLocation : public Location {
126 public:
127 SlotLocation(Slot::Type type, int index) : type_(type), index_(index) {}
128
129 void ToRegister(MacroAssembler* masm, Register reg);
130
131 #ifdef DEBUG
132 void Print();
133 #endif
134
135 private:
136 Slot::Type type_;
137 int index_;
138 };
139
140
69 // Instructions are computations. The represent non-trivial source 141 // Instructions are computations. The represent non-trivial source
70 // expressions: typically ones that have side effects and require code to 142 // expressions: typically ones that have side effects and require code to
71 // be generated. 143 // be generated.
72 class Instruction : public ZoneObject { 144 class Instruction : public ZoneObject {
73 public: 145 public:
74 virtual ~Instruction() {} 146 virtual ~Instruction() {}
75 147
76 virtual void Compile(MacroAssembler* masm) = 0; 148 virtual void Compile(MacroAssembler* masm) = 0;
77 149
78 #ifdef DEBUG 150 #ifdef DEBUG
(...skipping 28 matching lines...) Expand all
107 CfgNode() : is_marked_(false) { 179 CfgNode() : is_marked_(false) {
108 #ifdef DEBUG 180 #ifdef DEBUG
109 number_ = -1; 181 number_ = -1;
110 #endif 182 #endif
111 } 183 }
112 184
113 virtual ~CfgNode() {} 185 virtual ~CfgNode() {}
114 186
115 bool is_marked() { return is_marked_; } 187 bool is_marked() { return is_marked_; }
116 188
117 static void Reset();
118
119 virtual bool is_block() { return false; } 189 virtual bool is_block() { return false; }
120 190
121 virtual void Unmark() = 0; 191 virtual void Unmark() = 0;
122 192
123 virtual void Compile(MacroAssembler* masm) = 0; 193 virtual void Compile(MacroAssembler* masm) = 0;
124 194
125 #ifdef DEBUG 195 #ifdef DEBUG
126 int number() { 196 int number() {
127 if (number_ == -1) number_ = node_counter_++; 197 if (number_ == -1) number_ = CfgGlobals::current()->next_number();
128 return number_; 198 return number_;
129 } 199 }
130 200
131 virtual void Print() = 0; 201 virtual void Print() = 0;
132 #endif 202 #endif
133 203
134 protected: 204 protected:
135 bool is_marked_; 205 bool is_marked_;
136 206
137 #ifdef DEBUG 207 #ifdef DEBUG
138 int number_; 208 int number_;
139
140 static int node_counter_;
141 #endif 209 #endif
142 }; 210 };
143 211
144 212
145 // A block is a single-entry, single-exit block of instructions. 213 // A block is a single-entry, single-exit block of instructions.
146 class InstructionBlock : public CfgNode { 214 class InstructionBlock : public CfgNode {
147 public: 215 public:
148 InstructionBlock() : successor_(NULL), instructions_(4) {} 216 InstructionBlock() : successor_(NULL), instructions_(4) {}
149 217
150 virtual ~InstructionBlock() {} 218 virtual ~InstructionBlock() {}
(...skipping 24 matching lines...) Expand all
175 CfgNode* successor_; 243 CfgNode* successor_;
176 ZoneList<Instruction*> instructions_; 244 ZoneList<Instruction*> instructions_;
177 }; 245 };
178 246
179 247
180 // The CFG for a function has a distinguished entry node. It has no 248 // The CFG for a function has a distinguished entry node. It has no
181 // predecessors and a single successor. The successor is the block 249 // predecessors and a single successor. The successor is the block
182 // containing the function's first instruction. 250 // containing the function's first instruction.
183 class EntryNode : public CfgNode { 251 class EntryNode : public CfgNode {
184 public: 252 public:
185 EntryNode(FunctionLiteral* fun, InstructionBlock* succ); 253 explicit EntryNode(InstructionBlock* succ) : successor_(succ) {}
186 254
187 virtual ~EntryNode() {} 255 virtual ~EntryNode() {}
188 256
189 void Unmark(); 257 void Unmark();
190 258
191 void Compile(MacroAssembler* masm); 259 void Compile(MacroAssembler* masm);
192 260
193 #ifdef DEBUG 261 #ifdef DEBUG
194 void Print(); 262 void Print();
195 #endif 263 #endif
196 264
197 private: 265 private:
198 InstructionBlock* successor_; 266 InstructionBlock* successor_;
199 int local_count_;
200 }; 267 };
201 268
202 269
203 // The CFG for a function has a distinguished exit node. It has no 270 // The CFG for a function has a distinguished exit node. It has no
204 // successor and arbitrarily many predecessors. The predecessors are all 271 // successor and arbitrarily many predecessors. The predecessors are all
205 // the blocks returning from the function. 272 // the blocks returning from the function.
206 class ExitNode : public CfgNode { 273 class ExitNode : public CfgNode {
207 public: 274 public:
208 explicit ExitNode(FunctionLiteral* fun); 275 ExitNode() {}
209 276
210 virtual ~ExitNode() {} 277 virtual ~ExitNode() {}
211 278
212 void Unmark(); 279 void Unmark();
213 280
214 void Compile(MacroAssembler* masm); 281 void Compile(MacroAssembler* masm);
215 282
216 #ifdef DEBUG 283 #ifdef DEBUG
217 void Print(); 284 void Print();
218 #endif 285 #endif
219
220 private:
221 int parameter_count_;
222 }; 286 };
223 287
224 288
225 // A CFG is a consists of a linked structure of nodes. It has a single 289 // A CFG consists of a linked structure of nodes. It has a single entry
226 // entry node and optionally an exit node. There is a distinguished global 290 // node and optionally an exit node. There is a distinguished global exit
227 // exit node that is used as the successor of all blocks that return from 291 // node that is used as the successor of all blocks that return from the
228 // the function. 292 // function.
229 // 293 //
230 // Fragments of control-flow graphs, produced when traversing the statements 294 // Fragments of control-flow graphs, produced when traversing the statements
231 // and expressions in the source AST, are represented by the same class. 295 // and expressions in the source AST, are represented by the same class.
232 // They have instruction blocks as both their entry and exit (if there is 296 // They have instruction blocks as both their entry and exit (if there is
233 // one). Instructions can always be prepended or appended to fragments, and 297 // one). Instructions can always be prepended or appended to fragments, and
234 // fragments can always be concatenated. 298 // fragments can always be concatenated.
235 // 299 //
236 // A singleton CFG fragment (i.e., with only one node) has the same node as 300 // A singleton CFG fragment (i.e., with only one node) has the same node as
237 // both entry and exit (if the exit is available). 301 // both entry and exit (if the exit is available).
238 class Cfg : public ZoneObject { 302 class Cfg : public ZoneObject {
239 public: 303 public:
240 // Create a singleton CFG fragment. 304 // Create a singleton CFG fragment.
241 explicit Cfg(InstructionBlock* block) : entry_(block), exit_(block) {} 305 explicit Cfg(InstructionBlock* block) : entry_(block), exit_(block) {}
242 306
243 // Build the CFG for a function. 307 // Build the CFG for a function.
244 static Cfg* Build(FunctionLiteral* fun); 308 static Cfg* Build();
245 309
246 // The entry and exit nodes. 310 // The entry and exit nodes.
247 CfgNode* entry() { return entry_; } 311 CfgNode* entry() { return entry_; }
248 CfgNode* exit() { return exit_; } 312 CfgNode* exit() { return exit_; }
249 313
250 // True if the CFG has no nodes. 314 // True if the CFG has no nodes.
251 bool is_empty() { return entry_ == NULL; } 315 bool is_empty() { return entry_ == NULL; }
252 316
253 // True if the CFG has an available exit node (i.e., it can be appended or 317 // True if the CFG has an available exit node (i.e., it can be appended or
254 // concatenated to). 318 // concatenated to).
255 bool has_exit() { return exit_ != NULL; } 319 bool has_exit() { return exit_ != NULL; }
256 320
257 // Add an entry node to a CFG fragment. It is no longer a fragment 321 // Add an entry node to a CFG fragment. It is no longer a fragment
258 // (instructions cannot be prepended). 322 // (instructions cannot be prepended).
259 void PrependEntryNode(FunctionLiteral* fun); 323 void PrependEntryNode();
260 324
261 // Append an instruction to the end of a CFG fragment. Assumes it has an 325 // Append an instruction to the end of a CFG fragment. Assumes it has an
262 // available exit. 326 // available exit.
263 void Append(Instruction* instr); 327 void Append(Instruction* instr);
264 328
265 // Appends a return instruction to the end of a CFG fragment. It no 329 // Appends a return instruction to the end of a CFG fragment. It no
266 // longer has an available exit node. 330 // longer has an available exit node.
267 void AppendReturnInstruction(Value* value); 331 void AppendReturnInstruction(Value* value);
268 332
269 Handle<Code> Compile(FunctionLiteral* fun, Handle<Script> script); 333 Handle<Code> Compile(Handle<Script> script);
270 334
271 #ifdef DEBUG 335 #ifdef DEBUG
272 // Support for printing. 336 // Support for printing.
273 void Print(); 337 void Print();
274 #endif 338 #endif
275 339
276 private: 340 private:
277 // Reset static variables before building the CFG for a function.
278 static void Reset(FunctionLiteral* fun);
279
280 // Shared global exit nodes for all returns from the same function.
281 static ExitNode* global_exit_;
282
283 // Entry and exit nodes. 341 // Entry and exit nodes.
284 CfgNode* entry_; 342 CfgNode* entry_;
285 CfgNode* exit_; 343 CfgNode* exit_;
286 }; 344 };
287 345
288 346
289 // An Expression Builder traverses a trivial expression and returns a value. 347 // An Expression Builder traverses a trivial expression and returns a value.
290 class ExpressionBuilder : public AstVisitor { 348 class ExpressionBuilder : public AstVisitor {
291 public: 349 public:
292 ExpressionBuilder() : value_(new Constant(Handle<Object>::null())) {} 350 ExpressionBuilder() : value_(new Constant(Handle<Object>::null())) {}
(...skipping 25 matching lines...) Expand all
318 #undef DECLARE_VISIT 376 #undef DECLARE_VISIT
319 377
320 private: 378 private:
321 Cfg* cfg_; 379 Cfg* cfg_;
322 }; 380 };
323 381
324 382
325 } } // namespace v8::internal 383 } } // namespace v8::internal
326 384
327 #endif // V8_CFG_H_ 385 #endif // V8_CFG_H_
OLDNEW
« no previous file with comments | « src/arm/cfg-arm.cc ('k') | src/cfg.cc » ('j') | src/cfg.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698