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

Side by Side Diff: pkg/compiler/lib/src/ssa/builder.dart

Issue 912223003: Support @NoInlining in the ssa-builder. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Update old test with new name. Created 5 years, 10 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 class SsaFunctionCompiler implements FunctionCompiler { 7 class SsaFunctionCompiler implements FunctionCompiler {
8 SsaCodeGeneratorTask generator; 8 SsaCodeGeneratorTask generator;
9 SsaBuilderTask builder; 9 SsaBuilderTask builder;
10 SsaOptimizerTask optimizer; 10 SsaOptimizerTask optimizer;
(...skipping 1319 matching lines...) Expand 10 before | Expand all | Expand 10 after
1330 } 1330 }
1331 } 1331 }
1332 1332
1333 return true; 1333 return true;
1334 } 1334 }
1335 1335
1336 bool reductiveHeuristic() { 1336 bool reductiveHeuristic() {
1337 // The call is on a path which is executed rarely, so inline only if it 1337 // The call is on a path which is executed rarely, so inline only if it
1338 // does not make the program larger. 1338 // does not make the program larger.
1339 if (isCalledOnce(element)) { 1339 if (isCalledOnce(element)) {
1340 return InlineWeeder.canBeInlined(function.node, -1, false); 1340 return InlineWeeder.canBeInlined(function, -1, false);
1341 } 1341 }
1342 // TODO(sra): Measure if inlining would 'reduce' the size. One desirable 1342 // TODO(sra): Measure if inlining would 'reduce' the size. One desirable
1343 // case we miss my doing nothing is inlining very simple constructors 1343 // case we miss my doing nothing is inlining very simple constructors
1344 // where all fields are initialized with values from the arguments at this 1344 // where all fields are initialized with values from the arguments at this
1345 // call site. The code is slightly larger (`new Foo(1)` vs `Foo$(1)`) but 1345 // call site. The code is slightly larger (`new Foo(1)` vs `Foo$(1)`) but
1346 // that usually means the factory constructor is left unused and not 1346 // that usually means the factory constructor is left unused and not
1347 // emitted. 1347 // emitted.
1348 return false; 1348 return false;
1349 } 1349 }
1350 1350
1351 bool heuristicSayGoodToGo() { 1351 bool heuristicSayGoodToGo() {
1352 // Don't inline recursively 1352 // Don't inline recursively
1353 if (inliningStack.any((entry) => entry.function == function)) { 1353 if (inliningStack.any((entry) => entry.function == function)) {
1354 return false; 1354 return false;
1355 } 1355 }
1356 1356
1357 if (element.isSynthesized) return true; 1357 if (element.isSynthesized) return true;
1358 1358
1359 if (inExpressionOfThrow || inLazyInitializerExpression) { 1359 if (inExpressionOfThrow || inLazyInitializerExpression) {
1360 return reductiveHeuristic(); 1360 return reductiveHeuristic();
1361 } 1361 }
1362 1362
1363 if (cachedCanBeInlined == true) return cachedCanBeInlined; 1363 if (cachedCanBeInlined == true) return cachedCanBeInlined;
1364 1364
1365 if (backend.functionsToAlwaysInline.contains(function)) { 1365 if (backend.functionsToAlwaysInline.contains(function)) {
1366 // Inline this function regardless of it's size. 1366 // Inline this function regardless of it's size.
1367 assert(InlineWeeder.canBeInlined(function.node, -1, false, 1367 assert(InlineWeeder.canBeInlined(function, -1, false,
1368 allowLoops: true)); 1368 allowLoops: true));
1369 return true; 1369 return true;
1370 } 1370 }
1371 1371
1372 int numParameters = function.functionSignature.parameterCount; 1372 int numParameters = function.functionSignature.parameterCount;
1373 int maxInliningNodes; 1373 int maxInliningNodes;
1374 bool useMaxInliningNodes = true; 1374 bool useMaxInliningNodes = true;
1375 if (insideLoop) { 1375 if (insideLoop) {
1376 maxInliningNodes = InlineWeeder.INLINING_NODES_INSIDE_LOOP + 1376 maxInliningNodes = InlineWeeder.INLINING_NODES_INSIDE_LOOP +
1377 InlineWeeder.INLINING_NODES_INSIDE_LOOP_ARG_FACTOR * numParameters; 1377 InlineWeeder.INLINING_NODES_INSIDE_LOOP_ARG_FACTOR * numParameters;
1378 } else { 1378 } else {
1379 maxInliningNodes = InlineWeeder.INLINING_NODES_OUTSIDE_LOOP + 1379 maxInliningNodes = InlineWeeder.INLINING_NODES_OUTSIDE_LOOP +
1380 InlineWeeder.INLINING_NODES_OUTSIDE_LOOP_ARG_FACTOR * numParameters; 1380 InlineWeeder.INLINING_NODES_OUTSIDE_LOOP_ARG_FACTOR * numParameters;
1381 } 1381 }
1382 1382
1383 // If a method is called only once, and all the methods in the 1383 // If a method is called only once, and all the methods in the
1384 // inlining stack are called only once as well, we know we will 1384 // inlining stack are called only once as well, we know we will
1385 // save on output size by inlining this method. 1385 // save on output size by inlining this method.
1386 if (isCalledOnce(element)) { 1386 if (isCalledOnce(element)) {
1387 useMaxInliningNodes = false; 1387 useMaxInliningNodes = false;
1388 } 1388 }
1389 bool canInline; 1389 bool canInline;
1390 ast.FunctionExpression functionNode = function.node;
1391 canInline = InlineWeeder.canBeInlined( 1390 canInline = InlineWeeder.canBeInlined(
1392 functionNode, maxInliningNodes, useMaxInliningNodes); 1391 function, maxInliningNodes, useMaxInliningNodes);
1393 if (canInline) { 1392 if (canInline) {
1394 backend.inlineCache.markAsInlinable(element, insideLoop: insideLoop); 1393 backend.inlineCache.markAsInlinable(element, insideLoop: insideLoop);
1395 } else { 1394 } else {
1396 backend.inlineCache.markAsNonInlinable(element, insideLoop: insideLoop); 1395 backend.inlineCache.markAsNonInlinable(element, insideLoop: insideLoop);
1397 } 1396 }
1398 return canInline; 1397 return canInline;
1399 } 1398 }
1400 1399
1401 void doInlining() { 1400 void doInlining() {
1402 // Add an explicit null check on the receiver before doing the 1401 // Add an explicit null check on the receiver before doing the
(...skipping 5041 matching lines...) Expand 10 before | Expand all | Expand 10 after
6444 bool tooDifficult = false; 6443 bool tooDifficult = false;
6445 int nodeCount = 0; 6444 int nodeCount = 0;
6446 final int maxInliningNodes; 6445 final int maxInliningNodes;
6447 final bool useMaxInliningNodes; 6446 final bool useMaxInliningNodes;
6448 final bool allowLoops; 6447 final bool allowLoops;
6449 6448
6450 InlineWeeder(this.maxInliningNodes, 6449 InlineWeeder(this.maxInliningNodes,
6451 this.useMaxInliningNodes, 6450 this.useMaxInliningNodes,
6452 this.allowLoops); 6451 this.allowLoops);
6453 6452
6454 static bool canBeInlined(ast.FunctionExpression functionExpression, 6453 static bool canBeInlined(FunctionElement function,
6455 int maxInliningNodes, 6454 int maxInliningNodes,
6456 bool useMaxInliningNodes, 6455 bool useMaxInliningNodes,
6457 {bool allowLoops: false}) { 6456 {bool allowLoops: false}) {
6458 InlineWeeder weeder = 6457 InlineWeeder weeder =
6459 new InlineWeeder(maxInliningNodes, useMaxInliningNodes, allowLoops); 6458 new InlineWeeder(maxInliningNodes, useMaxInliningNodes, allowLoops);
6459 ast.FunctionExpression functionExpression = function.node;
6460 weeder.visit(functionExpression.initializers); 6460 weeder.visit(functionExpression.initializers);
6461 weeder.visit(functionExpression.body); 6461 weeder.visit(functionExpression.body);
6462 weeder.visit(functionExpression.asyncModifier); 6462 weeder.visit(functionExpression.asyncModifier);
6463 return !weeder.tooDifficult; 6463 return !weeder.tooDifficult;
6464 } 6464 }
6465 6465
6466 bool registerNode() { 6466 bool registerNode() {
6467 if (!useMaxInliningNodes) return true; 6467 if (!useMaxInliningNodes) return true;
6468 if (nodeCount++ > maxInliningNodes) { 6468 if (nodeCount++ > maxInliningNodes) {
6469 tooDifficult = true; 6469 tooDifficult = true;
(...skipping 445 matching lines...) Expand 10 before | Expand all | Expand 10 after
6915 if (unaliased is TypedefType) throw 'unable to unalias $type'; 6915 if (unaliased is TypedefType) throw 'unable to unalias $type';
6916 unaliased.accept(this, builder); 6916 unaliased.accept(this, builder);
6917 } 6917 }
6918 6918
6919 void visitDynamicType(DynamicType type, SsaBuilder builder) { 6919 void visitDynamicType(DynamicType type, SsaBuilder builder) {
6920 JavaScriptBackend backend = builder.compiler.backend; 6920 JavaScriptBackend backend = builder.compiler.backend;
6921 ClassElement cls = backend.findHelper('DynamicRuntimeType'); 6921 ClassElement cls = backend.findHelper('DynamicRuntimeType');
6922 builder.push(new HDynamicType(type, new TypeMask.exact(cls, classWorld))); 6922 builder.push(new HDynamicType(type, new TypeMask.exact(cls, classWorld)));
6923 } 6923 }
6924 } 6924 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698