Index: pkg/compiler/lib/src/cps_ir/eagerly_load_statics.dart |
diff --git a/pkg/compiler/lib/src/cps_ir/eagerly_load_statics.dart b/pkg/compiler/lib/src/cps_ir/eagerly_load_statics.dart |
new file mode 100644 |
index 0000000000000000000000000000000000000000..6f733e31f02e5df72ad70f907d39342804537361 |
--- /dev/null |
+++ b/pkg/compiler/lib/src/cps_ir/eagerly_load_statics.dart |
@@ -0,0 +1,67 @@ |
+// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file |
+// for details. All rights reserved. Use of this source code is governed by a |
+// BSD-style license that can be found in the LICENSE file. |
+ |
+library dart2js.cps_ir.eagerly_load_statics; |
+ |
+import 'cps_ir_nodes.dart'; |
+import 'optimizers.dart' show Pass; |
+import '../elements/elements.dart'; |
+ |
+/// Replaces [GetLazyStatic] with [GetStatic] when the static field is known |
+/// to have been initialized. |
+/// |
+/// Apart from [GetStatic] generating better code, this improves the side-effect |
+/// analysis in the [GVN] pass, since [GetStatic] has no effects. |
+class EagerlyLoadStatics extends TrampolineRecursiveVisitor implements Pass { |
+ String get passName => 'Eagerly load statics'; |
+ |
+ Map<FieldElement, Primitive> initializerFor = <FieldElement, Primitive>{}; |
+ |
+ final Map<Continuation, Map<FieldElement, Primitive>> initializersAt = |
+ <Continuation, Map<FieldElement, Primitive>>{}; |
+ |
+ static Map<FieldElement, Primitive> cloneFieldMap( |
+ Map<FieldElement, Primitive> map) { |
+ return new Map<FieldElement, Primitive>.from(map); |
+ } |
+ |
+ void rewrite(FunctionDefinition node) { |
+ visit(node.body); |
+ } |
+ |
+ Expression traverseLetCont(LetCont node) { |
+ for (Continuation cont in node.continuations) { |
+ initializersAt[cont] = cloneFieldMap(initializerFor); |
+ push(cont); |
+ } |
+ return node.body; |
+ } |
+ |
+ Expression traverseLetHandler(LetHandler node) { |
+ initializersAt[node.handler] = cloneFieldMap(initializerFor); |
+ push(node.handler); |
+ return node.body; |
+ } |
+ |
+ Expression traverseContinuation(Continuation cont) { |
+ initializerFor = initializersAt[cont]; |
+ return cont.body; |
+ } |
+ |
+ void visitGetLazyStatic(GetLazyStatic node) { |
+ Primitive initializer = initializerFor[node.element]; |
+ if (initializer != null) { |
+ GetStatic newNode = new GetStatic.witnessed(node.element, initializer, |
+ node.sourceInformation); |
+ newNode.type = node.type; |
+ node.replaceWith(newNode); |
+ } else { |
+ initializerFor[node.element] = node; |
+ } |
+ } |
+ |
+ void visitSetStatic(SetStatic node) { |
+ initializerFor.putIfAbsent(node.element, () => node); |
+ } |
+} |