| 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 #include "vm/intermediate_language.h" | 5 #include "vm/intermediate_language.h" |
| 6 | 6 |
| 7 #include "vm/bit_vector.h" | 7 #include "vm/bit_vector.h" |
| 8 #include "vm/dart_entry.h" | 8 #include "vm/dart_entry.h" |
| 9 #include "vm/flow_graph_allocator.h" | 9 #include "vm/flow_graph_allocator.h" |
| 10 #include "vm/flow_graph_builder.h" | 10 #include "vm/flow_graph_builder.h" |
| (...skipping 2069 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2080 | 2080 |
| 2081 RangeBoundary RangeBoundary::UpperBound() const { | 2081 RangeBoundary RangeBoundary::UpperBound() const { |
| 2082 if (IsConstant()) return *this; | 2082 if (IsConstant()) return *this; |
| 2083 if (symbol()->range() == NULL) return MaxSmi(); | 2083 if (symbol()->range() == NULL) return MaxSmi(); |
| 2084 return Add(symbol()->range()->max().UpperBound(), | 2084 return Add(symbol()->range()->max().UpperBound(), |
| 2085 RangeBoundary::FromConstant(offset_), | 2085 RangeBoundary::FromConstant(offset_), |
| 2086 MaxSmi()); | 2086 MaxSmi()); |
| 2087 } | 2087 } |
| 2088 | 2088 |
| 2089 | 2089 |
| 2090 bool Definition::InferRange(RangeOperator op) { | 2090 void Definition::InferRange() { |
| 2091 ASSERT(GetPropagatedCid() == kSmiCid); // Has meaning only for smis. | 2091 ASSERT(GetPropagatedCid() == kSmiCid); // Has meaning only for smis. |
| 2092 if (range_ == NULL) { | 2092 if (range_ == NULL) { |
| 2093 range_ = Range::Unknown(); | 2093 range_ = Range::Unknown(); |
| 2094 return true; | |
| 2095 } | 2094 } |
| 2096 return false; | |
| 2097 } | 2095 } |
| 2098 | 2096 |
| 2099 | 2097 |
| 2100 bool ConstantInstr::InferRange(RangeOperator op) { | 2098 void ConstantInstr::InferRange() { |
| 2101 ASSERT(value_.IsSmi()); | 2099 ASSERT(value_.IsSmi()); |
| 2102 if (range_ == NULL) { | 2100 if (range_ == NULL) { |
| 2103 intptr_t value = Smi::Cast(value_).Value(); | 2101 intptr_t value = Smi::Cast(value_).Value(); |
| 2104 range_ = new Range(RangeBoundary::FromConstant(value), | 2102 range_ = new Range(RangeBoundary::FromConstant(value), |
| 2105 RangeBoundary::FromConstant(value)); | 2103 RangeBoundary::FromConstant(value)); |
| 2106 return true; | |
| 2107 } | 2104 } |
| 2108 return false; | |
| 2109 } | 2105 } |
| 2110 | 2106 |
| 2111 | 2107 |
| 2112 bool ConstraintInstr::InferRange(RangeOperator op) { | 2108 void ConstraintInstr::InferRange() { |
| 2113 Range* value_range = value()->definition()->range(); | 2109 Range* value_range = value()->definition()->range(); |
| 2114 | 2110 |
| 2115 // Compute intersection of constraint and value ranges. | 2111 // Compute intersection of constraint and value ranges. |
| 2116 return Range::Update(&range_, | 2112 range_ = new Range( |
| 2117 RangeBoundary::Max(Range::ConstantMin(value_range), | 2113 RangeBoundary::Max(Range::ConstantMin(value_range), |
| 2118 Range::ConstantMin(constraint())), | 2114 Range::ConstantMin(constraint())), |
| 2119 RangeBoundary::Min(Range::ConstantMax(value_range), | 2115 RangeBoundary::Min(Range::ConstantMax(value_range), |
| 2120 Range::ConstantMax(constraint()))); | 2116 Range::ConstantMax(constraint()))); |
| 2121 } | 2117 } |
| 2122 | 2118 |
| 2123 | 2119 |
| 2124 bool PhiInstr::InferRange(RangeOperator op) { | 2120 void PhiInstr::InferRange() { |
| 2125 RangeBoundary new_min; | 2121 RangeBoundary new_min; |
| 2126 RangeBoundary new_max; | 2122 RangeBoundary new_max; |
| 2127 | 2123 |
| 2128 for (intptr_t i = 0; i < InputCount(); i++) { | 2124 for (intptr_t i = 0; i < InputCount(); i++) { |
| 2129 Range* input_range = InputAt(i)->definition()->range(); | 2125 Range* input_range = InputAt(i)->definition()->range(); |
| 2130 if (input_range == NULL) { | 2126 if (input_range == NULL) { |
| 2131 continue; | 2127 range_ = Range::Unknown(); |
| 2128 return; |
| 2132 } | 2129 } |
| 2133 | 2130 |
| 2134 if (new_min.IsUnknown()) { | 2131 if (new_min.IsUnknown()) { |
| 2135 new_min = Range::ConstantMin(input_range); | 2132 new_min = Range::ConstantMin(input_range); |
| 2136 } else { | 2133 } else { |
| 2137 new_min = RangeBoundary::Min(new_min, Range::ConstantMin(input_range)); | 2134 new_min = RangeBoundary::Min(new_min, Range::ConstantMin(input_range)); |
| 2138 } | 2135 } |
| 2139 | 2136 |
| 2140 if (new_max.IsUnknown()) { | 2137 if (new_max.IsUnknown()) { |
| 2141 new_max = Range::ConstantMax(input_range); | 2138 new_max = Range::ConstantMax(input_range); |
| 2142 } else { | 2139 } else { |
| 2143 new_max = RangeBoundary::Max(new_max, Range::ConstantMax(input_range)); | 2140 new_max = RangeBoundary::Max(new_max, Range::ConstantMax(input_range)); |
| 2144 } | 2141 } |
| 2145 } | 2142 } |
| 2146 | 2143 |
| 2147 ASSERT(new_min.IsUnknown() == new_max.IsUnknown()); | 2144 ASSERT(new_min.IsUnknown() == new_max.IsUnknown()); |
| 2148 if (new_min.IsUnknown()) { | 2145 if (new_min.IsUnknown()) { |
| 2149 range_ = Range::Unknown(); | 2146 range_ = Range::Unknown(); |
| 2150 return false; | 2147 return; |
| 2151 } | 2148 } |
| 2152 | 2149 |
| 2153 if (op == Definition::kRangeWiden) { | 2150 range_ = new Range(new_min, new_max); |
| 2154 // Apply widening operator. | |
| 2155 new_min = RangeBoundary::WidenMin(range_->min(), new_min); | |
| 2156 new_max = RangeBoundary::WidenMax(range_->max(), new_max); | |
| 2157 } else if (op == Definition::kRangeNarrow) { | |
| 2158 // Apply narrowing operator. | |
| 2159 new_min = RangeBoundary::NarrowMin(range_->min(), new_min); | |
| 2160 new_max = RangeBoundary::NarrowMax(range_->max(), new_max); | |
| 2161 } | |
| 2162 | |
| 2163 return Range::Update(&range_, new_min, new_max); | |
| 2164 } | 2151 } |
| 2165 | 2152 |
| 2166 | 2153 |
| 2167 bool BinarySmiOpInstr::InferRange(RangeOperator op) { | 2154 void BinarySmiOpInstr::InferRange() { |
| 2168 Range* left_range = left()->definition()->range(); | 2155 Range* left_range = left()->definition()->range(); |
| 2169 Range* right_range = right()->definition()->range(); | 2156 Range* right_range = right()->definition()->range(); |
| 2170 | 2157 |
| 2171 if ((left_range == NULL) || (right_range == NULL)) { | 2158 if ((left_range == NULL) || (right_range == NULL)) { |
| 2172 return Range::Update(&range_, | 2159 range_ = new Range(RangeBoundary::MinSmi(), RangeBoundary::MaxSmi()); |
| 2173 RangeBoundary::MinSmi(), | 2160 return; |
| 2174 RangeBoundary::MaxSmi()); | |
| 2175 } | 2161 } |
| 2176 | 2162 |
| 2177 RangeBoundary new_min; | 2163 RangeBoundary new_min; |
| 2178 RangeBoundary new_max; | 2164 RangeBoundary new_max; |
| 2179 switch (op_kind()) { | 2165 switch (op_kind()) { |
| 2180 case Token::kADD: | 2166 case Token::kADD: |
| 2181 new_min = | 2167 new_min = |
| 2182 RangeBoundary::Add(Range::ConstantMin(left_range), | 2168 RangeBoundary::Add(Range::ConstantMin(left_range), |
| 2183 Range::ConstantMin(right_range), | 2169 Range::ConstantMin(right_range), |
| 2184 RangeBoundary::OverflowedMinSmi()); | 2170 RangeBoundary::OverflowedMinSmi()); |
| (...skipping 10 matching lines...) Expand all Loading... |
| 2195 RangeBoundary::OverflowedMinSmi()); | 2181 RangeBoundary::OverflowedMinSmi()); |
| 2196 new_max = | 2182 new_max = |
| 2197 RangeBoundary::Sub(Range::ConstantMax(left_range), | 2183 RangeBoundary::Sub(Range::ConstantMax(left_range), |
| 2198 Range::ConstantMin(right_range), | 2184 Range::ConstantMin(right_range), |
| 2199 RangeBoundary::OverflowedMaxSmi()); | 2185 RangeBoundary::OverflowedMaxSmi()); |
| 2200 break; | 2186 break; |
| 2201 | 2187 |
| 2202 default: | 2188 default: |
| 2203 if (range_ == NULL) { | 2189 if (range_ == NULL) { |
| 2204 range_ = Range::Unknown(); | 2190 range_ = Range::Unknown(); |
| 2205 return true; | |
| 2206 } | 2191 } |
| 2207 return false; | 2192 return; |
| 2208 } | 2193 } |
| 2209 | 2194 |
| 2210 ASSERT(!new_min.IsUnknown() && !new_max.IsUnknown()); | 2195 ASSERT(!new_min.IsUnknown() && !new_max.IsUnknown()); |
| 2211 set_overflow(new_min.Overflowed() || new_max.Overflowed()); | 2196 set_overflow(new_min.Overflowed() || new_max.Overflowed()); |
| 2212 | 2197 |
| 2213 if (op == Definition::kRangeNarrow) { | 2198 range_ = new Range(new_min.Clamp(), new_max.Clamp()); |
| 2214 new_min = new_min.Clamp(); | |
| 2215 new_max = new_max.Clamp(); | |
| 2216 } | |
| 2217 | |
| 2218 return Range::Update(&range_, new_min, new_max); | |
| 2219 } | 2199 } |
| 2220 | 2200 |
| 2221 | 2201 |
| 2222 #undef __ | 2202 #undef __ |
| 2223 | 2203 |
| 2224 } // namespace dart | 2204 } // namespace dart |
| OLD | NEW |