| 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" |
| 11 #include "vm/object.h" | 11 #include "vm/object.h" |
| 12 | 12 |
| 13 namespace dart { | 13 namespace dart { |
| 14 | 14 |
| 15 class FlowGraphVisitor; |
| 15 class LocalVariable; | 16 class LocalVariable; |
| 16 class ConstantValue; | |
| 17 class TempValue; | |
| 18 | 17 |
| 19 // Computations and values. | 18 // Computations and values. |
| 20 // | 19 // |
| 21 // <Computation> ::= <Value> | 20 // <Computation> ::= <Value> |
| 22 // | AssertAssignable <Value> <AbstractType> | 21 // | AssertAssignable <Value> <AbstractType> |
| 23 // | InstanceCall <cstring> <Value> ... | 22 // | InstanceCall <cstring> <Value> ... |
| 24 // | StaticCall <Function> <Value> ... | 23 // | StaticCall <Function> <Value> ... |
| 25 // | LoadLocal <LocalVariable> | 24 // | LoadLocal <LocalVariable> |
| 26 // | StoreLocal <LocalVariable> <Value> | 25 // | StoreLocal <LocalVariable> <Value> |
| 27 // | StrictCompare <Token::kind> <Value> <Value> | 26 // | StrictCompare <Token::kind> <Value> <Value> |
| 28 // | 27 // |
| 29 // <Value> ::= Temp <int> | 28 // <Value> ::= Temp <int> |
| 30 // | Constant <Instance> | 29 // | Constant <Instance> |
| 31 | 30 |
| 31 // M is a two argument macro. It is applied to each concrete value's |
| 32 // typename and classname. |
| 33 #define FOR_EACH_VALUE(M) \ |
| 34 M(Temp, TempVal) \ |
| 35 M(Constant, ConstantVal) |
| 36 |
| 37 // M is a two argument macro. It is applied to each concrete instruction's |
| 38 // (including the values) typename and classname. |
| 39 #define FOR_EACH_COMPUTATION(M) \ |
| 40 FOR_EACH_VALUE(M) \ |
| 41 M(AssertAssignable, AssertAssignableComp) \ |
| 42 M(InstanceCall, InstanceCallComp) \ |
| 43 M(StrictCompare, StrictCompareComp) \ |
| 44 M(StaticCall, StaticCallComp) \ |
| 45 M(LoadLocal, LoadLocalComp) \ |
| 46 M(StoreLocal, StoreLocalComp) |
| 47 |
| 48 |
| 49 #define FORWARD_DECLARATION(ShortName, ClassName) class ClassName; |
| 50 FOR_EACH_COMPUTATION(FORWARD_DECLARATION) |
| 51 #undef FORWARD_DECLARATION |
| 52 |
| 32 class Computation : public ZoneAllocated { | 53 class Computation : public ZoneAllocated { |
| 33 public: | 54 public: |
| 34 Computation() { } | 55 Computation() { } |
| 35 | 56 |
| 36 // Prints a computation without indentation or trailing newlines. | 57 // Visiting support. |
| 37 virtual void Print() const = 0; | 58 virtual void Accept(FlowGraphVisitor* visitor) = 0; |
| 38 | 59 |
| 39 private: | 60 private: |
| 40 DISALLOW_COPY_AND_ASSIGN(Computation); | 61 DISALLOW_COPY_AND_ASSIGN(Computation); |
| 41 }; | 62 }; |
| 42 | 63 |
| 43 | 64 |
| 44 class Value : public Computation { | 65 class Value : public Computation { |
| 45 public: | 66 public: |
| 46 Value() { } | 67 Value() { } |
| 47 | 68 |
| 48 virtual TempValue* AsTemp() { return NULL; } | 69 #define DEFINE_TESTERS(ShortName, ClassName) \ |
| 49 virtual ConstantValue* AsConstant() { return NULL; } | 70 virtual ClassName* As##ShortName() { return NULL; } \ |
| 71 bool Is##ShortName() { return As##ShortName() != NULL; } |
| 50 | 72 |
| 51 bool IsTemp() { return AsTemp() != NULL; } | 73 FOR_EACH_VALUE(DEFINE_TESTERS) |
| 52 bool IsConstant() { return AsConstant() != NULL; } | 74 #undef DEFINE_TESTERS |
| 53 | 75 |
| 54 private: | 76 private: |
| 55 DISALLOW_COPY_AND_ASSIGN(Value); | 77 DISALLOW_COPY_AND_ASSIGN(Value); |
| 56 }; | 78 }; |
| 57 | 79 |
| 58 | 80 |
| 81 // Functions defined in all concrete computation classes. |
| 82 #define DECLARE_COMPUTATION(ShortName) \ |
| 83 virtual void Accept(FlowGraphVisitor* visitor); |
| 84 |
| 85 // Functions defined in all concrete value classes. |
| 86 #define DECLARE_VALUE(ShortName) \ |
| 87 DECLARE_COMPUTATION(ShortName) \ |
| 88 virtual ShortName##Val* As##ShortName() { return this; } |
| 89 |
| 90 |
| 91 class TempVal : public Value { |
| 92 public: |
| 93 explicit TempVal(intptr_t index) : index_(index) { } |
| 94 |
| 95 DECLARE_VALUE(Temp) |
| 96 |
| 97 intptr_t index() const { return index_; } |
| 98 |
| 99 private: |
| 100 intptr_t index_; |
| 101 |
| 102 DISALLOW_COPY_AND_ASSIGN(TempVal); |
| 103 }; |
| 104 |
| 105 |
| 106 class ConstantVal: public Value { |
| 107 public: |
| 108 explicit ConstantVal(const Instance& instance) : instance_(instance) { |
| 109 ASSERT(instance.IsZoneHandle()); |
| 110 } |
| 111 |
| 112 DECLARE_VALUE(Constant) |
| 113 |
| 114 const Instance& instance() const { return instance_; } |
| 115 |
| 116 private: |
| 117 const Instance& instance_; |
| 118 |
| 119 DISALLOW_COPY_AND_ASSIGN(ConstantVal); |
| 120 }; |
| 121 |
| 122 #undef DECLARE_VALUE |
| 123 |
| 124 |
| 59 class AssertAssignableComp : public Computation { | 125 class AssertAssignableComp : public Computation { |
| 60 public: | 126 public: |
| 61 AssertAssignableComp(Value* value, const AbstractType& type) | 127 AssertAssignableComp(Value* value, const AbstractType& type) |
| 62 : value_(value), type_(type) { } | 128 : value_(value), type_(type) { } |
| 63 | 129 |
| 64 virtual void Print() const; | 130 DECLARE_COMPUTATION(AssertAssignable) |
| 131 |
| 132 Value* value() const { return value_; } |
| 133 const AbstractType& type() const { return type_; } |
| 65 | 134 |
| 66 private: | 135 private: |
| 67 Value* value_; | 136 Value* value_; |
| 68 const AbstractType& type_; | 137 const AbstractType& type_; |
| 69 | 138 |
| 70 DISALLOW_COPY_AND_ASSIGN(AssertAssignableComp); | 139 DISALLOW_COPY_AND_ASSIGN(AssertAssignableComp); |
| 71 }; | 140 }; |
| 72 | 141 |
| 73 | 142 |
| 74 class InstanceCallComp : public Computation { | 143 class InstanceCallComp : public Computation { |
| 75 public: | 144 public: |
| 76 InstanceCallComp(const char* name, ZoneGrowableArray<Value*>* arguments) | 145 InstanceCallComp(const char* name, ZoneGrowableArray<Value*>* arguments) |
| 77 : name_(name), arguments_(arguments) { } | 146 : name_(name), arguments_(arguments) { } |
| 78 | 147 |
| 79 virtual void Print() const; | 148 DECLARE_COMPUTATION(InstanceCall) |
| 149 |
| 150 const char* name() const { return name_; } |
| 151 int ArgumentCount() const { return arguments_->length(); } |
| 152 Value* ArgumentAt(int index) const { return (*arguments_)[index]; } |
| 80 | 153 |
| 81 private: | 154 private: |
| 82 const char* name_; | 155 const char* name_; |
| 83 ZoneGrowableArray<Value*>* arguments_; | 156 ZoneGrowableArray<Value*>* arguments_; |
| 84 | 157 |
| 85 DISALLOW_COPY_AND_ASSIGN(InstanceCallComp); | 158 DISALLOW_COPY_AND_ASSIGN(InstanceCallComp); |
| 86 }; | 159 }; |
| 87 | 160 |
| 88 | 161 |
| 89 class StrictCompareComp : public Computation { | 162 class StrictCompareComp : public Computation { |
| 90 public: | 163 public: |
| 91 StrictCompareComp(Token::Kind kind, Value* left, Value* right) | 164 StrictCompareComp(Token::Kind kind, Value* left, Value* right) |
| 92 : kind_(kind), left_(left), right_(right) { | 165 : kind_(kind), left_(left), right_(right) { |
| 93 ASSERT((kind_ == Token::kEQ_STRICT) || (kind_ == Token::kNE_STRICT)); | 166 ASSERT((kind_ == Token::kEQ_STRICT) || (kind_ == Token::kNE_STRICT)); |
| 94 } | 167 } |
| 95 | 168 |
| 96 virtual void Print() const; | 169 DECLARE_COMPUTATION(StrictCompare) |
| 170 |
| 171 Token::Kind kind() const { return kind_; } |
| 172 Value* left() const { return left_; } |
| 173 Value* right() const { return right_; } |
| 97 | 174 |
| 98 private: | 175 private: |
| 99 const Token::Kind kind_; | 176 const Token::Kind kind_; |
| 100 Value* left_; | 177 Value* left_; |
| 101 Value* right_; | 178 Value* right_; |
| 102 | 179 |
| 103 DISALLOW_COPY_AND_ASSIGN(StrictCompareComp); | 180 DISALLOW_COPY_AND_ASSIGN(StrictCompareComp); |
| 104 }; | 181 }; |
| 105 | 182 |
| 106 | 183 |
| 107 class StaticCallComp : public Computation { | 184 class StaticCallComp : public Computation { |
| 108 public: | 185 public: |
| 109 StaticCallComp(const Function& function, ZoneGrowableArray<Value*>* arguments) | 186 StaticCallComp(const Function& function, ZoneGrowableArray<Value*>* arguments) |
| 110 : function_(function), arguments_(arguments) { | 187 : function_(function), arguments_(arguments) { |
| 111 ASSERT(function.IsZoneHandle()); | 188 ASSERT(function.IsZoneHandle()); |
| 112 } | 189 } |
| 113 | 190 |
| 114 virtual void Print() const; | 191 DECLARE_COMPUTATION(StaticCall) |
| 192 |
| 193 const Function& function() const { return function_; } |
| 194 int ArgumentCount() const { return arguments_->length(); } |
| 195 Value* ArgumentAt(int index) const { return (*arguments_)[index]; } |
| 115 | 196 |
| 116 private: | 197 private: |
| 117 const Function& function_; | 198 const Function& function_; |
| 118 ZoneGrowableArray<Value*>* arguments_; | 199 ZoneGrowableArray<Value*>* arguments_; |
| 119 | 200 |
| 120 DISALLOW_COPY_AND_ASSIGN(StaticCallComp); | 201 DISALLOW_COPY_AND_ASSIGN(StaticCallComp); |
| 121 }; | 202 }; |
| 122 | 203 |
| 123 | 204 |
| 124 class LoadLocalComp : public Computation { | 205 class LoadLocalComp : public Computation { |
| 125 public: | 206 public: |
| 126 explicit LoadLocalComp(const LocalVariable& local) : local_(local) { } | 207 explicit LoadLocalComp(const LocalVariable& local) : local_(local) { } |
| 127 | 208 |
| 128 virtual void Print() const; | 209 DECLARE_COMPUTATION(LoadLocal) |
| 210 |
| 211 const LocalVariable& local() const { return local_; } |
| 129 | 212 |
| 130 private: | 213 private: |
| 131 const LocalVariable& local_; | 214 const LocalVariable& local_; |
| 132 | 215 |
| 133 DISALLOW_COPY_AND_ASSIGN(LoadLocalComp); | 216 DISALLOW_COPY_AND_ASSIGN(LoadLocalComp); |
| 134 }; | 217 }; |
| 135 | 218 |
| 136 | 219 |
| 137 class StoreLocalComp : public Computation { | 220 class StoreLocalComp : public Computation { |
| 138 public: | 221 public: |
| 139 StoreLocalComp(const LocalVariable& local, Value* value) | 222 StoreLocalComp(const LocalVariable& local, Value* value) |
| 140 : local_(local), value_(value) { } | 223 : local_(local), value_(value) { } |
| 141 | 224 |
| 142 virtual void Print() const; | 225 DECLARE_COMPUTATION(StoreLocal) |
| 226 |
| 227 const LocalVariable& local() const { return local_; } |
| 228 Value* value() const { return value_; } |
| 143 | 229 |
| 144 private: | 230 private: |
| 145 const LocalVariable& local_; | 231 const LocalVariable& local_; |
| 146 Value* value_; | 232 Value* value_; |
| 147 | 233 |
| 148 DISALLOW_COPY_AND_ASSIGN(StoreLocalComp); | 234 DISALLOW_COPY_AND_ASSIGN(StoreLocalComp); |
| 149 }; | 235 }; |
| 150 | 236 |
| 151 | 237 #undef DECLARE_COMPUTATION |
| 152 class TempValue : public Value { | |
| 153 public: | |
| 154 explicit TempValue(intptr_t index) : index_(index) { } | |
| 155 | |
| 156 virtual TempValue* AsTemp() { return this; } | |
| 157 virtual void Print() const; | |
| 158 | |
| 159 private: | |
| 160 intptr_t index_; | |
| 161 | |
| 162 DISALLOW_COPY_AND_ASSIGN(TempValue); | |
| 163 }; | |
| 164 | |
| 165 | |
| 166 class ConstantValue: public Value { | |
| 167 public: | |
| 168 explicit ConstantValue(const Instance& instance) : instance_(instance) { | |
| 169 ASSERT(instance.IsZoneHandle()); | |
| 170 } | |
| 171 | |
| 172 virtual ConstantValue* AsConstant() { return this; } | |
| 173 virtual void Print() const; | |
| 174 | |
| 175 const Instance& instance() const { return instance_; } | |
| 176 | |
| 177 private: | |
| 178 const Instance& instance_; | |
| 179 | |
| 180 DISALLOW_COPY_AND_ASSIGN(ConstantValue); | |
| 181 }; | |
| 182 | 238 |
| 183 | 239 |
| 184 // Instructions. | 240 // Instructions. |
| 185 // | 241 // |
| 186 // <Instruction> ::= Do <Computation> <Instruction> | 242 // <Instruction> ::= Do <Computation> <Instruction> |
| 187 // | Bind <int> <Computation> <Instruction> | 243 // | Bind <int> <Computation> <Instruction> |
| 188 // | Return <Value> | 244 // | Return <Value> |
| 189 // | Branch <Value> <Instruction> <Instruction> | 245 // | Branch <Value> <Instruction> <Instruction> |
| 190 // | Empty <Instruction> | 246 // | Empty <Instruction> |
| 191 | 247 |
| 192 // M is a single argument macro. It is applied to each concrete instruction | 248 // M is a single argument macro. It is applied to each concrete instruction |
| 193 // type name. The concrete instruction classes are the name with Instr | 249 // type name. The concrete instruction classes are the name with Instr |
| 194 // concatenated. | 250 // concatenated. |
| 195 #define FOR_EACH_INSTRUCTION(M) \ | 251 #define FOR_EACH_INSTRUCTION(M) \ |
| 196 M(JoinEntry) \ | 252 M(JoinEntry) \ |
| 197 M(TargetEntry) \ | 253 M(TargetEntry) \ |
| 198 M(Do) \ | 254 M(Do) \ |
| 199 M(Bind) \ | 255 M(Bind) \ |
| 200 M(Return) \ | 256 M(Return) \ |
| 201 M(Branch) | 257 M(Branch) |
| 202 | 258 |
| 203 | 259 |
| 204 // Forward declarations for Instruction classes. | 260 // Forward declarations for Instruction classes. |
| 205 class BlockEntryInstr; | 261 class BlockEntryInstr; |
| 206 class InstructionVisitor; | |
| 207 #define FORWARD_DECLARATION(type) class type##Instr; | 262 #define FORWARD_DECLARATION(type) class type##Instr; |
| 208 FOR_EACH_INSTRUCTION(FORWARD_DECLARATION) | 263 FOR_EACH_INSTRUCTION(FORWARD_DECLARATION) |
| 209 #undef FORWARD_DECLARATION | 264 #undef FORWARD_DECLARATION |
| 210 | 265 |
| 211 | 266 |
| 212 // Functions required in all concrete instruction classes. | 267 // Functions required in all concrete instruction classes. |
| 213 #define DECLARE_INSTRUCTION(type) \ | 268 #define DECLARE_INSTRUCTION(type) \ |
| 214 virtual Instruction* Accept(InstructionVisitor* visitor); \ | 269 virtual Instruction* Accept(FlowGraphVisitor* visitor); \ |
| 215 virtual bool Is##type() const { return true; } \ | 270 virtual bool Is##type() const { return true; } \ |
| 216 virtual type##Instr* As##type() { return this; } \ | 271 virtual type##Instr* As##type() { return this; } \ |
| 217 | 272 |
| 218 | 273 |
| 219 class Instruction : public ZoneAllocated { | 274 class Instruction : public ZoneAllocated { |
| 220 public: | 275 public: |
| 221 Instruction() : mark_(false) { } | 276 Instruction() : mark_(false) { } |
| 222 | 277 |
| 223 virtual bool IsBlockEntry() const { return false; } | 278 virtual bool IsBlockEntry() const { return false; } |
| 224 | 279 |
| 225 // Visiting support. | 280 // Visiting support. |
| 226 virtual Instruction* Accept(InstructionVisitor* visitor) = 0; | 281 virtual Instruction* Accept(FlowGraphVisitor* visitor) = 0; |
| 227 | 282 |
| 228 virtual void SetSuccessor(Instruction* instr) = 0; | 283 virtual void SetSuccessor(Instruction* instr) = 0; |
| 229 // Perform a postorder traversal of the instruction graph reachable from | 284 // Perform a postorder traversal of the instruction graph reachable from |
| 230 // this instruction. Accumulate basic block entries in the order visited | 285 // this instruction. Accumulate basic block entries in the order visited |
| 231 // in the in/out parameter 'block_entries'. | 286 // in the in/out parameter 'block_entries'. |
| 232 virtual void Postorder(GrowableArray<BlockEntryInstr*>* block_entries) = 0; | 287 virtual void Postorder(GrowableArray<BlockEntryInstr*>* block_entries) = 0; |
| 233 | 288 |
| 234 // Mark bit to support non-reentrant recursive traversal (i.e., | 289 // Mark bit to support non-reentrant recursive traversal (i.e., |
| 235 // identification of cycles). Before and after a traversal, all the nodes | 290 // identification of cycles). Before and after a traversal, all the nodes |
| 236 // must have the same mark. | 291 // must have the same mark. |
| (...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 414 Value* value_; | 469 Value* value_; |
| 415 TargetEntryInstr* true_successor_; | 470 TargetEntryInstr* true_successor_; |
| 416 TargetEntryInstr* false_successor_; | 471 TargetEntryInstr* false_successor_; |
| 417 | 472 |
| 418 DISALLOW_COPY_AND_ASSIGN(BranchInstr); | 473 DISALLOW_COPY_AND_ASSIGN(BranchInstr); |
| 419 }; | 474 }; |
| 420 | 475 |
| 421 #undef DECLARE_INSTRUCTION | 476 #undef DECLARE_INSTRUCTION |
| 422 | 477 |
| 423 | 478 |
| 424 class InstructionVisitor { | 479 class FlowGraphVisitor { |
| 425 public: | 480 public: |
| 426 InstructionVisitor() { } | 481 FlowGraphVisitor() { } |
| 427 virtual ~InstructionVisitor() { } | 482 virtual ~FlowGraphVisitor() { } |
| 428 | 483 |
| 429 // Visit each block in the array list in reverse, and for each block its | 484 // Visit each block in the array list in reverse, and for each block its |
| 430 // instructions in order from the block entry to exit. | 485 // instructions in order from the block entry to exit. |
| 431 virtual void VisitBlocks(const GrowableArray<BlockEntryInstr*>& block_order); | 486 virtual void VisitBlocks(const GrowableArray<BlockEntryInstr*>& block_order); |
| 432 | 487 |
| 433 #define DECLARE_VISIT(type) \ | 488 #define DECLARE_VISIT_COMPUTATION(ShortName, ClassName) \ |
| 434 virtual void Visit##type(type##Instr* instr) { } | 489 virtual void Visit##ShortName(ClassName* comp) { } |
| 435 FOR_EACH_INSTRUCTION(DECLARE_VISIT) | 490 |
| 436 #undef DECLARE_VISIT | 491 #define DECLARE_VISIT_INSTRUCTION(ShortName) \ |
| 492 virtual void Visit##ShortName(ShortName##Instr* instr) { } |
| 493 |
| 494 FOR_EACH_COMPUTATION(DECLARE_VISIT_COMPUTATION) |
| 495 FOR_EACH_INSTRUCTION(DECLARE_VISIT_INSTRUCTION) |
| 496 |
| 497 #undef DECLARE_VISIT_COMPUTATION |
| 498 #undef DECLARE_VISIT_INSTRUCTION |
| 437 | 499 |
| 438 private: | 500 private: |
| 439 DISALLOW_COPY_AND_ASSIGN(InstructionVisitor); | 501 DISALLOW_COPY_AND_ASSIGN(FlowGraphVisitor); |
| 440 }; | 502 }; |
| 441 | 503 |
| 442 | 504 |
| 443 } // namespace dart | 505 } // namespace dart |
| 444 | 506 |
| 445 #endif // VM_INTERMEDIATE_LANGUAGE_H_ | 507 #endif // VM_INTERMEDIATE_LANGUAGE_H_ |
| OLD | NEW |