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

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

Issue 10495013: Recognize logical operations before code generation. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years, 6 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 | « lib/compiler/implementation/ssa/builder.dart ('k') | lib/compiler/implementation/ssa/codegen_helpers.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 8244)
+++ lib/compiler/implementation/ssa/codegen.dart (working copy)
@@ -147,7 +147,7 @@
final String parameters;
final Set<HInstruction> generateAtUseSite;
- final Map<HPhi, String> logicalOperations;
+ final Set<HInstruction> logicalOperations;
final Map<Element, ElementAction> breakAction;
final Map<Element, ElementAction> continueAction;
final Map<Element, String> parameterNames;
@@ -206,7 +206,7 @@
delayedVariablesDeclaration = new List<String>(),
buffer = new StringBuffer(),
generateAtUseSite = new Set<HInstruction>(),
- logicalOperations = new Map<HPhi, String>(),
+ logicalOperations = new Set<HInstruction>(),
breakAction = new Map<Element, ElementAction>(),
continueAction = new Map<Element, ElementAction>(),
unsignedShiftPrecedences = JSPrecedence.binary['>>>'] {
@@ -487,6 +487,11 @@
}
void define(HInstruction instruction) {
+ if (isGeneratingExpression()) {
+ addExpressionSeparator();
+ } else {
+ addIndentation();
+ }
if (instruction is !HCheck && variableNames.hasName(instruction)) {
declareInstruction(instruction);
buffer.add(" = ");
@@ -494,6 +499,7 @@
} else {
visit(instruction, JSPrecedence.STATEMENT_PRECEDENCE);
}
+ if (!isGeneratingExpression()) buffer.add(';\n');
}
void use(HInstruction argument, int expectedPrecedenceForArgument) {
@@ -533,6 +539,9 @@
}
bool visitIfInfo(HIfBlockInformation info) {
+ // If the [HIf] instruction is actually a logical operation, we
+ // let the flow-based traversal handle it.
+ if (logicalOperations.contains(info.condition.end.last)) return false;
HInstruction condition = info.condition.conditionExpression;
if (condition.isConstant()) {
// If the condition is constant, only generate one branch (if any).
@@ -809,16 +818,6 @@
return true;
}
- void emitLogicalOperation(HPhi node, String operation) {
- JSBinaryOperatorPrecedence operatorPrecedence =
- JSPrecedence.binary[operation];
- beginExpression(operatorPrecedence.precedence);
- use(node.inputs[0], operatorPrecedence.left);
- buffer.add(" $operation ");
- use(node.inputs[1], operatorPrecedence.right);
- endExpression(operatorPrecedence.precedence);
- }
-
// Wraps a loop body in a block to make continues have a target to break
// to (if necessary).
void wrapLoopBodyForContinue(HLoopBlockInformation info) {
@@ -1012,38 +1011,19 @@
void iterateBasicBlock(HBasicBlock node) {
HInstruction instruction = node.first;
- while (instruction != null) {
- if (instruction === node.last) {
- assignPhisOfSuccessors(node);
- }
-
- if (isGenerateAtUseSite(instruction)) {
- if (instruction is HIf) {
- HIf hif = instruction;
- // The "if" is implementing part of a logical expression.
- // Skip directly forward to to its latest successor, since everything
- // in-between must also be generateAtUseSite.
- assert(hif.trueBranch.id < hif.falseBranch.id);
- visitBasicBlock(hif.falseBranch);
- }
- } else if (instruction is HControlFlow) {
- if (instruction is HLoopBranch && isGeneratingExpression()) {
- addExpressionSeparator();
- }
+ while (instruction !== node.last) {
+ if (instruction is HTypeGuard) {
visit(instruction, JSPrecedence.STATEMENT_PRECEDENCE);
- } else if (instruction is HTypeGuard) {
- visit(instruction, JSPrecedence.STATEMENT_PRECEDENCE);
- } else {
- if (isGeneratingExpression()) {
- addExpressionSeparator();
- } else {
- addIndentation();
- }
+ } else if (!isGenerateAtUseSite(instruction)) {
define(instruction);
- if (!isGeneratingExpression()) buffer.add(';\n');
}
instruction = instruction.next;
}
+ assignPhisOfSuccessors(node);
+ if (instruction is HLoopBranch && isGeneratingExpression()) {
+ addExpressionSeparator();
+ }
+ visit(instruction, JSPrecedence.STATEMENT_PRECEDENCE);
}
visitInvokeBinary(HInvokeBinary node, String op) {
@@ -1263,7 +1243,6 @@
|| start.last is HContinue) {
return false;
}
- HInstruction instruction = start.first;
for (HInstruction instruction = start.first;
instruction != start.last;
instruction = instruction.next) {
@@ -1286,12 +1265,20 @@
}
visitIf(HIf node) {
+ if (logicalOperations.contains(node)) {
+ HPhi phi = node.joinBlock.phis.first;
+ if (!isGenerateAtUseSite(phi)) define(phi);
+ visitBasicBlock(node.joinBlock);
+ return;
+ }
+
if (subGraph !== null && node.block === subGraph.end) {
if (isGeneratingExpression()) {
use(node.inputs[0], JSPrecedence.EXPRESSION_PRECEDENCE);
}
return;
}
+
HInstruction condition = node.inputs[0];
int preVisitedBlocks = 0;
List<HBasicBlock> dominated = node.block.dominatedBlocks;
@@ -1587,17 +1574,20 @@
}
visitNot(HNot node) {
+ assert(node.inputs.length == 1);
+ generateNot(node.inputs[0]);
+ }
+
+
+ void generateNot(HInstruction input) {
bool isBuiltinRelational(HInstruction instruction) {
if (instruction is !HRelational) return false;
HRelational relational = instruction;
return relational.builtin;
}
- assert(node.inputs.length == 1);
- HInstruction input = node.inputs[0];
if (input is HBoolify && isGenerateAtUseSite(input)) {
beginExpression(JSPrecedence.EQUALITY_PRECEDENCE);
- assert(node.inputs.length == 1);
use(input.inputs[0], JSPrecedence.EQUALITY_PRECEDENCE);
buffer.add(' !== true');
endExpression(JSPrecedence.EQUALITY_PRECEDENCE);
@@ -1636,11 +1626,33 @@
}
visitPhi(HPhi node) {
- String operation = logicalOperations[node];
- if (operation !== null) {
- emitLogicalOperation(node, operation);
+ HBasicBlock ifBlock = node.block.predecessors[0].predecessors[0];
+ // This method is only called for phis that are generated at use
+ // site. A phi can be generated at use site only if it is the
+ // result of a logical operation.
+ assert(logicalOperations.contains(ifBlock.last));
+ HInstruction input = ifBlock.last.inputs[0];
+ if (input.isConstantFalse()) {
+ use(node.inputs[1], expectedPrecedence);
+ } else if (input.isConstantTrue()) {
+ use(node.inputs[0], expectedPrecedence);
} else {
- buffer.add('${variableNames.getName(node)}');
+ String operation = node.inputs[1].isConstantFalse() ? '&&' : '||';
+ JSBinaryOperatorPrecedence operatorPrecedence =
+ JSPrecedence.binary[operation];
+ beginExpression(operatorPrecedence.precedence);
+ if (operation == '||') {
+ if (input is HNot) {
+ use(input.inputs[0], operatorPrecedence.left);
+ } else {
+ generateNot(input);
+ }
+ } else {
+ use(input, operatorPrecedence.left);
+ }
+ buffer.add(" $operation ");
+ use(node.inputs[0], operatorPrecedence.right);
+ endExpression(operatorPrecedence.precedence);
}
}
« no previous file with comments | « lib/compiler/implementation/ssa/builder.dart ('k') | lib/compiler/implementation/ssa/codegen_helpers.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698