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 |