| 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 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 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 | 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 | 160 // type name. The concrete instruction classes are the name with Instr |
| 161 // concatenated. | 161 // concatenated. |
| 162 #define FOR_EACH_INSTRUCTION(M) \ | 162 #define FOR_EACH_INSTRUCTION(M) \ |
| 163 M(JoinEntry) \ | 163 M(JoinEntry) \ |
| 164 M(TargetEntry) \ | 164 M(TargetEntry) \ |
| 165 M(Do) \ | 165 M(Do) \ |
| 166 M(Bind) \ | 166 M(Bind) \ |
| 167 M(Return) \ | 167 M(Return) \ |
| 168 M(Branch) | 168 M(Branch) |
| 169 | 169 |
| 170 | 170 |
| 171 // Forward declarations for Instruction classes. | 171 // Forward declarations for Instruction classes. |
| 172 class BlockEntryInstr; | 172 class BlockEntryInstr; |
| 173 class InstructionVisitor; | 173 class InstructionVisitor; |
| 174 #define FORWARD_DECLARATION(type) class type##Instr; | 174 #define FORWARD_DECLARATION(type) class type##Instr; |
| 175 FOR_EACH_INSTRUCTION(FORWARD_DECLARATION) | 175 FOR_EACH_INSTRUCTION(FORWARD_DECLARATION) |
| 176 #undef FORWARD_DECLARATION | 176 #undef FORWARD_DECLARATION |
| 177 | 177 |
| 178 | 178 |
| 179 // Functions required in all concrete instruction classes. | 179 // Functions required in all concrete instruction classes. |
| 180 #define DECLARE_INSTRUCTION(type) \ | 180 #define DECLARE_INSTRUCTION(type) \ |
| 181 virtual Tag tag() const { return k##type; } \ | 181 virtual Instruction* Accept(InstructionVisitor* visitor); \ |
| 182 static type##Instr* cast(Instruction* instr) { \ | 182 virtual bool Is##type() const { return true; } \ |
| 183 ASSERT(instr->Is##type()); \ | 183 virtual type##Instr* As##type() { return this; } \ |
| 184 return reinterpret_cast<type##Instr*>(instr); \ | |
| 185 } \ | |
| 186 virtual Instruction* Accept(InstructionVisitor* visitor); | |
| 187 | 184 |
| 188 | 185 |
| 189 class Instruction : public ZoneAllocated { | 186 class Instruction : public ZoneAllocated { |
| 190 public: | 187 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 | |
| 199 Instruction() : mark_(false) { } | 188 Instruction() : mark_(false) { } |
| 200 | 189 |
| 201 // Pure virtual tag accessor. | 190 virtual bool IsBlockEntry() const { return false; } |
| 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 | 191 |
| 213 // Visiting support. | 192 // Visiting support. |
| 214 virtual Instruction* Accept(InstructionVisitor* visitor) = 0; | 193 virtual Instruction* Accept(InstructionVisitor* visitor) = 0; |
| 215 | 194 |
| 216 virtual void SetSuccessor(Instruction* instr) = 0; | 195 virtual void SetSuccessor(Instruction* instr) = 0; |
| 217 // Perform a postorder traversal of the instruction graph reachable from | 196 // Perform a postorder traversal of the instruction graph reachable from |
| 218 // this instruction. Accumulate basic block entries in the order visited | 197 // this instruction. Accumulate basic block entries in the order visited |
| 219 // in the in/out parameter 'block_entries'. | 198 // in the in/out parameter 'block_entries'. |
| 220 virtual void Postorder(GrowableArray<BlockEntryInstr*>* block_entries) = 0; | 199 virtual void Postorder(GrowableArray<BlockEntryInstr*>* block_entries) = 0; |
| 221 | 200 |
| 222 // Mark bit to support non-reentrant recursive traversal (i.e., | 201 // Mark bit to support non-reentrant recursive traversal (i.e., |
| 223 // identification of cycles). Before and after a traversal, all the nodes | 202 // identification of cycles). Before and after a traversal, all the nodes |
| 224 // must have the same mark. | 203 // must have the same mark. |
| 225 bool mark() const { return mark_; } | 204 bool mark() const { return mark_; } |
| 226 void flip_mark() { mark_ = !mark_; } | 205 void flip_mark() { mark_ = !mark_; } |
| 227 | 206 |
| 207 #define INSTRUCTION_TYPE_CHECK(type) \ |
| 208 virtual bool Is##type() const { return false; } \ |
| 209 virtual type##Instr* As##type() { return NULL; } |
| 210 FOR_EACH_INSTRUCTION(INSTRUCTION_TYPE_CHECK) |
| 211 #undef INSTRUCTION_TYPE_CHECK |
| 212 |
| 228 private: | 213 private: |
| 229 bool mark_; | 214 bool mark_; |
| 230 }; | 215 }; |
| 231 | 216 |
| 232 | 217 |
| 233 // Basic block entries are administrative nodes. Joins are the only nodes | 218 // Basic block entries are administrative nodes. Joins are the only nodes |
| 234 // with multiple predecessors. Targets are the other basic block entries. | 219 // with multiple predecessors. Targets are the other basic block entries. |
| 235 // The types enforce edge-split form---joins are forbidden as the successors | 220 // The types enforce edge-split form---joins are forbidden as the successors |
| 236 // of branches. | 221 // of branches. |
| 237 class BlockEntryInstr : public Instruction { | 222 class BlockEntryInstr : public Instruction { |
| 238 public: | 223 public: |
| 239 BlockEntryInstr() : Instruction(), block_number_(-1) { } | 224 virtual bool IsBlockEntry() const { return true; } |
| 240 | 225 |
| 241 static BlockEntryInstr* cast(Instruction* instr) { | 226 static BlockEntryInstr* cast(Instruction* instr) { |
| 242 ASSERT(instr->IsBlockEntry()); | 227 ASSERT(instr->IsBlockEntry()); |
| 243 return reinterpret_cast<BlockEntryInstr*>(instr); | 228 return reinterpret_cast<BlockEntryInstr*>(instr); |
| 244 } | 229 } |
| 245 | 230 |
| 246 intptr_t block_number() const { return block_number_; } | 231 intptr_t block_number() const { return block_number_; } |
| 247 void set_block_number(intptr_t number) { block_number_ = number; } | 232 void set_block_number(intptr_t number) { block_number_ = number; } |
| 248 | 233 |
| 234 protected: |
| 235 BlockEntryInstr() : Instruction(), block_number_(-1) { } |
| 236 |
| 249 private: | 237 private: |
| 250 intptr_t block_number_; | 238 intptr_t block_number_; |
| 251 }; | 239 }; |
| 252 | 240 |
| 253 | 241 |
| 254 class JoinEntryInstr : public BlockEntryInstr { | 242 class JoinEntryInstr : public BlockEntryInstr { |
| 255 public: | 243 public: |
| 256 JoinEntryInstr() : BlockEntryInstr(), successor_(NULL) { } | 244 JoinEntryInstr() : BlockEntryInstr(), successor_(NULL) { } |
| 257 | 245 |
| 258 DECLARE_INSTRUCTION(JoinEntry) | 246 DECLARE_INSTRUCTION(JoinEntry) |
| (...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 400 #undef DECLARE_VISIT | 388 #undef DECLARE_VISIT |
| 401 | 389 |
| 402 private: | 390 private: |
| 403 DISALLOW_COPY_AND_ASSIGN(InstructionVisitor); | 391 DISALLOW_COPY_AND_ASSIGN(InstructionVisitor); |
| 404 }; | 392 }; |
| 405 | 393 |
| 406 | 394 |
| 407 } // namespace dart | 395 } // namespace dart |
| 408 | 396 |
| 409 #endif // VM_INTERMEDIATE_LANGUAGE_H_ | 397 #endif // VM_INTERMEDIATE_LANGUAGE_H_ |
| OLD | NEW |