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 a 32-bit mint instruction. |
| 585 bool BindsTo32BitMint() const; |
| 586 |
| 587 // Returns true if this value binds to the constant: 0xFFFFFFFF. |
| 588 bool BindsTo32BitMaskConstant() const; |
| 589 |
584 // Return true if the value represents a constant. | 590 // Return true if the value represents a constant. |
585 bool BindsToConstant() const; | 591 bool BindsToConstant() const; |
586 | 592 |
587 // Return true if the value represents the constant null. | 593 // Return true if the value represents the constant null. |
588 bool BindsToConstantNull() const; | 594 bool BindsToConstantNull() const; |
589 | 595 |
590 // Assert if BindsToConstant() is false, otherwise returns the constant value. | 596 // Assert if BindsToConstant() is false, otherwise returns the constant value. |
591 const Object& BoundConstant() const; | 597 const Object& BoundConstant() const; |
592 | 598 |
593 // Compile time constants, Bool, Smi and Nulls do not need to update | 599 // Compile time constants, Bool, Smi and Nulls do not need to update |
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
732 M(MathUnary) \ | 738 M(MathUnary) \ |
733 M(MathMinMax) \ | 739 M(MathMinMax) \ |
734 M(UnboxDouble) \ | 740 M(UnboxDouble) \ |
735 M(BoxDouble) \ | 741 M(BoxDouble) \ |
736 M(BoxFloat32x4) \ | 742 M(BoxFloat32x4) \ |
737 M(UnboxFloat32x4) \ | 743 M(UnboxFloat32x4) \ |
738 M(BoxInt32x4) \ | 744 M(BoxInt32x4) \ |
739 M(UnboxInt32x4) \ | 745 M(UnboxInt32x4) \ |
740 M(UnboxInteger) \ | 746 M(UnboxInteger) \ |
741 M(BoxInteger) \ | 747 M(BoxInteger) \ |
| 748 M(MintConverter) \ |
742 M(BinaryMintOp) \ | 749 M(BinaryMintOp) \ |
743 M(ShiftMintOp) \ | 750 M(ShiftMintOp) \ |
744 M(UnaryMintOp) \ | 751 M(UnaryMintOp) \ |
745 M(CheckArrayBound) \ | 752 M(CheckArrayBound) \ |
746 M(Constraint) \ | 753 M(Constraint) \ |
747 M(StringToCharCode) \ | 754 M(StringToCharCode) \ |
748 M(StringFromCharCode) \ | 755 M(StringFromCharCode) \ |
749 M(StringInterpolate) \ | 756 M(StringInterpolate) \ |
750 M(InvokeMathCFunction) \ | 757 M(InvokeMathCFunction) \ |
751 M(MergedMath) \ | 758 M(MergedMath) \ |
(...skipping 2038 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2790 | 2797 |
2791 // Inclusive. | 2798 // Inclusive. |
2792 bool Overlaps(int64_t min_int, int64_t max_int) const; | 2799 bool Overlaps(int64_t min_int, int64_t max_int) const; |
2793 | 2800 |
2794 bool IsUnsatisfiable() const; | 2801 bool IsUnsatisfiable() const; |
2795 | 2802 |
2796 bool IsFinite() const { | 2803 bool IsFinite() const { |
2797 return !min_.IsInfinity() && !max_.IsInfinity(); | 2804 return !min_.IsInfinity() && !max_.IsInfinity(); |
2798 } | 2805 } |
2799 | 2806 |
| 2807 bool Is32BitMask() const { |
| 2808 return min_.IsConstant() && (min_.ConstantValue() == 0) && |
| 2809 max_.IsConstant() && (max_.ConstantValue() == kMaxUint32); |
| 2810 } |
| 2811 |
| 2812 void Make32BitMask() { |
| 2813 min_ = RangeBoundary::FromConstant(0); |
| 2814 // TODO(johnmccutchan): If the range has a smaller max we should use it. |
| 2815 max_ = RangeBoundary::FromConstant(kMaxUint32); |
| 2816 } |
| 2817 |
2800 // Clamp this to be within size. | 2818 // Clamp this to be within size. |
2801 void Clamp(RangeBoundary::RangeSize size); | 2819 void Clamp(RangeBoundary::RangeSize size); |
2802 | 2820 |
2803 static void Add(const Range* left_range, | 2821 static void Add(const Range* left_range, |
2804 const Range* right_range, | 2822 const Range* right_range, |
2805 RangeBoundary* min, | 2823 RangeBoundary* min, |
2806 RangeBoundary* max, | 2824 RangeBoundary* max, |
2807 Definition* left_defn); | 2825 Definition* left_defn); |
2808 | 2826 |
2809 static void Sub(const Range* left_range, | 2827 static void Sub(const Range* left_range, |
(...skipping 2459 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5269 | 5287 |
5270 Definition* Canonicalize(FlowGraph* flow_graph); | 5288 Definition* Canonicalize(FlowGraph* flow_graph); |
5271 | 5289 |
5272 private: | 5290 private: |
5273 DISALLOW_COPY_AND_ASSIGN(UnboxInt32x4Instr); | 5291 DISALLOW_COPY_AND_ASSIGN(UnboxInt32x4Instr); |
5274 }; | 5292 }; |
5275 | 5293 |
5276 | 5294 |
5277 class UnboxIntegerInstr : public TemplateDefinition<1> { | 5295 class UnboxIntegerInstr : public TemplateDefinition<1> { |
5278 public: | 5296 public: |
5279 UnboxIntegerInstr(Value* value, intptr_t deopt_id) { | 5297 UnboxIntegerInstr(Value* value, intptr_t deopt_id) |
| 5298 : is_32_bit_(false) { |
5280 SetInputAt(0, value); | 5299 SetInputAt(0, value); |
5281 deopt_id_ = deopt_id; | 5300 deopt_id_ = deopt_id; |
5282 } | 5301 } |
5283 | 5302 |
| 5303 virtual void PrintTo(BufferFormatter* f) const; |
| 5304 |
5284 Value* value() const { return inputs_[0]; } | 5305 Value* value() const { return inputs_[0]; } |
5285 | 5306 |
5286 virtual bool CanDeoptimize() const { | 5307 virtual bool CanDeoptimize() const { |
5287 return (value()->Type()->ToCid() != kSmiCid) | 5308 return (value()->Type()->ToCid() != kSmiCid) |
5288 && (value()->Type()->ToCid() != kMintCid); | 5309 && (value()->Type()->ToCid() != kMintCid); |
5289 } | 5310 } |
5290 | 5311 |
5291 virtual Representation representation() const { | 5312 virtual Representation representation() const { |
5292 return kUnboxedMint; | 5313 return is_32_bit() ? kUnboxedMint32 : kUnboxedMint; |
5293 } | 5314 } |
5294 | 5315 |
| 5316 bool is_32_bit() const { return is_32_bit_; } |
| 5317 void set_is_32_bit(bool v) { is_32_bit_ = v; } |
5295 | 5318 |
5296 virtual void InferRange(); | 5319 virtual void InferRange(); |
5297 | 5320 |
5298 DECLARE_INSTRUCTION(UnboxInteger) | 5321 DECLARE_INSTRUCTION(UnboxInteger) |
5299 virtual CompileType ComputeType() const; | 5322 virtual CompileType ComputeType() const; |
5300 | 5323 |
5301 virtual bool AllowsCSE() const { return true; } | 5324 virtual bool AllowsCSE() const { return true; } |
5302 virtual EffectSet Effects() const { return EffectSet::None(); } | 5325 virtual EffectSet Effects() const { return EffectSet::None(); } |
5303 virtual EffectSet Dependencies() const { return EffectSet::None(); } | 5326 virtual EffectSet Dependencies() const { return EffectSet::None(); } |
5304 virtual bool AttributesEqual(Instruction* other) const { return true; } | 5327 virtual bool AttributesEqual(Instruction* other) const { return true; } |
5305 | 5328 |
5306 virtual bool MayThrow() const { return false; } | 5329 virtual bool MayThrow() const { return false; } |
5307 | 5330 |
5308 private: | 5331 private: |
| 5332 bool is_32_bit_; |
5309 DISALLOW_COPY_AND_ASSIGN(UnboxIntegerInstr); | 5333 DISALLOW_COPY_AND_ASSIGN(UnboxIntegerInstr); |
5310 }; | 5334 }; |
5311 | 5335 |
5312 | 5336 |
5313 class MathUnaryInstr : public TemplateDefinition<1> { | 5337 class MathUnaryInstr : public TemplateDefinition<1> { |
5314 public: | 5338 public: |
5315 enum MathUnaryKind { | 5339 enum MathUnaryKind { |
5316 kIllegal, | 5340 kIllegal, |
5317 kSin, | 5341 kSin, |
5318 kCos, | 5342 kCos, |
(...skipping 1718 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7037 | 7061 |
7038 virtual bool MayThrow() const { return false; } | 7062 virtual bool MayThrow() const { return false; } |
7039 | 7063 |
7040 private: | 7064 private: |
7041 const Token::Kind op_kind_; | 7065 const Token::Kind op_kind_; |
7042 | 7066 |
7043 DISALLOW_COPY_AND_ASSIGN(BinaryFloat64x2OpInstr); | 7067 DISALLOW_COPY_AND_ASSIGN(BinaryFloat64x2OpInstr); |
7044 }; | 7068 }; |
7045 | 7069 |
7046 | 7070 |
| 7071 class MintConverterInstr : public TemplateDefinition<1> { |
| 7072 public: |
| 7073 enum Conversion { |
| 7074 kMint32ToMint, |
| 7075 kMintToMint32, |
| 7076 }; |
| 7077 |
| 7078 MintConverterInstr(Conversion conversion_kind, Value* val) |
| 7079 : conversion_kind_(conversion_kind) { |
| 7080 ASSERT((conversion_kind_ == kMint32ToMint) || |
| 7081 (conversion_kind_ == kMintToMint32)); |
| 7082 SetInputAt(0, val); |
| 7083 } |
| 7084 |
| 7085 Value* value() const { return inputs_[0]; } |
| 7086 |
| 7087 intptr_t conversion_kind() const { return conversion_kind_; } |
| 7088 |
| 7089 virtual bool CanDeoptimize() const { return false; } |
| 7090 |
| 7091 virtual Representation representation() const { |
| 7092 return (conversion_kind_ == kMint32ToMint) ? kUnboxedMint : kUnboxedMint32; |
| 7093 } |
| 7094 |
| 7095 virtual Representation RequiredInputRepresentation(intptr_t idx) const { |
| 7096 ASSERT(idx == 0); |
| 7097 return (conversion_kind_ == kMint32ToMint) ? kUnboxedMint32 : kUnboxedMint; |
| 7098 } |
| 7099 |
| 7100 virtual EffectSet Effects() const { return EffectSet::None(); } |
| 7101 virtual EffectSet Dependencies() const { return EffectSet::None(); } |
| 7102 virtual bool AttributesEqual(Instruction* other) const { |
| 7103 ASSERT(other->IsMintConverter()); |
| 7104 return conversion_kind() == other->AsMintConverter()->conversion_kind(); |
| 7105 } |
| 7106 |
| 7107 virtual bool MayThrow() const { return false; } |
| 7108 |
| 7109 DECLARE_INSTRUCTION(MintConverter) |
| 7110 |
| 7111 private: |
| 7112 intptr_t conversion_kind_; |
| 7113 DISALLOW_COPY_AND_ASSIGN(MintConverterInstr); |
| 7114 }; |
| 7115 |
| 7116 |
7047 class BinaryMintOpInstr : public TemplateDefinition<2> { | 7117 class BinaryMintOpInstr : public TemplateDefinition<2> { |
7048 public: | 7118 public: |
7049 BinaryMintOpInstr(Token::Kind op_kind, | 7119 BinaryMintOpInstr(Token::Kind op_kind, |
7050 Value* left, | 7120 Value* left, |
7051 Value* right, | 7121 Value* right, |
7052 intptr_t deopt_id) | 7122 intptr_t deopt_id) |
7053 : op_kind_(op_kind) { | 7123 : op_kind_(op_kind), |
| 7124 is_32_bit_(false) { |
7054 SetInputAt(0, left); | 7125 SetInputAt(0, left); |
7055 SetInputAt(1, right); | 7126 SetInputAt(1, right); |
7056 // Override generated deopt-id. | 7127 // Override generated deopt-id. |
7057 deopt_id_ = deopt_id; | 7128 deopt_id_ = deopt_id; |
7058 } | 7129 } |
7059 | 7130 |
7060 Value* left() const { return inputs_[0]; } | 7131 Value* left() const { return inputs_[0]; } |
7061 Value* right() const { return inputs_[1]; } | 7132 Value* right() const { return inputs_[1]; } |
7062 | 7133 |
7063 Token::Kind op_kind() const { return op_kind_; } | 7134 Token::Kind op_kind() const { return op_kind_; } |
7064 | 7135 |
| 7136 bool IsInput32Bit(intptr_t i) const { |
| 7137 return RequiredInputRepresentation(i) == kUnboxedMint32; |
| 7138 } |
| 7139 |
| 7140 bool is_32_bit() const { return is_32_bit_; } |
| 7141 void set_is_32_bit(bool v) { is_32_bit_ = v; } |
| 7142 |
7065 virtual void PrintOperandsTo(BufferFormatter* f) const; | 7143 virtual void PrintOperandsTo(BufferFormatter* f) const; |
| 7144 virtual void PrintTo(BufferFormatter* f) const; |
7066 | 7145 |
7067 virtual bool CanDeoptimize() const { | 7146 virtual bool CanDeoptimize() const { |
7068 return FLAG_throw_on_javascript_int_overflow || | 7147 return FLAG_throw_on_javascript_int_overflow || |
7069 (op_kind() == Token::kADD) || (op_kind() == Token::kSUB); | 7148 (!is_32_bit() && |
| 7149 ((op_kind() == Token::kADD) || (op_kind() == Token::kSUB))); |
7070 } | 7150 } |
7071 | 7151 |
7072 virtual Representation representation() const { | 7152 virtual Representation representation() const { |
7073 return kUnboxedMint; | 7153 return is_32_bit() ? kUnboxedMint32 : kUnboxedMint; |
7074 } | 7154 } |
7075 | 7155 |
7076 virtual Representation RequiredInputRepresentation(intptr_t idx) const { | 7156 virtual Representation RequiredInputRepresentation(intptr_t idx) const; |
7077 ASSERT((idx == 0) || (idx == 1)); | |
7078 return kUnboxedMint; | |
7079 } | |
7080 | 7157 |
7081 virtual intptr_t DeoptimizationTarget() const { | 7158 virtual intptr_t DeoptimizationTarget() const { |
7082 // Direct access since this instruction cannot deoptimize, and the deopt-id | 7159 // Direct access since this instruction cannot deoptimize, and the deopt-id |
7083 // was inherited from another instruction that could deoptimize. | 7160 // was inherited from another instruction that could deoptimize. |
7084 return deopt_id_; | 7161 return deopt_id_; |
7085 } | 7162 } |
7086 | 7163 |
7087 virtual void InferRange(); | 7164 virtual void InferRange(); |
7088 | 7165 |
7089 virtual Definition* Canonicalize(FlowGraph* flow_graph); | 7166 virtual Definition* Canonicalize(FlowGraph* flow_graph); |
7090 | 7167 |
7091 DECLARE_INSTRUCTION(BinaryMintOp) | 7168 DECLARE_INSTRUCTION(BinaryMintOp) |
7092 virtual CompileType ComputeType() const; | 7169 virtual CompileType ComputeType() const; |
7093 | 7170 |
7094 virtual bool AllowsCSE() const { return true; } | 7171 virtual bool AllowsCSE() const { return true; } |
7095 virtual EffectSet Effects() const { return EffectSet::None(); } | 7172 virtual EffectSet Effects() const { return EffectSet::None(); } |
7096 virtual EffectSet Dependencies() const { return EffectSet::None(); } | 7173 virtual EffectSet Dependencies() const { return EffectSet::None(); } |
7097 virtual bool AttributesEqual(Instruction* other) const { | 7174 virtual bool AttributesEqual(Instruction* other) const { |
7098 ASSERT(other->IsBinaryMintOp()); | 7175 ASSERT(other->IsBinaryMintOp()); |
7099 return op_kind() == other->AsBinaryMintOp()->op_kind(); | 7176 return op_kind() == other->AsBinaryMintOp()->op_kind(); |
7100 } | 7177 } |
7101 | 7178 |
7102 virtual bool MayThrow() const { return false; } | 7179 virtual bool MayThrow() const { return false; } |
7103 | 7180 |
7104 private: | 7181 private: |
7105 const Token::Kind op_kind_; | 7182 const Token::Kind op_kind_; |
| 7183 bool is_32_bit_; |
7106 | 7184 |
7107 DISALLOW_COPY_AND_ASSIGN(BinaryMintOpInstr); | 7185 DISALLOW_COPY_AND_ASSIGN(BinaryMintOpInstr); |
7108 }; | 7186 }; |
7109 | 7187 |
7110 | 7188 |
7111 class ShiftMintOpInstr : public TemplateDefinition<2> { | 7189 class ShiftMintOpInstr : public TemplateDefinition<2> { |
7112 public: | 7190 public: |
7113 ShiftMintOpInstr(Token::Kind op_kind, | 7191 ShiftMintOpInstr(Token::Kind op_kind, |
7114 Value* left, | 7192 Value* left, |
7115 Value* right, | 7193 Value* right, |
7116 intptr_t deopt_id) | 7194 intptr_t deopt_id) |
7117 : op_kind_(op_kind) { | 7195 : op_kind_(op_kind), |
| 7196 is_32_bit_(false) { |
7118 ASSERT(op_kind == Token::kSHR || op_kind == Token::kSHL); | 7197 ASSERT(op_kind == Token::kSHR || op_kind == Token::kSHL); |
7119 SetInputAt(0, left); | 7198 SetInputAt(0, left); |
7120 SetInputAt(1, right); | 7199 SetInputAt(1, right); |
7121 // Override generated deopt-id. | 7200 // Override generated deopt-id. |
7122 deopt_id_ = deopt_id; | 7201 deopt_id_ = deopt_id; |
7123 } | 7202 } |
7124 | 7203 |
7125 Value* left() const { return inputs_[0]; } | 7204 Value* left() const { return inputs_[0]; } |
7126 Value* right() const { return inputs_[1]; } | 7205 Value* right() const { return inputs_[1]; } |
7127 | 7206 |
7128 Token::Kind op_kind() const { return op_kind_; } | 7207 Token::Kind op_kind() const { return op_kind_; } |
7129 | 7208 |
| 7209 bool IsInput32Bit(intptr_t i) const { |
| 7210 return RequiredInputRepresentation(i) == kUnboxedMint32; |
| 7211 } |
| 7212 |
| 7213 bool is_32_bit() const { return is_32_bit_; } |
| 7214 void set_is_32_bit(bool v) { is_32_bit_ = v; } |
| 7215 |
7130 virtual void PrintOperandsTo(BufferFormatter* f) const; | 7216 virtual void PrintOperandsTo(BufferFormatter* f) const; |
| 7217 virtual void PrintTo(BufferFormatter* f) const; |
7131 | 7218 |
7132 virtual bool CanDeoptimize() const { return true; } | 7219 virtual bool CanDeoptimize() const { |
| 7220 return true; |
| 7221 } |
7133 | 7222 |
7134 virtual CompileType ComputeType() const; | 7223 virtual CompileType ComputeType() const; |
7135 | 7224 |
7136 virtual Representation representation() const { | 7225 virtual Representation representation() const { |
7137 return kUnboxedMint; | 7226 return is_32_bit() ? kUnboxedMint32 : kUnboxedMint; |
| 7227 } |
| 7228 |
| 7229 bool CanShiftLeftOverflow() const { |
| 7230 return !IsInput32Bit(0) && !is_32_bit(); |
7138 } | 7231 } |
7139 | 7232 |
7140 virtual Representation RequiredInputRepresentation(intptr_t idx) const { | 7233 virtual Representation RequiredInputRepresentation(intptr_t idx) const { |
7141 ASSERT((idx == 0) || (idx == 1)); | 7234 ASSERT((idx == 0) || (idx == 1)); |
7142 return (idx == 0) ? kUnboxedMint : kTagged; | 7235 if (idx == 1) { |
| 7236 return kTagged; |
| 7237 } |
| 7238 return InputAt(idx)->BindsTo32BitMint() ? kUnboxedMint32 : kUnboxedMint; |
7143 } | 7239 } |
7144 | 7240 |
7145 virtual intptr_t DeoptimizationTarget() const { | 7241 virtual intptr_t DeoptimizationTarget() const { |
7146 // Direct access since this instruction cannot deoptimize, and the deopt-id | 7242 // Direct access since this instruction cannot deoptimize, and the deopt-id |
7147 // was inherited from another instruction that could deoptimize. | 7243 // was inherited from another instruction that could deoptimize. |
7148 return deopt_id_; | 7244 return deopt_id_; |
7149 } | 7245 } |
7150 | 7246 |
7151 virtual void InferRange(); | 7247 virtual void InferRange(); |
7152 | 7248 |
7153 DECLARE_INSTRUCTION(ShiftMintOp) | 7249 DECLARE_INSTRUCTION(ShiftMintOp) |
7154 | 7250 |
7155 virtual bool AllowsCSE() const { return true; } | 7251 virtual bool AllowsCSE() const { return true; } |
7156 virtual EffectSet Effects() const { return EffectSet::None(); } | 7252 virtual EffectSet Effects() const { return EffectSet::None(); } |
7157 virtual EffectSet Dependencies() const { return EffectSet::None(); } | 7253 virtual EffectSet Dependencies() const { return EffectSet::None(); } |
7158 virtual bool AttributesEqual(Instruction* other) const { | 7254 virtual bool AttributesEqual(Instruction* other) const { |
7159 return op_kind() == other->AsShiftMintOp()->op_kind(); | 7255 return op_kind() == other->AsShiftMintOp()->op_kind(); |
7160 } | 7256 } |
7161 | 7257 |
7162 virtual bool MayThrow() const { return false; } | 7258 virtual bool MayThrow() const { return false; } |
7163 | 7259 |
7164 private: | 7260 private: |
7165 const Token::Kind op_kind_; | 7261 const Token::Kind op_kind_; |
| 7262 bool is_32_bit_; |
7166 | 7263 |
7167 DISALLOW_COPY_AND_ASSIGN(ShiftMintOpInstr); | 7264 DISALLOW_COPY_AND_ASSIGN(ShiftMintOpInstr); |
7168 }; | 7265 }; |
7169 | 7266 |
7170 | 7267 |
7171 class UnaryMintOpInstr : public TemplateDefinition<1> { | 7268 class UnaryMintOpInstr : public TemplateDefinition<1> { |
7172 public: | 7269 public: |
7173 UnaryMintOpInstr(Token::Kind op_kind, Value* value, intptr_t deopt_id) | 7270 UnaryMintOpInstr(Token::Kind op_kind, Value* value, intptr_t deopt_id) |
7174 : op_kind_(op_kind) { | 7271 : op_kind_(op_kind), |
| 7272 is_32_bit_(false) { |
7175 ASSERT(op_kind == Token::kBIT_NOT); | 7273 ASSERT(op_kind == Token::kBIT_NOT); |
7176 SetInputAt(0, value); | 7274 SetInputAt(0, value); |
7177 // Override generated deopt-id. | 7275 // Override generated deopt-id. |
7178 deopt_id_ = deopt_id; | 7276 deopt_id_ = deopt_id; |
7179 } | 7277 } |
7180 | 7278 |
7181 Value* value() const { return inputs_[0]; } | 7279 Value* value() const { return inputs_[0]; } |
7182 | 7280 |
7183 Token::Kind op_kind() const { return op_kind_; } | 7281 Token::Kind op_kind() const { return op_kind_; } |
7184 | 7282 |
| 7283 bool IsInput32Bit(intptr_t i) const { |
| 7284 return RequiredInputRepresentation(i) == kUnboxedMint32; |
| 7285 } |
| 7286 |
| 7287 bool is_32_bit() const { return is_32_bit_; } |
| 7288 void set_is_32_bit(bool v) { is_32_bit_ = v; } |
| 7289 |
7185 virtual void PrintOperandsTo(BufferFormatter* f) const; | 7290 virtual void PrintOperandsTo(BufferFormatter* f) const; |
| 7291 virtual void PrintTo(BufferFormatter* f) const; |
7186 | 7292 |
7187 virtual bool CanDeoptimize() const { | 7293 virtual bool CanDeoptimize() const { |
7188 return FLAG_throw_on_javascript_int_overflow; | 7294 return FLAG_throw_on_javascript_int_overflow && !is_32_bit(); |
7189 } | 7295 } |
7190 | 7296 |
7191 virtual Representation representation() const { | 7297 virtual Representation representation() const { |
7192 return kUnboxedMint; | 7298 return is_32_bit() ? kUnboxedMint32 : kUnboxedMint; |
7193 } | 7299 } |
7194 | 7300 |
7195 virtual Representation RequiredInputRepresentation(intptr_t idx) const { | 7301 virtual Representation RequiredInputRepresentation(intptr_t idx) const { |
7196 ASSERT(idx == 0); | 7302 ASSERT(idx == 0); |
7197 return kUnboxedMint; | 7303 return InputAt(idx)->BindsTo32BitMint() ? kUnboxedMint32 : kUnboxedMint; |
7198 } | 7304 } |
7199 | 7305 |
7200 virtual intptr_t DeoptimizationTarget() const { | 7306 virtual intptr_t DeoptimizationTarget() const { |
7201 // Direct access since this instruction cannot deoptimize, and the deopt-id | 7307 // Direct access since this instruction cannot deoptimize, and the deopt-id |
7202 // was inherited from another instruction that could deoptimize. | 7308 // was inherited from another instruction that could deoptimize. |
7203 return deopt_id_; | 7309 return deopt_id_; |
7204 } | 7310 } |
7205 | 7311 |
7206 DECLARE_INSTRUCTION(UnaryMintOp) | 7312 DECLARE_INSTRUCTION(UnaryMintOp) |
7207 virtual CompileType ComputeType() const; | 7313 virtual CompileType ComputeType() const; |
7208 | 7314 |
7209 virtual bool AllowsCSE() const { return true; } | 7315 virtual bool AllowsCSE() const { return true; } |
7210 virtual EffectSet Effects() const { return EffectSet::None(); } | 7316 virtual EffectSet Effects() const { return EffectSet::None(); } |
7211 virtual EffectSet Dependencies() const { return EffectSet::None(); } | 7317 virtual EffectSet Dependencies() const { return EffectSet::None(); } |
7212 virtual bool AttributesEqual(Instruction* other) const { | 7318 virtual bool AttributesEqual(Instruction* other) const { |
7213 return op_kind() == other->AsUnaryMintOp()->op_kind(); | 7319 return op_kind() == other->AsUnaryMintOp()->op_kind(); |
7214 } | 7320 } |
7215 | 7321 |
7216 virtual bool MayThrow() const { return false; } | 7322 virtual bool MayThrow() const { return false; } |
7217 | 7323 |
7218 private: | 7324 private: |
7219 const Token::Kind op_kind_; | 7325 const Token::Kind op_kind_; |
| 7326 bool is_32_bit_; |
7220 | 7327 |
7221 DISALLOW_COPY_AND_ASSIGN(UnaryMintOpInstr); | 7328 DISALLOW_COPY_AND_ASSIGN(UnaryMintOpInstr); |
7222 }; | 7329 }; |
7223 | 7330 |
7224 | 7331 |
7225 class BinarySmiOpInstr : public TemplateDefinition<2> { | 7332 class BinarySmiOpInstr : public TemplateDefinition<2> { |
7226 public: | 7333 public: |
7227 BinarySmiOpInstr(Token::Kind op_kind, | 7334 BinarySmiOpInstr(Token::Kind op_kind, |
7228 Value* left, | 7335 Value* left, |
7229 Value* right, | 7336 Value* right, |
(...skipping 25 matching lines...) Expand all Loading... |
7255 DECLARE_INSTRUCTION(BinarySmiOp) | 7362 DECLARE_INSTRUCTION(BinarySmiOp) |
7256 virtual CompileType ComputeType() const; | 7363 virtual CompileType ComputeType() const; |
7257 | 7364 |
7258 virtual bool CanDeoptimize() const; | 7365 virtual bool CanDeoptimize() const; |
7259 | 7366 |
7260 virtual bool AllowsCSE() const { return true; } | 7367 virtual bool AllowsCSE() const { return true; } |
7261 virtual EffectSet Effects() const { return EffectSet::None(); } | 7368 virtual EffectSet Effects() const { return EffectSet::None(); } |
7262 virtual EffectSet Dependencies() const { return EffectSet::None(); } | 7369 virtual EffectSet Dependencies() const { return EffectSet::None(); } |
7263 virtual bool AttributesEqual(Instruction* other) const; | 7370 virtual bool AttributesEqual(Instruction* other) const; |
7264 | 7371 |
7265 void PrintTo(BufferFormatter* f) const; | 7372 virtual void PrintTo(BufferFormatter* f) const; |
7266 | 7373 |
7267 virtual void InferRange(); | 7374 virtual void InferRange(); |
7268 | 7375 |
7269 virtual Definition* Canonicalize(FlowGraph* flow_graph); | 7376 virtual Definition* Canonicalize(FlowGraph* flow_graph); |
7270 | 7377 |
7271 // Returns true if right is a non-zero Smi constant which absolute value is | 7378 // Returns true if right is a non-zero Smi constant which absolute value is |
7272 // a power of two. | 7379 // a power of two. |
7273 bool RightIsPowerOfTwoConstant() const; | 7380 bool RightIsPowerOfTwoConstant() const; |
7274 | 7381 |
7275 virtual bool MayThrow() const { return false; } | 7382 virtual bool MayThrow() const { return false; } |
(...skipping 928 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8204 ForwardInstructionIterator* current_iterator_; | 8311 ForwardInstructionIterator* current_iterator_; |
8205 | 8312 |
8206 private: | 8313 private: |
8207 DISALLOW_COPY_AND_ASSIGN(FlowGraphVisitor); | 8314 DISALLOW_COPY_AND_ASSIGN(FlowGraphVisitor); |
8208 }; | 8315 }; |
8209 | 8316 |
8210 | 8317 |
8211 } // namespace dart | 8318 } // namespace dart |
8212 | 8319 |
8213 #endif // VM_INTERMEDIATE_LANGUAGE_H_ | 8320 #endif // VM_INTERMEDIATE_LANGUAGE_H_ |
OLD | NEW |