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 |