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

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

Issue 9454012: Add type testing and casting support. (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.
172 class BlockEntryInstr;
173 #define FORWARD_DECLARATION(type) class type##Instr;
174 FOR_EACH_INSTRUCTION(FORWARD_DECLARATION)
175 #undef FORWARD_DECLARATION
176
177
178 // Functions required in all concrete instruction classes.
179 #define DECLARE_INSTRUCTION(type) \
180 virtual Tag tag() const { return k##type; } \
181 static type##Instr* cast(Instruction* instr) { \
182 ASSERT(instr->Is##type()); \
183 return reinterpret_cast<type##Instr*>(instr); \
184 }
185
186
159 class Instruction : public ZoneAllocated { 187 class Instruction : public ZoneAllocated {
160 public: 188 public:
189 // Declare a tag for each concrete instruction type.
190 #define DECLARE_TAG(type) k##type,
191 enum Tag {
192 FOR_EACH_INSTRUCTION(DECLARE_TAG)
193 kInstructionCount // To follow the trailing comma from the macro.
194 };
195 #undef DECLARE_TAG
196
161 Instruction() : mark_(false) { } 197 Instruction() : mark_(false) { }
162 198
199 // Pure virtual tag accessor.
200 virtual Tag tag() const = 0;
201
202 // Non-virtual type testing functions.
203 #define DEFINE_TYPE_FUNCTIONS(type) \
204 bool Is##type() const { return tag() == k##type; }
205 FOR_EACH_INSTRUCTION(DEFINE_TYPE_FUNCTIONS)
206 #undef DEFINE_TYPE_FUNCTIONS
srdjan 2012/02/23 16:50:26 I think the IsXXX and AsXXX are better. Typical us
207
208 // Type testing and conversions for other classes of instructions.
209 bool IsBlockEntry() const { return IsJoinEntry() || IsTargetEntry(); }
210
163 virtual void SetSuccessor(Instruction* instr) = 0; 211 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 212
171 // Perform a postorder traversal of the instruction graph reachable from 213 // Perform a postorder traversal of the instruction graph reachable from
172 // this instruction. Accumulate basic block entries in the order visited 214 // this instruction. Accumulate basic block entries in the order visited
173 // in the in/out parameter 'block_entries'. 215 // in the in/out parameter 'block_entries'.
174 virtual void Postorder(GrowableArray<Instruction*>* block_entries) = 0; 216 virtual void Postorder(GrowableArray<BlockEntryInstr*>* block_entries) = 0;
175 217
176 // Print an instruction without a four space indent, and no trailing 218 // Print an instruction without a four space indent, and no trailing
177 // newline. Basic block entries are labeled with their block number. 219 // newline. Basic block entries are labeled with their block number.
178 // Return the instruction's successor if there is a single successor 220 // Return the instruction's successor if there is a single successor
179 // otherwise NULL. 221 // otherwise NULL.
180 virtual Instruction* Print() const = 0; 222 virtual Instruction* Print() const = 0;
181 223
182 // Mark bit to support non-reentrant recursive traversal (i.e., 224 // Mark bit to support non-reentrant recursive traversal (i.e.,
183 // identification of cycles). Before and after a traversal, all the nodes 225 // identification of cycles). Before and after a traversal, all the nodes
184 // must have the same mark. 226 // must have the same mark.
185 bool mark() const { return mark_; } 227 bool mark() const { return mark_; }
186 void flip_mark() { mark_ = !mark_; } 228 void flip_mark() { mark_ = !mark_; }
187 229
188 private: 230 private:
189 bool mark_; 231 bool mark_;
190 }; 232 };
191 233
192 234
235 // Basic block entries are administrative nodes. Joins are the only nodes
236 // with multiple predecessors. Targets are the other basic block entries.
237 // The types enforce edge-split form---joins are forbidden as the successors
238 // of branches.
239 class BlockEntryInstr : public Instruction {
240 public:
241 BlockEntryInstr() : Instruction(), block_number_(-1) { }
242
243 static BlockEntryInstr* cast(Instruction* instr) {
244 ASSERT(instr->IsBlockEntry());
245 return reinterpret_cast<BlockEntryInstr*>(instr);
246 }
247
248 intptr_t block_number() const { return block_number_; }
249 void set_block_number(intptr_t number) { block_number_ = number; }
250
251 private:
252 intptr_t block_number_;
srdjan 2012/02/23 16:50:26 Optional: DISALLOW_yada_yada (here and below), but
253 };
254
255
256 class JoinEntryInstr : public BlockEntryInstr {
257 public:
258 JoinEntryInstr() : BlockEntryInstr(), successor_(NULL) { }
259
260 DECLARE_INSTRUCTION(JoinEntry)
261
262 virtual void SetSuccessor(Instruction* instr) {
263 ASSERT(successor_ == NULL);
264 successor_ = instr;
265 }
266
267 virtual void Postorder(GrowableArray<BlockEntryInstr*>* block_entries);
268
269 virtual Instruction* Print() const;
270
271 private:
272 Instruction* successor_;
273 };
274
275
276 class TargetEntryInstr : public BlockEntryInstr {
277 public:
278 TargetEntryInstr() : BlockEntryInstr(), block_number_(-1), successor_(NULL) {
279 }
280
281 DECLARE_INSTRUCTION(TargetEntry)
282
283 virtual void SetSuccessor(Instruction* instr) {
284 ASSERT(successor_ == NULL);
285 successor_ = instr;
286 }
287
288 virtual void Postorder(GrowableArray<BlockEntryInstr*>* block_entries);
289
290 virtual Instruction* Print() const;
291
292 private:
293 intptr_t block_number_;
srdjan 2012/02/23 16:50:26 Superclass has already field block_number_, remove
294 Instruction* successor_;
295 };
296
297
193 class DoInstr : public Instruction { 298 class DoInstr : public Instruction {
194 public: 299 public:
195 explicit DoInstr(Computation* comp) 300 explicit DoInstr(Computation* comp)
196 : Instruction(), computation_(comp), successor_(NULL) { } 301 : Instruction(), computation_(comp), successor_(NULL) { }
197 302
303 DECLARE_INSTRUCTION(Do)
304
198 virtual void SetSuccessor(Instruction* instr) { 305 virtual void SetSuccessor(Instruction* instr) {
199 ASSERT(successor_ == NULL); 306 ASSERT(successor_ == NULL);
200 successor_ = instr; 307 successor_ = instr;
201 } 308 }
202 309
203 virtual void Postorder(GrowableArray<Instruction*>* block_entries); 310 virtual void Postorder(GrowableArray<BlockEntryInstr*>* block_entries);
204 311
205 virtual Instruction* Print() const; 312 virtual Instruction* Print() const;
206 313
207 private: 314 private:
208 Computation* computation_; 315 Computation* computation_;
209 Instruction* successor_; 316 Instruction* successor_;
210 }; 317 };
211 318
212 319
213 class BindInstr : public Instruction { 320 class BindInstr : public Instruction {
214 public: 321 public:
215 BindInstr(intptr_t temp_index, Computation* computation) 322 BindInstr(intptr_t temp_index, Computation* computation)
216 : Instruction(), 323 : Instruction(),
217 temp_index_(temp_index), 324 temp_index_(temp_index),
218 computation_(computation), 325 computation_(computation),
219 successor_(NULL) { } 326 successor_(NULL) { }
220 327
328 DECLARE_INSTRUCTION(Bind)
329
221 virtual void SetSuccessor(Instruction* instr) { 330 virtual void SetSuccessor(Instruction* instr) {
222 ASSERT(successor_ == NULL); 331 ASSERT(successor_ == NULL);
223 successor_ = instr; 332 successor_ = instr;
224 } 333 }
225 334
226 virtual void Postorder(GrowableArray<Instruction*>* block_entries); 335 virtual void Postorder(GrowableArray<BlockEntryInstr*>* block_entries);
227 336
228 virtual Instruction* Print() const; 337 virtual Instruction* Print() const;
229 338
230 private: 339 private:
231 const intptr_t temp_index_; 340 const intptr_t temp_index_;
232 Computation* computation_; 341 Computation* computation_;
233 Instruction* successor_; 342 Instruction* successor_;
234 }; 343 };
235 344
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 345
283 class ReturnInstr : public Instruction { 346 class ReturnInstr : public Instruction {
284 public: 347 public:
285 explicit ReturnInstr(Value* value) : Instruction(), value_(value) { } 348 explicit ReturnInstr(Value* value) : Instruction(), value_(value) { }
286 349
350 DECLARE_INSTRUCTION(Return)
351
287 virtual void SetSuccessor(Instruction* instr) { UNREACHABLE(); } 352 virtual void SetSuccessor(Instruction* instr) { UNREACHABLE(); }
288 353
289 virtual void Postorder(GrowableArray<Instruction*>* block_entries); 354 virtual void Postorder(GrowableArray<BlockEntryInstr*>* block_entries);
290 355
291 virtual Instruction* Print() const; 356 virtual Instruction* Print() const;
292 357
293 private: 358 private:
294 Value* value_; 359 Value* value_;
295 }; 360 };
296 361
297 362
298 class BranchInstr : public Instruction { 363 class BranchInstr : public Instruction {
299 public: 364 public:
300 explicit BranchInstr(Value* value) 365 explicit BranchInstr(Value* value)
301 : Instruction(), 366 : Instruction(),
302 value_(value), 367 value_(value),
303 true_successor_(NULL), 368 true_successor_(NULL),
304 false_successor_(NULL) { } 369 false_successor_(NULL) { }
305 370
371 DECLARE_INSTRUCTION(Branch)
372
306 virtual void SetSuccessor(Instruction* instr) { UNREACHABLE(); } 373 virtual void SetSuccessor(Instruction* instr) { UNREACHABLE(); }
307 374
308 TargetEntryInstr** true_successor_address() { return &true_successor_; } 375 TargetEntryInstr** true_successor_address() { return &true_successor_; }
309 TargetEntryInstr** false_successor_address() { return &false_successor_; } 376 TargetEntryInstr** false_successor_address() { return &false_successor_; }
310 377
311 virtual void Postorder(GrowableArray<Instruction*>* block_entries); 378 virtual void Postorder(GrowableArray<BlockEntryInstr*>* block_entries);
312 379
313 virtual Instruction* Print() const; 380 virtual Instruction* Print() const;
314 381
315 private: 382 private:
316 Value* value_; 383 Value* value_;
317 TargetEntryInstr* true_successor_; 384 TargetEntryInstr* true_successor_;
318 TargetEntryInstr* false_successor_; 385 TargetEntryInstr* false_successor_;
319 }; 386 };
320 387
388 #undef DECLARE_INSTRUCTION
389
321 390
322 } // namespace dart 391 } // namespace dart
323 392
324 #endif // VM_INTERMEDIATE_LANGUAGE_H_ 393 #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