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 563 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
574 void SetReachingType(CompileType* type) { | 574 void SetReachingType(CompileType* type) { |
575 reaching_type_ = type; | 575 reaching_type_ = type; |
576 } | 576 } |
577 | 577 |
578 void PrintTo(BufferFormatter* f) const; | 578 void PrintTo(BufferFormatter* f) const; |
579 | 579 |
580 const char* DebugName() const { return "Value"; } | 580 const char* DebugName() const { return "Value"; } |
581 | 581 |
582 bool IsSmiValue() { return Type()->ToCid() == kSmiCid; } | 582 bool IsSmiValue() { return Type()->ToCid() == kSmiCid; } |
583 | 583 |
584 // Returns true if this value binds to the constant: 0xFFFFFFFF. | |
585 bool BindsTo32BitMaskConstant() const; | |
586 | |
584 // Return true if the value represents a constant. | 587 // Return true if the value represents a constant. |
585 bool BindsToConstant() const; | 588 bool BindsToConstant() const; |
586 | 589 |
587 // Return true if the value represents the constant null. | 590 // Return true if the value represents the constant null. |
588 bool BindsToConstantNull() const; | 591 bool BindsToConstantNull() const; |
589 | 592 |
590 // Assert if BindsToConstant() is false, otherwise returns the constant value. | 593 // Assert if BindsToConstant() is false, otherwise returns the constant value. |
591 const Object& BoundConstant() const; | 594 const Object& BoundConstant() const; |
592 | 595 |
593 // Compile time constants, Bool, Smi and Nulls do not need to update | 596 // Compile time constants, Bool, Smi and Nulls do not need to update |
(...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
781 M(BinaryFloat64x2Op) \ | 784 M(BinaryFloat64x2Op) \ |
782 M(Float64x2Zero) \ | 785 M(Float64x2Zero) \ |
783 M(Float64x2Constructor) \ | 786 M(Float64x2Constructor) \ |
784 M(Float64x2Splat) \ | 787 M(Float64x2Splat) \ |
785 M(Float32x4ToFloat64x2) \ | 788 M(Float32x4ToFloat64x2) \ |
786 M(Float64x2ToFloat32x4) \ | 789 M(Float64x2ToFloat32x4) \ |
787 M(Simd64x2Shuffle) \ | 790 M(Simd64x2Shuffle) \ |
788 M(Float64x2ZeroArg) \ | 791 M(Float64x2ZeroArg) \ |
789 M(Float64x2OneArg) \ | 792 M(Float64x2OneArg) \ |
790 M(ExtractNthOutput) \ | 793 M(ExtractNthOutput) \ |
794 M(BinaryUint32Op) \ | |
795 M(ShiftUint32Op) \ | |
796 M(UnaryUint32Op) \ | |
797 M(BoxUint32) \ | |
798 M(UnboxUint32) \ | |
799 M(UnboxedIntConverter) \ | |
791 | 800 |
792 | 801 |
793 #define FORWARD_DECLARATION(type) class type##Instr; | 802 #define FORWARD_DECLARATION(type) class type##Instr; |
794 FOR_EACH_INSTRUCTION(FORWARD_DECLARATION) | 803 FOR_EACH_INSTRUCTION(FORWARD_DECLARATION) |
795 #undef FORWARD_DECLARATION | 804 #undef FORWARD_DECLARATION |
796 | 805 |
797 | 806 |
798 // Functions required in all concrete instruction classes. | 807 // Functions required in all concrete instruction classes. |
799 #define DECLARE_INSTRUCTION(type) \ | 808 #define DECLARE_INSTRUCTION(type) \ |
800 virtual Tag tag() const { return k##type; } \ | 809 virtual Tag tag() const { return k##type; } \ |
(...skipping 323 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1124 friend class JoinEntryInstr; | 1133 friend class JoinEntryInstr; |
1125 friend class InstanceOfInstr; | 1134 friend class InstanceOfInstr; |
1126 friend class PolymorphicInstanceCallInstr; | 1135 friend class PolymorphicInstanceCallInstr; |
1127 friend class SmiToDoubleInstr; | 1136 friend class SmiToDoubleInstr; |
1128 friend class DoubleToIntegerInstr; | 1137 friend class DoubleToIntegerInstr; |
1129 friend class BranchSimplifier; | 1138 friend class BranchSimplifier; |
1130 friend class BlockEntryInstr; | 1139 friend class BlockEntryInstr; |
1131 friend class RelationalOpInstr; | 1140 friend class RelationalOpInstr; |
1132 friend class EqualityCompareInstr; | 1141 friend class EqualityCompareInstr; |
1133 friend class TestCidsInstr; | 1142 friend class TestCidsInstr; |
1143 friend class BinaryUint32OpInstr; | |
1144 friend class UnaryUint32OpInstr; | |
1145 friend class ShiftUint32OpInstr; | |
1146 friend class UnboxUint32Instr; | |
1134 | 1147 |
1135 virtual void RawSetInputAt(intptr_t i, Value* value) = 0; | 1148 virtual void RawSetInputAt(intptr_t i, Value* value) = 0; |
1136 | 1149 |
1137 enum { | 1150 enum { |
1138 kNoPlaceId = -1 | 1151 kNoPlaceId = -1 |
1139 }; | 1152 }; |
1140 | 1153 |
1141 intptr_t deopt_id_; | 1154 intptr_t deopt_id_; |
1142 intptr_t lifetime_position_; // Position used by register allocator. | 1155 intptr_t lifetime_position_; // Position used by register allocator. |
1143 Instruction* previous_; | 1156 Instruction* previous_; |
(...skipping 4141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
5285 | 5298 |
5286 virtual bool CanDeoptimize() const { | 5299 virtual bool CanDeoptimize() const { |
5287 return (value()->Type()->ToCid() != kSmiCid) | 5300 return (value()->Type()->ToCid() != kSmiCid) |
5288 && (value()->Type()->ToCid() != kMintCid); | 5301 && (value()->Type()->ToCid() != kMintCid); |
5289 } | 5302 } |
5290 | 5303 |
5291 virtual Representation representation() const { | 5304 virtual Representation representation() const { |
5292 return kUnboxedMint; | 5305 return kUnboxedMint; |
5293 } | 5306 } |
5294 | 5307 |
5308 intptr_t deopt_id() const { return deopt_id_; } | |
5295 | 5309 |
5296 virtual void InferRange(); | 5310 virtual void InferRange(); |
5297 | 5311 |
5298 DECLARE_INSTRUCTION(UnboxInteger) | 5312 DECLARE_INSTRUCTION(UnboxInteger) |
5299 virtual CompileType ComputeType() const; | 5313 virtual CompileType ComputeType() const; |
5300 | 5314 |
5301 virtual bool AllowsCSE() const { return true; } | 5315 virtual bool AllowsCSE() const { return true; } |
5302 virtual EffectSet Effects() const { return EffectSet::None(); } | 5316 virtual EffectSet Effects() const { return EffectSet::None(); } |
5303 virtual EffectSet Dependencies() const { return EffectSet::None(); } | 5317 virtual EffectSet Dependencies() const { return EffectSet::None(); } |
5304 virtual bool AttributesEqual(Instruction* other) const { return true; } | 5318 virtual bool AttributesEqual(Instruction* other) const { return true; } |
(...skipping 1735 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
7040 private: | 7054 private: |
7041 const Token::Kind op_kind_; | 7055 const Token::Kind op_kind_; |
7042 | 7056 |
7043 DISALLOW_COPY_AND_ASSIGN(BinaryFloat64x2OpInstr); | 7057 DISALLOW_COPY_AND_ASSIGN(BinaryFloat64x2OpInstr); |
7044 }; | 7058 }; |
7045 | 7059 |
7046 | 7060 |
7047 class BinaryMintOpInstr : public TemplateDefinition<2> { | 7061 class BinaryMintOpInstr : public TemplateDefinition<2> { |
7048 public: | 7062 public: |
7049 BinaryMintOpInstr(Token::Kind op_kind, | 7063 BinaryMintOpInstr(Token::Kind op_kind, |
7050 Value* left, | 7064 Value* left, |
7051 Value* right, | 7065 Value* right, |
7052 intptr_t deopt_id) | 7066 intptr_t deopt_id) |
7053 : op_kind_(op_kind), can_overflow_(true) { | 7067 : op_kind_(op_kind), can_overflow_(true) { |
7054 SetInputAt(0, left); | 7068 SetInputAt(0, left); |
7055 SetInputAt(1, right); | 7069 SetInputAt(1, right); |
7056 // Override generated deopt-id. | 7070 // Override generated deopt-id. |
7057 deopt_id_ = deopt_id; | 7071 deopt_id_ = deopt_id; |
7058 } | 7072 } |
7059 | 7073 |
7060 Value* left() const { return inputs_[0]; } | 7074 Value* left() const { return inputs_[0]; } |
7061 Value* right() const { return inputs_[1]; } | 7075 Value* right() const { return inputs_[1]; } |
7062 | 7076 |
(...skipping 926 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
7989 enum { | 8003 enum { |
7990 kLengthPos = 0, | 8004 kLengthPos = 0, |
7991 kIndexPos = 1 | 8005 kIndexPos = 1 |
7992 }; | 8006 }; |
7993 | 8007 |
7994 private: | 8008 private: |
7995 DISALLOW_COPY_AND_ASSIGN(CheckArrayBoundInstr); | 8009 DISALLOW_COPY_AND_ASSIGN(CheckArrayBoundInstr); |
7996 }; | 8010 }; |
7997 | 8011 |
7998 | 8012 |
8013 class BinaryUint32OpInstr : public TemplateDefinition<2> { | |
8014 public: | |
8015 BinaryUint32OpInstr(Token::Kind op_kind, | |
8016 Value* left, | |
8017 Value* right, | |
8018 intptr_t deopt_id) | |
8019 : op_kind_(op_kind) { | |
8020 SetInputAt(0, left); | |
8021 SetInputAt(1, right); | |
8022 // Override generated deopt-id. | |
8023 deopt_id_ = deopt_id; | |
8024 } | |
8025 | |
8026 Value* left() const { return inputs_[0]; } | |
8027 Value* right() const { return inputs_[1]; } | |
8028 | |
8029 Token::Kind op_kind() const { return op_kind_; } | |
8030 | |
8031 virtual void PrintOperandsTo(BufferFormatter* f) const; | |
8032 | |
8033 virtual bool CanDeoptimize() const { | |
8034 return false; | |
8035 } | |
8036 | |
8037 virtual Representation representation() const { | |
8038 return kUnboxedUint32; | |
8039 } | |
8040 | |
8041 virtual Representation RequiredInputRepresentation(intptr_t idx) const { | |
8042 ASSERT((idx == 0) || (idx == 1)); | |
8043 return kUnboxedUint32; | |
8044 } | |
8045 | |
8046 virtual intptr_t DeoptimizationTarget() const { | |
8047 // Direct access since this instruction cannot deoptimize, and the deopt-id | |
8048 // was inherited from another instruction that could deoptimize. | |
8049 return deopt_id_; | |
8050 } | |
8051 | |
8052 virtual Definition* Canonicalize(FlowGraph* flow_graph); | |
8053 | |
8054 DECLARE_INSTRUCTION(BinaryUint32Op) | |
8055 virtual CompileType ComputeType() const; | |
8056 | |
8057 virtual bool AllowsCSE() const { return true; } | |
8058 virtual EffectSet Effects() const { return EffectSet::None(); } | |
8059 virtual EffectSet Dependencies() const { return EffectSet::None(); } | |
8060 virtual bool AttributesEqual(Instruction* other) const { | |
8061 ASSERT(other->IsBinaryUint32Op()); | |
8062 return op_kind() == other->AsBinaryUint32Op()->op_kind(); | |
8063 } | |
8064 | |
8065 virtual bool MayThrow() const { return false; } | |
8066 | |
8067 private: | |
8068 const Token::Kind op_kind_; | |
8069 | |
8070 DISALLOW_COPY_AND_ASSIGN(BinaryUint32OpInstr); | |
8071 }; | |
8072 | |
8073 | |
8074 class ShiftUint32OpInstr : public TemplateDefinition<2> { | |
8075 public: | |
8076 ShiftUint32OpInstr(Token::Kind op_kind, | |
8077 Value* left, | |
8078 Value* right, | |
8079 intptr_t deopt_id) | |
8080 : op_kind_(op_kind) { | |
8081 ASSERT(op_kind == Token::kSHR || op_kind == Token::kSHL); | |
8082 SetInputAt(0, left); | |
8083 SetInputAt(1, right); | |
8084 // Override generated deopt-id. | |
8085 deopt_id_ = deopt_id; | |
8086 } | |
8087 | |
8088 Value* left() const { return inputs_[0]; } | |
8089 Value* right() const { return inputs_[1]; } | |
8090 | |
8091 Token::Kind op_kind() const { return op_kind_; } | |
8092 | |
8093 virtual void PrintOperandsTo(BufferFormatter* f) const; | |
8094 | |
8095 virtual bool CanDeoptimize() const { | |
8096 return true; | |
8097 } | |
8098 | |
8099 virtual CompileType ComputeType() const; | |
8100 | |
8101 virtual Representation representation() const { | |
8102 return kUnboxedUint32; | |
8103 } | |
8104 | |
8105 virtual Representation RequiredInputRepresentation(intptr_t idx) const { | |
8106 ASSERT((idx == 0) || (idx == 1)); | |
8107 return (idx == 0) ? kUnboxedUint32 : kTagged; | |
8108 } | |
8109 | |
8110 virtual intptr_t DeoptimizationTarget() const { | |
8111 // Direct access since this instruction cannot deoptimize, and the deopt-id | |
Florian Schneider
2014/07/10 13:05:05
This instruction can deoptimize, so the comment is
| |
8112 // was inherited from another instruction that could deoptimize. | |
8113 return deopt_id_; | |
8114 } | |
8115 | |
8116 DECLARE_INSTRUCTION(ShiftUint32Op) | |
8117 | |
8118 virtual bool AllowsCSE() const { return true; } | |
8119 virtual EffectSet Effects() const { return EffectSet::None(); } | |
8120 virtual EffectSet Dependencies() const { return EffectSet::None(); } | |
8121 virtual bool AttributesEqual(Instruction* other) const { | |
8122 return op_kind() == other->AsShiftUint32Op()->op_kind(); | |
8123 } | |
8124 | |
8125 virtual bool MayThrow() const { return false; } | |
8126 | |
8127 private: | |
8128 const Token::Kind op_kind_; | |
8129 | |
8130 DISALLOW_COPY_AND_ASSIGN(ShiftUint32OpInstr); | |
8131 }; | |
8132 | |
8133 | |
8134 class UnaryUint32OpInstr : public TemplateDefinition<1> { | |
8135 public: | |
8136 UnaryUint32OpInstr(Token::Kind op_kind, | |
8137 Value* value, | |
8138 intptr_t deopt_id) | |
8139 : op_kind_(op_kind) { | |
8140 ASSERT(op_kind == Token::kBIT_NOT); | |
8141 SetInputAt(0, value); | |
8142 // Override generated deopt-id. | |
8143 deopt_id_ = deopt_id; | |
8144 } | |
8145 | |
8146 Value* value() const { return inputs_[0]; } | |
8147 | |
8148 Token::Kind op_kind() const { return op_kind_; } | |
8149 | |
8150 virtual void PrintOperandsTo(BufferFormatter* f) const; | |
8151 | |
8152 virtual bool CanDeoptimize() const { | |
8153 return false; | |
8154 } | |
8155 | |
8156 virtual Representation representation() const { | |
8157 return kUnboxedUint32; | |
8158 } | |
8159 | |
8160 virtual Representation RequiredInputRepresentation(intptr_t idx) const { | |
8161 ASSERT(idx == 0); | |
8162 return kUnboxedUint32; | |
8163 } | |
8164 | |
8165 virtual intptr_t DeoptimizationTarget() const { | |
8166 // Direct access since this instruction cannot deoptimize, and the deopt-id | |
8167 // was inherited from another instruction that could deoptimize. | |
8168 return deopt_id_; | |
8169 } | |
8170 | |
8171 DECLARE_INSTRUCTION(UnaryUint32Op) | |
8172 virtual CompileType ComputeType() const; | |
8173 | |
8174 virtual bool AllowsCSE() const { return true; } | |
8175 virtual EffectSet Effects() const { return EffectSet::None(); } | |
8176 virtual EffectSet Dependencies() const { return EffectSet::None(); } | |
8177 virtual bool AttributesEqual(Instruction* other) const { | |
8178 return op_kind() == other->AsUnaryUint32Op()->op_kind(); | |
8179 } | |
8180 | |
8181 virtual bool MayThrow() const { return false; } | |
8182 | |
8183 private: | |
8184 const Token::Kind op_kind_; | |
8185 | |
8186 DISALLOW_COPY_AND_ASSIGN(UnaryUint32OpInstr); | |
8187 }; | |
8188 | |
8189 | |
8190 class BoxUint32Instr : public TemplateDefinition<1> { | |
8191 public: | |
8192 explicit BoxUint32Instr(Value* value) { | |
8193 SetInputAt(0, value); | |
8194 } | |
8195 | |
8196 Value* value() const { return inputs_[0]; } | |
8197 | |
8198 virtual bool CanDeoptimize() const { return false; } | |
8199 | |
8200 virtual intptr_t DeoptimizationTarget() const { | |
8201 return Isolate::kNoDeoptId; | |
8202 } | |
8203 | |
8204 virtual Representation RequiredInputRepresentation(intptr_t idx) const { | |
8205 ASSERT(idx == 0); | |
8206 return kUnboxedUint32; | |
8207 } | |
8208 | |
8209 DECLARE_INSTRUCTION(BoxUint32) | |
8210 virtual CompileType ComputeType() const; | |
8211 | |
8212 virtual bool AllowsCSE() const { return true; } | |
8213 virtual EffectSet Effects() const { return EffectSet::None(); } | |
8214 virtual EffectSet Dependencies() const { return EffectSet::None(); } | |
8215 virtual bool AttributesEqual(Instruction* other) const { return true; } | |
8216 | |
8217 virtual bool MayThrow() const { return false; } | |
8218 | |
8219 private: | |
8220 DISALLOW_COPY_AND_ASSIGN(BoxUint32Instr); | |
8221 }; | |
8222 | |
8223 | |
8224 class UnboxUint32Instr : public TemplateDefinition<1> { | |
8225 public: | |
8226 UnboxUint32Instr(Value* value, intptr_t deopt_id) { | |
8227 SetInputAt(0, value); | |
8228 deopt_id_ = deopt_id; | |
8229 } | |
8230 | |
8231 Value* value() const { return inputs_[0]; } | |
8232 | |
8233 virtual bool CanDeoptimize() const { | |
8234 return (value()->Type()->ToCid() != kSmiCid) | |
8235 && (value()->Type()->ToCid() != kMintCid); | |
8236 } | |
8237 | |
8238 virtual Representation representation() const { | |
8239 return kUnboxedUint32; | |
8240 } | |
8241 | |
8242 | |
8243 DECLARE_INSTRUCTION(UnboxUint32) | |
8244 virtual CompileType ComputeType() const; | |
8245 | |
8246 virtual bool AllowsCSE() const { return true; } | |
8247 virtual EffectSet Effects() const { return EffectSet::None(); } | |
8248 virtual EffectSet Dependencies() const { return EffectSet::None(); } | |
8249 virtual bool AttributesEqual(Instruction* other) const { return true; } | |
8250 | |
8251 virtual bool MayThrow() const { return false; } | |
8252 | |
8253 private: | |
8254 DISALLOW_COPY_AND_ASSIGN(UnboxUint32Instr); | |
8255 }; | |
8256 | |
8257 | |
8258 class UnboxedIntConverterInstr : public TemplateDefinition<1> { | |
8259 public: | |
8260 UnboxedIntConverterInstr(Representation from, | |
8261 Representation to, | |
8262 Value* value) | |
8263 : from_representation_(from), | |
8264 to_representation_(to) { | |
8265 ASSERT(from != to); | |
8266 ASSERT((from == kUnboxedMint) || (from == kUnboxedUint32)); | |
8267 ASSERT((to == kUnboxedMint) || (to == kUnboxedUint32)); | |
8268 SetInputAt(0, value); | |
8269 } | |
8270 | |
8271 Value* value() const { return inputs_[0]; } | |
8272 | |
8273 Representation from() const { return from_representation_; } | |
8274 Representation to() const { return to_representation_; } | |
8275 | |
8276 virtual bool CanDeoptimize() const { return false; } | |
8277 | |
8278 virtual Representation representation() const { | |
8279 return to(); | |
8280 } | |
8281 | |
8282 virtual Representation RequiredInputRepresentation(intptr_t idx) const { | |
8283 ASSERT(idx == 0); | |
8284 return from(); | |
8285 } | |
8286 | |
8287 virtual EffectSet Effects() const { return EffectSet::None(); } | |
8288 virtual EffectSet Dependencies() const { return EffectSet::None(); } | |
8289 virtual bool AttributesEqual(Instruction* other) const { | |
8290 ASSERT(other->IsUnboxedIntConverter()); | |
8291 UnboxedIntConverterInstr* converter = other->AsUnboxedIntConverter(); | |
8292 return (converter->from() == from()) && (converter->to() == to()); | |
8293 } | |
8294 | |
8295 virtual bool MayThrow() const { return false; } | |
8296 | |
8297 DECLARE_INSTRUCTION(UnboxedIntConverter); | |
8298 | |
8299 private: | |
8300 const Representation from_representation_; | |
8301 const Representation to_representation_; | |
8302 DISALLOW_COPY_AND_ASSIGN(UnboxedIntConverterInstr); | |
8303 }; | |
8304 | |
8305 | |
7999 #undef DECLARE_INSTRUCTION | 8306 #undef DECLARE_INSTRUCTION |
8000 | 8307 |
8001 class Environment : public ZoneAllocated { | 8308 class Environment : public ZoneAllocated { |
8002 public: | 8309 public: |
8003 // Iterate the non-NULL values in the innermost level of an environment. | 8310 // Iterate the non-NULL values in the innermost level of an environment. |
8004 class ShallowIterator : public ValueObject { | 8311 class ShallowIterator : public ValueObject { |
8005 public: | 8312 public: |
8006 explicit ShallowIterator(Environment* environment) | 8313 explicit ShallowIterator(Environment* environment) |
8007 : environment_(environment), index_(0) { } | 8314 : environment_(environment), index_(0) { } |
8008 | 8315 |
(...skipping 210 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
8219 ForwardInstructionIterator* current_iterator_; | 8526 ForwardInstructionIterator* current_iterator_; |
8220 | 8527 |
8221 private: | 8528 private: |
8222 DISALLOW_COPY_AND_ASSIGN(FlowGraphVisitor); | 8529 DISALLOW_COPY_AND_ASSIGN(FlowGraphVisitor); |
8223 }; | 8530 }; |
8224 | 8531 |
8225 | 8532 |
8226 } // namespace dart | 8533 } // namespace dart |
8227 | 8534 |
8228 #endif // VM_INTERMEDIATE_LANGUAGE_H_ | 8535 #endif // VM_INTERMEDIATE_LANGUAGE_H_ |
OLD | NEW |