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

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

Issue 11359068: Do not use hack around aborting loop body for a do/while. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years, 1 month 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | sdk/lib/_internal/compiler/implementation/ssa/codegen.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: sdk/lib/_internal/compiler/implementation/ssa/builder.dart
===================================================================
--- sdk/lib/_internal/compiler/implementation/ssa/builder.dart (revision 14555)
+++ sdk/lib/_internal/compiler/implementation/ssa/builder.dart (working copy)
@@ -771,6 +771,7 @@
void forEachContinue(void action(HContinue instruction,
LocalsHandler locals));
bool hasAnyContinue();
+ bool hasAnyBreak();
void close();
final TargetElement target;
List<LabelElement> labels();
@@ -796,6 +797,7 @@
void forEachContinue(Function ignored) { }
void close() { }
bool hasAnyContinue() => false;
+ bool hasAnyBreak() => false;
List<LabelElement> labels() => const <LabelElement>[];
TargetElement get target => null;
@@ -860,6 +862,13 @@
return false;
}
+ bool hasAnyBreak() {
+ for (JumpHandlerEntry entry in jumps) {
+ if (entry.isBreak()) return true;
+ }
+ return false;
+ }
+
void close() {
// The mapping from TargetElement to JumpHandler is no longer needed.
builder.jumpTargets.remove(target);
@@ -1728,14 +1737,18 @@
HBasicBlock branchBlock,
JumpHandler jumpHandler,
LocalsHandler savedLocals) {
+ if (branchBlock == null && !jumpHandler.hasAnyBreak()) return;
+
HBasicBlock loopExitBlock = addNewBlock();
- assert(branchBlock.successors.length == 1);
+ assert(branchBlock == null || branchBlock.successors.length == 1);
List<LocalsHandler> breakLocals = <LocalsHandler>[];
jumpHandler.forEachBreak((HBreak breakInstruction, LocalsHandler locals) {
breakInstruction.block.addSuccessor(loopExitBlock);
breakLocals.add(locals);
});
- branchBlock.addSuccessor(loopExitBlock);
+ if (branchBlock != null) {
+ branchBlock.addSuccessor(loopExitBlock);
+ }
open(loopExitBlock);
localsHandler.endLoop(loopEntry);
if (!breakLocals.isEmpty) {
@@ -1953,51 +1966,71 @@
bodyEntryBlock = openNewBlock();
}
localsHandler.enterLoopBody(node);
- hackAroundPossiblyAbortingBody(node, () { visit(node.body); });
+ visit(node.body);
// If there are no continues we could avoid the creation of the condition
// block. This could also lead to a block having multiple entries and exits.
- HBasicBlock bodyExitBlock = close(new HGoto());
- HBasicBlock conditionBlock = addNewBlock();
+ HBasicBlock bodyExitBlock;
+ bool isAbortingBody = false;
+ if (current != null) {
+ bodyExitBlock = close(new HGoto());
+ } else {
+ isAbortingBody = true;
+ bodyExitBlock = lastOpenedBlock;
+ }
- List<LocalsHandler> continueLocals = <LocalsHandler>[];
- jumpHandler.forEachContinue((HContinue instruction, LocalsHandler locals) {
- instruction.block.addSuccessor(conditionBlock);
- continueLocals.add(locals);
- });
- bodyExitBlock.addSuccessor(conditionBlock);
- if (!continueLocals.isEmpty) {
- continueLocals.add(localsHandler);
- localsHandler = savedLocals.mergeMultiple(continueLocals, conditionBlock);
- SubGraph bodyGraph = new SubGraph(bodyEntryBlock, bodyExitBlock);
- List<LabelElement> labels = jumpHandler.labels();
- HSubGraphBlockInformation bodyInfo =
- new HSubGraphBlockInformation(bodyGraph);
- HLabeledBlockInformation info;
- if (!labels.isEmpty) {
- info = new HLabeledBlockInformation(bodyInfo, labels, isContinue: true);
- } else {
- info = new HLabeledBlockInformation.implicit(bodyInfo, target,
- isContinue: true);
+ SubExpression conditionExpression;
+ HBasicBlock conditionEndBlock;
+ if (!isAbortingBody || hasContinues) {
+ HBasicBlock conditionBlock = addNewBlock();
+
+ List<LocalsHandler> continueLocals = <LocalsHandler>[];
+ jumpHandler.forEachContinue((HContinue instruction,
+ LocalsHandler locals) {
+ instruction.block.addSuccessor(conditionBlock);
+ continueLocals.add(locals);
+ });
+
+ if (!isAbortingBody) {
+ bodyExitBlock.addSuccessor(conditionBlock);
}
- bodyEntryBlock.setBlockFlow(info, conditionBlock);
+
+ if (!continueLocals.isEmpty) {
+ if (!isAbortingBody) continueLocals.add(localsHandler);
+ localsHandler =
+ savedLocals.mergeMultiple(continueLocals, conditionBlock);
+ SubGraph bodyGraph = new SubGraph(bodyEntryBlock, bodyExitBlock);
+ List<LabelElement> labels = jumpHandler.labels();
+ HSubGraphBlockInformation bodyInfo =
+ new HSubGraphBlockInformation(bodyGraph);
+ HLabeledBlockInformation info;
+ if (!labels.isEmpty) {
+ info = new HLabeledBlockInformation(bodyInfo, labels,
+ isContinue: true);
+ } else {
+ info = new HLabeledBlockInformation.implicit(bodyInfo, target,
+ isContinue: true);
+ }
+ bodyEntryBlock.setBlockFlow(info, conditionBlock);
+ }
+ open(conditionBlock);
+
+ visit(node.condition);
+ assert(!isAborted());
+ HInstruction conditionInstruction = popBoolified();
+ conditionEndBlock = close(
+ new HLoopBranch(conditionInstruction, HLoopBranch.DO_WHILE_LOOP));
+
+ conditionEndBlock.addSuccessor(loopEntryBlock); // The back-edge.
+ conditionExpression =
+ new SubExpression(conditionBlock, conditionEndBlock);
}
- open(conditionBlock);
- visit(node.condition);
- assert(!isAborted());
- HInstruction conditionInstruction = popBoolified();
- HBasicBlock conditionEndBlock =
- close(new HLoopBranch(conditionInstruction, HLoopBranch.DO_WHILE_LOOP));
-
- conditionEndBlock.addSuccessor(loopEntryBlock); // The back-edge.
loopEntryBlock.postProcessLoopHeader();
endLoop(loopEntryBlock, conditionEndBlock, jumpHandler, localsHandler);
jumpHandler.close();
- SubExpression conditionExpression =
- new SubExpression(conditionBlock, conditionEndBlock);
SubGraph bodyGraph = new SubGraph(bodyEntryBlock, bodyExitBlock);
HLoopBlockInformation loopBlockInfo =
« no previous file with comments | « no previous file | sdk/lib/_internal/compiler/implementation/ssa/codegen.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698