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