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 06ebf8962cfea79447a88d956b8996545239366c..8565a0f75c465ebbe352ab7570e32f332f3b07dd 100644 |
--- a/sdk/lib/_internal/compiler/implementation/ssa/builder.dart |
+++ b/sdk/lib/_internal/compiler/implementation/ssa/builder.dart |
@@ -1254,6 +1254,13 @@ class SsaBuilder extends ResolvedVisitor { |
if (cachedCanBeInlined == true) return cachedCanBeInlined; |
+ if (backend.functionsToAlwaysInline.contains(function)) { |
+ // Inline this function regardless of it's size. |
+ assert(InlineWeeder.canBeInlined(function.node, -1, false, |
+ allowLoops: true)); |
+ return true; |
+ } |
+ |
int numParameters = function.functionSignature.parameterCount; |
int maxInliningNodes; |
bool useMaxInliningNodes = true; |
@@ -5994,6 +6001,9 @@ class StringBuilderVisitor extends ast.Visitor { |
* This class visits the method that is a candidate for inlining and |
* finds whether it is too difficult to inline. |
*/ |
+// TODO(karlklose): refactor to make it possible to distinguish between |
+// implementation restrictions (for example, we *can't* inline multiple returns) |
+// and heuristics (we *shouldn't* inline large functions). |
class InlineWeeder extends ast.Visitor { |
// Invariant: *INSIDE_LOOP* > *OUTSIDE_LOOP* |
static const INLINING_NODES_OUTSIDE_LOOP = 18; |
@@ -6006,14 +6016,18 @@ class InlineWeeder extends ast.Visitor { |
int nodeCount = 0; |
final int maxInliningNodes; |
final bool useMaxInliningNodes; |
+ final bool allowLoops; |
- InlineWeeder(this.maxInliningNodes, this.useMaxInliningNodes); |
+ InlineWeeder(this.maxInliningNodes, |
+ this.useMaxInliningNodes, |
+ this.allowLoops); |
static bool canBeInlined(ast.FunctionExpression functionExpression, |
int maxInliningNodes, |
- bool useMaxInliningNodes) { |
+ bool useMaxInliningNodes, |
+ {bool allowLoops: false}) { |
InlineWeeder weeder = |
- new InlineWeeder(maxInliningNodes, useMaxInliningNodes); |
+ new InlineWeeder(maxInliningNodes, useMaxInliningNodes, allowLoops); |
weeder.visit(functionExpression.initializers); |
weeder.visit(functionExpression.body); |
return !weeder.tooDifficult; |
@@ -6061,7 +6075,7 @@ class InlineWeeder extends ast.Visitor { |
// It's actually not difficult to inline a method with a loop, but |
// our measurements show that it's currently better to not inline a |
// method that contains a loop. |
- tooDifficult = true; |
+ if (!allowLoops) tooDifficult = true; |
} |
void visitRedirectingFactoryBody(ast.RedirectingFactoryBody node) { |