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

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

Issue 9500010: Fix break implementation. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Addressed 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
« no previous file with comments | « no previous file | frog/leg/ssa/nodes.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 520 matching lines...) Expand 10 before | Expand all | Expand 10 after
531 joinedLocals[element] = instruction; 531 joinedLocals[element] = instruction;
532 } else { 532 } else {
533 HInstruction phi = new HPhi.manyInputs(element, [instruction, mine]); 533 HInstruction phi = new HPhi.manyInputs(element, [instruction, mine]);
534 joinBlock.addPhi(phi); 534 joinBlock.addPhi(phi);
535 joinedLocals[element] = phi; 535 joinedLocals[element] = phi;
536 } 536 }
537 } 537 }
538 }); 538 });
539 directLocals = joinedLocals; 539 directLocals = joinedLocals;
540 } 540 }
541
542 /**
543 * The current localsHandler is not used for its values, only for its
544 * declared variables. This is a way to exclude local values from the
545 * result when they are no longer in scope.
546 * Returns the new LocalsHandler to use (may not be [this]).
547 */
548 LocalsHandler mergeMultiple(List<LocalsHandler> locals,
549 HBasicBlock joinBlock) {
550 assert(locals.length > 0);
551 if (locals.length == 1) return locals[0];
552 Map<Element, HInstruction> joinedLocals = new Map<Element,HInstruction>();
553 HInstruction thisValue = null;
554 directLocals.forEach((Element element, HInstruction instruction) {
555 if (element !== closureData.thisElement) {
556 HPhi phi = new HPhi.noInputs(element);
557 joinedLocals[element] = phi;
558 joinBlock.addPhi(phi);
559 } else {
560 // We know that "this" never changes, if it's there.
561 // Save it for later. While merging, there is no phi for "this",
562 // so we don't have to special case it in the merge loop.
563 thisValue = instruction;
564 }
565 });
566 for (LocalsHandler local in locals) {
567 local.directLocals.forEach((Element element, HInstruction instruction) {
568 HPhi phi = joinedLocals[element];
569 if (phi !== null) {
570 phi.addInput(instruction);
571 }
572 });
573 }
574 if (thisValue !== null) {
575 // If there was a "this" for the scope, add it to the new locals.
576 joinedLocals[closureData.thisElement] = thisValue;
577 }
578 directLocals = joinedLocals;
579 return this;
580 }
541 } 581 }
542 582
543 583
544 // Represents a single break instruction. 584 // Represents a single break instruction.
545 class BreakHandlerEntry { 585 class BreakHandlerEntry {
546 final HBreak breakInstruction; 586 final HBreak breakInstruction;
547 final LocalsHandler locals; 587 final LocalsHandler locals;
548 BreakHandlerEntry(this.breakInstruction, this.locals); 588 BreakHandlerEntry(this.breakInstruction, this.locals);
549 } 589 }
550 590
(...skipping 400 matching lines...) Expand 10 before | Expand all | Expand 10 after
951 * Ends the loop: 991 * Ends the loop:
952 * - creates a new block and adds it as successor to the [branchBlock]. 992 * - creates a new block and adds it as successor to the [branchBlock].
953 * - opens the new block (setting as [current]). 993 * - opens the new block (setting as [current]).
954 * - notifies the locals handler that we're exiting a loop. 994 * - notifies the locals handler that we're exiting a loop.
955 */ 995 */
956 void endLoop(HBasicBlock loopEntry, 996 void endLoop(HBasicBlock loopEntry,
957 HBasicBlock branchBlock, 997 HBasicBlock branchBlock,
958 BreakHandler breakHandler) { 998 BreakHandler breakHandler) {
959 HBasicBlock loopExitBlock = addNewBlock(); 999 HBasicBlock loopExitBlock = addNewBlock();
960 assert(branchBlock.successors.length == 1); 1000 assert(branchBlock.successors.length == 1);
1001 List<LocalsHandler> breakLocals = <LocalsHandler>[];
1002 breakHandler.forEachBreak((HBreak breakInstruction, LocalsHandler locals) {
1003 breakInstruction.block.addSuccessor(loopExitBlock);
1004 breakLocals.add(locals);
1005 });
961 branchBlock.addSuccessor(loopExitBlock); 1006 branchBlock.addSuccessor(loopExitBlock);
962 open(loopExitBlock); 1007 open(loopExitBlock);
963 localsHandler.endLoop(loopEntry); 1008 localsHandler.endLoop(loopEntry);
964 breakHandler.forEachBreak((HBreak breakInstruction, LocalsHandler locals) { 1009 if (!breakLocals.isEmpty()) {
965 HBasicBlock joinBlock = addNewBlock(); 1010 breakLocals.add(localsHandler);
966 breakInstruction.block.addSuccessor(joinBlock); 1011 localsHandler = localsHandler.mergeMultiple(breakLocals, loopExitBlock);
967 goto(current, joinBlock); 1012 }
968 open(joinBlock);
969 localsHandler.mergeWith(locals, joinBlock);
970 });
971 } 1013 }
972 1014
973 // For while loops, initializer and update are null. 1015 // For while loops, initializer and update are null.
974 visitLoop(Node loop, Node initializer, Expression condition, NodeList updates, 1016 visitLoop(Node loop, Node initializer, Expression condition, NodeList updates,
975 Node body) { 1017 Node body) {
976 // Generate: 1018 // Generate:
977 // <initializer> 1019 // <initializer>
978 // loop-entry: 1020 // loop-entry:
979 // if (!<condition>) goto loop-exit; 1021 // if (!<condition>) goto loop-exit;
980 // <body> 1022 // <body>
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
1070 } 1112 }
1071 1113
1072 // If there are no continues we could avoid the creation of the condition 1114 // If there are no continues we could avoid the creation of the condition
1073 // block. This could also lead to a block having multiple entries and exits. 1115 // block. This could also lead to a block having multiple entries and exits.
1074 HBasicBlock bodyExitBlock = close(new HGoto()); 1116 HBasicBlock bodyExitBlock = close(new HGoto());
1075 HBasicBlock conditionBlock = addNewBlock(); 1117 HBasicBlock conditionBlock = addNewBlock();
1076 bodyExitBlock.addSuccessor(conditionBlock); 1118 bodyExitBlock.addSuccessor(conditionBlock);
1077 open(conditionBlock); 1119 open(conditionBlock);
1078 visit(node.condition); 1120 visit(node.condition);
1079 assert(!isAborted()); 1121 assert(!isAborted());
1080 conditionBlock = close(new HLoopBranch(popBoolified())); 1122 conditionBlock = close(new HLoopBranch(popBoolified(),
1123 HLoopBranch.DO_WHILE_LOOP));
1081 1124
1082 conditionBlock.addSuccessor(loopEntryBlock); // The back-edge. 1125 conditionBlock.addSuccessor(loopEntryBlock); // The back-edge.
1083 loopEntryBlock.postProcessLoopHeader(); 1126 loopEntryBlock.postProcessLoopHeader();
1084 1127
1085 endLoop(loopEntryBlock, conditionBlock, breakHandler); 1128 endLoop(loopEntryBlock, conditionBlock, breakHandler);
1086 } 1129 }
1087 1130
1088 visitFunctionExpression(FunctionExpression node) { 1131 visitFunctionExpression(FunctionExpression node) {
1089 ClosureData nestedClosureData = closureDataCache[node]; 1132 ClosureData nestedClosureData = closureDataCache[node];
1090 assert(nestedClosureData !== null); 1133 assert(nestedClosureData !== null);
(...skipping 1048 matching lines...) Expand 10 before | Expand all | Expand 10 after
2139 BreakHandler handler = new BreakHandler(this, targetElement); 2182 BreakHandler handler = new BreakHandler(this, targetElement);
2140 // Introduce a new basic block. 2183 // Introduce a new basic block.
2141 HBasicBlock entryBlock = graph.addNewBlock(); 2184 HBasicBlock entryBlock = graph.addNewBlock();
2142 goto(current, entryBlock); 2185 goto(current, entryBlock);
2143 open(entryBlock); 2186 open(entryBlock);
2144 visit(body); 2187 visit(body);
2145 if (isAborted()) { 2188 if (isAborted()) {
2146 compiler.unimplemented( 2189 compiler.unimplemented(
2147 "SsaBuilder for labeled statement with aborting body", node: node); 2190 "SsaBuilder for labeled statement with aborting body", node: node);
2148 } 2191 }
2149 HBasicBlock exitBlock = current; 2192
2193 HBasicBlock joinBlock = graph.addNewBlock();
2194 List<LocalsHandler> breakLocals = <LocalsHandler>[];
2150 handler.forEachBreak((HBreak breakInstruction, LocalsHandler locals) { 2195 handler.forEachBreak((HBreak breakInstruction, LocalsHandler locals) {
2151 HBasicBlock joinBlock = graph.addNewBlock();
2152 breakInstruction.block.addSuccessor(joinBlock); 2196 breakInstruction.block.addSuccessor(joinBlock);
2153 if (!isAborted()) { 2197 breakLocals.add(locals);
2154 goto(current, joinBlock);
2155 open(joinBlock);
2156 localsHandler.mergeWith(locals, joinBlock);
2157 } else {
2158 open(joinBlock);
2159 localsHandler = locals;
2160 }
2161 }); 2198 });
2162 if (current !== exitBlock) { 2199 bool hasBreak = breakLocals.length > 0;
2200 if (!isAborted()) {
2201 goto(current, joinBlock);
2202 breakLocals.add(localsHandler);
2203 }
2204 localsHandler = beforeLocals.mergeMultiple(breakLocals, joinBlock);
2205
2206 if (hasBreak) {
2163 // There was at least one reachable break, so the label is needed. 2207 // There was at least one reachable break, so the label is needed.
2164 HLabeledBlockInformation blockInfo = 2208 HLabeledBlockInformation blockInfo =
2165 new HLabeledBlockInformation(entryBlock, current, 2209 new HLabeledBlockInformation(entryBlock, current,
2166 handler.labels()); 2210 handler.labels());
2167 handler.close(); 2211 handler.close();
2168 entryBlock.labeledBlockInformation = blockInfo;
2169 // Mark both entry and exit with the information. You can 2212 // Mark both entry and exit with the information. You can
2170 // tell which one is which by comparing with blockInfo.start/end. 2213 // tell which one is which by comparing with blockInfo.start/end.
2171 // It doesn't matter which merge block we use, they won't be generating 2214 // It doesn't matter which merge block we use, they won't be generating
2172 // any code, so put the end-marker on the last join block. 2215 // any code, so put the end-marker on the last join block.
2216 entryBlock.labeledBlockInformation = blockInfo;
2173 current.labeledBlockInformation = blockInfo; 2217 current.labeledBlockInformation = blockInfo;
2174 } 2218 }
2175 } 2219 }
2176 2220
2177 visitLiteralMap(LiteralMap node) { 2221 visitLiteralMap(LiteralMap node) {
2178 compiler.unimplemented('SsaBuilder.visitLiteralMap', node: node); 2222 compiler.unimplemented('SsaBuilder.visitLiteralMap', node: node);
2179 } 2223 }
2180 2224
2181 visitLiteralMapEntry(LiteralMapEntry node) { 2225 visitLiteralMapEntry(LiteralMapEntry node) {
2182 compiler.unimplemented('SsaBuilder.visitLiteralMapEntry', node: node); 2226 compiler.unimplemented('SsaBuilder.visitLiteralMapEntry', node: node);
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after
2291 } 2335 }
2292 2336
2293 visitCatchBlock(CatchBlock node) { 2337 visitCatchBlock(CatchBlock node) {
2294 visit(node.block); 2338 visit(node.block);
2295 } 2339 }
2296 2340
2297 visitTypedef(Typedef node) { 2341 visitTypedef(Typedef node) {
2298 compiler.unimplemented('SsaBuilder.visitTypedef', node: node); 2342 compiler.unimplemented('SsaBuilder.visitTypedef', node: node);
2299 } 2343 }
2300 } 2344 }
OLDNEW
« no previous file with comments | « no previous file | frog/leg/ssa/nodes.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698