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

Side by Side Diff: sdk/lib/_internal/compiler/implementation/ssa/builder.dart

Issue 543583002: Add a whitelist for functions that we always want to inline. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years, 3 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 part of ssa; 5 part of ssa;
6 6
7 /// A synthetic local variable only used with the SSA graph. 7 /// A synthetic local variable only used with the SSA graph.
8 /// 8 ///
9 /// For instance used for holding return value of function or the exception of a 9 /// For instance used for holding return value of function or the exception of a
10 /// try-catch statement. 10 /// try-catch statement.
(...skipping 1236 matching lines...) Expand 10 before | Expand all | Expand 10 after
1247 if (inliningStack.any((entry) => entry.function == function)) { 1247 if (inliningStack.any((entry) => entry.function == function)) {
1248 return false; 1248 return false;
1249 } 1249 }
1250 1250
1251 if (inExpressionOfThrow) return false; 1251 if (inExpressionOfThrow) return false;
1252 1252
1253 if (element.isSynthesized) return true; 1253 if (element.isSynthesized) return true;
1254 1254
1255 if (cachedCanBeInlined == true) return cachedCanBeInlined; 1255 if (cachedCanBeInlined == true) return cachedCanBeInlined;
1256 1256
1257 if (backend.functionsToAlwaysInline.contains(function)) {
1258 // Inline this function regardless of it's size.
1259 assert(InlineWeeder.canBeInlined(function.node, -1, false,
1260 allowLoops: true));
1261 return true;
1262 }
1263
1257 int numParameters = function.functionSignature.parameterCount; 1264 int numParameters = function.functionSignature.parameterCount;
1258 int maxInliningNodes; 1265 int maxInliningNodes;
1259 bool useMaxInliningNodes = true; 1266 bool useMaxInliningNodes = true;
1260 if (insideLoop) { 1267 if (insideLoop) {
1261 maxInliningNodes = InlineWeeder.INLINING_NODES_INSIDE_LOOP + 1268 maxInliningNodes = InlineWeeder.INLINING_NODES_INSIDE_LOOP +
1262 InlineWeeder.INLINING_NODES_INSIDE_LOOP_ARG_FACTOR * numParameters; 1269 InlineWeeder.INLINING_NODES_INSIDE_LOOP_ARG_FACTOR * numParameters;
1263 } else { 1270 } else {
1264 maxInliningNodes = InlineWeeder.INLINING_NODES_OUTSIDE_LOOP + 1271 maxInliningNodes = InlineWeeder.INLINING_NODES_OUTSIDE_LOOP +
1265 InlineWeeder.INLINING_NODES_OUTSIDE_LOOP_ARG_FACTOR * numParameters; 1272 InlineWeeder.INLINING_NODES_OUTSIDE_LOOP_ARG_FACTOR * numParameters;
1266 } 1273 }
(...skipping 4720 matching lines...) Expand 10 before | Expand all | Expand 10 after
5987 new HStringify(expression, node, builder.backend.stringType); 5994 new HStringify(expression, node, builder.backend.stringType);
5988 builder.add(instruction); 5995 builder.add(instruction);
5989 return instruction; 5996 return instruction;
5990 } 5997 }
5991 } 5998 }
5992 5999
5993 /** 6000 /**
5994 * This class visits the method that is a candidate for inlining and 6001 * This class visits the method that is a candidate for inlining and
5995 * finds whether it is too difficult to inline. 6002 * finds whether it is too difficult to inline.
5996 */ 6003 */
6004 // TODO(karlklose): refactor to make it possible to distinguish between
6005 // implementation restrictions (for example, we *can't* inline multiple returns)
6006 // and heuristics (we *shouldn't* inline large functions).
5997 class InlineWeeder extends ast.Visitor { 6007 class InlineWeeder extends ast.Visitor {
5998 // Invariant: *INSIDE_LOOP* > *OUTSIDE_LOOP* 6008 // Invariant: *INSIDE_LOOP* > *OUTSIDE_LOOP*
5999 static const INLINING_NODES_OUTSIDE_LOOP = 18; 6009 static const INLINING_NODES_OUTSIDE_LOOP = 18;
6000 static const INLINING_NODES_OUTSIDE_LOOP_ARG_FACTOR = 3; 6010 static const INLINING_NODES_OUTSIDE_LOOP_ARG_FACTOR = 3;
6001 static const INLINING_NODES_INSIDE_LOOP = 42; 6011 static const INLINING_NODES_INSIDE_LOOP = 42;
6002 static const INLINING_NODES_INSIDE_LOOP_ARG_FACTOR = 4; 6012 static const INLINING_NODES_INSIDE_LOOP_ARG_FACTOR = 4;
6003 6013
6004 bool seenReturn = false; 6014 bool seenReturn = false;
6005 bool tooDifficult = false; 6015 bool tooDifficult = false;
6006 int nodeCount = 0; 6016 int nodeCount = 0;
6007 final int maxInliningNodes; 6017 final int maxInliningNodes;
6008 final bool useMaxInliningNodes; 6018 final bool useMaxInliningNodes;
6019 final bool allowLoops;
6009 6020
6010 InlineWeeder(this.maxInliningNodes, this.useMaxInliningNodes); 6021 InlineWeeder(this.maxInliningNodes,
6022 this.useMaxInliningNodes,
6023 this.allowLoops);
6011 6024
6012 static bool canBeInlined(ast.FunctionExpression functionExpression, 6025 static bool canBeInlined(ast.FunctionExpression functionExpression,
6013 int maxInliningNodes, 6026 int maxInliningNodes,
6014 bool useMaxInliningNodes) { 6027 bool useMaxInliningNodes,
6028 {bool allowLoops: false}) {
6015 InlineWeeder weeder = 6029 InlineWeeder weeder =
6016 new InlineWeeder(maxInliningNodes, useMaxInliningNodes); 6030 new InlineWeeder(maxInliningNodes, useMaxInliningNodes, allowLoops);
6017 weeder.visit(functionExpression.initializers); 6031 weeder.visit(functionExpression.initializers);
6018 weeder.visit(functionExpression.body); 6032 weeder.visit(functionExpression.body);
6019 return !weeder.tooDifficult; 6033 return !weeder.tooDifficult;
6020 } 6034 }
6021 6035
6022 bool registerNode() { 6036 bool registerNode() {
6023 if (!useMaxInliningNodes) return true; 6037 if (!useMaxInliningNodes) return true;
6024 if (nodeCount++ > maxInliningNodes) { 6038 if (nodeCount++ > maxInliningNodes) {
6025 tooDifficult = true; 6039 tooDifficult = true;
6026 return false; 6040 return false;
(...skipping 27 matching lines...) Expand all
6054 6068
6055 void visitSend(ast.Send node) { 6069 void visitSend(ast.Send node) {
6056 if (!registerNode()) return; 6070 if (!registerNode()) return;
6057 node.visitChildren(this); 6071 node.visitChildren(this);
6058 } 6072 }
6059 6073
6060 visitLoop(ast.Node node) { 6074 visitLoop(ast.Node node) {
6061 // It's actually not difficult to inline a method with a loop, but 6075 // It's actually not difficult to inline a method with a loop, but
6062 // our measurements show that it's currently better to not inline a 6076 // our measurements show that it's currently better to not inline a
6063 // method that contains a loop. 6077 // method that contains a loop.
6064 tooDifficult = true; 6078 if (!allowLoops) tooDifficult = true;
6065 } 6079 }
6066 6080
6067 void visitRedirectingFactoryBody(ast.RedirectingFactoryBody node) { 6081 void visitRedirectingFactoryBody(ast.RedirectingFactoryBody node) {
6068 if (!registerNode()) return; 6082 if (!registerNode()) return;
6069 tooDifficult = true; 6083 tooDifficult = true;
6070 } 6084 }
6071 6085
6072 void visitRethrow(ast.Rethrow node) { 6086 void visitRethrow(ast.Rethrow node) {
6073 if (!registerNode()) return; 6087 if (!registerNode()) return;
6074 tooDifficult = true; 6088 tooDifficult = true;
(...skipping 380 matching lines...) Expand 10 before | Expand all | Expand 10 after
6455 if (unaliased is TypedefType) throw 'unable to unalias $type'; 6469 if (unaliased is TypedefType) throw 'unable to unalias $type';
6456 unaliased.accept(this, builder); 6470 unaliased.accept(this, builder);
6457 } 6471 }
6458 6472
6459 void visitDynamicType(DynamicType type, SsaBuilder builder) { 6473 void visitDynamicType(DynamicType type, SsaBuilder builder) {
6460 JavaScriptBackend backend = builder.compiler.backend; 6474 JavaScriptBackend backend = builder.compiler.backend;
6461 ClassElement cls = backend.findHelper('DynamicRuntimeType'); 6475 ClassElement cls = backend.findHelper('DynamicRuntimeType');
6462 builder.push(new HDynamicType(type, new TypeMask.exact(cls))); 6476 builder.push(new HDynamicType(type, new TypeMask.exact(cls)));
6463 } 6477 }
6464 } 6478 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698