Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(59)

Side by Side Diff: runtime/vm/intermediate_language.h

Issue 11262033: Simple array bounds check elimination on top of range analysis framework. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 8 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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
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
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
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_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698