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

Unified Diff: lib/compiler/implementation/ssa/codegen.dart

Issue 10446098: Avoid generating empty else. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years, 7 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | lib/compiler/implementation/ssa/variable_allocator.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: lib/compiler/implementation/ssa/codegen.dart
===================================================================
--- lib/compiler/implementation/ssa/codegen.dart (revision 8145)
+++ lib/compiler/implementation/ssa/codegen.dart (working copy)
@@ -549,10 +549,11 @@
generateStatements(info.thenGraph);
indent--;
addIndented("}");
- if (info.elseGraph !== null) {
+ HSubGraphBlockInformation elseGraph = info.elseGraph;
+ if (elseGraph !== null && !isEmptyElse(elseGraph.start, elseGraph.end)) {
buffer.add(" else {\n");
indent++;
- generateStatements(info.elseGraph);
+ generateStatements(elseGraph);
indent--;
addIndented("}");
}
@@ -1251,6 +1252,35 @@
compiler.internalError('visitTry should not be called', instruction: node);
}
+ bool isEmptyElse(HBasicBlock start, HBasicBlock end) {
+ if (start !== end) return false;
+ if (start.last is !HGoto
+ || start.last is HBreak
+ || start.last is HContinue) {
+ return false;
+ }
+ HInstruction instruction = start.first;
+ for (HInstruction instruction = start.first;
+ instruction != start.last;
+ instruction = instruction.next) {
+ // Instructions generated at use site are okay because they do
+ // not generate code in this else block.
+ if (!isGenerateAtUseSite(instruction)) return false;
+ }
+ CopyHandler handler = variableNames.getCopyHandler(start);
+ if (handler == null || handler.isEmpty()) return true;
+ if (!handler.assignments.isEmpty()) return false;
+ // If the block has a copy where the destination and source are
+ // different, we will emit that copy, and therefore the block is
+ // not empty.
+ for (Copy copy in handler.copies) {
+ String sourceName = variableNames.getName(copy.source);
+ String destinationName = variableNames.getName(copy.destination);
+ if (sourceName != destinationName) return false;
+ }
+ return true;
+ }
+
visitIf(HIf node) {
if (subGraph !== null && node.block === subGraph.end) {
if (isGeneratingExpression()) {
@@ -1262,6 +1292,7 @@
int preVisitedBlocks = 0;
List<HBasicBlock> dominated = node.block.dominatedBlocks;
HIfBlockInformation info = node.blockInformation.body;
+ HBasicBlock joinBlock = node.joinBlock;
if (condition.isConstant()) {
HConstant constant = condition;
if (constant.constant.isTrue()) {
@@ -1279,7 +1310,11 @@
generateStatements(info.thenGraph);
preVisitedBlocks++;
endThen(node);
- if (node.hasElse) {
+ HBasicBlock endBlock =
+ (joinBlock == null || joinBlock.predecessors.length != 2)
+ ? null
+ : joinBlock.predecessors[1];
+ if (node.hasElse && !isEmptyElse(node.elseBlock, endBlock)) {
startElse(node);
assert(node.elseBlock === dominated[1]);
generateStatements(info.elseGraph);
@@ -1288,7 +1323,6 @@
}
endIf(node);
}
- HBasicBlock joinBlock = node.joinBlock;
if (joinBlock !== null && joinBlock.dominator !== node.block) {
// The join block is dominated by a block in one of the branches.
// The subgraph traversal never reached it, so we visit it here
« no previous file with comments | « no previous file | lib/compiler/implementation/ssa/variable_allocator.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698