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

Side by Side Diff: runtime/vm/intermediate_language.h

Issue 9453014: Implement a simple InstructionVisitor class. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 8 years, 10 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 | « runtime/vm/flow_graph_builder.cc ('k') | runtime/vm/intermediate_language.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 (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #ifndef VM_INTERMEDIATE_LANGUAGE_H_ 5 #ifndef VM_INTERMEDIATE_LANGUAGE_H_
6 #define VM_INTERMEDIATE_LANGUAGE_H_ 6 #define VM_INTERMEDIATE_LANGUAGE_H_
7 7
8 #include "vm/allocation.h" 8 #include "vm/allocation.h"
9 #include "vm/growable_array.h" 9 #include "vm/growable_array.h"
10 #include "vm/handles_impl.h" 10 #include "vm/handles_impl.h"
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after
149 149
150 150
151 // Instructions. 151 // Instructions.
152 // 152 //
153 // <Instruction> ::= Do <Computation> <Instruction> 153 // <Instruction> ::= Do <Computation> <Instruction>
154 // | Bind <int> <Computation> <Instruction> 154 // | Bind <int> <Computation> <Instruction>
155 // | Return <Value> 155 // | Return <Value>
156 // | Branch <Value> <Instruction> <Instruction> 156 // | Branch <Value> <Instruction> <Instruction>
157 // | Empty <Instruction> 157 // | Empty <Instruction>
158 158
159 // M is a single argument macro. It is applied to each concrete instruction
160 // type name. The concrete instruction classes are the name with Instr
161 // concatenated.
162 #define FOR_EACH_INSTRUCTION(M) \
163 M(JoinEntry) \
164 M(TargetEntry) \
165 M(Do) \
166 M(Bind) \
167 M(Return) \
168 M(Branch)
169
170
171 // Forward declarations for Instruction classes.
172 class BlockEntryInstr;
173 class InstructionVisitor;
174 #define FORWARD_DECLARATION(type) class type##Instr;
175 FOR_EACH_INSTRUCTION(FORWARD_DECLARATION)
176 #undef FORWARD_DECLARATION
177
178
179 // Functions required in all concrete instruction classes.
180 #define DECLARE_INSTRUCTION(type) \
181 virtual Tag tag() const { return k##type; } \
182 static type##Instr* cast(Instruction* instr) { \
183 ASSERT(instr->Is##type()); \
184 return reinterpret_cast<type##Instr*>(instr); \
185 } \
186 virtual Instruction* Accept(InstructionVisitor* visitor);
187
188
159 class Instruction : public ZoneAllocated { 189 class Instruction : public ZoneAllocated {
160 public: 190 public:
191 // Declare a tag for each concrete instruction type.
192 #define DECLARE_TAG(type) k##type,
193 enum Tag {
194 FOR_EACH_INSTRUCTION(DECLARE_TAG)
195 kInstructionCount // To follow the trailing comma from the macro.
196 };
197 #undef DECLARE_TAG
198
161 Instruction() : mark_(false) { } 199 Instruction() : mark_(false) { }
162 200
201 // Pure virtual tag accessor.
202 virtual Tag tag() const = 0;
203
204 // Non-virtual type testing functions.
205 #define DEFINE_TYPE_FUNCTIONS(type) \
206 bool Is##type() const { return tag() == k##type; }
207 FOR_EACH_INSTRUCTION(DEFINE_TYPE_FUNCTIONS)
208 #undef DEFINE_TYPE_FUNCTIONS
209
210 // Type testing and conversions for other classes of instructions.
211 bool IsBlockEntry() const { return IsJoinEntry() || IsTargetEntry(); }
212
213 // Visiting support.
214 virtual Instruction* Accept(InstructionVisitor* visitor) = 0;
215
163 virtual void SetSuccessor(Instruction* instr) = 0; 216 virtual void SetSuccessor(Instruction* instr) = 0;
164 virtual bool IsBlockEntry() const { return false; }
165 virtual void SetBlockNumber(intptr_t number) { UNREACHABLE(); }
166 virtual intptr_t GetBlockNumber() const {
167 UNREACHABLE();
168 return -1;
169 }
170
171 // Perform a postorder traversal of the instruction graph reachable from 217 // Perform a postorder traversal of the instruction graph reachable from
172 // this instruction. Accumulate basic block entries in the order visited 218 // this instruction. Accumulate basic block entries in the order visited
173 // in the in/out parameter 'block_entries'. 219 // in the in/out parameter 'block_entries'.
174 virtual void Postorder(GrowableArray<Instruction*>* block_entries) = 0; 220 virtual void Postorder(GrowableArray<BlockEntryInstr*>* block_entries) = 0;
175
176 // Print an instruction without a four space indent, and no trailing
177 // newline. Basic block entries are labeled with their block number.
178 // Return the instruction's successor if there is a single successor
179 // otherwise NULL.
180 virtual Instruction* Print() const = 0;
181 221
182 // Mark bit to support non-reentrant recursive traversal (i.e., 222 // Mark bit to support non-reentrant recursive traversal (i.e.,
183 // identification of cycles). Before and after a traversal, all the nodes 223 // identification of cycles). Before and after a traversal, all the nodes
184 // must have the same mark. 224 // must have the same mark.
185 bool mark() const { return mark_; } 225 bool mark() const { return mark_; }
186 void flip_mark() { mark_ = !mark_; } 226 void flip_mark() { mark_ = !mark_; }
187 227
188 private: 228 private:
189 bool mark_; 229 bool mark_;
190 }; 230 };
191 231
192 232
233 // Basic block entries are administrative nodes. Joins are the only nodes
234 // with multiple predecessors. Targets are the other basic block entries.
235 // The types enforce edge-split form---joins are forbidden as the successors
236 // of branches.
237 class BlockEntryInstr : public Instruction {
238 public:
239 BlockEntryInstr() : Instruction(), block_number_(-1) { }
240
241 static BlockEntryInstr* cast(Instruction* instr) {
242 ASSERT(instr->IsBlockEntry());
243 return reinterpret_cast<BlockEntryInstr*>(instr);
244 }
245
246 intptr_t block_number() const { return block_number_; }
247 void set_block_number(intptr_t number) { block_number_ = number; }
248
249 private:
250 intptr_t block_number_;
251 };
252
253
254 class JoinEntryInstr : public BlockEntryInstr {
255 public:
256 JoinEntryInstr() : BlockEntryInstr(), successor_(NULL) { }
257
258 DECLARE_INSTRUCTION(JoinEntry)
259
260 virtual void SetSuccessor(Instruction* instr) {
261 ASSERT(successor_ == NULL);
262 successor_ = instr;
263 }
264
265 virtual void Postorder(GrowableArray<BlockEntryInstr*>* block_entries);
266
267 private:
268 Instruction* successor_;
269 };
270
271
272 class TargetEntryInstr : public BlockEntryInstr {
273 public:
274 TargetEntryInstr() : BlockEntryInstr(), block_number_(-1), successor_(NULL) {
275 }
276
277 DECLARE_INSTRUCTION(TargetEntry)
278
279 virtual void SetSuccessor(Instruction* instr) {
280 ASSERT(successor_ == NULL);
281 successor_ = instr;
282 }
283
284 virtual void Postorder(GrowableArray<BlockEntryInstr*>* block_entries);
285
286 private:
287 intptr_t block_number_;
288 Instruction* successor_;
289 };
290
291
193 class DoInstr : public Instruction { 292 class DoInstr : public Instruction {
194 public: 293 public:
195 explicit DoInstr(Computation* comp) 294 explicit DoInstr(Computation* comp)
196 : Instruction(), computation_(comp), successor_(NULL) { } 295 : Instruction(), computation_(comp), successor_(NULL) { }
197 296
297 DECLARE_INSTRUCTION(Do)
298
299 Computation* computation() const { return computation_; }
300
198 virtual void SetSuccessor(Instruction* instr) { 301 virtual void SetSuccessor(Instruction* instr) {
199 ASSERT(successor_ == NULL); 302 ASSERT(successor_ == NULL);
200 successor_ = instr; 303 successor_ = instr;
201 } 304 }
202 305
203 virtual void Postorder(GrowableArray<Instruction*>* block_entries); 306 virtual void Postorder(GrowableArray<BlockEntryInstr*>* block_entries);
204
205 virtual Instruction* Print() const;
206 307
207 private: 308 private:
208 Computation* computation_; 309 Computation* computation_;
209 Instruction* successor_; 310 Instruction* successor_;
210 }; 311 };
211 312
212 313
213 class BindInstr : public Instruction { 314 class BindInstr : public Instruction {
214 public: 315 public:
215 BindInstr(intptr_t temp_index, Computation* computation) 316 BindInstr(intptr_t temp_index, Computation* computation)
216 : Instruction(), 317 : Instruction(),
217 temp_index_(temp_index), 318 temp_index_(temp_index),
218 computation_(computation), 319 computation_(computation),
219 successor_(NULL) { } 320 successor_(NULL) { }
220 321
322 DECLARE_INSTRUCTION(Bind)
323
324 intptr_t temp_index() const { return temp_index_; }
325 Computation* computation() const { return computation_; }
326
221 virtual void SetSuccessor(Instruction* instr) { 327 virtual void SetSuccessor(Instruction* instr) {
222 ASSERT(successor_ == NULL); 328 ASSERT(successor_ == NULL);
223 successor_ = instr; 329 successor_ = instr;
224 } 330 }
225 331
226 virtual void Postorder(GrowableArray<Instruction*>* block_entries); 332 virtual void Postorder(GrowableArray<BlockEntryInstr*>* block_entries);
227
228 virtual Instruction* Print() const;
229 333
230 private: 334 private:
231 const intptr_t temp_index_; 335 const intptr_t temp_index_;
232 Computation* computation_; 336 Computation* computation_;
233 Instruction* successor_; 337 Instruction* successor_;
234 }; 338 };
235 339
236
237 class JoinEntryInstr : public Instruction {
238 public:
239 JoinEntryInstr() : Instruction(), block_number_(-1), successor_(NULL) { }
240
241 virtual void SetSuccessor(Instruction* instr) {
242 ASSERT(successor_ == NULL);
243 successor_ = instr;
244 }
245
246 virtual bool IsBlockEntry() const { return true; }
247 virtual void SetBlockNumber(intptr_t number) { block_number_ = number; }
248 virtual intptr_t GetBlockNumber() const { return block_number_; }
249
250 virtual void Postorder(GrowableArray<Instruction*>* block_entries);
251
252 virtual Instruction* Print() const;
253
254 private:
255 intptr_t block_number_;
256 Instruction* successor_;
257 };
258
259
260 class TargetEntryInstr : public Instruction {
261 public:
262 TargetEntryInstr() : Instruction(), block_number_(-1), successor_(NULL) { }
263
264 virtual void SetSuccessor(Instruction* instr) {
265 ASSERT(successor_ == NULL);
266 successor_ = instr;
267 }
268
269 virtual bool IsBlockEntry() const { return true; }
270 virtual void SetBlockNumber(intptr_t number) { block_number_ = number; }
271 virtual intptr_t GetBlockNumber() const { return block_number_; }
272
273 virtual void Postorder(GrowableArray<Instruction*>* block_entries);
274
275 virtual Instruction* Print() const;
276
277 private:
278 intptr_t block_number_;
279 Instruction* successor_;
280 };
281
282 340
283 class ReturnInstr : public Instruction { 341 class ReturnInstr : public Instruction {
284 public: 342 public:
285 explicit ReturnInstr(Value* value) : Instruction(), value_(value) { } 343 explicit ReturnInstr(Value* value) : Instruction(), value_(value) { }
286 344
345 DECLARE_INSTRUCTION(Return)
346
347 Value* value() const { return value_; }
348
287 virtual void SetSuccessor(Instruction* instr) { UNREACHABLE(); } 349 virtual void SetSuccessor(Instruction* instr) { UNREACHABLE(); }
288 350
289 virtual void Postorder(GrowableArray<Instruction*>* block_entries); 351 virtual void Postorder(GrowableArray<BlockEntryInstr*>* block_entries);
290
291 virtual Instruction* Print() const;
292 352
293 private: 353 private:
294 Value* value_; 354 Value* value_;
295 }; 355 };
296 356
297 357
298 class BranchInstr : public Instruction { 358 class BranchInstr : public Instruction {
299 public: 359 public:
300 explicit BranchInstr(Value* value) 360 explicit BranchInstr(Value* value)
301 : Instruction(), 361 : Instruction(),
302 value_(value), 362 value_(value),
303 true_successor_(NULL), 363 true_successor_(NULL),
304 false_successor_(NULL) { } 364 false_successor_(NULL) { }
305 365
306 virtual void SetSuccessor(Instruction* instr) { UNREACHABLE(); } 366 DECLARE_INSTRUCTION(Branch)
367
368 Value* value() const { return value_; }
369 TargetEntryInstr* true_successor() const { return true_successor_; }
370 TargetEntryInstr* false_successor() const { return false_successor_; }
307 371
308 TargetEntryInstr** true_successor_address() { return &true_successor_; } 372 TargetEntryInstr** true_successor_address() { return &true_successor_; }
309 TargetEntryInstr** false_successor_address() { return &false_successor_; } 373 TargetEntryInstr** false_successor_address() { return &false_successor_; }
310 374
311 virtual void Postorder(GrowableArray<Instruction*>* block_entries); 375 virtual void SetSuccessor(Instruction* instr) { UNREACHABLE(); }
312 376
313 virtual Instruction* Print() const; 377 virtual void Postorder(GrowableArray<BlockEntryInstr*>* block_entries);
314 378
315 private: 379 private:
316 Value* value_; 380 Value* value_;
317 TargetEntryInstr* true_successor_; 381 TargetEntryInstr* true_successor_;
318 TargetEntryInstr* false_successor_; 382 TargetEntryInstr* false_successor_;
319 }; 383 };
320 384
385 #undef DECLARE_INSTRUCTION
386
387
388 class InstructionVisitor {
389 public:
390 InstructionVisitor() { }
391 virtual ~InstructionVisitor() { }
392
393 // Visit each block in the array list in reverse, and for each block its
394 // instructions in order from the block entry to exit.
395 void VisitBlocks(const GrowableArray<BlockEntryInstr*>& block_order);
396
397 #define DECLARE_VISIT(type) \
398 virtual void Visit##type(type##Instr* instr) { }
399 FOR_EACH_INSTRUCTION(DECLARE_VISIT)
400 #undef DECLARE_VISIT
401
402 private:
403 DISALLOW_COPY_AND_ASSIGN(InstructionVisitor);
404 };
405
321 406
322 } // namespace dart 407 } // namespace dart
323 408
324 #endif // VM_INTERMEDIATE_LANGUAGE_H_ 409 #endif // VM_INTERMEDIATE_LANGUAGE_H_
OLDNEW
« no previous file with comments | « runtime/vm/flow_graph_builder.cc ('k') | runtime/vm/intermediate_language.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698