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

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

Issue 1525163002: dart2js cps: Use oneshot interceptors and 'instanceof' expressions. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Merge Created 5 years 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 | « pkg/compiler/lib/src/cps_ir/cps_ir_nodes.dart ('k') | pkg/compiler/lib/src/js_backend/codegen/codegen.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: pkg/compiler/lib/src/cps_ir/optimize_interceptors.dart
diff --git a/pkg/compiler/lib/src/cps_ir/optimize_interceptors.dart b/pkg/compiler/lib/src/cps_ir/optimize_interceptors.dart
index 1e9d702b2fde03c69223f085621ae93657bc168c..9f05e390f6f6ca038def6a44ce5ebaf3c481c099 100644
--- a/pkg/compiler/lib/src/cps_ir/optimize_interceptors.dart
+++ b/pkg/compiler/lib/src/cps_ir/optimize_interceptors.dart
@@ -14,6 +14,7 @@ import '../js_backend/backend_helpers.dart' show BackendHelpers;
import '../js_backend/js_backend.dart' show JavaScriptBackend;
import '../types/types.dart' show TypeMask;
import '../io/source_information.dart' show SourceInformation;
+import '../universe/selector.dart';
/// Replaces `getInterceptor` calls with interceptor constants when possible,
/// or with "almost constant" expressions like "x && CONST" when the input
@@ -31,6 +32,8 @@ class OptimizeInterceptors extends TrampolineRecursiveVisitor implements Pass {
BackendHelpers get helpers => backend.helpers;
+ Map<Interceptor, Continuation> loopHeaderFor = <Interceptor, Continuation>{};
+
void rewrite(FunctionDefinition node) {
// TODO(asgerf): Computing the LoopHierarchy here may be overkill when all
// we want is to hoist constants out of loops.
@@ -101,11 +104,11 @@ class OptimizeInterceptors extends TrampolineRecursiveVisitor implements Pass {
return prim;
}
- void constifyInterceptor(Interceptor interceptor) {
+ bool constifyInterceptor(Interceptor interceptor) {
LetPrim let = interceptor.parent;
InterceptorConstantValue constant = getInterceptorConstant(interceptor);
- if (constant == null) return;
+ if (constant == null) return false;
if (interceptor.isAlwaysIntercepted) {
Primitive constantPrim = makeConstantFor(constant,
@@ -141,16 +144,54 @@ class OptimizeInterceptors extends TrampolineRecursiveVisitor implements Pass {
interceptor..replaceUsesWith(param)..destroy();
let.remove();
}
+ return true;
}
@override
Expression traverseLetPrim(LetPrim node) {
Expression next = node.body;
- if (node.primitive is Interceptor) {
- constifyInterceptor(node.primitive);
- }
+ visit(node.primitive);
return next;
}
+
+ @override
+ void visitInterceptor(Interceptor node) {
+ if (constifyInterceptor(node)) return;
+ if (node.hasExactlyOneUse) {
+ // Set the loop header on single-use interceptors so [visitInvokeMethod]
+ // can determine if it should become a one-shot interceptor.
+ loopHeaderFor[node] = currentLoopHeader;
+ }
+ }
+
+ @override
+ void visitInvokeMethod(InvokeMethod node) {
+ if (node.callingConvention != CallingConvention.Intercepted) return;
+ Primitive interceptor = node.receiver.definition;
+ if (interceptor is! Interceptor ||
+ interceptor.hasMultipleUses ||
+ loopHeaderFor[interceptor] != currentLoopHeader) {
+ return;
+ }
+ // TODO(asgerf): Consider heuristics for when to use one-shot interceptors.
+ // E.g. using only one-shot interceptors with a fast path.
+ node.callingConvention = CallingConvention.OneShotIntercepted;
+ node..receiver.unlink()..receiver = node.arguments.removeAt(0);
+ }
+
+ @override
+ void visitTypeTestViaFlag(TypeTestViaFlag node) {
+ Primitive interceptor = node.interceptor.definition;
+ if (interceptor is! Interceptor ||
+ interceptor.hasMultipleUses ||
+ loopHeaderFor[interceptor] != currentLoopHeader ||
+ !backend.mayGenerateInstanceofCheck(node.dartType)) {
+ return;
+ }
+ Interceptor inter = interceptor;
+ Primitive value = inter.input.definition;
+ node.replaceWith(new TypeTest(value, node.dartType, [])..type = node.type);
+ }
}
/// Shares interceptor constants when one is in scope of another.
« no previous file with comments | « pkg/compiler/lib/src/cps_ir/cps_ir_nodes.dart ('k') | pkg/compiler/lib/src/js_backend/codegen/codegen.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698