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

Side by Side Diff: frog/leg/ssa/builder.dart

Issue 9632018: Switch-implementation. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Address review comments. Created 8 years, 9 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 class Interceptors { 5 class Interceptors {
6 Compiler compiler; 6 Compiler compiler;
7 Interceptors(Compiler this.compiler); 7 Interceptors(Compiler this.compiler);
8 8
9 SourceString mapOperatorToMethodName(Operator op) { 9 SourceString mapOperatorToMethodName(Operator op) {
10 String name = op.source.stringValue; 10 String name = op.source.stringValue;
(...skipping 602 matching lines...) Expand 10 before | Expand all | Expand 10 after
613 final HBreak breakInstruction; 613 final HBreak breakInstruction;
614 final LocalsHandler locals; 614 final LocalsHandler locals;
615 BreakHandlerEntry(this.breakInstruction, this.locals); 615 BreakHandlerEntry(this.breakInstruction, this.locals);
616 } 616 }
617 617
618 interface BreakHandler default BreakHandlerImpl { 618 interface BreakHandler default BreakHandlerImpl {
619 BreakHandler(SsaBuilder builder, StatementElement target); 619 BreakHandler(SsaBuilder builder, StatementElement target);
620 void addBreak(HBreak breakInstruction, LocalsHandler locals); 620 void addBreak(HBreak breakInstruction, LocalsHandler locals);
621 void forEachBreak(Function action); 621 void forEachBreak(Function action);
622 void close(); 622 void close();
623 List<SourceString> labels(); 623 List<LabelElement> labels();
624 } 624 }
625 625
626 // Inert break handler used to avoid null checks when a loop isn't 626 // Inert break handler used to avoid null checks when a loop isn't
627 // used as the target of a break, and therefore doesn't need a break 627 // used as the target of a break, and therefore doesn't need a break
628 // handler associated with it. 628 // handler associated with it.
629 class NullBreakHandler implements BreakHandler { 629 class NullBreakHandler implements BreakHandler {
630 const NullBreakHandler(); 630 const NullBreakHandler();
631 void addBreak(HBreak breakInstruction, LocalsHandler locals) { 631 void addBreak(HBreak breakInstruction, LocalsHandler locals) {
632 unreachable(); 632 unreachable();
633 } 633 }
634 void forEachBreak(Function ignored) { } 634 void forEachBreak(Function ignored) { }
635 void close() { } 635 void close() { }
636 List<SourceString> labels() => const <SourceString>[]; 636 List<LabelElement> labels() => const <LabelElement>[];
637 } 637 }
638 638
639 // Records breaks until a target block is available. 639 // Records breaks until a target block is available.
640 // Breaks are always forward jumps. 640 // Breaks are always forward jumps.
641 class BreakHandlerImpl implements BreakHandler { 641 class BreakHandlerImpl implements BreakHandler {
642 final BreakHandler previous; 642 final BreakHandler previous;
643 final SsaBuilder builder; 643 final SsaBuilder builder;
644 final StatementElement target; 644 final StatementElement target;
645 final List<BreakHandlerEntry> breaks; 645 final List<BreakHandlerEntry> breaks;
646 BreakHandlerImpl(SsaBuilder builder, this.target) 646 BreakHandlerImpl(SsaBuilder builder, this.target)
(...skipping 15 matching lines...) Expand all
662 } 662 }
663 } 663 }
664 664
665 void close() { 665 void close() {
666 assert(builder.currentBreakHandler === this); 666 assert(builder.currentBreakHandler === this);
667 // The mapping from StatementElement to BreakHandler is no longer needed. 667 // The mapping from StatementElement to BreakHandler is no longer needed.
668 builder.breakTargets.remove(target); 668 builder.breakTargets.remove(target);
669 builder.currentBreakHandler = previous; 669 builder.currentBreakHandler = previous;
670 } 670 }
671 671
672 List<SourceString> labels() { 672 List<LabelElement> labels() {
673 List<SourceString> result = null; 673 List<LabelElement> result = null;
674 for (LabelElement element in target.labels) { 674 for (LabelElement element in target.labels) {
675 if (element.isBreakTarget) { 675 if (element.isBreakTarget) {
676 if (result === null) result = <SourceString>[]; 676 if (result === null) result = <LabelElement>[];
677 result.add(element.label.source); 677 result.add(element);
678 } 678 }
679 } 679 }
680 return (result === null) ? const <SourceString>[] : result; 680 return (result === null) ? const <LabelElement>[] : result;
681 } 681 }
682 } 682 }
683 683
684 class SsaBuilder implements Visitor { 684 class SsaBuilder implements Visitor {
685 final Compiler compiler; 685 final Compiler compiler;
686 TreeElements elements; 686 TreeElements elements;
687 final Interceptors interceptors; 687 final Interceptors interceptors;
688 final WorkItem work; 688 final WorkItem work;
689 bool methodInterceptionEnabled; 689 bool methodInterceptionEnabled;
690 HGraph graph; 690 HGraph graph;
691 LocalsHandler localsHandler; 691 LocalsHandler localsHandler;
692 HInstruction rethrowableException; 692 HInstruction rethrowableException;
693 693
694 Map<StatementElement, BreakHandler> breakTargets; 694 Map<StatementElement, BreakHandler> breakTargets;
695 695
696 // We build the Ssa graph by simulating a stack machine. 696 // We build the Ssa graph by simulating a stack machine.
697 List<HInstruction> stack; 697 List<HInstruction> stack;
698 698
699 // The current block to add instructions to. Might be null, if we are 699 // The current block to add instructions to. Might be null, if we are
700 // visiting dead code. 700 // visiting dead code.
701 HBasicBlock current; 701 HBasicBlock current;
702 // The most recently opened block. Has the same value as [current] while 702 // The most recently opened block. Has the same value as [current] while
703 // the block is open, but unlike [current], it isn't cleared when the current 703 // the block is open, but unlike [current], it isn't cleared when the current
704 // block is closed. 704 // block is closed.
705 HBasicBlock lastOpenedBlock; 705 HBasicBlock lastOpenedBlock;
706 706
707 // Linked list of active break-handlers. Will be removed in the order 707 // Linked list of active break-handlers. Will be removed in the order
708 // they are added. 708 // they are added.
709 BreakHandler currentBreakHandler = const NullBreakHandler(); 709 BreakHandler currentBreakHandler = const NullBreakHandler();
710 // The break handler to use for an upcoming loop statement (temporarily set
711 // if a labeled statement is labeling a loop).
712 BreakHandler loopBreakHandler = null;
713 710
714 SsaBuilder(Compiler compiler, WorkItem work) 711 SsaBuilder(Compiler compiler, WorkItem work)
715 : this.compiler = compiler, 712 : this.compiler = compiler,
716 this.work = work, 713 this.work = work,
717 interceptors = compiler.builder.interceptors, 714 interceptors = compiler.builder.interceptors,
718 methodInterceptionEnabled = true, 715 methodInterceptionEnabled = true,
719 elements = work.resolutionTree, 716 elements = work.resolutionTree,
720 graph = new HGraph(), 717 graph = new HGraph(),
721 stack = new List<HInstruction>(), 718 stack = new List<HInstruction>(),
722 breakTargets = new Map<StatementElement, BreakHandler>() { 719 breakTargets = new Map<StatementElement, BreakHandler>() {
(...skipping 275 matching lines...) Expand 10 before | Expand all | Expand 10 after
998 } 995 }
999 996
1000 /** 997 /**
1001 * Creates a new loop-header block. The previous [current] block 998 * Creates a new loop-header block. The previous [current] block
1002 * is closed with an [HGoto] and replaced by the newly created block. 999 * is closed with an [HGoto] and replaced by the newly created block.
1003 * Also notifies the locals handler that we're entering a loop. 1000 * Also notifies the locals handler that we're entering a loop.
1004 */ 1001 */
1005 BreakHandler beginLoopHeader(Node node) { 1002 BreakHandler beginLoopHeader(Node node) {
1006 assert(!isAborted()); 1003 assert(!isAborted());
1007 HBasicBlock previousBlock = close(new HGoto()); 1004 HBasicBlock previousBlock = close(new HGoto());
1008 BreakHandler breakHandler = getLoopBreakHandler(node); 1005 BreakHandler breakHandler = getBreakHandler(node);
1009 HBasicBlock loopEntry = graph.addNewLoopHeaderBlock(breakHandler.labels()); 1006 HBasicBlock loopEntry = graph.addNewLoopHeaderBlock(breakHandler.labels());
1010 previousBlock.addSuccessor(loopEntry); 1007 previousBlock.addSuccessor(loopEntry);
1011 open(loopEntry); 1008 open(loopEntry);
1012 1009
1013 localsHandler.beginLoopHeader(node, loopEntry); 1010 localsHandler.beginLoopHeader(node, loopEntry);
1014 return breakHandler; 1011 return breakHandler;
1015 } 1012 }
1016 1013
1017 /** 1014 /**
1018 * Ends the loop: 1015 * Ends the loop:
(...skipping 233 matching lines...) Expand 10 before | Expand all | Expand 10 after
1252 } else if (thenBlock !== null) { 1249 } else if (thenBlock !== null) {
1253 // The only predecessor is the then branch. 1250 // The only predecessor is the then branch.
1254 localsHandler = thenLocals; 1251 localsHandler = thenLocals;
1255 } 1252 }
1256 } 1253 }
1257 condition.blockInformation = 1254 condition.blockInformation =
1258 new HIfBlockInformation(condition, thenGraph, elseGraph, joinBlock); 1255 new HIfBlockInformation(condition, thenGraph, elseGraph, joinBlock);
1259 } 1256 }
1260 1257
1261 void visitLogicalAndOr(Send node, Operator op) { 1258 void visitLogicalAndOr(Send node, Operator op) {
1259 handleLogicalAndOr(() { visit(node.receiver); },
1260 () { visit(node.argumentsNode); },
1261 isAnd: (const SourceString("&&") == op.source));
1262 }
1263
1264
1265 void handleLogicalAndOr(void left(), void right(), [bool isAnd = true]) {
1262 // x && y is transformed into: 1266 // x && y is transformed into:
1263 // t0 = boolify(x); 1267 // t0 = boolify(x);
1264 // if (t0) t1 = boolify(y); 1268 // if (t0) t1 = boolify(y);
1265 // result = phi(t0, t1); 1269 // result = phi(t0, t1);
1266 // 1270 //
1267 // x || y is transformed into: 1271 // x || y is transformed into:
1268 // t0 = boolify(x); 1272 // t0 = boolify(x);
1269 // if (not(t0)) t1 = boolify(y); 1273 // if (not(t0)) t1 = boolify(y);
1270 // result = phi(t0, t1); 1274 // result = phi(t0, t1);
1271 bool isAnd = (const SourceString("&&") == op.source); 1275 left();
1272
1273 visit(node.receiver);
1274 HInstruction boolifiedLeft = popBoolified(); 1276 HInstruction boolifiedLeft = popBoolified();
1275 HInstruction condition; 1277 HInstruction condition;
1276 if (isAnd) { 1278 if (isAnd) {
1277 condition = boolifiedLeft; 1279 condition = boolifiedLeft;
1278 } else { 1280 } else {
1279 condition = new HNot(boolifiedLeft); 1281 condition = new HNot(boolifiedLeft);
1280 add(condition); 1282 add(condition);
1281 } 1283 }
1282 HIf branch = new HIf(condition, false); 1284 HIf branch = new HIf(condition, false);
1283 HBasicBlock leftBlock = close(branch); 1285 HBasicBlock leftBlock = close(branch);
1284 LocalsHandler savedLocals = new LocalsHandler.from(localsHandler); 1286 LocalsHandler savedLocals = new LocalsHandler.from(localsHandler);
1285 1287
1286 HBasicBlock rightBlock = addNewBlock(); 1288 HBasicBlock rightBlock = addNewBlock();
1287 leftBlock.addSuccessor(rightBlock); 1289 leftBlock.addSuccessor(rightBlock);
1288 open(rightBlock); 1290 open(rightBlock);
1289 visit(node.argumentsNode); 1291
1292 right();
1290 HInstruction boolifiedRight = popBoolified(); 1293 HInstruction boolifiedRight = popBoolified();
1291 SubGraph rightGraph = new SubGraph(rightBlock, current); 1294 SubGraph rightGraph = new SubGraph(rightBlock, current);
1292 rightBlock = close(new HGoto()); 1295 rightBlock = close(new HGoto());
1293 1296
1294 HBasicBlock joinBlock = addNewBlock(); 1297 HBasicBlock joinBlock = addNewBlock();
1295 leftBlock.addSuccessor(joinBlock); 1298 leftBlock.addSuccessor(joinBlock);
1296 rightBlock.addSuccessor(joinBlock); 1299 rightBlock.addSuccessor(joinBlock);
1297 open(joinBlock); 1300 open(joinBlock);
1298 1301
1299 branch.blockInformation = 1302 branch.blockInformation =
(...skipping 334 matching lines...) Expand 10 before | Expand all | Expand 10 after
1634 SourceString name = selector.namedArguments[i]; 1637 SourceString name = selector.namedArguments[i];
1635 if (name == parameter.name) { 1638 if (name == parameter.name) {
1636 foundIndex = i; 1639 foundIndex = i;
1637 break; 1640 break;
1638 } 1641 }
1639 } 1642 }
1640 if (foundIndex != -1) { 1643 if (foundIndex != -1) {
1641 list.add(namedArguments[foundIndex]); 1644 list.add(namedArguments[foundIndex]);
1642 } else { 1645 } else {
1643 Constant constant = compiler.compileVariable(parameter); 1646 Constant constant = compiler.compileVariable(parameter);
1644 list.add(graph.addConstant(constant)); 1647 list.add(graph.addConstant(constant));
1645 } 1648 }
1646 } 1649 }
1647 } 1650 }
1648 } 1651 }
1649 1652
1650 void addGenericSendArgumentsToList(Link<Node> link, List<HInstruction> list) { 1653 void addGenericSendArgumentsToList(Link<Node> link, List<HInstruction> list) {
1651 for (; !link.isEmpty(); link = link.tail) { 1654 for (; !link.isEmpty(); link = link.tail) {
1652 visit(link.head); 1655 visit(link.head);
1653 list.add(pop()); 1656 list.add(pop());
1654 } 1657 }
(...skipping 460 matching lines...) Expand 10 before | Expand all | Expand 10 after
2115 visitBreakStatement(BreakStatement node) { 2118 visitBreakStatement(BreakStatement node) {
2116 work.allowSpeculativeOptimization = false; 2119 work.allowSpeculativeOptimization = false;
2117 assert(!isAborted()); 2120 assert(!isAborted());
2118 StatementElement target = elements[node]; 2121 StatementElement target = elements[node];
2119 assert(target !== null); 2122 assert(target !== null);
2120 BreakHandler handler = breakTargets[target]; 2123 BreakHandler handler = breakTargets[target];
2121 assert(handler !== null); 2124 assert(handler !== null);
2122 LocalsHandler savedLocals = new LocalsHandler.from(localsHandler); 2125 LocalsHandler savedLocals = new LocalsHandler.from(localsHandler);
2123 HBreak breakInstruction; 2126 HBreak breakInstruction;
2124 if (node.target === null) { 2127 if (node.target === null) {
2125 breakInstruction = new HBreak(); 2128 breakInstruction = new HBreak(target);
2126 } else { 2129 } else {
2127 breakInstruction = new HBreak(node.target.source); 2130 LabelElement label = elements[node.target];
2131 breakInstruction = new HBreak.toLabel(label);
2128 } 2132 }
2129 close(breakInstruction); 2133 close(breakInstruction);
2130 handler.addBreak(breakInstruction, savedLocals); 2134 handler.addBreak(breakInstruction, savedLocals);
2131 } 2135 }
2132 2136
2133 visitContinueStatement(ContinueStatement node) { 2137 visitContinueStatement(ContinueStatement node) {
2134 // TODO(lrn): Replace this with a real implementation of continue. 2138 // TODO(lrn): Replace this with a real implementation of continue.
2135 compiler.reportWarning(node, 'continue not implemented'); 2139 compiler.reportWarning(node, 'continue not implemented');
2136 generateUnimplemented('continue not implemented'); 2140 generateUnimplemented('continue not implemented');
2137 } 2141 }
2138 2142
2139 BreakHandler getLoopBreakHandler(Node node) { 2143 BreakHandler getBreakHandler(Node node) {
2140 StatementElement element = elements[node]; 2144 StatementElement element = elements[node];
2141 BreakHandler handler; 2145 if (element === null) return const NullBreakHandler();
2142 if (loopBreakHandler === null) { 2146 return new BreakHandler(this, element);
2143 if (element === null) return const NullBreakHandler();
2144 handler = new BreakHandler(this, element);
2145 } else {
2146 handler = loopBreakHandler;
2147 loopBreakHandler = null;
2148 if (element === null) return handler;
2149 }
2150 return handler;
2151 } 2147 }
2152 2148
2153 visitForInStatement(ForInStatement node) { 2149 visitForInStatement(ForInStatement node) {
2154 // Generate a structure equivalent to: 2150 // Generate a structure equivalent to:
2155 // Iterator<E> $iter = <iterable>.iterator() 2151 // Iterator<E> $iter = <iterable>.iterator()
2156 // while ($iter.hasNext()) { 2152 // while ($iter.hasNext()) {
2157 // E <declaredIdentifier> = $iter.next(); 2153 // E <declaredIdentifier> = $iter.next();
2158 // <body> 2154 // <body>
2159 // } 2155 // }
2160 localsHandler.startLoop(node); 2156 localsHandler.startLoop(node);
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after
2294 visit(node.value); 2290 visit(node.value);
2295 visit(node.key); 2291 visit(node.key);
2296 } 2292 }
2297 2293
2298 visitNamedArgument(NamedArgument node) { 2294 visitNamedArgument(NamedArgument node) {
2299 visit(node.expression); 2295 visit(node.expression);
2300 } 2296 }
2301 2297
2302 visitSwitchStatement(SwitchStatement node) { 2298 visitSwitchStatement(SwitchStatement node) {
2303 work.allowSpeculativeOptimization = false; 2299 work.allowSpeculativeOptimization = false;
2300 LocalsHandler savedLocals = new LocalsHandler.from(localsHandler);
2301 HBasicBlock startBlock = graph.addNewBlock();
2302 goto(current, startBlock);
2303 open(startBlock);
2304 visit(node.expression); 2304 visit(node.expression);
2305 HInstruction expression = pop(); 2305 HInstruction expression = pop();
2306 if (node.cases.isEmpty()) {
2307 return;
2308 }
2306 Link<Node> cases = node.cases.nodes; 2309 Link<Node> cases = node.cases.nodes;
2307 int count = 0; 2310
2308 handleThen() { 2311 BreakHandler breakHandler = getBreakHandler(node);
2309 if (cases.head.statements.nodes.isEmpty()) { 2312
2310 compiler.unimplemented('fall-through', node: cases.head); 2313 buildSwitchCases(cases, expression);
2314
2315 HBasicBlock lastBlock = lastOpenedBlock;
2316
2317 // Create merge block for break targets.
2318 HBasicBlock joinBlock = new HBasicBlock();
2319 List<LocalsHandler> caseLocals = <LocalsHandler>[];
2320 breakHandler.forEachBreak((HBreak instruction, LocalsHandler locals) {
2321 instruction.block.addSuccessor(joinBlock);
2322 caseLocals.add(locals);
2323 });
2324 if (!isAborted()) {
2325 // The current flow is only aborted if the switch has a default that
2326 // aborts (all previous cases must abort, and if there is no default,
2327 // it's possible to miss all the cases).
2328 caseLocals.add(localsHandler);
2329 goto(current, joinBlock);
2330 }
2331 if (caseLocals.length != 0) {
2332 graph.addBlock(joinBlock);
2333 open(joinBlock);
2334 if (caseLocals.length == 1) {
2335 localsHandler = caseLocals[0];
2336 } else {
2337 localsHandler = savedLocals.mergeMultiple(caseLocals, joinBlock);
2311 } 2338 }
2312 visit(cases.head.statements); 2339 } else {
2313 cases = cases.tail; 2340 // The joinblock is not used.
2341 joinBlock = null;
2314 } 2342 }
2315 handleElse() { 2343 startBlock.labeledBlockInformation = new HLabeledBlockInformation.implicit(
2316 if (cases.isEmpty()) return; 2344 new SubGraph(startBlock, lastBlock),
2317 if (cases.head.asDefaultCase() !== null) { 2345 joinBlock,
2318 stack.add(graph.addConstantBool(true)); 2346 elements[node]);
2319 if (!cases.tail.isEmpty()) { 2347 }
2320 compiler.unimplemented('default case not last', node: cases.head); 2348
2321 } 2349
2322 } else { 2350 // Recursively build an if/else structure to match the cases.
2323 SwitchCase switchCase = cases.head; 2351 buildSwitchCases(Link<Node> cases, HInstruction expression) {
2324 visit(switchCase.expression); 2352 SwitchCase node = cases.head;
2325 HInstruction caseExpression = pop(); 2353
2354 // Called for the statements on all but the last case block.
2355 // Ensures that a user expecting a fallthrough gets an error.
2356 void visitStatementsAndAbort() {
2357 visit(node.statements);
2358 if (!isAborted()) {
2359 compiler.reportWarning(node, 'Missing break at end of switch case');
2360 Element element =
2361 compiler.findHelper(const SourceString("getFallThroughError"));
2362 push(new HStatic(element));
2363 HInstruction error = new HInvokeStatic(
2364 Selector.INVOCATION_0, <HInstruction>[pop()]);
2365 add(error);
2366 close(new HThrow(error));
2367 }
2368 }
2369
2370 Link<Node> expressions = node.expressions.nodes;
2371 if (expressions.isEmpty()) {
2372 // Default case with no expressions.
2373 if (!node.isDefaultCase) {
2374 compiler.internalError("Case with no expression and not default");
2375 }
2376 visit(node.statements);
2377 // This must be the final case (otherwise "default" would be invalid),
2378 // so we don't need to check for fallthrough.
2379 return;
2380 }
2381
2382 // Recursively build the test conditions. Leaves the result on the
2383 // expression stack.
2384 void buildTests(Link<Node> expressions) {
2385 // Build comparison for one case expression.
2386 void left() {
2326 Element equalsHelper = interceptors.getEqualsInterceptor(); 2387 Element equalsHelper = interceptors.getEqualsInterceptor();
2327 HInstruction target = new HStatic(equalsHelper); 2388 HInstruction target = new HStatic(equalsHelper);
2328 add(target); 2389 add(target);
2329 push(new HEquals(target, caseExpression, expression)); 2390 visit(expressions.head);
2391 push(new HEquals(target, pop(), expression));
2330 } 2392 }
2331 handleIf(handleThen, handleElse); 2393
2394 // If this is the last expression, just return it.
2395 if (expressions.tail.isEmpty()) {
2396 left();
2397 return;
2398 }
2399
2400 void right() {
2401 buildTests(expressions.tail);
2402 }
2403 handleLogicalAndOr(left, right, isAnd: false);
2332 } 2404 }
2333 2405
2334 localsHandler.startLoop(node); 2406 buildTests(expressions);
2335 BreakHandler breakHandler = beginLoopHeader(node); 2407 HInstruction result = popBoolified();
2336 HBasicBlock loopEntryBlock = current;
2337 localsHandler.enterLoopBody(node);
2338 2408
2339 handleElse(); 2409 if (node.isDefaultCase) {
2410 // Don't actually use the condition result.
2411 // This must be final case, so don't check for abort.
2412 visit(node.statements);
2413 } else {
2414 stack.add(result);
2415 if (cases.tail.isEmpty()) {
2416 handleIf(() { visit(node.statements); }, null);
2417 } else {
2418 handleIf(() { visitStatementsAndAbort(); },
2419 () { buildSwitchCases(cases.tail, expression); });
2420 }
2421 }
2422 }
2340 2423
2341 if (isAborted()) { 2424 visitSwitchCase(SwitchCase node) {
2342 compiler.unimplemented("SsaBuilder for loop with aborting body", 2425 unreachable();
2343 node: node);
2344 }
2345
2346 HBasicBlock bodyExitBlock = close(new HGoto());
2347 HBasicBlock conditionBlock = addNewBlock();
2348 bodyExitBlock.addSuccessor(conditionBlock);
2349 open(conditionBlock);
2350 stack.add(graph.addConstantBool(false));
2351
2352 conditionBlock = close(new HLoopBranch(popBoolified(),
2353 HLoopBranch.DO_WHILE_LOOP));
2354
2355 conditionBlock.addSuccessor(loopEntryBlock); // The back-edge.
2356 loopEntryBlock.postProcessLoopHeader();
2357
2358 endLoop(loopEntryBlock, conditionBlock, breakHandler);
2359 } 2426 }
2360 2427
2361 visitTryStatement(TryStatement node) { 2428 visitTryStatement(TryStatement node) {
2362 work.allowSpeculativeOptimization = false; 2429 work.allowSpeculativeOptimization = false;
2363 assert(!work.isBailoutVersion()); 2430 assert(!work.isBailoutVersion());
2364 HBasicBlock enterBlock = graph.addNewBlock(); 2431 HBasicBlock enterBlock = graph.addNewBlock();
2365 close(new HGoto()).addSuccessor(enterBlock); 2432 close(new HGoto()).addSuccessor(enterBlock);
2366 open(enterBlock); 2433 open(enterBlock);
2367 HTry tryInstruction = new HTry(); 2434 HTry tryInstruction = new HTry();
2368 List<HBasicBlock> blocks = <HBasicBlock>[]; 2435 List<HBasicBlock> blocks = <HBasicBlock>[];
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after
2493 buildBody() { 2560 buildBody() {
2494 // TODO(lrn): Make sure to take continue into account. 2561 // TODO(lrn): Make sure to take continue into account.
2495 visit(body); 2562 visit(body);
2496 if (isAborted()) { 2563 if (isAborted()) {
2497 compiler.reportWarning(body, "aborting loop body"); 2564 compiler.reportWarning(body, "aborting loop body");
2498 } 2565 }
2499 } 2566 }
2500 handleIf(buildBody, null); 2567 handleIf(buildBody, null);
2501 } 2568 }
2502 } 2569 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698