Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 Loading... | |
| 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 Loading... | |
| 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 |
| OLD | NEW |