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

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

Issue 10383062: Avoid inserting new temporaries because of HTypeConversion nodes. (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
Index: lib/compiler/implementation/ssa/codegen.dart
===================================================================
--- lib/compiler/implementation/ssa/codegen.dart (revision 7378)
+++ lib/compiler/implementation/ssa/codegen.dart (working copy)
@@ -517,24 +517,80 @@
}
void define(HInstruction instruction) {
- String name = temporary(instruction);
- declareVariable(name);
- buffer.add(" = ");
- visit(instruction, JSPrecedence.ASSIGNMENT_PRECEDENCE);
+ bool needsVar = !instruction.usedBy.isEmpty();
+ if (needsVar) {
+ if (instruction.returnsInput()) {
Lasse Reichstein Nielsen 2012/05/08 12:39:08 Use single if with '&&'.
ngeoffray 2012/05/08 16:09:12 Done.
+ HInstruction input = instruction.input;
+ // We only need a new var if [input] is generated at use site
+ // but is not a trivial code motion invariant instruction (eg
floitsch 2012/05/08 13:21:42 "like for". There is enough space.
ngeoffray 2012/05/08 16:09:12 Done.
+ // parameters or this).
+ //
+ // For example:
+ // Foo a = this;
+ // print(a);
+ // print(a);
+ //
+ // In checked mode does not need a new variable:
floitsch 2012/05/08 13:21:42 In checked mode no new variable is needed:
ngeoffray 2012/05/08 16:09:12 Done.
+ // FooTypeCheck(this);
+ // print(this);
+ // print(this);
+ //
+ // But for this example:
+ // Foo a = foo();
+ // print(a);
+ // print(a);
+ //
+ // We need a new variable:
+ // var a = FooTypeCheck(foo());
+ // print(a);
+ // print(a);
+ needsVar = isGenerateAtUseSite(input) && !input.isCodeMotionInvariant();
floitsch 2012/05/08 13:21:42 If I understand correctly it is crucial that 'defi
ngeoffray 2012/05/08 16:09:12 Done.
+ }
+ }
+ if (needsVar) {
+ String name = temporary(instruction);
+ declareVariable(name);
+ buffer.add(" = ");
+ visit(instruction, JSPrecedence.ASSIGNMENT_PRECEDENCE);
+ } else {
+ visit(instruction, JSPrecedence.STATEMENT_PRECEDENCE);
+ }
}
void use(HInstruction argument, int expectedPrecedenceForArgument) {
- if (isGenerateAtUseSite(argument)) {
+ if (argument.returnsInput()) {
+ HInstruction input = argument.input;
+ if (isGenerateAtUseSite(argument) && isGenerateAtUseSite(input)) {
+ // If both instructions can be generated at use site, we can
+ // just visit [argument].
+ //
+ // For example:
+ // Foo a = foo();
+ // print(a);
+ //
+ // In checked mode will turn into:
+ // print(FooTypeCheck(foo()));
+ visit(argument, expectedPrecedenceForArgument);
+ } else if (isGenerateAtUseSite(input) && !input.isCodeMotionInvariant()) {
Lasse Reichstein Nielsen 2012/05/08 12:39:08 Please explain the use of isCodeMotionInvariant.
ngeoffray 2012/05/08 16:09:12 Done.
+ // If [argument] cannot be generated at use site, but [input]
+ // can, use the temporary of [argument].
+ //
+ // For example:
+ // Foo a = foo();
+ // print(a);
+ // print(a);
+ //
+ // In checked mode will turn into:
+ // var a = FooTypeCheck(foo());
+ // print(a);
+ // print(a);
+ buffer.add(temporary(argument));
+ } else {
+ // Otherwise we just use [input].
Lasse Reichstein Nielsen 2012/05/08 12:39:08 Please give example of output here too. What happe
ngeoffray 2012/05/08 16:09:12 Done.
+ use(input, expectedPrecedenceForArgument);
+ }
+ } else if (isGenerateAtUseSite(argument)) {
visit(argument, expectedPrecedenceForArgument);
- } else if (argument is HIntegerCheck) {
- HIntegerCheck instruction = argument;
- use(instruction.value, expectedPrecedenceForArgument);
- } else if (argument is HBoundsCheck) {
- HBoundsCheck instruction = argument;
- use(instruction.index, expectedPrecedenceForArgument);
- } else if (argument is HTypeGuard) {
- HTypeGuard instruction = argument;
- use(instruction.guarded, expectedPrecedenceForArgument);
} else {
buffer.add(temporary(argument));
}
@@ -1063,41 +1119,26 @@
assignPhisOfAllSuccessors(node);
}
- if (instruction is HGoto || instruction is HExit || instruction is HTry) {
- visit(instruction, JSPrecedence.STATEMENT_PRECEDENCE);
- return;
- } else if (!isGenerateAtUseSite(instruction)) {
- if (instruction is !HIf
- && instruction is !HTypeGuard
- && instruction is !HLoopBranch
- && !isGeneratingExpression()) {
- addIndentation();
+ 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);
}
- if (isGeneratingExpression()) {
+ } else if (instruction is HControlFlow) {
+ if (instruction is HLoopBranch && isGeneratingExpression()) {
addExpressionSeparator();
}
- if (instruction.usedBy.isEmpty()
- || instruction is HTypeGuard
- || instruction is HCheck) {
- visit(instruction, JSPrecedence.STATEMENT_PRECEDENCE);
- } else {
- define(instruction);
- }
- // Control flow instructions, and some other instructions,
- // know how to handle ';'.
- if (instruction is !HControlFlow
- && instruction is !HTypeGuard
- && !isGeneratingExpression()) {
- buffer.add(';\n');
- }
- } else 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);
- return;
+ visit(instruction, JSPrecedence.STATEMENT_PRECEDENCE);
+ } else if (instruction is HTypeGuard) {
+ visit(instruction, JSPrecedence.STATEMENT_PRECEDENCE);
+ } else {
+ isGeneratingExpression() ? addExpressionSeparator() : addIndentation();
Lasse Reichstein Nielsen 2012/05/08 12:39:08 Use if. Please don't (try) to be clever with the c
ngeoffray 2012/05/08 16:09:12 Done.
+ define(instruction);
+ if (!isGeneratingExpression()) buffer.add(';\n');
}
instruction = instruction.next;
}
@@ -1618,6 +1659,7 @@
}
visitReturn(HReturn node) {
+ addIndentation();
assert(node.inputs.length == 1);
HInstruction input = node.inputs[0];
if (input.isConstantNull()) {
@@ -1634,6 +1676,7 @@
}
visitThrow(HThrow node) {
+ addIndentation();
if (node.isRethrow) {
buffer.add('throw ');
use(node.inputs[0], JSPrecedence.EXPRESSION_PRECEDENCE);
@@ -2033,6 +2076,7 @@
}
void visitTypeConversion(HTypeConversion node) {
+ HInstruction input = node.inputs[0];
Lasse Reichstein Nielsen 2012/05/08 12:39:08 node.input? Why extract input here, when it's only
ngeoffray 2012/05/08 16:09:12 Done.
if (node.checked) {
Element element = node.type.computeType(compiler).element;
compiler.registerIsCheck(element);
@@ -2080,12 +2124,12 @@
compiler.registerStaticUse(helperElement);
buffer.add(compiler.namer.isolateAccess(helperElement));
buffer.add('(');
- use(node.inputs[0], JSPrecedence.EXPRESSION_PRECEDENCE);
+ use(input, JSPrecedence.EXPRESSION_PRECEDENCE);
if (additionalArgument !== null) buffer.add(", '$additionalArgument'");
buffer.add(')');
endExpression(JSPrecedence.CALL_PRECEDENCE);
} else {
- use(node.inputs[0], expectedPrecedence);
+ visit(input, expectedPrecedence);
}
}
}
« no previous file with comments | « no previous file | lib/compiler/implementation/ssa/codegen_helpers.dart » ('j') | lib/compiler/implementation/ssa/nodes.dart » ('J')

Powered by Google App Engine
This is Rietveld 408576698