| OLD | NEW |
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, 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/ast.h" | 9 #include "vm/ast.h" |
| 10 #include "vm/growable_array.h" | 10 #include "vm/growable_array.h" |
| (...skipping 546 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 557 M(UnboxInt32) \ | 557 M(UnboxInt32) \ |
| 558 M(UnboxedIntConverter) \ | 558 M(UnboxedIntConverter) \ |
| 559 | 559 |
| 560 | 560 |
| 561 #define FORWARD_DECLARATION(type) class type##Instr; | 561 #define FORWARD_DECLARATION(type) class type##Instr; |
| 562 FOR_EACH_INSTRUCTION(FORWARD_DECLARATION) | 562 FOR_EACH_INSTRUCTION(FORWARD_DECLARATION) |
| 563 #undef FORWARD_DECLARATION | 563 #undef FORWARD_DECLARATION |
| 564 | 564 |
| 565 | 565 |
| 566 // Functions required in all concrete instruction classes. | 566 // Functions required in all concrete instruction classes. |
| 567 #define DECLARE_INSTRUCTION(type) \ | 567 #define DECLARE_INSTRUCTION_NO_BACKEND(type) \ |
| 568 virtual Tag tag() const { return k##type; } \ | 568 virtual Tag tag() const { return k##type; } \ |
| 569 virtual void Accept(FlowGraphVisitor* visitor); \ | 569 virtual void Accept(FlowGraphVisitor* visitor); \ |
| 570 virtual type##Instr* As##type() { return this; } \ | 570 virtual type##Instr* As##type() { return this; } \ |
| 571 virtual const char* DebugName() const { return #type; } \ | 571 virtual const char* DebugName() const { return #type; } \ |
| 572 |
| 573 #define DECLARE_INSTRUCTION_BACKEND(type) \ |
| 572 virtual LocationSummary* MakeLocationSummary(Isolate* isolate, \ | 574 virtual LocationSummary* MakeLocationSummary(Isolate* isolate, \ |
| 573 bool optimizing) const; \ | 575 bool optimizing) const; \ |
| 574 virtual void EmitNativeCode(FlowGraphCompiler* compiler); \ | 576 virtual void EmitNativeCode(FlowGraphCompiler* compiler); \ |
| 575 | 577 |
| 578 // Functions required in all concrete instruction classes. |
| 579 #define DECLARE_INSTRUCTION(type) \ |
| 580 DECLARE_INSTRUCTION_NO_BACKEND(type) \ |
| 581 DECLARE_INSTRUCTION_BACKEND(type) \ |
| 576 | 582 |
| 577 class Instruction : public ZoneAllocated { | 583 class Instruction : public ZoneAllocated { |
| 578 public: | 584 public: |
| 579 #define DECLARE_TAG(type) k##type, | 585 #define DECLARE_TAG(type) k##type, |
| 580 enum Tag { | 586 enum Tag { |
| 581 FOR_EACH_INSTRUCTION(DECLARE_TAG) | 587 FOR_EACH_INSTRUCTION(DECLARE_TAG) |
| 582 }; | 588 }; |
| 583 #undef DECLARE_TAG | 589 #undef DECLARE_TAG |
| 584 | 590 |
| 585 Instruction() | 591 Instruction() |
| (...skipping 7370 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7956 private: | 7962 private: |
| 7957 const Token::Kind op_kind_; | 7963 const Token::Kind op_kind_; |
| 7958 | 7964 |
| 7959 DISALLOW_COPY_AND_ASSIGN(UnaryUint32OpInstr); | 7965 DISALLOW_COPY_AND_ASSIGN(UnaryUint32OpInstr); |
| 7960 }; | 7966 }; |
| 7961 | 7967 |
| 7962 | 7968 |
| 7963 class BoxIntNInstr : public TemplateDefinition<1> { | 7969 class BoxIntNInstr : public TemplateDefinition<1> { |
| 7964 public: | 7970 public: |
| 7965 BoxIntNInstr(Representation representation, Value* value) | 7971 BoxIntNInstr(Representation representation, Value* value) |
| 7966 : representation_(representation) { | 7972 : from_representation_(representation) { |
| 7967 SetInputAt(0, value); | 7973 SetInputAt(0, value); |
| 7968 } | 7974 } |
| 7969 | 7975 |
| 7976 Representation from_representation() const { return from_representation_; } |
| 7977 |
| 7970 Value* value() const { return inputs_[0]; } | 7978 Value* value() const { return inputs_[0]; } |
| 7971 virtual bool ValueFitsSmi() const; | 7979 virtual bool ValueFitsSmi() const; |
| 7972 | 7980 |
| 7973 virtual CompileType ComputeType() const; | 7981 virtual CompileType ComputeType() const; |
| 7974 virtual bool RecomputeType(); | 7982 virtual bool RecomputeType(); |
| 7975 | 7983 |
| 7976 virtual bool CanDeoptimize() const { return false; } | 7984 virtual bool CanDeoptimize() const { return false; } |
| 7977 | 7985 |
| 7978 virtual intptr_t DeoptimizationTarget() const { | 7986 virtual intptr_t DeoptimizationTarget() const { |
| 7979 return Isolate::kNoDeoptId; | 7987 return Isolate::kNoDeoptId; |
| 7980 } | 7988 } |
| 7981 | 7989 |
| 7982 virtual Representation RequiredInputRepresentation(intptr_t idx) const { | 7990 virtual Representation RequiredInputRepresentation(intptr_t idx) const { |
| 7983 ASSERT(idx == 0); | 7991 ASSERT(idx == 0); |
| 7984 return representation_; | 7992 return from_representation_; |
| 7985 } | 7993 } |
| 7986 | 7994 |
| 7987 virtual bool AllowsCSE() const { return true; } | 7995 virtual bool AllowsCSE() const { return true; } |
| 7988 virtual EffectSet Effects() const { return EffectSet::None(); } | 7996 virtual EffectSet Effects() const { return EffectSet::None(); } |
| 7989 virtual EffectSet Dependencies() const { return EffectSet::None(); } | 7997 virtual EffectSet Dependencies() const { return EffectSet::None(); } |
| 7990 virtual bool AttributesEqual(Instruction* other) const { | 7998 virtual bool AttributesEqual(Instruction* other) const { |
| 7991 return other->AsBoxIntN()->representation_ == representation_; | 7999 return other->AsBoxIntN()->from_representation_ == from_representation_; |
| 7992 } | 8000 } |
| 7993 | 8001 |
| 7994 virtual bool MayThrow() const { return false; } | 8002 virtual bool MayThrow() const { return false; } |
| 7995 | 8003 |
| 7996 virtual Definition* Canonicalize(FlowGraph* flow_graph); | 8004 virtual Definition* Canonicalize(FlowGraph* flow_graph); |
| 7997 | 8005 |
| 7998 virtual BoxIntNInstr* AsBoxIntN() { return this; } | 8006 virtual BoxIntNInstr* AsBoxIntN() { return this; } |
| 7999 | 8007 |
| 8008 DECLARE_INSTRUCTION_BACKEND(BoxIntN) |
| 8009 |
| 8000 private: | 8010 private: |
| 8001 const Representation representation_; | 8011 const Representation from_representation_; |
| 8002 | 8012 |
| 8003 DISALLOW_COPY_AND_ASSIGN(BoxIntNInstr); | 8013 DISALLOW_COPY_AND_ASSIGN(BoxIntNInstr); |
| 8004 }; | 8014 }; |
| 8005 | 8015 |
| 8006 | 8016 |
| 8007 class BoxUint32Instr : public BoxIntNInstr { | 8017 class BoxUint32Instr : public BoxIntNInstr { |
| 8008 public: | 8018 public: |
| 8009 explicit BoxUint32Instr(Value* value) | 8019 explicit BoxUint32Instr(Value* value) |
| 8010 : BoxIntNInstr(kUnboxedUint32, value) { } | 8020 : BoxIntNInstr(kUnboxedUint32, value) { } |
| 8011 | 8021 |
| 8012 DECLARE_INSTRUCTION(BoxUint32) | 8022 DECLARE_INSTRUCTION_NO_BACKEND(BoxUint32) |
| 8013 | 8023 |
| 8014 private: | 8024 private: |
| 8015 DISALLOW_COPY_AND_ASSIGN(BoxUint32Instr); | 8025 DISALLOW_COPY_AND_ASSIGN(BoxUint32Instr); |
| 8016 }; | 8026 }; |
| 8017 | 8027 |
| 8018 | 8028 |
| 8019 class BoxInt32Instr : public BoxIntNInstr { | 8029 class BoxInt32Instr : public BoxIntNInstr { |
| 8020 public: | 8030 public: |
| 8021 explicit BoxInt32Instr(Value* value) | 8031 explicit BoxInt32Instr(Value* value) |
| 8022 : BoxIntNInstr(kUnboxedInt32, value) { } | 8032 : BoxIntNInstr(kUnboxedInt32, value) { } |
| 8023 | 8033 |
| 8024 virtual void InferRange(RangeAnalysis* analysis, Range* range); | 8034 virtual void InferRange(RangeAnalysis* analysis, Range* range); |
| 8025 | 8035 |
| 8026 DECLARE_INSTRUCTION(BoxInt32) | 8036 DECLARE_INSTRUCTION_NO_BACKEND(BoxInt32) |
| 8027 | 8037 |
| 8028 private: | 8038 private: |
| 8029 DISALLOW_COPY_AND_ASSIGN(BoxInt32Instr); | 8039 DISALLOW_COPY_AND_ASSIGN(BoxInt32Instr); |
| 8030 }; | 8040 }; |
| 8031 | 8041 |
| 8032 | 8042 |
| 8033 class UnboxIntNInstr : public TemplateDefinition<1> { | 8043 class UnboxIntNInstr : public TemplateDefinition<1> { |
| 8034 public: | 8044 public: |
| 8035 UnboxIntNInstr(Representation representation, | 8045 UnboxIntNInstr(Representation representation, |
| 8036 Value* value, | 8046 Value* value, |
| 8037 intptr_t deopt_id) | 8047 intptr_t deopt_id) |
| 8038 : representation_(representation) { | 8048 : representation_(representation), |
| 8049 is_truncating_(representation == kUnboxedUint32) { |
| 8039 SetInputAt(0, value); | 8050 SetInputAt(0, value); |
| 8040 deopt_id_ = deopt_id; | 8051 deopt_id_ = deopt_id; |
| 8041 } | 8052 } |
| 8042 | 8053 |
| 8043 Value* value() const { return inputs_[0]; } | 8054 Value* value() const { return inputs_[0]; } |
| 8044 | 8055 |
| 8056 bool is_truncating() const { return is_truncating_; } |
| 8057 void mark_truncating() { is_truncating_ = true; } |
| 8058 |
| 8045 virtual Representation representation() const { | 8059 virtual Representation representation() const { |
| 8046 return representation_; | 8060 return representation_; |
| 8047 } | 8061 } |
| 8048 | 8062 |
| 8049 virtual CompileType ComputeType() const; | 8063 virtual CompileType ComputeType() const; |
| 8050 | 8064 |
| 8051 virtual bool AllowsCSE() const { return true; } | 8065 virtual bool AllowsCSE() const { return true; } |
| 8052 virtual EffectSet Effects() const { return EffectSet::None(); } | 8066 virtual EffectSet Effects() const { return EffectSet::None(); } |
| 8053 virtual EffectSet Dependencies() const { return EffectSet::None(); } | 8067 virtual EffectSet Dependencies() const { return EffectSet::None(); } |
| 8054 virtual bool AttributesEqual(Instruction* other) const { | 8068 virtual bool AttributesEqual(Instruction* other) const { |
| 8055 return other->AsUnboxIntN()->representation_ == representation_; | 8069 UnboxIntNInstr* other_unbox = other->AsUnboxIntN(); |
| 8070 return (other_unbox->representation_ == representation_) && |
| 8071 (other_unbox->is_truncating_ == is_truncating_); |
| 8056 } | 8072 } |
| 8057 | 8073 |
| 8058 virtual bool MayThrow() const { return false; } | 8074 virtual bool MayThrow() const { return false; } |
| 8059 | 8075 |
| 8060 virtual Definition* Canonicalize(FlowGraph* flow_graph); | 8076 virtual Definition* Canonicalize(FlowGraph* flow_graph); |
| 8061 | 8077 |
| 8062 virtual UnboxIntNInstr* AsUnboxIntN() { return this; } | 8078 virtual UnboxIntNInstr* AsUnboxIntN() { return this; } |
| 8063 | 8079 |
| 8080 virtual void PrintOperandsTo(BufferFormatter* f) const; |
| 8081 |
| 8082 DECLARE_INSTRUCTION_BACKEND(UnboxIntNInstr); |
| 8083 |
| 8064 private: | 8084 private: |
| 8065 const Representation representation_; | 8085 const Representation representation_; |
| 8086 bool is_truncating_; |
| 8066 | 8087 |
| 8067 DISALLOW_COPY_AND_ASSIGN(UnboxIntNInstr); | 8088 DISALLOW_COPY_AND_ASSIGN(UnboxIntNInstr); |
| 8068 }; | 8089 }; |
| 8069 | 8090 |
| 8070 | 8091 |
| 8071 class UnboxUint32Instr : public UnboxIntNInstr { | 8092 class UnboxUint32Instr : public UnboxIntNInstr { |
| 8072 public: | 8093 public: |
| 8073 UnboxUint32Instr(Value* value, intptr_t deopt_id) | 8094 UnboxUint32Instr(Value* value, intptr_t deopt_id) |
| 8074 : UnboxIntNInstr(kUnboxedUint32, value, deopt_id) { | 8095 : UnboxIntNInstr(kUnboxedUint32, value, deopt_id) { |
| 8096 ASSERT(is_truncating()); |
| 8075 } | 8097 } |
| 8076 | 8098 |
| 8077 virtual bool CanDeoptimize() const { | 8099 virtual bool CanDeoptimize() const { |
| 8078 return (value()->Type()->ToCid() != kSmiCid) | 8100 return (value()->Type()->ToCid() != kSmiCid) |
| 8079 && (value()->Type()->ToCid() != kMintCid); | 8101 && (value()->Type()->ToCid() != kMintCid); |
| 8080 } | 8102 } |
| 8081 | 8103 |
| 8082 DECLARE_INSTRUCTION(UnboxUint32) | 8104 DECLARE_INSTRUCTION_NO_BACKEND(UnboxUint32) |
| 8083 | 8105 |
| 8084 private: | 8106 private: |
| 8085 DISALLOW_COPY_AND_ASSIGN(UnboxUint32Instr); | 8107 DISALLOW_COPY_AND_ASSIGN(UnboxUint32Instr); |
| 8086 }; | 8108 }; |
| 8087 | 8109 |
| 8088 | 8110 |
| 8089 class UnboxInt32Instr : public UnboxIntNInstr { | 8111 class UnboxInt32Instr : public UnboxIntNInstr { |
| 8090 public: | 8112 public: |
| 8091 UnboxInt32Instr(Value* value, intptr_t deopt_id) | 8113 UnboxInt32Instr(Value* value, intptr_t deopt_id) |
| 8092 : UnboxIntNInstr(kUnboxedInt32, value, deopt_id) { | 8114 : UnboxIntNInstr(kUnboxedInt32, value, deopt_id) { |
| 8093 } | 8115 } |
| 8094 | 8116 |
| 8095 virtual bool CanDeoptimize() const; | 8117 virtual bool CanDeoptimize() const; |
| 8096 | 8118 |
| 8097 virtual void InferRange(RangeAnalysis* analysis, Range* range); | 8119 virtual void InferRange(RangeAnalysis* analysis, Range* range); |
| 8098 | 8120 |
| 8099 virtual Definition* Canonicalize(FlowGraph* flow_graph); | 8121 virtual Definition* Canonicalize(FlowGraph* flow_graph); |
| 8100 | 8122 |
| 8101 DECLARE_INSTRUCTION(UnboxInt32) | 8123 DECLARE_INSTRUCTION_NO_BACKEND(UnboxInt32) |
| 8102 | 8124 |
| 8103 private: | 8125 private: |
| 8104 DISALLOW_COPY_AND_ASSIGN(UnboxInt32Instr); | 8126 DISALLOW_COPY_AND_ASSIGN(UnboxInt32Instr); |
| 8105 }; | 8127 }; |
| 8106 | 8128 |
| 8107 | 8129 |
| 8108 class UnboxedIntConverterInstr : public TemplateDefinition<1> { | 8130 class UnboxedIntConverterInstr : public TemplateDefinition<1> { |
| 8109 public: | 8131 public: |
| 8110 UnboxedIntConverterInstr(Representation from, | 8132 UnboxedIntConverterInstr(Representation from, |
| 8111 Representation to, | 8133 Representation to, |
| 8112 Value* value, | 8134 Value* value, |
| 8113 intptr_t deopt_id) | 8135 intptr_t deopt_id) |
| 8114 : from_representation_(from), | 8136 : from_representation_(from), |
| 8115 to_representation_(to) { | 8137 to_representation_(to), |
| 8138 is_truncating_(to == kUnboxedUint32) { |
| 8116 ASSERT(from != to); | 8139 ASSERT(from != to); |
| 8117 ASSERT((from == kUnboxedMint) || | 8140 ASSERT((from == kUnboxedMint) || |
| 8118 (from == kUnboxedUint32) || | 8141 (from == kUnboxedUint32) || |
| 8119 (from == kUnboxedInt32)); | 8142 (from == kUnboxedInt32)); |
| 8120 ASSERT((to == kUnboxedMint) || | 8143 ASSERT((to == kUnboxedMint) || |
| 8121 (to == kUnboxedUint32) || | 8144 (to == kUnboxedUint32) || |
| 8122 (to == kUnboxedInt32)); | 8145 (to == kUnboxedInt32)); |
| 8123 ASSERT((to != kUnboxedInt32) || (deopt_id != Isolate::kNoDeoptId)); | 8146 ASSERT((to != kUnboxedInt32) || (deopt_id != Isolate::kNoDeoptId)); |
| 8124 SetInputAt(0, value); | 8147 SetInputAt(0, value); |
| 8125 deopt_id_ = deopt_id; | 8148 deopt_id_ = deopt_id; |
| 8126 } | 8149 } |
| 8127 | 8150 |
| 8128 Value* value() const { return inputs_[0]; } | 8151 Value* value() const { return inputs_[0]; } |
| 8129 | 8152 |
| 8130 Representation from() const { return from_representation_; } | 8153 Representation from() const { return from_representation_; } |
| 8131 Representation to() const { return to_representation_; } | 8154 Representation to() const { return to_representation_; } |
| 8155 bool is_truncating() const { return is_truncating_; } |
| 8156 |
| 8157 void mark_truncating() { is_truncating_ = true; } |
| 8132 | 8158 |
| 8133 Definition* Canonicalize(FlowGraph* flow_graph); | 8159 Definition* Canonicalize(FlowGraph* flow_graph); |
| 8134 | 8160 |
| 8135 virtual bool CanDeoptimize() const; | 8161 virtual bool CanDeoptimize() const; |
| 8136 | 8162 |
| 8137 virtual Representation representation() const { | 8163 virtual Representation representation() const { |
| 8138 return to(); | 8164 return to(); |
| 8139 } | 8165 } |
| 8140 | 8166 |
| 8141 virtual Representation RequiredInputRepresentation(intptr_t idx) const { | 8167 virtual Representation RequiredInputRepresentation(intptr_t idx) const { |
| 8142 ASSERT(idx == 0); | 8168 ASSERT(idx == 0); |
| 8143 return from(); | 8169 return from(); |
| 8144 } | 8170 } |
| 8145 | 8171 |
| 8146 virtual EffectSet Effects() const { return EffectSet::None(); } | 8172 virtual EffectSet Effects() const { return EffectSet::None(); } |
| 8147 virtual EffectSet Dependencies() const { return EffectSet::None(); } | 8173 virtual EffectSet Dependencies() const { return EffectSet::None(); } |
| 8148 virtual bool AttributesEqual(Instruction* other) const { | 8174 virtual bool AttributesEqual(Instruction* other) const { |
| 8149 ASSERT(other->IsUnboxedIntConverter()); | 8175 ASSERT(other->IsUnboxedIntConverter()); |
| 8150 UnboxedIntConverterInstr* converter = other->AsUnboxedIntConverter(); | 8176 UnboxedIntConverterInstr* converter = other->AsUnboxedIntConverter(); |
| 8151 return (converter->from() == from()) && (converter->to() == to()); | 8177 return (converter->from() == from()) && |
| 8178 (converter->to() == to()) && |
| 8179 (converter->is_truncating() == is_truncating()); |
| 8152 } | 8180 } |
| 8153 | 8181 |
| 8154 virtual bool MayThrow() const { return false; } | 8182 virtual bool MayThrow() const { return false; } |
| 8155 | 8183 |
| 8156 virtual void InferRange(RangeAnalysis* analysis, Range* range); | 8184 virtual void InferRange(RangeAnalysis* analysis, Range* range); |
| 8157 | 8185 |
| 8158 virtual void PrintOperandsTo(BufferFormatter* f) const; | 8186 virtual void PrintOperandsTo(BufferFormatter* f) const; |
| 8159 | 8187 |
| 8160 DECLARE_INSTRUCTION(UnboxedIntConverter); | 8188 DECLARE_INSTRUCTION(UnboxedIntConverter); |
| 8161 | 8189 |
| 8162 private: | 8190 private: |
| 8163 const Representation from_representation_; | 8191 const Representation from_representation_; |
| 8164 const Representation to_representation_; | 8192 const Representation to_representation_; |
| 8193 bool is_truncating_; |
| 8194 |
| 8165 DISALLOW_COPY_AND_ASSIGN(UnboxedIntConverterInstr); | 8195 DISALLOW_COPY_AND_ASSIGN(UnboxedIntConverterInstr); |
| 8166 }; | 8196 }; |
| 8167 | 8197 |
| 8168 | 8198 |
| 8169 #undef DECLARE_INSTRUCTION | 8199 #undef DECLARE_INSTRUCTION |
| 8170 | 8200 |
| 8171 class Environment : public ZoneAllocated { | 8201 class Environment : public ZoneAllocated { |
| 8172 public: | 8202 public: |
| 8173 // Iterate the non-NULL values in the innermost level of an environment. | 8203 // Iterate the non-NULL values in the innermost level of an environment. |
| 8174 class ShallowIterator : public ValueObject { | 8204 class ShallowIterator : public ValueObject { |
| (...skipping 224 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8399 Isolate* isolate, bool opt) const { \ | 8429 Isolate* isolate, bool opt) const { \ |
| 8400 UNIMPLEMENTED(); \ | 8430 UNIMPLEMENTED(); \ |
| 8401 return NULL; \ | 8431 return NULL; \ |
| 8402 } \ | 8432 } \ |
| 8403 void Name::EmitNativeCode(FlowGraphCompiler* compiler) { UNIMPLEMENTED(); } | 8433 void Name::EmitNativeCode(FlowGraphCompiler* compiler) { UNIMPLEMENTED(); } |
| 8404 | 8434 |
| 8405 | 8435 |
| 8406 } // namespace dart | 8436 } // namespace dart |
| 8407 | 8437 |
| 8408 #endif // VM_INTERMEDIATE_LANGUAGE_H_ | 8438 #endif // VM_INTERMEDIATE_LANGUAGE_H_ |
| OLD | NEW |