| Index: pkg/compiler/lib/src/cps_ir/bounds_checker.dart
|
| diff --git a/pkg/compiler/lib/src/cps_ir/bounds_checker.dart b/pkg/compiler/lib/src/cps_ir/bounds_checker.dart
|
| index 14677456e216d84d8ebf5e451c481f534b8f8197..28dbd624e99acdb4c5156e06549e893c1f5cdf5a 100644
|
| --- a/pkg/compiler/lib/src/cps_ir/bounds_checker.dart
|
| +++ b/pkg/compiler/lib/src/cps_ir/bounds_checker.dart
|
| @@ -12,6 +12,9 @@ import 'cps_fragment.dart';
|
| import 'type_mask_system.dart';
|
| import '../world.dart';
|
| import '../elements/elements.dart';
|
| +import 'loop_effects.dart';
|
| +
|
| +
|
|
|
| /// Eliminates bounds checks when they can be proven safe.
|
| ///
|
| @@ -30,7 +33,6 @@ import '../elements/elements.dart';
|
| ///
|
| /// Loops are analyzed in two passes. The first pass establishes monotonicity
|
| /// of loop variables, which the second pass uses to compute upper/lower bounds.
|
| -/// The first pass also records whether any side effects occurred in the loop.
|
| ///
|
| /// The two-pass scheme is suboptimal compared to a least fixed-point
|
| /// computation, but does not require repeated iteration. Repeated iteration
|
| @@ -56,7 +58,6 @@ class BoundsChecker extends TrampolineRecursiveVisitor implements Pass {
|
| final Map<Primitive, Map<int, SignedVariable>> lengthOf = {};
|
|
|
| /// Fields for the two-pass handling of loops.
|
| - final Set<Continuation> loopsWithSideEffects = new Set<Continuation>();
|
| final Map<Parameter, Monotonicity> monotonicity = <Parameter, Monotonicity>{};
|
| bool isStrongLoopPass;
|
| bool foundLoop = false;
|
| @@ -65,6 +66,7 @@ class BoundsChecker extends TrampolineRecursiveVisitor implements Pass {
|
| ///
|
| /// The IR is divided into regions wherein the lengths of indexable objects
|
| /// are known not to change. Regions are identified by their "effect number".
|
| + LoopSideEffects loopEffects;
|
| final Map<Continuation, int> effectNumberAt = <Continuation, int>{};
|
| int currentEffectNumber = 0;
|
| int effectNumberCounter = 0;
|
| @@ -72,6 +74,7 @@ class BoundsChecker extends TrampolineRecursiveVisitor implements Pass {
|
| BoundsChecker(this.types, this.world);
|
|
|
| void rewrite(FunctionDefinition node) {
|
| + loopEffects = new LoopSideEffects(node, world);
|
| isStrongLoopPass = false;
|
| visit(node);
|
| if (foundLoop) {
|
| @@ -402,12 +405,8 @@ class BoundsChecker extends TrampolineRecursiveVisitor implements Pass {
|
| makeLessThanOrEqual(getValue(param), initialVariable);
|
| }
|
| }
|
| - if (loopsWithSideEffects.contains(cont)) {
|
| - currentEffectNumber = makeNewEffect();
|
| - }
|
| - } else {
|
| - // During the weak pass, conservatively make a new effect number in the
|
| - // loop body. This may be strengthened during the strong pass.
|
| + }
|
| + if (loopEffects.loopChangesLength(cont)) {
|
| currentEffectNumber = effectNumberAt[cont] = makeNewEffect();
|
| }
|
| push(cont);
|
| @@ -440,12 +439,6 @@ class BoundsChecker extends TrampolineRecursiveVisitor implements Pass {
|
| markMonotonicity(cont.parameters[i], Monotonicity.Decreasing);
|
| }
|
| }
|
| -
|
| - // If a side effect has occurred between the entry and continue, mark
|
| - // the loop as having side effects.
|
| - if (currentEffectNumber != effectNumberAt[cont]) {
|
| - loopsWithSideEffects.add(cont);
|
| - }
|
| }
|
|
|
| void markMonotonicity(Parameter param, Monotonicity mono) {
|
|
|