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

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: 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') | frog/leg/ssa/nodes.dart » ('J')
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 exclude local values from the
ngeoffray 2012/02/29 10:02:54 way *to*
Lasse Reichstein Nielsen 2012/02/29 10:42:02 Done.
545 * result when they are no longer in scope.
546 * Returns the new LocalsHandler to use (may not be [this]).
547 */
548 void mergeMultiple(List<LocalsHandler> locals, HBasicBlock joinBlock) {
ngeoffray 2012/02/29 10:02:54 void -> LocalsHandler
Lasse Reichstein Nielsen 2012/02/29 10:42:02 Done.
549 assert(locals.length > 0);
550 if (locals.length == 1) return locals[0];
551 Map<Element, HInstruction> joinedLocals = new Map<Element,HInstruction>();
552 HInstruction thisValue = null;
553 directLocals.forEach((Element element, HInstruction instruction) {
554 if (element !== closureData.thisElement) {
555 HPhi phi = new HPhi(element);
556 joinedLocals[element] = phi;
557 joinBlock.addPhi(phi);
558 } else {
559 // We know that "this" never changes, if it's there.
560 // Save it for later. While merging, there is no phi for "this",
561 // so we don't have to special case it in the merge loop.
562 thisValue = instruction;
563 }
564 });
565 for (LocalsHandler local in locals) {
566 local.directLocals.forEach((Element element, HInstruction instruction) {
567 HPhi phi = joinedLocals[element];
568 if (phi !== null) {
569 phi.addInput(instruction);
570 }
571 });
572 }
573 if (thisValue !== null) {
574 // If there was a "this" for the scope, add it to the new locals.
575 joinedLocals[closureData.thisElement] = thisValue;
576 }
577 directLocals = joinedLocals;
578 return this;
579 }
541 } 580 }
542 581
543 582
544 // Represents a single break instruction. 583 // Represents a single break instruction.
545 class BreakHandlerEntry { 584 class BreakHandlerEntry {
546 final HBreak breakInstruction; 585 final HBreak breakInstruction;
547 final LocalsHandler locals; 586 final LocalsHandler locals;
548 BreakHandlerEntry(this.breakInstruction, this.locals); 587 BreakHandlerEntry(this.breakInstruction, this.locals);
549 } 588 }
550 589
(...skipping 411 matching lines...) Expand 10 before | Expand all | Expand 10 after
962 * Ends the loop: 1001 * Ends the loop:
963 * - creates a new block and adds it as successor to the [branchBlock]. 1002 * - creates a new block and adds it as successor to the [branchBlock].
964 * - opens the new block (setting as [current]). 1003 * - opens the new block (setting as [current]).
965 * - notifies the locals handler that we're exiting a loop. 1004 * - notifies the locals handler that we're exiting a loop.
966 */ 1005 */
967 void endLoop(HBasicBlock loopEntry, 1006 void endLoop(HBasicBlock loopEntry,
968 HBasicBlock branchBlock, 1007 HBasicBlock branchBlock,
969 BreakHandler breakHandler) { 1008 BreakHandler breakHandler) {
970 HBasicBlock loopExitBlock = addNewBlock(); 1009 HBasicBlock loopExitBlock = addNewBlock();
971 assert(branchBlock.successors.length == 1); 1010 assert(branchBlock.successors.length == 1);
1011 List<LocalsHandler> breakLocals = <LocalsHandler>[];
1012 breakHandler.forEachBreak((HBreak breakInstruction, LocalsHandler locals) {
1013 breakInstruction.block.addSuccessor(loopExitBlock);
1014 breakLocals.add(locals);
1015 });
972 branchBlock.addSuccessor(loopExitBlock); 1016 branchBlock.addSuccessor(loopExitBlock);
973 open(loopExitBlock); 1017 open(loopExitBlock);
974 localsHandler.endLoop(loopEntry); 1018 localsHandler.endLoop(loopEntry);
975 breakHandler.forEachBreak((HBreak breakInstruction, LocalsHandler locals) { 1019 if (!breakLocals.isEmpty()) {
976 HBasicBlock joinBlock = addNewBlock(); 1020 breakLocals.add(localsHandler);
977 breakInstruction.block.addSuccessor(joinBlock); 1021 localsHandler = localsHandler.mergeMultiple(breakLocals, loopExitBlock);
978 goto(current, joinBlock); 1022 }
979 open(joinBlock);
980 localsHandler.mergeWith(locals, joinBlock);
981 });
982 } 1023 }
983 1024
984 // For while loops, initializer and update are null. 1025 // For while loops, initializer and update are null.
985 visitLoop(Node loop, Node initializer, Expression condition, NodeList updates, 1026 visitLoop(Node loop, Node initializer, Expression condition, NodeList updates,
986 Node body) { 1027 Node body) {
987 // Generate: 1028 // Generate:
988 // <initializer> 1029 // <initializer>
989 // loop-entry: 1030 // loop-entry:
990 // if (!<condition>) goto loop-exit; 1031 // if (!<condition>) goto loop-exit;
991 // <body> 1032 // <body>
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
1081 } 1122 }
1082 1123
1083 // If there are no continues we could avoid the creation of the condition 1124 // If there are no continues we could avoid the creation of the condition
1084 // block. This could also lead to a block having multiple entries and exits. 1125 // block. This could also lead to a block having multiple entries and exits.
1085 HBasicBlock bodyExitBlock = close(new HGoto()); 1126 HBasicBlock bodyExitBlock = close(new HGoto());
1086 HBasicBlock conditionBlock = addNewBlock(); 1127 HBasicBlock conditionBlock = addNewBlock();
1087 bodyExitBlock.addSuccessor(conditionBlock); 1128 bodyExitBlock.addSuccessor(conditionBlock);
1088 open(conditionBlock); 1129 open(conditionBlock);
1089 visit(node.condition); 1130 visit(node.condition);
1090 assert(!isAborted()); 1131 assert(!isAborted());
1091 conditionBlock = close(new HLoopBranch(popBoolified())); 1132 conditionBlock = close(new HLoopBranch(popBoolified(),
1133 HLoopBranch.DO_WHILE_LOOP));
1092 1134
1093 conditionBlock.addSuccessor(loopEntryBlock); // The back-edge. 1135 conditionBlock.addSuccessor(loopEntryBlock); // The back-edge.
1094 loopEntryBlock.postProcessLoopHeader(); 1136 loopEntryBlock.postProcessLoopHeader();
1095 1137
1096 endLoop(loopEntryBlock, conditionBlock, breakHandler); 1138 endLoop(loopEntryBlock, conditionBlock, breakHandler);
1097 } 1139 }
1098 1140
1099 visitFunctionExpression(FunctionExpression node) { 1141 visitFunctionExpression(FunctionExpression node) {
1100 ClosureData nestedClosureData = closureDataCache[node]; 1142 ClosureData nestedClosureData = closureDataCache[node];
1101 assert(nestedClosureData !== null); 1143 assert(nestedClosureData !== null);
(...skipping 1045 matching lines...) Expand 10 before | Expand all | Expand 10 after
2147 if (handler === null) { 2189 if (handler === null) {
2148 // The labels are not break targets. 2190 // The labels are not break targets.
2149 visit(currentNode); 2191 visit(currentNode);
2150 } else if (currentNode is Loop || currentNode is SwitchStatement) { 2192 } else if (currentNode is Loop || currentNode is SwitchStatement) {
2151 // The labels apply to that statement, and will be handled there. 2193 // The labels apply to that statement, and will be handled there.
2152 loopBreakHandler = handler; 2194 loopBreakHandler = handler;
2153 visit(currentNode); 2195 visit(currentNode);
2154 assert(loopBreakHandler === null); 2196 assert(loopBreakHandler === null);
2155 } else { 2197 } else {
2156 // Introduce a new basic block. 2198 // Introduce a new basic block.
2199 LocalsHandler beforeLocals = new LocalsHandler.from(localsHandler);
2157 HBasicBlock entryBlock = graph.addNewBlock(); 2200 HBasicBlock entryBlock = graph.addNewBlock();
2158 goto(current, entryBlock); 2201 goto(current, entryBlock);
2159 open(entryBlock); 2202 open(entryBlock);
2160 visit(currentNode); 2203 visit(currentNode);
2161 if (isAborted()) { 2204 if (isAborted()) {
2162 compiler.unimplemented( 2205 compiler.unimplemented(
2163 "SsaBuilder for labeled statement with aborting body", node: node); 2206 "SsaBuilder for labeled statement with aborting body", node: node);
2164 } 2207 }
2165 HBasicBlock exitBlock = current; 2208 HBasicBlock joinBlock = graph.addNewBlock();
2209 List<LocalsHandler> breakLocals = <LocalsHandler>[];
2166 handler.forEachBreak((HBreak breakInstruction, LocalsHandler locals) { 2210 handler.forEachBreak((HBreak breakInstruction, LocalsHandler locals) {
2167 HBasicBlock joinBlock = graph.addNewBlock();
2168 breakInstruction.block.addSuccessor(joinBlock); 2211 breakInstruction.block.addSuccessor(joinBlock);
2169 if (!isAborted()) { 2212 breakLocals.add(locals);
2170 goto(current, joinBlock);
2171 open(joinBlock);
2172 localsHandler.mergeWith(locals, joinBlock);
2173 } else {
2174 open(joinBlock);
2175 localsHandler = locals;
2176 }
2177 }); 2213 });
2178 if (current !== exitBlock) { 2214 bool hasBreak = breakLocals.length > 0;
2215 if (!isAborted()) {
2216 goto(current, joinBlock);
2217 breakLocals.add(localsHandler);
2218 }
2219 localsHandler = beforeLocals.mergeMultiple(breakLocals, joinBlock);
2220
2221 if (hasBreak) {
2179 // There was at least one reachable break, so the label is needed. 2222 // There was at least one reachable break, so the label is needed.
2180 HLabeledBlockInformation blockInfo = 2223 HLabeledBlockInformation blockInfo =
2181 new HLabeledBlockInformation(entryBlock, current, 2224 new HLabeledBlockInformation(entryBlock, current,
2182 handler.labels()); 2225 handler.labels());
2183 handler.close(); 2226 handler.close();
2184 entryBlock.labeledBlockInformation = blockInfo;
2185 // Mark both entry and exit with the information. You can 2227 // Mark both entry and exit with the information. You can
2186 // tell which one is which by comparing with blockInfo.start/end. 2228 // tell which one is which by comparing with blockInfo.start/end.
2187 // It doesn't matter which merge block we use, they won't be generating 2229 // It doesn't matter which merge block we use, they won't be generating
2188 // any code, so put the end-marker on the last join block. 2230 // any code, so put the end-marker on the last join block.
2231 entryBlock.labeledBlockInformation = blockInfo;
2189 current.labeledBlockInformation = blockInfo; 2232 current.labeledBlockInformation = blockInfo;
2190 } 2233 }
2191 } 2234 }
2192 } 2235 }
2193 2236
2194 visitLiteralMap(LiteralMap node) { 2237 visitLiteralMap(LiteralMap node) {
2195 compiler.unimplemented('SsaBuilder.visitLiteralMap', node: node); 2238 compiler.unimplemented('SsaBuilder.visitLiteralMap', node: node);
2196 } 2239 }
2197 2240
2198 visitLiteralMapEntry(LiteralMapEntry node) { 2241 visitLiteralMapEntry(LiteralMapEntry node) {
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after
2308 } 2351 }
2309 2352
2310 visitCatchBlock(CatchBlock node) { 2353 visitCatchBlock(CatchBlock node) {
2311 visit(node.block); 2354 visit(node.block);
2312 } 2355 }
2313 2356
2314 visitTypedef(Typedef node) { 2357 visitTypedef(Typedef node) {
2315 compiler.unimplemented('SsaBuilder.visitTypedef', node: node); 2358 compiler.unimplemented('SsaBuilder.visitTypedef', node: node);
2316 } 2359 }
2317 } 2360 }
OLDNEW
« no previous file with comments | « no previous file | frog/leg/ssa/nodes.dart » ('j') | frog/leg/ssa/nodes.dart » ('J')

Powered by Google App Engine
This is Rietveld 408576698