| OLD | NEW |
| 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 Loading... |
| 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_ |
| OLD | NEW |