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

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

Issue 17580016: Limit the amount of inlining we do to try to avoid generating too much code. (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 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 /** 7 /**
8 * A special element for the extra parameter taken by intercepted 8 * A special element for the extra parameter taken by intercepted
9 * methods. We need to override [Element.computeType] because our 9 * methods. We need to override [Element.computeType] because our
10 * optimizers may look at its declared type. 10 * optimizers may look at its declared type.
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
46 } else if (kind == ElementKind.FIELD) { 46 } else if (kind == ElementKind.FIELD) {
47 assert(!element.isInstanceMember()); 47 assert(!element.isInstanceMember());
48 graph = builder.buildLazyInitializer(element); 48 graph = builder.buildLazyInitializer(element);
49 } else { 49 } else {
50 compiler.internalErrorOnElement(element, 50 compiler.internalErrorOnElement(element,
51 'unexpected element kind $kind'); 51 'unexpected element kind $kind');
52 } 52 }
53 assert(graph.isValid()); 53 assert(graph.isValid());
54 if (!identical(kind, ElementKind.FIELD)) { 54 if (!identical(kind, ElementKind.FIELD)) {
55 FunctionElement function = element; 55 FunctionElement function = element;
56 graph.calledInLoop = compiler.world.isCalledInLoop(function);
57 FunctionSignature signature = function.computeSignature(compiler); 56 FunctionSignature signature = function.computeSignature(compiler);
58 signature.forEachOptionalParameter((Element parameter) { 57 signature.forEachOptionalParameter((Element parameter) {
59 // This ensures the default value will be computed. 58 // This ensures the default value will be computed.
60 builder.compileVariable(parameter); 59 builder.compileVariable(parameter);
61 }); 60 });
62 } 61 }
63 62
64 if (compiler.tracer.enabled) { 63 if (compiler.tracer.enabled) {
65 String name; 64 String name;
66 if (element.isMember()) { 65 if (element.isMember()) {
(...skipping 858 matching lines...) Expand 10 before | Expand all | Expand 10 after
925 parameters = new Map<Element, HInstruction>(), 924 parameters = new Map<Element, HInstruction>(),
926 sourceElementStack = <Element>[work.element], 925 sourceElementStack = <Element>[work.element],
927 inliningStack = <InliningState>[], 926 inliningStack = <InliningState>[],
928 rti = builder.backend.rti, 927 rti = builder.backend.rti,
929 super(work.resolutionTree) { 928 super(work.resolutionTree) {
930 localsHandler = new LocalsHandler(this); 929 localsHandler = new LocalsHandler(this);
931 } 930 }
932 931
933 static const MAX_INLINING_DEPTH = 3; 932 static const MAX_INLINING_DEPTH = 3;
934 static const MAX_INLINING_NODES = 46; 933 static const MAX_INLINING_NODES = 46;
934
935 List<InliningState> inliningStack; 935 List<InliningState> inliningStack;
936
936 Element returnElement; 937 Element returnElement;
937 DartType returnType; 938 DartType returnType;
939
938 bool inTryStatement = false; 940 bool inTryStatement = false;
941 int loopNesting = 0;
939 942
940 HBasicBlock get current => _current; 943 HBasicBlock get current => _current;
941 void set current(c) { 944 void set current(c) {
942 isReachable = c != null; 945 isReachable = c != null;
943 _current = c; 946 _current = c;
944 } 947 }
945 948
946 /** 949 /**
947 * Compiles compile-time constants. Never returns [:null:]. If the 950 * Compiles compile-time constants. Never returns [:null:]. If the
948 * initial value is not a compile-time constants, it reports an 951 * initial value is not a compile-time constants, it reports an
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
995 }); 998 });
996 } 999 }
997 1000
998 /** 1001 /**
999 * Documentation wanted -- johnniwinther 1002 * Documentation wanted -- johnniwinther
1000 * 1003 *
1001 * Invariant: [functionElement] must be an implementation element. 1004 * Invariant: [functionElement] must be an implementation element.
1002 */ 1005 */
1003 HGraph buildMethod(FunctionElement functionElement) { 1006 HGraph buildMethod(FunctionElement functionElement) {
1004 assert(invariant(functionElement, functionElement.isImplementation)); 1007 assert(invariant(functionElement, functionElement.isImplementation));
1008 graph.calledInLoop = compiler.world.isCalledInLoop(functionElement);
1005 FunctionExpression function = functionElement.parseNode(compiler); 1009 FunctionExpression function = functionElement.parseNode(compiler);
1006 assert(function != null); 1010 assert(function != null);
1007 assert(!function.modifiers.isExternal()); 1011 assert(!function.modifiers.isExternal());
1008 assert(elements[function] != null); 1012 assert(elements[function] != null);
1009 openFunction(functionElement, function); 1013 openFunction(functionElement, function);
1010 SourceString name = functionElement.name; 1014 SourceString name = functionElement.name;
1011 // If [functionElement] is `operator==` we explicitely add a null check at 1015 // If [functionElement] is `operator==` we explicitely add a null check at
1012 // the beginning of the method. This is to avoid having call sites do the 1016 // the beginning of the method. This is to avoid having call sites do the
1013 // null check. 1017 // null check.
1014 if (name == const SourceString('==')) { 1018 if (name == const SourceString('==')) {
(...skipping 200 matching lines...) Expand 10 before | Expand all | Expand 10 after
1215 Selector selector, 1219 Selector selector,
1216 List<HInstruction> providedArguments, 1220 List<HInstruction> providedArguments,
1217 Node currentNode) { 1221 Node currentNode) {
1218 backend.registerStaticUse(element, compiler.enqueuer.codegen); 1222 backend.registerStaticUse(element, compiler.enqueuer.codegen);
1219 // We cannot inline a method from a deferred library into a method 1223 // We cannot inline a method from a deferred library into a method
1220 // which isn't deferred. 1224 // which isn't deferred.
1221 // TODO(ahe): But we should still inline into the same 1225 // TODO(ahe): But we should still inline into the same
1222 // connected-component of the deferred library. 1226 // connected-component of the deferred library.
1223 if (compiler.deferredLoadTask.isDeferred(element)) return false; 1227 if (compiler.deferredLoadTask.isDeferred(element)) return false;
1224 if (compiler.disableInlining) return false; 1228 if (compiler.disableInlining) return false;
1225 if (inliningStack.length > MAX_INLINING_DEPTH) return false; 1229
1230 if (loopNesting == 0 && !graph.calledInLoop) return false;
1231 int maxDepth = (loopNesting > 0) ? MAX_INLINING_DEPTH : 1;
1232 if (inliningStack.length >= maxDepth) return false;
1226 1233
1227 // Ensure that [element] is an implementation element. 1234 // Ensure that [element] is an implementation element.
1228 element = element.implementation; 1235 element = element.implementation;
1229 FunctionElement function = element; 1236 FunctionElement function = element;
1230 bool canBeInlined = backend.canBeInlined[function]; 1237 bool canBeInlined = backend.canBeInlined[function];
1231 if (canBeInlined == false) return false; 1238 if (canBeInlined == false) return false;
1232 assert(selector != null 1239 assert(selector != null
1233 || Elements.isStaticOrTopLevel(element) 1240 || Elements.isStaticOrTopLevel(element)
1234 || element.isGenerativeConstructorBody()); 1241 || element.isGenerativeConstructorBody());
1235 if (selector != null && !selector.applies(function, compiler)) return false; 1242 if (selector != null && !selector.applies(function, compiler)) return false;
(...skipping 856 matching lines...) Expand 10 before | Expand all | Expand 10 after
2092 HBasicBlock startBlock; 2099 HBasicBlock startBlock;
2093 if (initialize != null) { 2100 if (initialize != null) {
2094 HBasicBlock initializerBlock = openNewBlock(); 2101 HBasicBlock initializerBlock = openNewBlock();
2095 startBlock = initializerBlock; 2102 startBlock = initializerBlock;
2096 initialize(); 2103 initialize();
2097 assert(!isAborted()); 2104 assert(!isAborted());
2098 initializerGraph = 2105 initializerGraph =
2099 new SubExpression(initializerBlock, current); 2106 new SubExpression(initializerBlock, current);
2100 } 2107 }
2101 2108
2109 loopNesting++;
2102 JumpHandler jumpHandler = beginLoopHeader(loop); 2110 JumpHandler jumpHandler = beginLoopHeader(loop);
2103 HLoopInformation loopInfo = current.loopInformation; 2111 HLoopInformation loopInfo = current.loopInformation;
2104 HBasicBlock conditionBlock = current; 2112 HBasicBlock conditionBlock = current;
2105 if (startBlock == null) startBlock = conditionBlock; 2113 if (startBlock == null) startBlock = conditionBlock;
2106 2114
2107 HInstruction conditionInstruction = condition(); 2115 HInstruction conditionInstruction = condition();
2108 HBasicBlock conditionExitBlock = 2116 HBasicBlock conditionExitBlock =
2109 close(new HLoopBranch(conditionInstruction)); 2117 close(new HLoopBranch(conditionInstruction));
2110 SubExpression conditionExpression = 2118 SubExpression conditionExpression =
2111 new SubExpression(conditionBlock, conditionExitBlock); 2119 new SubExpression(conditionBlock, conditionExitBlock);
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after
2251 conditionBlock.setBlockFlow(labelInfo, current); 2259 conditionBlock.setBlockFlow(labelInfo, current);
2252 2260
2253 jumpHandler.forEachBreak((HBreak breakInstruction, _) { 2261 jumpHandler.forEachBreak((HBreak breakInstruction, _) {
2254 HBasicBlock block = breakInstruction.block; 2262 HBasicBlock block = breakInstruction.block;
2255 block.addAtExit(new HBreak.toLabel(label)); 2263 block.addAtExit(new HBreak.toLabel(label));
2256 block.remove(breakInstruction); 2264 block.remove(breakInstruction);
2257 }); 2265 });
2258 } 2266 }
2259 } 2267 }
2260 jumpHandler.close(); 2268 jumpHandler.close();
2269 loopNesting--;
2261 } 2270 }
2262 2271
2263 visitFor(For node) { 2272 visitFor(For node) {
2264 assert(isReachable); 2273 assert(isReachable);
2265 assert(node.body != null); 2274 assert(node.body != null);
2266 void buildInitializer() { 2275 void buildInitializer() {
2267 if (node.initializer == null) return; 2276 if (node.initializer == null) return;
2268 Node initializer = node.initializer; 2277 Node initializer = node.initializer;
2269 if (initializer != null) { 2278 if (initializer != null) {
2270 visit(initializer); 2279 visit(initializer);
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
2305 () {}, 2314 () {},
2306 buildCondition, 2315 buildCondition,
2307 () {}, 2316 () {},
2308 () { visit(node.body); }); 2317 () { visit(node.body); });
2309 } 2318 }
2310 2319
2311 visitDoWhile(DoWhile node) { 2320 visitDoWhile(DoWhile node) {
2312 assert(isReachable); 2321 assert(isReachable);
2313 LocalsHandler savedLocals = new LocalsHandler.from(localsHandler); 2322 LocalsHandler savedLocals = new LocalsHandler.from(localsHandler);
2314 localsHandler.startLoop(node); 2323 localsHandler.startLoop(node);
2324 loopNesting++;
2315 JumpHandler jumpHandler = beginLoopHeader(node); 2325 JumpHandler jumpHandler = beginLoopHeader(node);
2316 HLoopInformation loopInfo = current.loopInformation; 2326 HLoopInformation loopInfo = current.loopInformation;
2317 HBasicBlock loopEntryBlock = current; 2327 HBasicBlock loopEntryBlock = current;
2318 HBasicBlock bodyEntryBlock = current; 2328 HBasicBlock bodyEntryBlock = current;
2319 TargetElement target = elements[node]; 2329 TargetElement target = elements[node];
2320 bool hasContinues = target != null && target.isContinueTarget; 2330 bool hasContinues = target != null && target.isContinueTarget;
2321 if (hasContinues) { 2331 if (hasContinues) {
2322 // Add extra block to hang labels on. 2332 // Add extra block to hang labels on.
2323 // It doesn't currently work if they are on the same block as the 2333 // It doesn't currently work if they are on the same block as the
2324 // HLoopInfo. The handling of HLabeledBlockInformation will visit a 2334 // HLoopInfo. The handling of HLabeledBlockInformation will visit a
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after
2430 new HSubGraphBlockInformation(bodyGraph), <LabelElement>[label]); 2440 new HSubGraphBlockInformation(bodyGraph), <LabelElement>[label]);
2431 loopEntryBlock.setBlockFlow(info, current); 2441 loopEntryBlock.setBlockFlow(info, current);
2432 jumpHandler.forEachBreak((HBreak breakInstruction, _) { 2442 jumpHandler.forEachBreak((HBreak breakInstruction, _) {
2433 HBasicBlock block = breakInstruction.block; 2443 HBasicBlock block = breakInstruction.block;
2434 block.addAtExit(new HBreak.toLabel(label)); 2444 block.addAtExit(new HBreak.toLabel(label));
2435 block.remove(breakInstruction); 2445 block.remove(breakInstruction);
2436 }); 2446 });
2437 } 2447 }
2438 } 2448 }
2439 jumpHandler.close(); 2449 jumpHandler.close();
2450 loopNesting--;
2440 } 2451 }
2441 2452
2442 visitFunctionExpression(FunctionExpression node) { 2453 visitFunctionExpression(FunctionExpression node) {
2443 ClosureClassMap nestedClosureData = 2454 ClosureClassMap nestedClosureData =
2444 compiler.closureToClassMapper.getMappingForNestedFunction(node); 2455 compiler.closureToClassMapper.getMappingForNestedFunction(node);
2445 assert(nestedClosureData != null); 2456 assert(nestedClosureData != null);
2446 assert(nestedClosureData.closureClassElement != null); 2457 assert(nestedClosureData.closureClassElement != null);
2447 ClassElement closureClassElement = 2458 ClassElement closureClassElement =
2448 nestedClosureData.closureClassElement; 2459 nestedClosureData.closureClassElement;
2449 FunctionElement callElement = nestedClosureData.callElement; 2460 FunctionElement callElement = nestedClosureData.callElement;
(...skipping 3065 matching lines...) Expand 10 before | Expand all | Expand 10 after
5515 new HSubGraphBlockInformation(elseBranch.graph)); 5526 new HSubGraphBlockInformation(elseBranch.graph));
5516 5527
5517 HBasicBlock conditionStartBlock = conditionBranch.block; 5528 HBasicBlock conditionStartBlock = conditionBranch.block;
5518 conditionStartBlock.setBlockFlow(info, joinBlock); 5529 conditionStartBlock.setBlockFlow(info, joinBlock);
5519 SubGraph conditionGraph = conditionBranch.graph; 5530 SubGraph conditionGraph = conditionBranch.graph;
5520 HIf branch = conditionGraph.end.last; 5531 HIf branch = conditionGraph.end.last;
5521 assert(branch is HIf); 5532 assert(branch is HIf);
5522 branch.blockInformation = conditionStartBlock.blockFlow; 5533 branch.blockInformation = conditionStartBlock.blockFlow;
5523 } 5534 }
5524 } 5535 }
OLDNEW
« no previous file with comments | « sdk/lib/_internal/compiler/implementation/enqueue.dart ('k') | sdk/lib/_internal/compiler/implementation/ssa/codegen.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698