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

Unified Diff: runtime/vm/intermediate_language.cc

Issue 11273111: Allow bound check elimination to eliminate checks when both array length and index boundaries are e… (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: address Florian's comments Created 8 years, 2 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « runtime/vm/intermediate_language.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: runtime/vm/intermediate_language.cc
diff --git a/runtime/vm/intermediate_language.cc b/runtime/vm/intermediate_language.cc
index 7e1986c8bb933a7b781d15b3b83964b2703a854c..d1421dde0e8d78b86f6fa3a6e8336343cbf4f336 100644
--- a/runtime/vm/intermediate_language.cc
+++ b/runtime/vm/intermediate_language.cc
@@ -2121,13 +2121,15 @@ RangeBoundary RangeBoundary::UpperBound() const {
}
+static bool AreEqualDefinitions(Definition* a, Definition* b) {
+ return (a == b) || (!a->AffectedBySideEffect() && a->Equals(b));
+}
+
+
// Returns true if two range boundaries refer to the same symbol.
static bool DependOnSameSymbol(const RangeBoundary& a, const RangeBoundary& b) {
- if (!a.IsSymbol() || !b.IsSymbol()) return false;
- if (a.symbol() == b.symbol()) return true;
-
- return !a.symbol()->AffectedBySideEffect() &&
- a.symbol()->Equals(b.symbol());
+ return a.IsSymbol() && b.IsSymbol() &&
+ AreEqualDefinitions(a.symbol(), b.symbol());
}
@@ -2453,12 +2455,6 @@ static bool IsArrayLength(Definition* defn) {
}
-static bool IsLengthOf(Definition* defn, Definition* array) {
- return IsArrayLength(defn) &&
- (defn->AsLoadField()->value()->definition() == array);
-}
-
-
void BinarySmiOpInstr::InferRange() {
// TODO(vegorov): canonicalize BinarySmiOp to always have constant on the
// right and a non-constant on the left.
@@ -2534,7 +2530,7 @@ void BinarySmiOpInstr::InferRange() {
}
-bool CheckArrayBoundInstr::IsRedundant() {
+bool CheckArrayBoundInstr::IsRedundant(RangeBoundary length) {
// Check that array has an immutable length.
if ((array_type() != kArrayCid) && (array_type() != kImmutableArrayCid)) {
return false;
@@ -2550,13 +2546,21 @@ bool CheckArrayBoundInstr::IsRedundant() {
RangeBoundary max = CanonicalizeBoundary(index_range->max(),
RangeBoundary::OverflowedMaxSmi());
+
+ if (max.Overflowed()) return false;
+
+ // Try to compare constant boundaries.
+ if (max.UpperBound().value() < length.LowerBound().value()) {
+ return true;
+ }
+
+ length = CanonicalizeBoundary(length, RangeBoundary::OverflowedMaxSmi());
+ if (length.Overflowed()) return false;
+
+ // Try symbolic comparison.
do {
- if (max.IsSymbol() &&
- (max.offset() < 0) &&
- IsLengthOf(max.symbol(), array()->definition())) {
- return true;
- }
- } while (CanonicalizeMaxBoundary(&max));
+ if (DependOnSameSymbol(max, length)) return max.offset() < length.offset();
+ } while (CanonicalizeMaxBoundary(&max) || CanonicalizeMinBoundary(&length));
// Failed to prove that maximum is bounded with array length.
return false;
« no previous file with comments | « runtime/vm/intermediate_language.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698