Chromium Code Reviews| Index: runtime/vm/intermediate_language.h |
| =================================================================== |
| --- runtime/vm/intermediate_language.h (revision 7698) |
| +++ runtime/vm/intermediate_language.h (working copy) |
| @@ -88,6 +88,9 @@ |
| virtual intptr_t InputCount() const = 0; |
| + // Static type propagation support. |
|
srdjan
2012/05/16 20:16:15
Maybe instead: "Static type of the computation".
regis
2012/05/16 23:20:37
Done.
|
| + virtual RawAbstractType* StaticType() const = 0; |
| + |
| // Mutate assigned_vars to add the local variable index for all |
| // frame-allocated locals assigned to by the computation. |
| virtual void RecordAssignedVars(BitVector* assigned_vars); |
| @@ -126,7 +129,11 @@ |
| public: |
| EmbeddedArray() : elements_() { } |
| - intptr_t length() { return N; } |
| + intptr_t length() const { return N; } |
| + const T& operator[](intptr_t i) const { |
| + ASSERT(i < length()); |
| + return elements_[i]; |
| + } |
| T& operator[](intptr_t i) { |
| ASSERT(i < length()); |
| return elements_[i]; |
| @@ -140,12 +147,7 @@ |
| template<typename T> |
| class EmbeddedArray<T, 0> { |
| public: |
| - int length() { return 0; } |
| - T& operator[](intptr_t i) { |
| - UNREACHABLE(); |
| - static T sentinel = 0; |
| - return sentinel; |
| - } |
| + int length() const { return 0; } |
| }; |
| @@ -180,6 +182,7 @@ |
| // Functions defined in all concrete computation classes. |
| #define DECLARE_COMPUTATION(ShortName) \ |
| virtual void Accept(FlowGraphVisitor* visitor); \ |
| + virtual RawAbstractType* StaticType() const; \ |
| // Functions defined in all concrete value classes. |
| #define DECLARE_VALUE(ShortName) \ |
| @@ -283,7 +286,7 @@ |
| intptr_t token_index() const { return token_index_; } |
| intptr_t try_index() const { return try_index_; } |
| - Value* value() { return inputs_[0]; } |
| + Value* value() const { return inputs_[0]; } |
| private: |
| const intptr_t token_index_; |
| @@ -315,7 +318,7 @@ |
| DECLARE_COMPUTATION(StoreContext); |
| - Value* value() { return inputs_[0]; } |
| + Value* value() const { return inputs_[0]; } |
| private: |
| DISALLOW_COPY_AND_ASSIGN(StoreContextComp); |
| @@ -412,8 +415,8 @@ |
| DECLARE_COMPUTATION(StrictCompare) |
| Token::Kind kind() const { return kind_; } |
| - Value* left() { return inputs_[0]; } |
| - Value* right() { return inputs_[1]; } |
| + Value* left() const { return inputs_[0]; } |
| + Value* right() const { return inputs_[1]; } |
| private: |
| const Token::Kind kind_; |
| @@ -440,8 +443,8 @@ |
| intptr_t token_index() const { return token_index_; } |
| intptr_t try_index() const { return try_index_; } |
| - Value* left() { return inputs_[0]; } |
| - Value* right() { return inputs_[1]; } |
| + Value* left() const { return inputs_[0]; } |
| + Value* right() const { return inputs_[1]; } |
| private: |
| const intptr_t token_index_; |
| @@ -521,7 +524,7 @@ |
| DECLARE_COMPUTATION(StoreLocal) |
| const LocalVariable& local() const { return local_; } |
| - Value* value() { return inputs_[0]; } |
| + Value* value() const { return inputs_[0]; } |
| intptr_t context_level() const { return context_level_; } |
| virtual void RecordAssignedVars(BitVector* assigned_vars); |
| @@ -578,7 +581,7 @@ |
| const Field& field() const { return ast_node_.field(); } |
| - Value* instance() { return inputs_[0]; } |
| + Value* instance() const { return inputs_[0]; } |
| private: |
| const LoadInstanceFieldNode& ast_node_; |
| @@ -604,8 +607,8 @@ |
| intptr_t token_index() const { return ast_node_.token_index(); } |
| const Field& field() const { return ast_node_.field(); } |
| - Value* instance() { return inputs_[0]; } |
| - Value* value() { return inputs_[1]; } |
| + Value* instance() const { return inputs_[0]; } |
| + Value* value() const { return inputs_[1]; } |
| private: |
| const StoreInstanceFieldNode& ast_node_; |
| @@ -641,7 +644,7 @@ |
| DECLARE_COMPUTATION(StoreStaticField); |
| const Field& field() const { return field_; } |
| - Value* value() { return inputs_[0]; } |
| + Value* value() const { return inputs_[0]; } |
| private: |
| const Field& field_; |
| @@ -670,9 +673,9 @@ |
| intptr_t token_index() const { return token_index_; } |
| intptr_t try_index() const { return try_index_; } |
| - Value* array() { return inputs_[0]; } |
| - Value* index() { return inputs_[1]; } |
| - Value* value() { return inputs_[2]; } |
| + Value* array() const { return inputs_[0]; } |
| + Value* index() const { return inputs_[1]; } |
| + Value* value() const { return inputs_[2]; } |
| private: |
| const intptr_t token_index_; |
| @@ -703,8 +706,8 @@ |
| intptr_t token_index() const { return token_index_; } |
| intptr_t try_index() const { return try_index_; } |
| const String& field_name() const { return field_name_; } |
| - Value* receiver() { return inputs_[0]; } |
| - Value* value() { return inputs_[1]; } |
| + Value* receiver() const { return inputs_[0]; } |
| + Value* value() const { return inputs_[1]; } |
| private: |
| const intptr_t token_index_; |
| @@ -734,7 +737,7 @@ |
| intptr_t token_index() const { return token_index_; } |
| intptr_t try_index() const { return try_index_; } |
| const Function& setter_function() const { return setter_function_; } |
| - Value* value() { return inputs_[0]; } |
| + Value* value() const { return inputs_[0]; } |
| private: |
| const intptr_t token_index_; |
| @@ -754,7 +757,7 @@ |
| DECLARE_COMPUTATION(BooleanNegate) |
| - Value* value() { return inputs_[0]; } |
| + Value* value() const { return inputs_[0]; } |
| private: |
| DISALLOW_COPY_AND_ASSIGN(BooleanNegateComp); |
| @@ -924,19 +927,23 @@ |
| class NativeLoadFieldComp : public TemplateComputation<1> { |
| public: |
| - NativeLoadFieldComp(Value* value, intptr_t offset_in_bytes) |
| - : offset_in_bytes_(offset_in_bytes) { |
| + NativeLoadFieldComp(Value* value, |
| + intptr_t offset_in_bytes, |
| + const AbstractType& type) |
|
srdjan
2012/05/16 20:16:15
Can type be null or can you assert !type.IsNull()
regis
2012/05/16 23:20:37
Added assert for ZoneHandle and comment about allo
|
| + : offset_in_bytes_(offset_in_bytes), type_(type) { |
| ASSERT(value != NULL); |
| inputs_[0] = value; |
| } |
| DECLARE_COMPUTATION(NativeLoadField) |
| - Value* value() { return inputs_[0]; } |
| + Value* value() const { return inputs_[0]; } |
| intptr_t offset_in_bytes() const { return offset_in_bytes_; } |
| + const AbstractType& type() const { return type_; } |
| private: |
| const intptr_t offset_in_bytes_; |
| + const AbstractType& type_; // Null type if loaded field is not an instance. |
| DISALLOW_COPY_AND_ASSIGN(NativeLoadFieldComp); |
| }; |
| @@ -953,8 +960,8 @@ |
| DECLARE_COMPUTATION(NativeStoreField) |
| - Value* dest() { return inputs_[0]; } |
| - Value* value() { return inputs_[1]; } |
| + Value* dest() const { return inputs_[0]; } |
| + Value* value() const { return inputs_[1]; } |
| intptr_t offset_in_bytes() const { return offset_in_bytes_; } |
| private: |
| @@ -979,7 +986,7 @@ |
| DECLARE_COMPUTATION(InstantiateTypeArguments) |
| - Value* instantiator() { return inputs_[0]; } |
| + Value* instantiator() const { return inputs_[0]; } |
| const AbstractTypeArguments& type_arguments() const { |
| return type_arguments_; |
| } |
| @@ -1011,7 +1018,7 @@ |
| DECLARE_COMPUTATION(ExtractConstructorTypeArguments) |
| - Value* instantiator() { return inputs_[0]; } |
| + Value* instantiator() const { return inputs_[0]; } |
| const AbstractTypeArguments& type_arguments() const { |
| return type_arguments_; |
| } |
| @@ -1040,8 +1047,8 @@ |
| DECLARE_COMPUTATION(ExtractConstructorInstantiator) |
| - Value* instantiator() { return inputs_[0]; } |
| - Value* discard_value() { return inputs_[1]; } |
| + Value* instantiator() const { return inputs_[0]; } |
| + Value* discard_value() const { return inputs_[1]; } |
| const AbstractTypeArguments& type_arguments() const { |
| return ast_node_.type_arguments(); |
| } |
| @@ -1088,7 +1095,7 @@ |
| DECLARE_COMPUTATION(ChainContext) |
| - Value* context_value() { return inputs_[0]; } |
| + Value* context_value() const { return inputs_[0]; } |
| private: |
| DISALLOW_COPY_AND_ASSIGN(ChainContextComp); |
| @@ -1108,7 +1115,7 @@ |
| intptr_t token_index() const { return token_index_; } |
| intptr_t try_index() const { return try_index_; } |
| - Value* context_value() { return inputs_[0]; } |
| + Value* context_value() const { return inputs_[0]; } |
| DECLARE_COMPUTATION(CloneContext) |
| @@ -1246,6 +1253,9 @@ |
| FOR_EACH_INSTRUCTION(INSTRUCTION_TYPE_CHECK) |
| #undef INSTRUCTION_TYPE_CHECK |
| + // Static type propagation support. |
| + virtual RawAbstractType* StaticType() const = 0; |
| + |
| private: |
| intptr_t cid_; |
| ICData* ic_data_; |
| @@ -1278,6 +1288,11 @@ |
| Instruction* last_instruction() const { return last_instruction_; } |
| void set_last_instruction(Instruction* instr) { last_instruction_ = instr; } |
| + virtual RawAbstractType* StaticType() const { |
| + UNREACHABLE(); |
| + return Type::VoidType(); |
| + } |
| + |
| virtual void DiscoverBlocks( |
| BlockEntryInstr* current_block, |
| GrowableArray<BlockEntryInstr*>* preorder, |
| @@ -1443,6 +1458,11 @@ |
| successor_ = instr; |
| } |
| + // Static type propagation support. |
| + virtual RawAbstractType* StaticType() const { |
| + return computation()->StaticType(); |
|
srdjan
2012/05/16 20:16:15
When would you need the static type of a DoInstr?
regis
2012/05/16 23:20:37
You are right. Never needed. Changed to UNREACHABL
|
| + } |
| + |
| virtual void RecordAssignedVars(BitVector* assigned_vars); |
| private: |
| @@ -1462,6 +1482,9 @@ |
| intptr_t temp_index() const { return temp_index_; } |
| void set_temp_index(intptr_t index) { temp_index_ = index; } |
| + // Static type propagation support. |
| + virtual RawAbstractType* StaticType() const = 0; |
| + |
| private: |
| intptr_t temp_index_; |
| @@ -1486,6 +1509,11 @@ |
| successor_ = instr; |
| } |
| + // Static type propagation support. |
| + virtual RawAbstractType* StaticType() const { |
| + return computation()->StaticType(); |
| + } |
| + |
| virtual void RecordAssignedVars(BitVector* assigned_vars); |
| private: |
| @@ -1511,6 +1539,11 @@ |
| virtual Instruction* StraightLineSuccessor() const { return NULL; } |
| virtual void SetSuccessor(Instruction* instr) { UNREACHABLE(); } |
| + virtual RawAbstractType* StaticType() const { |
| + UNREACHABLE(); |
| + return Type::VoidType(); |
|
srdjan
2012/05/16 20:16:15
Maybe move this into Instructions, so that you do
regis
2012/05/16 23:20:37
Good point. Done.
|
| + } |
| + |
| private: |
| const intptr_t token_index_; |
| Value* value_; |
| @@ -1544,6 +1577,11 @@ |
| ASSERT(successor_ == NULL); |
| } |
| + virtual RawAbstractType* StaticType() const { |
| + UNREACHABLE(); |
| + return Type::VoidType(); |
| + } |
| + |
| private: |
| const intptr_t token_index_; |
| const intptr_t try_index_; |
| @@ -1585,6 +1623,11 @@ |
| ASSERT(successor_ == NULL); |
| } |
| + virtual RawAbstractType* StaticType() const { |
| + UNREACHABLE(); |
| + return Type::VoidType(); |
| + } |
| + |
| private: |
| const intptr_t token_index_; |
| const intptr_t try_index_; |
| @@ -1623,6 +1666,11 @@ |
| GrowableArray<BitVector*>* assigned_vars, |
| intptr_t variable_count); |
| + virtual RawAbstractType* StaticType() const { |
| + UNREACHABLE(); |
| + return Type::VoidType(); |
| + } |
| + |
| private: |
| Value* value_; |
| TargetEntryInstr* true_successor_; |