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