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..630433302fa84de39e0bec7cc922f9956d3e7499 |
--- /dev/null |
+++ b/pkg/compiler/lib/src/cps_ir/eagerly_load_statics.dart |
@@ -0,0 +1,68 @@ |
+// 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] is known to have no effects. |
sra1
2015/12/11 17:13:09
"is known to have" -> "has"
asgerf
2015/12/14 17:05:39
Done.
|
+class EagerlyLoadStatics extends TrampolineRecursiveVisitor implements Pass { |
+ String get passName => 'Eagerly load statics'; |
+ |
+ Set<FieldElement> loadedStatics = new Set<FieldElement>(); |
+ final Map<Continuation, Set<FieldElement>> loadedStaticsAt = {}; |
sra1
2015/12/11 17:13:08
Put types on the map literal - that is what is che
asgerf
2015/12/14 17:05:39
The pass has changed quite a bit now, but there ar
|
+ |
+ void rewrite(FunctionDefinition node) { |
+ visit(node); |
+ } |
+ |
+ void visitBranch(Branch node) { |
+ Continuation trueCont = node.trueContinuation.definition; |
+ Continuation falseCont = node.falseContinuation.definition; |
+ loadedStaticsAt[trueCont] = loadedStatics; |
+ loadedStaticsAt[falseCont] = new Set<FieldElement>.from(loadedStatics); |
+ } |
+ |
+ Expression traverseContinuation(Continuation cont) { |
+ loadedStatics = loadedStaticsAt[cont] ?? new Set<FieldElement>(); |
sra1
2015/12/11 17:13:08
Why is it null?
I would add two helpers - newSet
asgerf
2015/12/14 17:05:39
Null was for the case of unreachable continuations
|
+ return cont.body; |
+ } |
+ |
+ Expression traverseLetHandler(LetHandler node) { |
+ loadedStaticsAt[node.handler] = new Set<FieldElement>.from(loadedStatics); |
+ push(node.handler); |
+ return node.body; |
+ } |
+ |
+ void visitInvokeContinuation(InvokeContinuation node) { |
+ if (node.isRecursive) return; |
+ Continuation cont = node.continuation.definition; |
+ if (cont.isReturnContinuation) return; |
+ Set<FieldElement> targetSet = loadedStaticsAt[cont]; |
+ if (targetSet == null) { |
+ loadedStaticsAt[cont] = loadedStatics; |
+ } else { |
+ targetSet.retainAll(loadedStatics); |
+ } |
+ } |
+ |
+ void visitGetLazyStatic(GetLazyStatic node) { |
+ // Mark the field as loaded, and replace it with a GetStatic if it was |
+ // already loaded. |
+ if (!loadedStatics.add(node.element)) { |
+ node.replaceWith(new GetStatic(node.element, node.sourceInformation) |
+ ..type = node.type); |
+ } |
+ } |
+ |
+ void visitSetStatic(SetStatic node) { |
+ loadedStatics.add(node.element); |
+ } |
sra1
2015/12/11 17:13:08
Could there already be a GetStatic?
Is the pass id
asgerf
2015/12/14 17:05:39
There can't be any GetStatics unless the pass is r
|
+} |