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

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

Issue 11283002: Simplify range analysis algorithm. (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 1092 matching lines...) Expand 10 before | Expand all | Expand 10 after
1103 // formatting. Otherwise, it prints in the format "opcode(op1, op2, op3)". 1103 // formatting. Otherwise, it prints in the format "opcode(op1, op2, op3)".
1104 virtual void PrintTo(BufferFormatter* f) const; 1104 virtual void PrintTo(BufferFormatter* f) const;
1105 virtual void PrintOperandsTo(BufferFormatter* f) const; 1105 virtual void PrintOperandsTo(BufferFormatter* f) const;
1106 1106
1107 // A value in the constant propagation lattice. 1107 // A value in the constant propagation lattice.
1108 // - non-constant sentinel 1108 // - non-constant sentinel
1109 // - a constant (any non-sentinel value) 1109 // - a constant (any non-sentinel value)
1110 // - unknown sentinel 1110 // - unknown sentinel
1111 Object& constant_value() const { return constant_value_; } 1111 Object& constant_value() const { return constant_value_; }
1112 1112
1113 enum RangeOperator { kRangeInit, kRangeWiden, kRangeNarrow }; 1113 virtual void InferRange();
1114
1115 virtual bool InferRange(RangeOperator op);
1116 1114
1117 Range* range() const { return range_; } 1115 Range* range() const { return range_; }
1118 1116
1119 // Definitions can be canonicalized only into definitions to ensure 1117 // Definitions can be canonicalized only into definitions to ensure
1120 // this check statically we override base Canonicalize with a Canonicalize 1118 // this check statically we override base Canonicalize with a Canonicalize
1121 // returning Definition (return type is covariant). 1119 // returning Definition (return type is covariant).
1122 virtual Definition* Canonicalize(); 1120 virtual Definition* Canonicalize();
1123 1121
1124 protected: 1122 protected:
1123 friend class RangeAnalysis;
1124
1125 Range* range_; 1125 Range* range_;
1126 1126
1127 private: 1127 private:
1128 intptr_t temp_index_; 1128 intptr_t temp_index_;
1129 intptr_t ssa_temp_index_; 1129 intptr_t ssa_temp_index_;
1130 // TODO(regis): GrowableArray<const AbstractType*> propagated_types_; 1130 // TODO(regis): GrowableArray<const AbstractType*> propagated_types_;
1131 // For now: 1131 // For now:
1132 AbstractType& propagated_type_; 1132 AbstractType& propagated_type_;
1133 intptr_t propagated_cid_; 1133 intptr_t propagated_cid_;
1134 Value* input_use_list_; 1134 Value* input_use_list_;
1135 Value* env_use_list_; 1135 Value* env_use_list_;
1136 UseKind use_kind_; 1136 UseKind use_kind_;
1137 1137
1138 Object& constant_value_; 1138 Object& constant_value_;
1139 1139
1140 DISALLOW_COPY_AND_ASSIGN(Definition); 1140 DISALLOW_COPY_AND_ASSIGN(Definition);
1141 }; 1141 };
1142 1142
1143 1143
1144 class PhiInstr : public Definition { 1144 class PhiInstr : public Definition {
1145 public: 1145 public:
1146 explicit PhiInstr(JoinEntryInstr* block, intptr_t num_inputs) 1146 explicit PhiInstr(JoinEntryInstr* block, intptr_t num_inputs)
1147 : block_(block), 1147 : block_(block),
1148 inputs_(num_inputs), 1148 inputs_(num_inputs),
1149 is_alive_(false), 1149 is_alive_(false),
1150 representation_(kTagged), 1150 representation_(kTagged) {
1151 has_inputs_without_range_(true) {
1152 for (intptr_t i = 0; i < num_inputs; ++i) { 1151 for (intptr_t i = 0; i < num_inputs; ++i) {
1153 inputs_.Add(NULL); 1152 inputs_.Add(NULL);
1154 } 1153 }
1155 } 1154 }
1156 1155
1157 // Get the block entry for that instruction. 1156 // Get the block entry for that instruction.
1158 virtual BlockEntryInstr* GetBlock() const { return block(); } 1157 virtual BlockEntryInstr* GetBlock() const { return block(); }
1159 JoinEntryInstr* block() const { return block_; } 1158 JoinEntryInstr* block() const { return block_; }
1160 1159
1161 virtual RawAbstractType* CompileType() const; 1160 virtual RawAbstractType* CompileType() const;
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
1199 1198
1200 virtual intptr_t ResultCid() const { 1199 virtual intptr_t ResultCid() const {
1201 UNREACHABLE(); 1200 UNREACHABLE();
1202 return kIllegalCid; 1201 return kIllegalCid;
1203 } 1202 }
1204 1203
1205 DECLARE_INSTRUCTION(Phi) 1204 DECLARE_INSTRUCTION(Phi)
1206 1205
1207 virtual void PrintTo(BufferFormatter* f) const; 1206 virtual void PrintTo(BufferFormatter* f) const;
1208 1207
1209 virtual bool InferRange(RangeOperator op); 1208 virtual void InferRange();
1210 1209
1211 private: 1210 private:
1212 friend class ConstantPropagator; // Direct access to inputs_. 1211 friend class ConstantPropagator; // Direct access to inputs_.
1213 1212
1214 JoinEntryInstr* block_; 1213 JoinEntryInstr* block_;
1215 GrowableArray<Value*> inputs_; 1214 GrowableArray<Value*> inputs_;
1216 bool is_alive_; 1215 bool is_alive_;
1217 Representation representation_; 1216 Representation representation_;
1218 1217
1219 // Used to determine an interation of a range analysis after all phi inputs
1220 // were initialized to apply widening.
1221 bool has_inputs_without_range_;
1222
1223 DISALLOW_COPY_AND_ASSIGN(PhiInstr); 1218 DISALLOW_COPY_AND_ASSIGN(PhiInstr);
1224 }; 1219 };
1225 1220
1226 1221
1227 class ParameterInstr : public Definition { 1222 class ParameterInstr : public Definition {
1228 public: 1223 public:
1229 explicit ParameterInstr(intptr_t index, GraphEntryInstr* block) 1224 explicit ParameterInstr(intptr_t index, GraphEntryInstr* block)
1230 : index_(index), block_(block) { } 1225 : index_(index), block_(block) { }
1231 1226
1232 DECLARE_INSTRUCTION(Parameter) 1227 DECLARE_INSTRUCTION(Parameter)
(...skipping 413 matching lines...) Expand 10 before | Expand all | Expand 10 after
1646 } 1641 }
1647 1642
1648 Definition* symbol() const { 1643 Definition* symbol() const {
1649 ASSERT(IsSymbol()); 1644 ASSERT(IsSymbol());
1650 return reinterpret_cast<Definition*>(value_); 1645 return reinterpret_cast<Definition*>(value_);
1651 } 1646 }
1652 1647
1653 RangeBoundary LowerBound() const; 1648 RangeBoundary LowerBound() const;
1654 RangeBoundary UpperBound() const; 1649 RangeBoundary UpperBound() const;
1655 1650
1656 static RangeBoundary WidenMin(const RangeBoundary& old_min,
1657 const RangeBoundary& new_min) {
1658 if (new_min.LowerBound().value() < old_min.LowerBound().value()) {
1659 return OverflowedMinSmi();
1660 }
1661 return old_min;
1662 }
1663
1664 static RangeBoundary WidenMax(const RangeBoundary& old_max,
1665 const RangeBoundary& new_max) {
1666 if (new_max.UpperBound().value() > old_max.UpperBound().value()) {
1667 return OverflowedMaxSmi();
1668 }
1669 return old_max;
1670 }
1671
1672 static RangeBoundary NarrowMin(const RangeBoundary& old_min,
1673 const RangeBoundary& new_min) {
1674 ASSERT(old_min.IsConstant());
1675 ASSERT(new_min.IsConstant());
1676 return (old_min.value() == kMinusInfinity) ? new_min
1677 : Min(old_min, new_min);
1678 }
1679
1680 static RangeBoundary NarrowMax(const RangeBoundary& old_max,
1681 const RangeBoundary& new_max) {
1682 return (old_max.value() == kPlusInfinity) ? new_max
1683 : Max(old_max, new_max);
1684 }
1685
1686 void PrintTo(BufferFormatter* f) const; 1651 void PrintTo(BufferFormatter* f) const;
1687 1652
1688 static RangeBoundary Add(const RangeBoundary& a, 1653 static RangeBoundary Add(const RangeBoundary& a,
1689 const RangeBoundary& b, 1654 const RangeBoundary& b,
1690 const RangeBoundary& overflow) { 1655 const RangeBoundary& overflow) {
1691 ASSERT(a.IsConstant() && b.IsConstant()); 1656 ASSERT(a.IsConstant() && b.IsConstant());
1692 1657
1693 intptr_t result = a.value() + b.value(); 1658 intptr_t result = a.value() + b.value();
1694 if (!Smi::IsValid(result)) { 1659 if (!Smi::IsValid(result)) {
1695 return overflow; 1660 return overflow;
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
1730 void PrintTo(BufferFormatter* f) const; 1695 void PrintTo(BufferFormatter* f) const;
1731 static const char* ToCString(Range* range); 1696 static const char* ToCString(Range* range);
1732 1697
1733 const RangeBoundary& min() { return min_; } 1698 const RangeBoundary& min() { return min_; }
1734 const RangeBoundary& max() { return max_; } 1699 const RangeBoundary& max() { return max_; }
1735 1700
1736 bool Equals(Range* other) { 1701 bool Equals(Range* other) {
1737 return min_.Equals(other->min_) && max_.Equals(other->max_); 1702 return min_.Equals(other->min_) && max_.Equals(other->max_);
1738 } 1703 }
1739 1704
1740 static bool Update(Range** range_slot,
1741 const RangeBoundary& min,
1742 const RangeBoundary& max) {
1743 if (*range_slot == NULL) {
1744 *range_slot = new Range(min, max);
1745 return true;
1746 }
1747
1748 Range* range = *range_slot;
1749 if (range->min_.Equals(min) && range->max_.Equals(max)) {
1750 return false;
1751 }
1752
1753 range->min_ = min;
1754 range->max_ = max;
1755
1756 return true;
1757 }
1758
1759 static RangeBoundary ConstantMin(Range* range) { 1705 static RangeBoundary ConstantMin(Range* range) {
1760 if (range == NULL) return RangeBoundary::MinSmi(); 1706 if (range == NULL) return RangeBoundary::MinSmi();
1761 return range->min().LowerBound(); 1707 return range->min().LowerBound();
1762 } 1708 }
1763 1709
1764 static RangeBoundary ConstantMax(Range* range) { 1710 static RangeBoundary ConstantMax(Range* range) {
1765 if (range == NULL) return RangeBoundary::MaxSmi(); 1711 if (range == NULL) return RangeBoundary::MaxSmi();
1766 return range->max().UpperBound(); 1712 return range->max().UpperBound();
1767 } 1713 }
1768 1714
(...skipping 26 matching lines...) Expand all
1795 virtual bool AttributesEqual(Instruction* other) const { 1741 virtual bool AttributesEqual(Instruction* other) const {
1796 UNREACHABLE(); 1742 UNREACHABLE();
1797 return false; 1743 return false;
1798 } 1744 }
1799 1745
1800 virtual void PrintOperandsTo(BufferFormatter* f) const; 1746 virtual void PrintOperandsTo(BufferFormatter* f) const;
1801 1747
1802 Value* value() const { return inputs_[0]; } 1748 Value* value() const { return inputs_[0]; }
1803 Range* constraint() const { return constraint_; } 1749 Range* constraint() const { return constraint_; }
1804 1750
1805 virtual bool InferRange(RangeOperator op); 1751 virtual void InferRange();
1806 1752
1807 void AddDependency(Definition* defn) { 1753 void AddDependency(Definition* defn) {
1808 Value* val = new Value(defn); 1754 Value* val = new Value(defn);
1809 val->set_use_index(1); 1755 val->set_use_index(1);
1810 val->set_instruction(this); 1756 val->set_instruction(this);
1811 val->AddToInputUseList(); 1757 val->AddToInputUseList();
1812 set_dependency(val); 1758 set_dependency(val);
1813 } 1759 }
1814 1760
1815 void RemoveDependency() { 1761 void RemoveDependency() {
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
1848 1794
1849 virtual bool CanDeoptimize() const { return false; } 1795 virtual bool CanDeoptimize() const { return false; }
1850 1796
1851 virtual bool HasSideEffect() const { return false; } 1797 virtual bool HasSideEffect() const { return false; }
1852 1798
1853 virtual intptr_t ResultCid() const; 1799 virtual intptr_t ResultCid() const;
1854 1800
1855 virtual bool AttributesEqual(Instruction* other) const; 1801 virtual bool AttributesEqual(Instruction* other) const;
1856 virtual bool AffectedBySideEffect() const { return false; } 1802 virtual bool AffectedBySideEffect() const { return false; }
1857 1803
1858 virtual bool InferRange(RangeOperator op); 1804 virtual void InferRange();
1859 1805
1860 private: 1806 private:
1861 const Object& value_; 1807 const Object& value_;
1862 1808
1863 DISALLOW_COPY_AND_ASSIGN(ConstantInstr); 1809 DISALLOW_COPY_AND_ASSIGN(ConstantInstr);
1864 }; 1810 };
1865 1811
1866 1812
1867 class AssertAssignableInstr : public TemplateDefinition<3> { 1813 class AssertAssignableInstr : public TemplateDefinition<3> {
1868 public: 1814 public:
(...skipping 1901 matching lines...) Expand 10 before | Expand all | Expand 10 after
3770 virtual bool AttributesEqual(Instruction* other) const; 3716 virtual bool AttributesEqual(Instruction* other) const;
3771 3717
3772 virtual intptr_t ResultCid() const; 3718 virtual intptr_t ResultCid() const;
3773 3719
3774 void set_overflow(bool overflow) { 3720 void set_overflow(bool overflow) {
3775 overflow_ = overflow; 3721 overflow_ = overflow;
3776 } 3722 }
3777 3723
3778 void PrintTo(BufferFormatter* f) const; 3724 void PrintTo(BufferFormatter* f) const;
3779 3725
3780 virtual bool InferRange(RangeOperator op); 3726 virtual void InferRange();
3781 3727
3782 private: 3728 private:
3783 const Token::Kind op_kind_; 3729 const Token::Kind op_kind_;
3784 InstanceCallInstr* instance_call_; 3730 InstanceCallInstr* instance_call_;
3785 bool overflow_; 3731 bool overflow_;
3786 3732
3787 DISALLOW_COPY_AND_ASSIGN(BinarySmiOpInstr); 3733 DISALLOW_COPY_AND_ASSIGN(BinarySmiOpInstr);
3788 }; 3734 };
3789 3735
3790 3736
(...skipping 455 matching lines...) Expand 10 before | Expand all | Expand 10 after
4246 ForwardInstructionIterator* current_iterator_; 4192 ForwardInstructionIterator* current_iterator_;
4247 4193
4248 private: 4194 private:
4249 DISALLOW_COPY_AND_ASSIGN(FlowGraphVisitor); 4195 DISALLOW_COPY_AND_ASSIGN(FlowGraphVisitor);
4250 }; 4196 };
4251 4197
4252 4198
4253 } // namespace dart 4199 } // namespace dart
4254 4200
4255 #endif // VM_INTERMEDIATE_LANGUAGE_H_ 4201 #endif // VM_INTERMEDIATE_LANGUAGE_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698