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

Unified Diff: pkg/compiler/lib/src/cps_ir/gvn.dart

Issue 1578963002: dart2js cps: Hoist unsafe expressions from loop entry. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Update test expectations Created 4 years, 11 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 | « no previous file | tests/compiler/dart2js/cps_ir/expected/codeUnitAt_2.js » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: pkg/compiler/lib/src/cps_ir/gvn.dart
diff --git a/pkg/compiler/lib/src/cps_ir/gvn.dart b/pkg/compiler/lib/src/cps_ir/gvn.dart
index c22db8b353641eb58d6a5563dc4cbf15f79367d5..a4a591f3ae2811db3ca1dd12abcc77a5bc15858e 100644
--- a/pkg/compiler/lib/src/cps_ir/gvn.dart
+++ b/pkg/compiler/lib/src/cps_ir/gvn.dart
@@ -176,15 +176,48 @@ class GVN extends TrampolineRecursiveVisitor implements Pass {
return next;
}
+ bool isFirstImpureExpressionInLoop(Expression exp) {
+ InteriorNode node = exp.parent;
+ for (; node is Expression; node = node.parent) {
+ if (node is LetPrim && node.primitive.isSafeForElimination) {
+ continue;
+ }
+ if (node is LetCont) {
+ continue;
+ }
+ return false;
+ }
+ return node == currentLoopHeader;
+ }
+
+ bool isHoistablePrimitive(Primitive prim) {
+ if (prim.isSafeForElimination) return true;
+ if (prim is NullCheck ||
+ prim is BoundsCheck ||
+ prim is GetLength ||
+ prim is GetField ||
+ prim is GetIndex) {
+ // Expressions that potentially throw but have no other effects can be
+ // hoisted if they occur as the first impure expression in a loop.
+ // Note regarding BoundsCheck: the current array length is an input to
+ // check, so the check itself has no heap dependency. It will only be
+ // hoisted if the length was hoisted.
+ // TODO(asgerf): In general we could hoist these out of multiple loops,
+ // but the trick we use here only works for one loop level.
+ return isFirstImpureExpressionInLoop(prim.parent);
+ }
+ return false;
+ }
+
/// Try to hoist the binding of [prim] out of loops. Returns `true` if it was
/// hoisted or marked as a trivial hoist-on-demand primitive.
bool tryToHoistOutOfLoop(Primitive prim, int gvn) {
- // Do not hoist primitives with side effects.
- if (!prim.isSafeForElimination) return false;
-
// Bail out fast if the primitive is not inside a loop.
if (currentLoopHeader == null) return false;
+ // Do not hoist primitives with side effects.
+ if (!isHoistablePrimitive(prim)) return false;
+
LetPrim letPrim = prim.parent;
// Find the depth of the outermost scope where we can bind the primitive
@@ -327,9 +360,15 @@ class GVN extends TrampolineRecursiveVisitor implements Pass {
}
/// Assuming [prim] has no side effects, returns true if it can safely
- /// be hoisted out of [loop] without changing its value.
+ /// be hoisted out of [loop] without changing its value or changing the timing
+ /// of a thrown exception.
bool canHoistHeapDependencyOutOfLoop(Primitive prim, Continuation loop) {
- assert(prim.isSafeForElimination);
+ // If the primitive might throw, we have to check that it is the first
+ // impure expression in the loop. This has already been checked if
+ // [loop] is the current loop header, but for other loops we just give up.
+ if (!prim.isSafeForElimination && loop != currentLoopHeader) {
+ return false;
+ }
if (prim is GetLength && !isImmutableLength(prim)) {
return !loopEffects.loopChangesLength(loop);
} else if (prim is GetField && !isImmutable(prim.field)) {
@@ -343,7 +382,6 @@ class GVN extends TrampolineRecursiveVisitor implements Pass {
}
}
-
// ------------------ TRAVERSAL AND EFFECT NUMBERING ---------------------
//
// These methods traverse the IR while updating the current effect numbers.
« no previous file with comments | « no previous file | tests/compiler/dart2js/cps_ir/expected/codeUnitAt_2.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698