OLD | NEW |
---|---|
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, 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 1565 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1576 class RangeBoundary : public ValueObject { | 1576 class RangeBoundary : public ValueObject { |
1577 public: | 1577 public: |
1578 enum Kind { kUnknown, kSymbol, kConstant }; | 1578 enum Kind { kUnknown, kSymbol, kConstant }; |
1579 | 1579 |
1580 RangeBoundary() : kind_(kUnknown), value_(0), offset_(0) { } | 1580 RangeBoundary() : kind_(kUnknown), value_(0), offset_(0) { } |
1581 | 1581 |
1582 static RangeBoundary FromConstant(intptr_t val) { | 1582 static RangeBoundary FromConstant(intptr_t val) { |
1583 return RangeBoundary(kConstant, val, 0); | 1583 return RangeBoundary(kConstant, val, 0); |
1584 } | 1584 } |
1585 | 1585 |
1586 static RangeBoundary FromDefinition(Definition* defn, intptr_t offs = 0) { | 1586 static RangeBoundary FromDefinition(Definition* defn, intptr_t offs = 0); |
1587 return RangeBoundary(kSymbol, reinterpret_cast<intptr_t>(defn), offs); | |
1588 } | |
1589 | 1587 |
1590 static RangeBoundary MinSmi() { | 1588 static RangeBoundary MinSmi() { |
1591 return FromConstant(Smi::kMinValue); | 1589 return FromConstant(Smi::kMinValue); |
1592 } | 1590 } |
1593 | 1591 |
1594 static RangeBoundary MaxSmi() { | 1592 static RangeBoundary MaxSmi() { |
1595 return FromConstant(Smi::kMaxValue); | 1593 return FromConstant(Smi::kMaxValue); |
1596 } | 1594 } |
1597 | 1595 |
1598 static const intptr_t kMinusInfinity = Smi::kMinValue - 1; | 1596 static const intptr_t kMinusInfinity = Smi::kMinValue - 1; |
1599 static const intptr_t kPlusInfinity = Smi::kMaxValue + 1; | 1597 static const intptr_t kPlusInfinity = Smi::kMaxValue + 1; |
1600 | 1598 |
1601 static RangeBoundary OverflowedMinSmi() { | 1599 static RangeBoundary OverflowedMinSmi() { |
1602 return FromConstant(Smi::kMinValue - 1); | 1600 return FromConstant(Smi::kMinValue - 1); |
1603 } | 1601 } |
1604 | 1602 |
1605 static RangeBoundary OverflowedMaxSmi() { | 1603 static RangeBoundary OverflowedMaxSmi() { |
1606 return FromConstant(Smi::kMaxValue + 1); | 1604 return FromConstant(Smi::kMaxValue + 1); |
1607 } | 1605 } |
1608 | 1606 |
1609 static RangeBoundary Min(RangeBoundary a, RangeBoundary b) { | 1607 static RangeBoundary Min(RangeBoundary a, RangeBoundary b); |
1610 const intptr_t min_a = a.LowerBound().value(); | |
1611 const intptr_t min_b = b.LowerBound().value(); | |
1612 | 1608 |
1613 return RangeBoundary::FromConstant(Utils::Minimum(min_a, min_b)); | 1609 static RangeBoundary Max(RangeBoundary a, RangeBoundary b); |
1614 } | |
1615 | |
1616 static RangeBoundary Max(RangeBoundary a, RangeBoundary b) { | |
1617 const intptr_t max_a = a.UpperBound().value(); | |
1618 const intptr_t max_b = b.UpperBound().value(); | |
1619 | |
1620 return RangeBoundary::FromConstant(Utils::Maximum(max_a, max_b)); | |
1621 } | |
1622 | 1610 |
1623 bool Overflowed() const { | 1611 bool Overflowed() const { |
1624 return !Smi::IsValid(value()); | 1612 return !Smi::IsValid(value()); |
1625 } | 1613 } |
1626 | 1614 |
1627 RangeBoundary Clamp() const { | 1615 RangeBoundary Clamp() const { |
1628 if (IsConstant()) { | 1616 if (IsConstant()) { |
1629 if (value() < Smi::kMinValue) return MinSmi(); | 1617 if (value() < Smi::kMinValue) return MinSmi(); |
1630 if (value() > Smi::kMaxValue) return MaxSmi(); | 1618 if (value() > Smi::kMaxValue) return MaxSmi(); |
1631 } | 1619 } |
1632 return *this; | 1620 return *this; |
1633 } | 1621 } |
1634 | 1622 |
1635 bool Equals(const RangeBoundary& other) const { | 1623 bool Equals(const RangeBoundary& other) const { |
1636 return (kind_ == other.kind_) && (value_ == other.value_); | 1624 return (kind_ == other.kind_) && (value_ == other.value_); |
1637 } | 1625 } |
1638 | 1626 |
1639 bool IsUnknown() const { return kind_ == kUnknown; } | 1627 bool IsUnknown() const { return kind_ == kUnknown; } |
1640 bool IsConstant() const { return kind_ == kConstant; } | 1628 bool IsConstant() const { return kind_ == kConstant; } |
1641 bool IsSymbol() const { return kind_ == kSymbol; } | 1629 bool IsSymbol() const { return kind_ == kSymbol; } |
srdjan
2012/10/25 20:51:36
IsSymbol is a pretty widely used operation on cla
Vyacheslav Egorov (Google)
2012/10/26 14:23:29
I am not sure how to rename it. I agree that it is
| |
1642 | 1630 |
1643 intptr_t value() const { | 1631 intptr_t value() const { |
1644 ASSERT(IsConstant()); | 1632 ASSERT(IsConstant()); |
1645 return value_; | 1633 return value_; |
1646 } | 1634 } |
1647 | 1635 |
1648 Definition* symbol() const { | 1636 Definition* symbol() const { |
1649 ASSERT(IsSymbol()); | 1637 ASSERT(IsSymbol()); |
1650 return reinterpret_cast<Definition*>(value_); | 1638 return reinterpret_cast<Definition*>(value_); |
1651 } | 1639 } |
1652 | 1640 |
1641 intptr_t offset() const { | |
1642 return offset_; | |
1643 } | |
1644 | |
1653 RangeBoundary LowerBound() const; | 1645 RangeBoundary LowerBound() const; |
1654 RangeBoundary UpperBound() const; | 1646 RangeBoundary UpperBound() const; |
1655 | 1647 |
1656 void PrintTo(BufferFormatter* f) const; | 1648 void PrintTo(BufferFormatter* f) const; |
1649 const char* ToCString() const; | |
1657 | 1650 |
1658 static RangeBoundary Add(const RangeBoundary& a, | 1651 static RangeBoundary Add(const RangeBoundary& a, |
1659 const RangeBoundary& b, | 1652 const RangeBoundary& b, |
1660 const RangeBoundary& overflow) { | 1653 const RangeBoundary& overflow) { |
1661 ASSERT(a.IsConstant() && b.IsConstant()); | 1654 ASSERT(a.IsConstant() && b.IsConstant()); |
1662 | 1655 |
1663 intptr_t result = a.value() + b.value(); | 1656 intptr_t result = a.value() + b.value(); |
1664 if (!Smi::IsValid(result)) { | 1657 if (!Smi::IsValid(result)) { |
1665 return overflow; | 1658 return overflow; |
1666 } | 1659 } |
(...skipping 1274 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2941 | 2934 |
2942 class LoadFieldInstr : public TemplateDefinition<1> { | 2935 class LoadFieldInstr : public TemplateDefinition<1> { |
2943 public: | 2936 public: |
2944 LoadFieldInstr(Value* value, | 2937 LoadFieldInstr(Value* value, |
2945 intptr_t offset_in_bytes, | 2938 intptr_t offset_in_bytes, |
2946 const AbstractType& type, | 2939 const AbstractType& type, |
2947 bool immutable = false) | 2940 bool immutable = false) |
2948 : offset_in_bytes_(offset_in_bytes), | 2941 : offset_in_bytes_(offset_in_bytes), |
2949 type_(type), | 2942 type_(type), |
2950 result_cid_(kDynamicCid), | 2943 result_cid_(kDynamicCid), |
2951 immutable_(immutable) { | 2944 immutable_(immutable), |
2945 recognized_kind_(MethodRecognizer::kUnknown) { | |
2952 ASSERT(value != NULL); | 2946 ASSERT(value != NULL); |
2953 ASSERT(type.IsZoneHandle()); // May be null if field is not an instance. | 2947 ASSERT(type.IsZoneHandle()); // May be null if field is not an instance. |
2954 inputs_[0] = value; | 2948 inputs_[0] = value; |
2955 } | 2949 } |
2956 | 2950 |
2957 DECLARE_INSTRUCTION(LoadField) | 2951 DECLARE_INSTRUCTION(LoadField) |
2958 virtual RawAbstractType* CompileType() const; | 2952 virtual RawAbstractType* CompileType() const; |
2959 | 2953 |
2960 Value* value() const { return inputs_[0]; } | 2954 Value* value() const { return inputs_[0]; } |
2961 intptr_t offset_in_bytes() const { return offset_in_bytes_; } | 2955 intptr_t offset_in_bytes() const { return offset_in_bytes_; } |
2962 const AbstractType& type() const { return type_; } | 2956 const AbstractType& type() const { return type_; } |
2963 void set_result_cid(intptr_t value) { result_cid_ = value; } | 2957 void set_result_cid(intptr_t value) { result_cid_ = value; } |
2964 | 2958 |
2965 virtual void PrintOperandsTo(BufferFormatter* f) const; | 2959 virtual void PrintOperandsTo(BufferFormatter* f) const; |
2966 | 2960 |
2967 virtual bool CanDeoptimize() const { return false; } | 2961 virtual bool CanDeoptimize() const { return false; } |
2968 | 2962 |
2969 virtual bool HasSideEffect() const { return false; } | 2963 virtual bool HasSideEffect() const { return false; } |
2970 | 2964 |
2971 virtual intptr_t ResultCid() const { return result_cid_; } | 2965 virtual intptr_t ResultCid() const { return result_cid_; } |
2972 | 2966 |
2973 virtual bool AttributesEqual(Instruction* other) const; | 2967 virtual bool AttributesEqual(Instruction* other) const; |
2974 | 2968 |
2975 virtual bool AffectedBySideEffect() const { return !immutable_; } | 2969 virtual bool AffectedBySideEffect() const { return !immutable_; } |
2976 | 2970 |
2971 virtual void InferRange(); | |
2972 | |
2973 void set_recognized_kind(MethodRecognizer::Kind kind) { | |
2974 recognized_kind_ = kind; | |
2975 } | |
2976 | |
2977 MethodRecognizer::Kind recognized_kind() const { | |
2978 return recognized_kind_; | |
2979 } | |
2980 | |
2977 private: | 2981 private: |
2978 const intptr_t offset_in_bytes_; | 2982 const intptr_t offset_in_bytes_; |
2979 const AbstractType& type_; | 2983 const AbstractType& type_; |
2980 intptr_t result_cid_; | 2984 intptr_t result_cid_; |
2981 const bool immutable_; | 2985 const bool immutable_; |
2982 | 2986 |
2987 MethodRecognizer::Kind recognized_kind_; | |
2988 | |
2983 DISALLOW_COPY_AND_ASSIGN(LoadFieldInstr); | 2989 DISALLOW_COPY_AND_ASSIGN(LoadFieldInstr); |
2984 }; | 2990 }; |
2985 | 2991 |
2986 | 2992 |
2987 class StoreVMFieldInstr : public TemplateDefinition<2> { | 2993 class StoreVMFieldInstr : public TemplateDefinition<2> { |
2988 public: | 2994 public: |
2989 StoreVMFieldInstr(Value* dest, | 2995 StoreVMFieldInstr(Value* dest, |
2990 intptr_t offset_in_bytes, | 2996 intptr_t offset_in_bytes, |
2991 Value* value, | 2997 Value* value, |
2992 const AbstractType& type) | 2998 const AbstractType& type) |
(...skipping 986 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3979 | 3985 |
3980 virtual bool AttributesEqual(Instruction* other) const; | 3986 virtual bool AttributesEqual(Instruction* other) const; |
3981 | 3987 |
3982 virtual bool AffectedBySideEffect() const { return false; } | 3988 virtual bool AffectedBySideEffect() const { return false; } |
3983 | 3989 |
3984 Value* array() const { return inputs_[0]; } | 3990 Value* array() const { return inputs_[0]; } |
3985 Value* index() const { return inputs_[1]; } | 3991 Value* index() const { return inputs_[1]; } |
3986 | 3992 |
3987 intptr_t array_type() const { return array_type_; } | 3993 intptr_t array_type() const { return array_type_; } |
3988 | 3994 |
3995 bool IsRedundant(); | |
3996 | |
3989 private: | 3997 private: |
3990 intptr_t array_type_; | 3998 intptr_t array_type_; |
3991 | 3999 |
3992 DISALLOW_COPY_AND_ASSIGN(CheckArrayBoundInstr); | 4000 DISALLOW_COPY_AND_ASSIGN(CheckArrayBoundInstr); |
3993 }; | 4001 }; |
3994 | 4002 |
3995 | 4003 |
3996 #undef DECLARE_INSTRUCTION | 4004 #undef DECLARE_INSTRUCTION |
3997 | 4005 |
3998 class Environment : public ZoneAllocated { | 4006 class Environment : public ZoneAllocated { |
(...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4200 ForwardInstructionIterator* current_iterator_; | 4208 ForwardInstructionIterator* current_iterator_; |
4201 | 4209 |
4202 private: | 4210 private: |
4203 DISALLOW_COPY_AND_ASSIGN(FlowGraphVisitor); | 4211 DISALLOW_COPY_AND_ASSIGN(FlowGraphVisitor); |
4204 }; | 4212 }; |
4205 | 4213 |
4206 | 4214 |
4207 } // namespace dart | 4215 } // namespace dart |
4208 | 4216 |
4209 #endif // VM_INTERMEDIATE_LANGUAGE_H_ | 4217 #endif // VM_INTERMEDIATE_LANGUAGE_H_ |
OLD | NEW |