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

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

Issue 556353002: Fix bug in range analysis. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 6 years, 3 months 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
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2014, 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/flow_graph_range_analysis.h" 5 #include "vm/flow_graph_range_analysis.h"
6 6
7 #include "vm/bit_vector.h" 7 #include "vm/bit_vector.h"
8 #include "vm/il_printer.h" 8 #include "vm/il_printer.h"
9 9
10 namespace dart { 10 namespace dart {
(...skipping 1804 matching lines...) Expand 10 before | Expand all | Expand 10 after
1815 // expand the minimum. 1815 // expand the minimum.
1816 range->set_min(other.min()); 1816 range->set_min(other.min());
1817 } else { 1817 } else {
1818 // Can't compare ranges as whole. Join minimum and maximum separately. 1818 // Can't compare ranges as whole. Join minimum and maximum separately.
1819 *range = Range(RangeBoundary::JoinMin(range->min(), other.min(), size), 1819 *range = Range(RangeBoundary::JoinMin(range->min(), other.min(), size),
1820 RangeBoundary::JoinMax(range->max(), other.max(), size)); 1820 RangeBoundary::JoinMax(range->max(), other.max(), size));
1821 } 1821 }
1822 } 1822 }
1823 1823
1824 1824
1825 // A definition dominates a phi if its block dominates the phi's block
1826 // and the two blocks are different.
1827 static bool DominatesPhi(BlockEntryInstr* a, BlockEntryInstr* phi_block) {
1828 return a->Dominates(phi_block) && (a != phi_block);
Vyacheslav Egorov (Google) 2014/09/10 18:33:41 You reoder (a != phi_block) && ...
1829 }
1830
1831
1825 // When assigning range to a phi we must take care to avoid self-reference 1832 // When assigning range to a phi we must take care to avoid self-reference
1826 // cycles when phi's range depends on the phi itself. 1833 // cycles when phi's range depends on the phi itself.
1827 // To prevent such cases we impose additional restriction on symbols that 1834 // To prevent such cases we impose additional restriction on symbols that
1828 // can be used as boundaries for phi's range: they must dominate 1835 // can be used as boundaries for phi's range: they must dominate
1829 // phi's definition. 1836 // phi's definition.
1830 static RangeBoundary EnsureAcyclicSymbol(BlockEntryInstr* phi_block, 1837 static RangeBoundary EnsureAcyclicSymbol(BlockEntryInstr* phi_block,
1831 const RangeBoundary& a, 1838 const RangeBoundary& a,
1832 const RangeBoundary& limit) { 1839 const RangeBoundary& limit) {
1833 if (!a.IsSymbol() || a.symbol()->GetBlock()->Dominates(phi_block)) { 1840 if (!a.IsSymbol() || DominatesPhi(a.symbol()->GetBlock(), phi_block)) {
1834 return a; 1841 return a;
1835 } 1842 }
1836 1843
1837 // Symbol does not dominate phi. Try unwrapping constraint and check again. 1844 // Symbol does not dominate phi. Try unwrapping constraint and check again.
1838 Definition* unwrapped = UnwrapConstraint(a.symbol()); 1845 Definition* unwrapped = UnwrapConstraint(a.symbol());
1839 if ((unwrapped != a.symbol()) && 1846 if ((unwrapped != a.symbol()) &&
1840 unwrapped->GetBlock()->Dominates(phi_block)) { 1847 DominatesPhi(unwrapped->GetBlock(), phi_block)) {
1841 return RangeBoundary::FromDefinition(unwrapped, a.offset()); 1848 return RangeBoundary::FromDefinition(unwrapped, a.offset());
1842 } 1849 }
1843 1850
1844 return limit; 1851 return limit;
1845 } 1852 }
1846 1853
1847 1854
1848 void PhiInstr::InferRange(RangeAnalysis* analysis, Range* range) { 1855 void PhiInstr::InferRange(RangeAnalysis* analysis, Range* range) {
1849 ASSERT((Type()->ToCid() == kSmiCid) || (representation() == kUnboxedInt32)); 1856 ASSERT((Type()->ToCid() == kSmiCid) || (representation() == kUnboxedInt32));
1850 const RangeBoundary::RangeSize size = (Type()->ToCid() == kSmiCid) ? 1857 const RangeBoundary::RangeSize size = (Type()->ToCid() == kSmiCid) ?
(...skipping 367 matching lines...) Expand 10 before | Expand all | Expand 10 after
2218 } 2225 }
2219 } while (CanonicalizeMaxBoundary(&max) || 2226 } while (CanonicalizeMaxBoundary(&max) ||
2220 CanonicalizeMinBoundary(&canonical_length)); 2227 CanonicalizeMinBoundary(&canonical_length));
2221 2228
2222 // Failed to prove that maximum is bounded with array length. 2229 // Failed to prove that maximum is bounded with array length.
2223 return false; 2230 return false;
2224 } 2231 }
2225 2232
2226 2233
2227 } // namespace dart 2234 } // namespace dart
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698