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

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

Issue 19250002: Support for inlining small methods (independent of they're called inside a loop or not) (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 7 years, 5 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
« no previous file with comments | « sdk/lib/_internal/compiler/implementation/js_backend/backend.dart ('k') | tests/co19/co19-dart2js.status » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: sdk/lib/_internal/compiler/implementation/ssa/builder.dart
diff --git a/sdk/lib/_internal/compiler/implementation/ssa/builder.dart b/sdk/lib/_internal/compiler/implementation/ssa/builder.dart
index 6ba92acfa136a5ef5cce0926dbb209887ac92d0e..195334d10cf4afff46228971514460a80115bc2d 100644
--- a/sdk/lib/_internal/compiler/implementation/ssa/builder.dart
+++ b/sdk/lib/_internal/compiler/implementation/ssa/builder.dart
@@ -929,9 +929,6 @@ class SsaBuilder extends ResolvedVisitor implements Visitor {
localsHandler = new LocalsHandler(this);
}
- static const MAX_INLINING_DEPTH = 3;
- static const MAX_INLINING_NODES = 46;
-
List<InliningState> inliningStack;
Element returnElement;
@@ -1225,7 +1222,12 @@ class SsaBuilder extends ResolvedVisitor implements Visitor {
element = element.implementation;
FunctionElement function = element;
- bool cachedCanBeInlined = backend.canBeInlined[function];
+ bool insideLoop = loopNesting > 0 || graph.calledInLoop;
+
+ // Bail out early if the inlining decision is in the cache and we can't
+ // inline (no need to check the hard constraints).
+ bool cachedCanBeInlined =
+ backend.inlineCache.canInline(function, insideLoop: insideLoop);
if (cachedCanBeInlined == false) return false;
bool meetsHardConstraints() {
@@ -1259,23 +1261,34 @@ class SsaBuilder extends ResolvedVisitor implements Visitor {
return false;
}
+ // Don't inline recursivly
ngeoffray 2013/07/16 17:17:37 As discussed, removing the inlining depth is a heu
kustermann 2013/07/17 09:46:42 Done.
+ if (inliningStack.any((entry) => entry.function == function)) {
+ return false;
+ }
+
return true;
}
- bool heuristicsSayGoodToGo(FunctionExpression functionExpression,
- TreeElements newElements) {
- if (loopNesting == 0 && !graph.calledInLoop) return false;
+ bool heuristicSayGoodToGo(FunctionExpression functionExpression) {
+ if (cachedCanBeInlined == true) return cachedCanBeInlined;
- int maxDepth = (loopNesting > 0) ? MAX_INLINING_DEPTH : 1;
- if (inliningStack.length >= maxDepth) return false;
-
- if (cachedCanBeInlined == null) {
- var canBeInlined =
- InlineWeeder.canBeInlined(functionExpression, newElements);
- backend.canBeInlined[function] = canBeInlined;
- return canBeInlined;
+ int numParameters = function.functionSignature.parameterCount;
+ int maxInliningNodes;
+ if (insideLoop) {
+ maxInliningNodes = InlineWeeder.INLINING_NODES_INSIDE_LOOP +
+ InlineWeeder.INLINING_NODES_INSIDE_LOOP_ARG_FACTOR * numParameters;
+ } else {
+ maxInliningNodes = InlineWeeder.INLINING_NODES_OUTSIDE_LOOP +
+ InlineWeeder.INLINING_NODES_OUTSIDE_LOOP_ARG_FACTOR * numParameters;
}
- return cachedCanBeInlined;
+ bool canBeInlined = InlineWeeder.canBeInlined(
+ functionExpression, maxInliningNodes);
+ if (canBeInlined) {
+ backend.inlineCache.markAsInlinable(element, insideLoop: insideLoop);
+ } else {
+ backend.inlineCache.markAsNonInlinable(element, insideLoop: insideLoop);
+ }
+ return canBeInlined;
}
void doInlining(FunctionExpression functionExpression) {
@@ -1307,13 +1320,8 @@ class SsaBuilder extends ResolvedVisitor implements Visitor {
if (meetsHardConstraints()) {
FunctionExpression functionExpression = function.parseNode(compiler);
- TreeElements newElements =
- compiler.enqueuer.resolution.getCachedElements(function);
- if (newElements == null) {
- compiler.internalError("Element not resolved: $function");
- }
- if (heuristicsSayGoodToGo(functionExpression, newElements)) {
+ if (heuristicSayGoodToGo(functionExpression)) {
doInlining(functionExpression);
return true;
}
@@ -5125,25 +5133,29 @@ class StringBuilderVisitor extends Visitor {
* finds whether it is too difficult to inline.
*/
class InlineWeeder extends Visitor {
- final TreeElements elements;
+ // Invariant: *INSIDE_LOOP* > *OUTSIDE_LOOP*
+ static const INLINING_NODES_OUTSIDE_LOOP = 18;
+ static const INLINING_NODES_OUTSIDE_LOOP_ARG_FACTOR = 3;
+ static const INLINING_NODES_INSIDE_LOOP = 42;
+ static const INLINING_NODES_INSIDE_LOOP_ARG_FACTOR = 4;
bool seenReturn = false;
bool tooDifficult = false;
int nodeCount = 0;
+ final int maxInliningNodes;
- InlineWeeder(this.elements);
+ InlineWeeder(this.maxInliningNodes);
static bool canBeInlined(FunctionExpression functionExpression,
- TreeElements elements) {
- InlineWeeder weeder = new InlineWeeder(elements);
+ int maxInliningNodes) {
+ InlineWeeder weeder = new InlineWeeder(maxInliningNodes);
weeder.visit(functionExpression.initializers);
weeder.visit(functionExpression.body);
- if (weeder.tooDifficult) return false;
- return true;
+ return !weeder.tooDifficult;
}
bool registerNode() {
- if (nodeCount++ > SsaBuilder.MAX_INLINING_NODES) {
+ if (nodeCount++ > maxInliningNodes) {
tooDifficult = true;
return false;
} else {
« no previous file with comments | « sdk/lib/_internal/compiler/implementation/js_backend/backend.dart ('k') | tests/co19/co19-dart2js.status » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698