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

Side by Side Diff: src/cfg.h

Issue 165056: Add support for (some) assignment expressions to the CFG builder and... (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') | no next file with comments »
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 25 matching lines...) Expand all
36 class ExitNode; 36 class ExitNode;
37 class Location; 37 class Location;
38 38
39 // Translate a source AST into a control-flow graph (CFG). The CFG contains 39 // Translate a source AST into a control-flow graph (CFG). The CFG contains
40 // single-entry, single-exit blocks of straight-line instructions and 40 // single-entry, single-exit blocks of straight-line instructions and
41 // administrative nodes. 41 // administrative nodes.
42 // 42 //
43 // Instructions are described by the following grammar. 43 // Instructions are described by the following grammar.
44 // 44 //
45 // <Instruction> ::= 45 // <Instruction> ::=
46 // BinaryOpInstr <Location> Token::Value <Value> <Value> 46 // MoveInstr <Location> <Value>
47 // | ReturnInstr Effect <Value> 47 // | BinaryOpInstr <Location> Token::Value <Value> <Value>
48 // | ReturnInstr Nowhere <Value>
49 // | PositionInstr <Int>
48 // 50 //
49 // Values are trivial expressions: 51 // Values are trivial expressions:
50 // 52 //
51 // <Value> ::= Constant | <Location> 53 // <Value> ::= Constant | <Location>
52 // 54 //
53 // Locations are storable values ('lvalues'). They can be slots, 55 // Locations are storable values ('lvalues'). They can be slots,
54 // compiler-generated temporaries, or the special location 'Effect' 56 // compiler-generated temporaries, or the special location 'Nowhere'
55 // indicating that no value is needed. 57 // indicating that no value is needed.
56 // 58 //
57 // <Location> ::= 59 // <Location> ::=
58 // SlotLocation Slot::Type <Index> 60 // SlotLocation Slot::Type <Index>
59 // | TempLocation 61 // | TempLocation
60 // | Effect 62 // | Nowhere
61 63
62 64
63 // Administrative nodes: There are several types of 'administrative' nodes 65 // Administrative nodes: There are several types of 'administrative' nodes
64 // that do not contain instructions and do not necessarily have a single 66 // that do not contain instructions and do not necessarily have a single
65 // predecessor and a single successor. 67 // predecessor and a single successor.
66 // 68 //
67 // EntryNode: there is a distinguished entry node that has no predecessors 69 // EntryNode: there is a distinguished entry node that has no predecessors
68 // and a single successor. 70 // and a single successor.
69 // 71 //
70 // ExitNode: there is a distinguished exit node that has arbitrarily many 72 // ExitNode: there is a distinguished exit node that has arbitrarily many
(...skipping 17 matching lines...) Expand all
88 ASSERT(top_ != NULL); 90 ASSERT(top_ != NULL);
89 return top_; 91 return top_;
90 } 92 }
91 93
92 // The function currently being compiled. 94 // The function currently being compiled.
93 FunctionLiteral* fun() { return global_fun_; } 95 FunctionLiteral* fun() { return global_fun_; }
94 96
95 // The shared global exit node for all exits from the function. 97 // The shared global exit node for all exits from the function.
96 ExitNode* exit() { return global_exit_; } 98 ExitNode* exit() { return global_exit_; }
97 99
98 // A singleton effect location. 100 // A singleton.
99 Location* effect_location() { return effect_; } 101 Location* nowhere() { return nowhere_; }
100 102
101 #ifdef DEBUG 103 #ifdef DEBUG
102 int next_node_number() { return node_counter_++; } 104 int next_node_number() { return node_counter_++; }
103 int next_temp_number() { return temp_counter_++; } 105 int next_temp_number() { return temp_counter_++; }
104 #endif 106 #endif
105 107
106 private: 108 private:
107 static CfgGlobals* top_; 109 static CfgGlobals* top_;
108 FunctionLiteral* global_fun_; 110 FunctionLiteral* global_fun_;
109 ExitNode* global_exit_; 111 ExitNode* global_exit_;
110 Location* effect_; 112 Location* nowhere_;
111 113
112 #ifdef DEBUG 114 #ifdef DEBUG
113 // Used to number nodes and temporaries when printing. 115 // Used to number nodes and temporaries when printing.
114 int node_counter_; 116 int node_counter_;
115 int temp_counter_; 117 int temp_counter_;
116 #endif 118 #endif
117 119
118 CfgGlobals* previous_; 120 CfgGlobals* previous_;
119 }; 121 };
120 122
121 123
124 class SlotLocation;
125
122 // Values represent trivial source expressions: ones with no side effects 126 // Values represent trivial source expressions: ones with no side effects
123 // and that do not require code to be generated. 127 // and that do not require code to be generated.
124 class Value : public ZoneObject { 128 class Value : public ZoneObject {
125 public: 129 public:
126 virtual ~Value() {} 130 virtual ~Value() {}
127 131
128 // Predicates: 132 // Predicates:
129 133
130 // True if the value is a temporary allocated to the stack in 134 // True if the value is a temporary allocated to the stack in
131 // fast-compilation mode. 135 // fast-compilation mode.
132 virtual bool is_on_stack() { return false; } 136 virtual bool is_on_stack() { return false; }
133 137
134 // True if the value is a compiler-generated temporary location. 138 // True if the value is a compiler-generated temporary location.
135 virtual bool is_temporary() { return false; } 139 virtual bool is_temporary() { return false; }
136 140
141 // True if the value is a slot location.
142 virtual bool is_slot() { return false; }
143
137 // Support for fast-compilation mode: 144 // Support for fast-compilation mode:
138 145
139 // Move the value into a register. 146 // Move the value into a register.
140 virtual void Get(MacroAssembler* masm, Register reg) = 0; 147 virtual void Get(MacroAssembler* masm, Register reg) = 0;
141 148
142 // Push the value on the stack. 149 // Push the value on the stack.
143 virtual void Push(MacroAssembler* masm) = 0; 150 virtual void Push(MacroAssembler* masm) = 0;
144 151
152 // Move the value into a slot location.
153 virtual void MoveToSlot(MacroAssembler* masm, SlotLocation* loc) = 0;
154
145 #ifdef DEBUG 155 #ifdef DEBUG
146 virtual void Print() = 0; 156 virtual void Print() = 0;
147 #endif 157 #endif
148 }; 158 };
149 159
150 160
151 // A compile-time constant that appeared as a literal in the source AST. 161 // A compile-time constant that appeared as a literal in the source AST.
152 class Constant : public Value { 162 class Constant : public Value {
153 public: 163 public:
154 explicit Constant(Handle<Object> handle) : handle_(handle) {} 164 explicit Constant(Handle<Object> handle) : handle_(handle) {}
155 165
156 virtual ~Constant() {} 166 virtual ~Constant() {}
157 167
158 // Support for fast-compilation mode. 168 // Support for fast-compilation mode.
159 void Get(MacroAssembler* masm, Register reg); 169 void Get(MacroAssembler* masm, Register reg);
160 void Push(MacroAssembler* masm); 170 void Push(MacroAssembler* masm);
171 void MoveToSlot(MacroAssembler* masm, SlotLocation* loc);
161 172
162 #ifdef DEBUG 173 #ifdef DEBUG
163 void Print(); 174 void Print();
164 #endif 175 #endif
165 176
166 private: 177 private:
167 Handle<Object> handle_; 178 Handle<Object> handle_;
168 }; 179 };
169 180
170 181
171 // Locations are values that can be stored into ('lvalues'). 182 // Locations are values that can be stored into ('lvalues').
172 class Location : public Value { 183 class Location : public Value {
173 public: 184 public:
174 virtual ~Location() {} 185 virtual ~Location() {}
175 186
176 // Static factory function returning the singleton effect location. 187 // Static factory function returning the singleton nowhere location.
177 static Location* Effect() { 188 static Location* Nowhere() {
178 return CfgGlobals::current()->effect_location(); 189 return CfgGlobals::current()->nowhere();
179 } 190 }
180 191
181 // Support for fast-compilation mode: 192 // Support for fast-compilation mode:
182 193
183 // Assumes temporaries have been allocated. 194 // Assumes temporaries have been allocated.
184 virtual void Get(MacroAssembler* masm, Register reg) = 0; 195 virtual void Get(MacroAssembler* masm, Register reg) = 0;
185 196
186 // Store the value in a register to the location. Assumes temporaries 197 // Store the value in a register to the location. Assumes temporaries
187 // have been allocated. 198 // have been allocated.
188 virtual void Set(MacroAssembler* masm, Register reg) = 0; 199 virtual void Set(MacroAssembler* masm, Register reg) = 0;
189 200
190 // Assumes temporaries have been allocated, and if the value is a 201 // Assumes temporaries have been allocated, and if the value is a
191 // temporary it was not allocated to the stack. 202 // temporary it was not allocated to the stack.
192 virtual void Push(MacroAssembler* masm) = 0; 203 virtual void Push(MacroAssembler* masm) = 0;
193 204
205 // Emit code to move a value into this location.
206 virtual void Move(MacroAssembler* masm, Value* value) = 0;
207
194 #ifdef DEBUG 208 #ifdef DEBUG
195 virtual void Print() = 0; 209 virtual void Print() = 0;
196 #endif 210 #endif
197 }; 211 };
198 212
199 213
200 // Effect is a special (singleton) location that indicates the value of a 214 // Nowhere is a special (singleton) location that indicates the value of a
201 // computation is not needed (though its side effects are). 215 // computation is not needed (though its side effects are).
202 class Effect : public Location { 216 class Nowhere : public Location {
203 public: 217 public:
204 // We should not try to emit code to read Effect. 218 // We should not try to emit code to read Nowhere.
205 void Get(MacroAssembler* masm, Register reg) { UNREACHABLE(); } 219 void Get(MacroAssembler* masm, Register reg) { UNREACHABLE(); }
206 void Push(MacroAssembler* masm) { UNREACHABLE(); } 220 void Push(MacroAssembler* masm) { UNREACHABLE(); }
221 void MoveToSlot(MacroAssembler* masm, SlotLocation* loc) { UNREACHABLE(); }
207 222
208 // Setting Effect is ignored. 223 // Setting Nowhere is ignored.
209 void Set(MacroAssembler* masm, Register reg) {} 224 void Set(MacroAssembler* masm, Register reg) {}
225 void Move(MacroAssembler* masm, Value* value) {}
210 226
211 #ifdef DEBUG 227 #ifdef DEBUG
212 void Print(); 228 void Print();
213 #endif 229 #endif
214 230
215 private: 231 private:
216 Effect() {} 232 Nowhere() {}
217 233
218 friend class CfgGlobals; 234 friend class CfgGlobals;
219 }; 235 };
220 236
221 237
222 // SlotLocations represent parameters and stack-allocated (i.e., 238 // SlotLocations represent parameters and stack-allocated (i.e.,
223 // non-context) local variables. 239 // non-context) local variables.
224 class SlotLocation : public Location { 240 class SlotLocation : public Location {
225 public: 241 public:
226 SlotLocation(Slot::Type type, int index) : type_(type), index_(index) {} 242 SlotLocation(Slot::Type type, int index) : type_(type), index_(index) {}
227 243
244 // Cast accessor.
245 static SlotLocation* cast(Value* value) {
246 ASSERT(value->is_slot());
247 return reinterpret_cast<SlotLocation*>(value);
248 }
249
228 // Accessors. 250 // Accessors.
229 Slot::Type type() { return type_; } 251 Slot::Type type() { return type_; }
230 int index() { return index_; } 252 int index() { return index_; }
231 253
254 // Predicates.
255 bool is_slot() { return true; }
256
232 // Support for fast-compilation mode. 257 // Support for fast-compilation mode.
233 void Get(MacroAssembler* masm, Register reg); 258 void Get(MacroAssembler* masm, Register reg);
234 void Set(MacroAssembler* masm, Register reg); 259 void Set(MacroAssembler* masm, Register reg);
235 void Push(MacroAssembler* masm); 260 void Push(MacroAssembler* masm);
261 void Move(MacroAssembler* masm, Value* value);
262 void MoveToSlot(MacroAssembler* masm, SlotLocation* loc);
236 263
237 #ifdef DEBUG 264 #ifdef DEBUG
238 void Print(); 265 void Print();
239 #endif 266 #endif
240 267
241 private: 268 private:
242 Slot::Type type_; 269 Slot::Type type_;
243 int index_; 270 int index_;
244 }; 271 };
245 272
246 273
247 // TempLocations represent compiler generated temporaries. They are 274 // TempLocations represent compiler generated temporaries. They are
248 // allocated to registers or memory either before code generation (in the 275 // allocated to registers or memory either before code generation (in the
249 // optimized-for-speed compiler) or on the fly during code generation (in 276 // optimized-for-speed compiler) or on the fly during code generation (in
250 // the optimized-for-space compiler). 277 // the optimized-for-space compiler).
251 class TempLocation : public Location { 278 class TempLocation : public Location {
252 public: 279 public:
253 // Fast-compilation mode allocation decisions. 280 // Fast-compilation mode allocation decisions.
254 enum Where { 281 enum Where {
255 NOWHERE, // Not yet allocated. 282 NOT_ALLOCATED, // Not yet allocated.
256 ACCUMULATOR, // Allocated to the dedicated accumulator register. 283 ACCUMULATOR, // Allocated to the dedicated accumulator register.
257 STACK // " " " " stack. 284 STACK // " " " " stack.
258 }; 285 };
259 286
260 TempLocation() : where_(NOWHERE) { 287 TempLocation() : where_(NOT_ALLOCATED) {
261 #ifdef DEBUG 288 #ifdef DEBUG
262 number_ = -1; 289 number_ = -1;
263 #endif 290 #endif
264 } 291 }
265 292
266 // Cast accessor. 293 // Cast accessor.
267 static TempLocation* cast(Location* loc) { 294 static TempLocation* cast(Value* value) {
268 ASSERT(loc->is_temporary()); 295 ASSERT(value->is_temporary());
269 return reinterpret_cast<TempLocation*>(loc); 296 return reinterpret_cast<TempLocation*>(value);
270 } 297 }
271 298
272 // Accessors. 299 // Accessors.
273 Where where() { return where_; } 300 Where where() { return where_; }
274 void set_where(Where where) { where_ = where; } 301 void set_where(Where where) { where_ = where; }
275 302
276 // Predicates. 303 // Predicates.
277 bool is_on_stack() { return where_ == STACK; } 304 bool is_on_stack() { return where_ == STACK; }
278 bool is_temporary() { return true; } 305 bool is_temporary() { return true; }
279 306
280 // Support for fast-compilation mode. Assume the temp has been allocated. 307 // Support for fast-compilation mode. Assume the temp has been allocated.
281 void Get(MacroAssembler* masm, Register reg); 308 void Get(MacroAssembler* masm, Register reg);
282 void Set(MacroAssembler* masm, Register reg); 309 void Set(MacroAssembler* masm, Register reg);
283 void Push(MacroAssembler* masm); 310 void Push(MacroAssembler* masm);
311 void Move(MacroAssembler* masm, Value* value);
312 void MoveToSlot(MacroAssembler* masm, SlotLocation* loc);
284 313
285 #ifdef DEBUG 314 #ifdef DEBUG
286 int number() { 315 int number() {
287 if (number_ == -1) number_ = CfgGlobals::current()->next_temp_number(); 316 if (number_ == -1) number_ = CfgGlobals::current()->next_temp_number();
288 return number_; 317 return number_;
289 } 318 }
290 319
291 void Print(); 320 void Print();
292 #endif 321 #endif
293 322
294 private: 323 private:
295 Where where_; 324 Where where_;
296 325
297 #ifdef DEBUG 326 #ifdef DEBUG
298 int number_; 327 int number_;
299 #endif 328 #endif
300 }; 329 };
301 330
302 331
303 // Instructions are computations. The represent non-trivial source 332 // Instructions are computations. The represent non-trivial source
304 // expressions: typically ones that have side effects and require code to 333 // expressions: typically ones that have side effects and require code to
305 // be generated. 334 // be generated.
306 class Instruction : public ZoneObject { 335 class Instruction : public ZoneObject {
307 public: 336 public:
308 // Every instruction has a location where its result is stored (which may 337 // Every instruction has a location where its result is stored (which may
309 // be Effect, the default). 338 // be Nowhere, the default).
310 Instruction() : loc_(CfgGlobals::current()->effect_location()) {} 339 Instruction() : location_(CfgGlobals::current()->nowhere()) {}
311 340
312 explicit Instruction(Location* loc) : loc_(loc) {} 341 explicit Instruction(Location* location) : location_(location) {}
313 342
314 virtual ~Instruction() {} 343 virtual ~Instruction() {}
315 344
316 // Accessors. 345 // Accessors.
317 Location* location() { return loc_; } 346 Location* location() { return location_; }
318 void set_location(Location* loc) { loc_ = loc; } 347 void set_location(Location* location) { location_ = location; }
319 348
320 // Support for fast-compilation mode: 349 // Support for fast-compilation mode:
321 350
322 // Emit code to perform the instruction. 351 // Emit code to perform the instruction.
323 virtual void Compile(MacroAssembler* masm) = 0; 352 virtual void Compile(MacroAssembler* masm) = 0;
324 353
325 // Allocate a temporary which is the result of the immediate predecessor 354 // Allocate a temporary which is the result of the immediate predecessor
326 // instruction. It is allocated to the accumulator register if it is used 355 // instruction. It is allocated to the accumulator register if it is used
327 // as an operand to this instruction, otherwise to the stack. 356 // as an operand to this instruction, otherwise to the stack.
328 virtual void FastAllocate(TempLocation* temp) = 0; 357 virtual void FastAllocate(TempLocation* temp) = 0;
329 358
330 #ifdef DEBUG 359 #ifdef DEBUG
331 virtual void Print() = 0; 360 virtual void Print() = 0;
332 #endif 361 #endif
333 362
334 protected: 363 protected:
335 Location* loc_; 364 Location* location_;
336 }; 365 };
337 366
338 367
339 // A phantom instruction that indicates the start of a statement. It 368 // A phantom instruction that indicates the start of a statement. It
340 // causes the statement position to be recorded in the relocation 369 // causes the statement position to be recorded in the relocation
341 // information but generates no code. 370 // information but generates no code.
342 class PositionInstr : public Instruction { 371 class PositionInstr : public Instruction {
343 public: 372 public:
344 explicit PositionInstr(int pos) : pos_(pos) {} 373 explicit PositionInstr(int pos) : pos_(pos) {}
345 374
346 // Support for fast-compilation mode. 375 // Support for fast-compilation mode.
347 void Compile(MacroAssembler* masm); 376 void Compile(MacroAssembler* masm);
348 377
349 // This should not be called. The last instruction of the previous 378 // This should not be called. The last instruction of the previous
350 // statement should not have a temporary as its location. 379 // statement should not have a temporary as its location.
351 void FastAllocate(TempLocation* temp) { UNREACHABLE(); } 380 void FastAllocate(TempLocation* temp) { UNREACHABLE(); }
352 381
353 #ifdef DEBUG 382 #ifdef DEBUG
354 // Printing support. Print nothing. 383 // Printing support. Print nothing.
355 void Print() {} 384 void Print() {}
356 #endif 385 #endif
357 386
358 private: 387 private:
359 int pos_; 388 int pos_;
360 }; 389 };
361 390
362 391
392 // Move a value to a location.
393 class MoveInstr : public Instruction {
394 public:
395 MoveInstr(Location* loc, Value* value) : Instruction(loc), value_(value) {}
396
397 // Accessors.
398 Value* value() { return value_; }
399
400 // Support for fast-compilation mode.
401 void Compile(MacroAssembler* masm);
402 void FastAllocate(TempLocation* temp);
403
404 #ifdef DEBUG
405 void Print();
406 #endif
407
408 private:
409 Value* value_;
410 };
411
412
363 // Perform a (non-short-circuited) binary operation on a pair of values, 413 // Perform a (non-short-circuited) binary operation on a pair of values,
364 // leaving the result in a location. 414 // leaving the result in a location.
365 class BinaryOpInstr : public Instruction { 415 class BinaryOpInstr : public Instruction {
366 public: 416 public:
367 BinaryOpInstr(Location* loc, Token::Value op, Value* val0, Value* val1) 417 BinaryOpInstr(Location* loc, Token::Value op, Value* value0, Value* value1)
368 : Instruction(loc), op_(op), val0_(val0), val1_(val1) { 418 : Instruction(loc), op_(op), value0_(value0), value1_(value1) {
369 } 419 }
370 420
421 // Accessors.
422 Token::Value op() { return op_; }
423 Value* value0() { return value0_; }
424 Value* value1() { return value1_; }
425
371 // Support for fast-compilation mode. 426 // Support for fast-compilation mode.
372 void Compile(MacroAssembler* masm); 427 void Compile(MacroAssembler* masm);
373 void FastAllocate(TempLocation* temp); 428 void FastAllocate(TempLocation* temp);
374 429
375 #ifdef DEBUG 430 #ifdef DEBUG
376 void Print(); 431 void Print();
377 #endif 432 #endif
378 433
379 private: 434 private:
380 Token::Value op_; 435 Token::Value op_;
381 Value* val0_; 436 Value* value0_;
382 Value* val1_; 437 Value* value1_;
383 }; 438 };
384 439
385 440
386 // Return a value. Has the side effect of moving its value into the return 441 // Return a value. Has the side effect of moving its value into the return
387 // value register. Can only occur as the last instruction in an instruction 442 // value register. Can only occur as the last instruction in an instruction
388 // block, and implies that the block is closed (cannot have instructions 443 // block, and implies that the block is closed (cannot have instructions
389 // appended or graph fragments concatenated to the end) and that the block's 444 // appended or graph fragments concatenated to the end) and that the block's
390 // successor is the global exit node for the current function. 445 // successor is the global exit node for the current function.
391 class ReturnInstr : public Instruction { 446 class ReturnInstr : public Instruction {
392 public: 447 public:
393 // Location is always Effect.
394 explicit ReturnInstr(Value* value) : value_(value) {} 448 explicit ReturnInstr(Value* value) : value_(value) {}
395 449
396 virtual ~ReturnInstr() {} 450 virtual ~ReturnInstr() {}
397 451
398 // Support for fast-compilation mode. 452 // Support for fast-compilation mode.
399 void Compile(MacroAssembler* masm); 453 void Compile(MacroAssembler* masm);
400 void FastAllocate(TempLocation* temp); 454 void FastAllocate(TempLocation* temp);
401 455
402 #ifdef DEBUG 456 #ifdef DEBUG
403 void Print(); 457 void Print();
(...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after
598 void Print(); 652 void Print();
599 #endif 653 #endif
600 654
601 private: 655 private:
602 // Entry and exit nodes. 656 // Entry and exit nodes.
603 CfgNode* entry_; 657 CfgNode* entry_;
604 CfgNode* exit_; 658 CfgNode* exit_;
605 }; 659 };
606 660
607 661
662 // An implementation of a set of locations (currently slot locations).
663 class LocationSet BASE_EMBEDDED {
664 public:
665 // Construct an empty location set.
666 LocationSet() : parameters_(0), locals_(0) {}
667
668 // Raw accessors.
669 uintptr_t parameters() { return parameters_; }
670 uintptr_t locals() { return locals_; }
671
672 // Insert an element.
673 void AddElement(SlotLocation* location) {
674 if (location->type() == Slot::PARAMETER) {
675 // Parameter indexes begin with -1 ('this').
676 ASSERT(location->index() < kPointerSize - 1);
677 parameters_ |= (1 << (location->index() + 1));
678 } else {
679 ASSERT(location->type() == Slot::LOCAL);
680 ASSERT(location->index() < kPointerSize);
681 locals_ |= (1 << location->index());
682 }
683 }
684
685 // (Destructively) compute the union with another set.
686 void Union(LocationSet* other) {
687 parameters_ |= other->parameters();
688 locals_ |= other->locals();
689 }
690
691 bool Contains(SlotLocation* location) {
692 if (location->type() == Slot::PARAMETER) {
693 ASSERT(location->index() < kPointerSize - 1);
694 return (parameters_ & (1 << (location->index() + 1)));
695 } else {
696 ASSERT(location->type() == Slot::LOCAL);
697 ASSERT(location->index() < kPointerSize);
698 return (locals_ & (1 << location->index()));
699 }
700 }
701
702 private:
703 uintptr_t parameters_;
704 uintptr_t locals_;
705 };
706
707
608 // An ExpressionBuilder traverses an expression and returns an open CFG 708 // An ExpressionBuilder traverses an expression and returns an open CFG
609 // fragment (currently a possibly empty list of instructions represented by 709 // fragment (currently a possibly empty list of instructions represented by
610 // a singleton instruction block) and the expression's value. 710 // a singleton instruction block) and the expression's value.
611 // 711 //
612 // Failure is to build the CFG is indicated by a NULL CFG. 712 // Failure is to build the CFG is indicated by a NULL CFG.
613 class ExpressionBuilder : public AstVisitor { 713 class ExpressionBuilder : public AstVisitor {
614 public: 714 public:
615 ExpressionBuilder() : value_(NULL), cfg_(NULL) {} 715 ExpressionBuilder() : value_(NULL), graph_(NULL), destination_(NULL) {}
616 716
617 // Result accessors. 717 // Result accessors.
618 Value* value() { return value_; } 718 Value* value() { return value_; }
619 Cfg* cfg() { return cfg_; } 719 Cfg* graph() { return graph_; }
720 LocationSet* assigned_vars() { return &assigned_vars_; }
620 721
621 void Build(Expression* expr) { 722 // Build the cfg for an expression and remember its value. The
723 // destination is a 'hint' where the value should go which may be ignored.
724 // NULL is used to indicate no preference.
725 //
726 // Concretely, if the expression needs to generate a temporary for its
727 // value, it should use the passed destination or generate one if NULL.
728 void Build(Expression* expr, Location* destination) {
622 value_ = NULL; 729 value_ = NULL;
623 cfg_ = new Cfg(); 730 graph_ = new Cfg();
731 destination_ = destination;
624 Visit(expr); 732 Visit(expr);
625 } 733 }
626 734
627 // AST node visitors. 735 // AST node visitors.
628 #define DECLARE_VISIT(type) void Visit##type(type* node); 736 #define DECLARE_VISIT(type) void Visit##type(type* node);
629 AST_NODE_LIST(DECLARE_VISIT) 737 AST_NODE_LIST(DECLARE_VISIT)
630 #undef DECLARE_VISIT 738 #undef DECLARE_VISIT
631 739
632 private: 740 private:
741 // State for the visitor. Output parameters.
633 Value* value_; 742 Value* value_;
634 Cfg* cfg_; 743 Cfg* graph_;
744 LocationSet assigned_vars_;
745
746 // Input parameters.
747 Location* destination_;
635 }; 748 };
636 749
637 750
638 // A StatementBuilder maintains a CFG fragment accumulator. When it visits 751 // A StatementBuilder maintains a CFG fragment accumulator. When it visits
639 // a statement, it concatenates the CFG for the statement to the end of the 752 // a statement, it concatenates the CFG for the statement to the end of the
640 // accumulator. 753 // accumulator.
641 class StatementBuilder : public AstVisitor { 754 class StatementBuilder : public AstVisitor {
642 public: 755 public:
643 StatementBuilder() : cfg_(new Cfg()) {} 756 StatementBuilder() : graph_(new Cfg()) {}
644 757
645 Cfg* cfg() { return cfg_; } 758 Cfg* graph() { return graph_; }
646 759
647 void VisitStatements(ZoneList<Statement*>* stmts); 760 void VisitStatements(ZoneList<Statement*>* stmts);
648 761
649 // AST node visitors. 762 // AST node visitors.
650 #define DECLARE_VISIT(type) void Visit##type(type* node); 763 #define DECLARE_VISIT(type) void Visit##type(type* node);
651 AST_NODE_LIST(DECLARE_VISIT) 764 AST_NODE_LIST(DECLARE_VISIT)
652 #undef DECLARE_VISIT 765 #undef DECLARE_VISIT
653 766
654 private: 767 private:
655 Cfg* cfg_; 768 Cfg* graph_;
656 }; 769 };
657 770
658 771
659 } } // namespace v8::internal 772 } } // namespace v8::internal
660 773
661 #endif // V8_CFG_H_ 774 #endif // V8_CFG_H_
OLDNEW
« no previous file with comments | « src/arm/cfg-arm.cc ('k') | src/cfg.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698