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