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

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

Issue 1319303002: dart2js cps: Scalar replacement of aggregates (Closed) Base URL: https://github.com/dart-lang/sdk.git@master
Patch Set: Created 5 years, 4 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
Index: pkg/compiler/lib/src/cps_ir/type_propagation.dart
diff --git a/pkg/compiler/lib/src/cps_ir/type_propagation.dart b/pkg/compiler/lib/src/cps_ir/type_propagation.dart
index 2e2da582d2a10fcb850cac6e2716f41d6258305f..3fed74f20d2da26fde512c1d26b5e69968aba7c9 100644
--- a/pkg/compiler/lib/src/cps_ir/type_propagation.dart
+++ b/pkg/compiler/lib/src/cps_ir/type_propagation.dart
@@ -4,8 +4,10 @@
import 'optimizers.dart';
+import '../closure.dart' show
+ ClosureClassElement, Identifiers;
import '../common/names.dart' show
- Selectors;
+ Selectors, Identifiers;
import '../compiler.dart' as dart2js show
Compiler;
import '../constants/constant_system.dart';
@@ -27,6 +29,7 @@ import '../universe/universe.dart';
import '../world.dart' show World;
import 'cps_fragment.dart';
import 'cps_ir_nodes.dart';
+import 'cps_ir_nodes_sexpr.dart' show SExpressionStringifier;
enum AbstractBool {
True, False, Maybe, Nothing
@@ -1574,6 +1577,60 @@ class TransformingVisitor extends LeafVisitor {
return false;
}
+ /// Inlines a single-use closure if it leaves the closure object with only
+ /// field accesses. This is optimized later by [ScalarReplacer].
+ bool specializeSingleUseClosureCall(InvokeMethod node) {
+ Selector call = node.selector;
+ if (!call.isClosureCall) return false;
+
+ assert(!isInterceptedSelector(call));
+ assert(call.argumentCount == node.arguments.length);
+
+ Primitive receiver = node.receiver.definition;
+ if (receiver is !CreateInstance) return false;
+ if (!receiver.hasExactlyOneUse) return false;
+
+ ClosureClassElement closureClassElement = receiver.classElement;
+ Element element = closureClassElement.localLookup(Identifiers.call);
+
+ if (element == null || !element.isFunction) return false;
+ FunctionElement functionElement = element;
+
+ if (!call.signatureApplies(functionElement)) return false;
+ // Inline only for exact match.
+ // TODO(sra): Handle call with defaulted arguments.
+ Selector targetSelector = new Selector.fromElement(functionElement);
+ if (call.callStructure != targetSelector.callStructure) return false;
+
+ FunctionDefinition target =
+ functionCompiler.compileToCpsIR(functionElement);
+
+ // Accesses to closed-over values are field access primitives. We we don't
+ // inline if there are other uses of 'this' since that could be an escape or
+ // a recursive call.
+ for (Reference ref = target.thisParameter.firstRef;
+ ref != null;
+ ref = ref.next) {
+ Node use = ref.parent;
+ if (use is GetField) continue;
+ if (use is SetField && ref == use.object) continue;
+ return false;
+ }
+
+ // Don't inline if [target] contains try-catch or try-finally.
+ if (ContainsTry.analyze(target)) return false;
+
+ node.receiver.definition.substituteFor(target.thisParameter);
+ for (int i = 0; i < node.arguments.length; ++i) {
+ node.arguments[i].definition.substituteFor(target.parameters[i]);
+ }
+ node.continuation.definition.substituteFor(target.returnContinuation);
+
+ replaceSubtree(node, target.body);
+ push(target.body);
+ return true;
+ }
+
/// Side-effect free expressions with constant results are be replaced by:
///
/// (LetPrim p = constant (InvokeContinuation k p)).
@@ -1598,6 +1655,7 @@ class TransformingVisitor extends LeafVisitor {
if (specializeFieldAccess(node)) return;
if (specializeIndexableAccess(node)) return;
if (specializeArrayAccess(node)) return;
+ if (specializeSingleUseClosureCall(node)) return;
if (specializeClosureCall(node)) return;
AbstractValue receiver = getValue(node.receiver.definition);
@@ -2751,3 +2809,25 @@ class ResetAnalysisInfo extends RecursiveVisitor {
values.remove(node.variable);
}
}
+
+
+class ContainsTry extends RecursiveVisitor {
+ bool _found = false;
+ ContainsTry._();
+
+ /// Scans [root] for evidence of try-catch and try-finally.
+ static bool analyze(Node root) {
+ ContainsTry visitor = new ContainsTry._();
+ visitor.visit(root);
+ return visitor._found;
+ }
+
+ visit(Node node) {
+ if (_found) return; // Early exit if we know the answer.
+ super.visit(node);
+ }
+
+ processLetHandler(LetHandler node) {
+ _found = true;
+ }
+}

Powered by Google App Engine
This is Rietveld 408576698