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

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

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 #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
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
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
OLDNEW
« runtime/vm/flow_graph_optimizer.cc ('K') | « runtime/vm/intermediate_language.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698