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

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

Issue 10539106: Simplify generated code for trivial bailout methods. (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
Index: lib/compiler/implementation/ssa/codegen.dart
===================================================================
--- lib/compiler/implementation/ssa/codegen.dart (revision 8532)
+++ lib/compiler/implementation/ssa/codegen.dart (working copy)
@@ -72,7 +72,6 @@
String generateBailoutMethod(WorkItem work, HGraph graph) {
return measure(() {
compiler.tracer.traceGraph("codegen-bailout", graph);
- new SsaBailoutPropagator(compiler).visitGraph(graph);
Map<Element, String> parameterNames = getParameterNames(work);
String parameters = Strings.join(parameterNames.getValues(), ', ');
@@ -80,17 +79,9 @@
backend, work, parameters, parameterNames);
codegen.visitGraph(graph);
- StringBuffer newParameters = new StringBuffer();
- if (!parameterNames.isEmpty()) newParameters.add('$parameters, ');
- newParameters.add('state');
-
- for (int i = 0; i < codegen.maxBailoutParameters; i++) {
- newParameters.add(', env$i');
- }
-
- Element element = work.element;
String body = '${codegen.setup}${codegen.buffer}';
- return buildJavaScriptFunction(element, newParameters.toString(), body);
+ return buildJavaScriptFunction(
+ work.element, codegen.newParameters.toString(), body);
});
}
@@ -273,8 +264,8 @@
currentGraph = graph;
indent++; // We are already inside a function.
subGraph = new SubGraph(graph.entry, graph.exit);
- beginGraph(graph);
- visitBasicBlock(graph.entry);
+ HBasicBlock start = beginGraph(graph);
+ visitBasicBlock(start);
if (!delayedVariableDeclarations.isEmpty()) {
addIndented("var ");
buffer.add(Strings.join(
@@ -2447,7 +2438,7 @@
int maxBailoutParameters;
- void beginGraph(HGraph graph) {}
+ HBasicBlock beginGraph(HGraph graph) => graph.entry;
void endGraph(HGraph graph) {}
void bailout(HTypeGuard guard, String reason) {
@@ -2471,17 +2462,13 @@
} else {
buffer.add(namer.isolateBailoutAccess(element));
}
- int parametersCount = parameterNames.length;
- buffer.add('($parameters');
- if (parametersCount != 0) buffer.add(', ');
- buffer.add('${guard.state}');
+ buffer.add('(${guard.state}');
// TODO(ngeoffray): try to put a variable at a deterministic
// location, so that multiple bailout calls put the variable at
// the same parameter index.
int i = 0;
- for (; i < guard.inputs.length; i++) {
- buffer.add(', ');
- use(guard.inputs[i], JSPrecedence.ASSIGNMENT_PRECEDENCE);
+ for (; i < guard.sortedVariableNames.length; i++) {
+ buffer.add(', ${guard.sortedVariableNames[i]}');
}
// Make sure we call the bailout method with the number of
// arguments it expects. This avoids having the underlying
@@ -2591,14 +2578,20 @@
class SsaUnoptimizedCodeGenerator extends SsaCodeGenerator {
final StringBuffer setup;
+ final StringBuffer newParameters;
final List<String> labels;
int labelId = 0;
int maxBailoutParameters = 0;
+ SsaBailoutPropagator propagator;
+ HInstruction savedFirstInstruction;
+
SsaUnoptimizedCodeGenerator(backend, work, parameters, parameterNames)
: super(backend, work, parameters, parameterNames),
setup = new StringBuffer(),
- labels = <String>[];
+ newParameters = new StringBuffer(),
+ labels = <String>[] {
kasperl 2012/06/12 12:18:40 Keep ;
ngeoffray 2012/06/12 12:28:18 Done.
+ }
String pushLabel() {
String label = 'L${labelId++}';
@@ -2614,46 +2607,77 @@
return labels.last();
}
- void beginGraph(HGraph graph) {
- if (!graph.entry.hasGuards()) return;
- addIndented('switch (state) {\n');
- indent++;
- addIndented('case 0:\n');
- indent++;
+ HBasicBlock beginGraph(HGraph graph) {
+ propagator = new SsaBailoutPropagator(
+ compiler, generateAtUseSite, variableNames);
+ propagator.visitGraph(graph);
- // The setup phase of a bailout function sets up the environment for
- // each bailout target. Each bailout target will populate this
- // setup phase. It is put at the beginning of the function.
- setup.add(' switch (state) {\n');
+ if (propagator.hasComplexTypeGuards) {
+ startBailoutSwitch();
+
+ // The setup phase of a bailout function sets up the environment for
+ // each bailout target. Each bailout target will populate this
+ // setup phase. It is put at the beginning of the function.
+ setup.add(' switch (state) {\n');
+ }
+
+ if (propagator.startGeneratingAt !== null) {
+ return propagator.startGeneratingAt;
+ }
+
+ // We change the first instruction of the first guard to be the
+ // guard. We will change it back in the call to [endGraph].
+ HBasicBlock block = propagator.firstTypeGuard.block;
+ savedFirstInstruction = block.first;
+ block.first = propagator.firstTypeGuard;
+ return block;
}
void endGraph(HGraph graph) {
- if (!graph.entry.hasGuards()) return;
- indent--; // Close original case.
- indent--;
- addIndented('}\n'); // Close 'switch'.
- setup.add(' }\n');
+ // Restore the first instruction of the first guard.
+ if (propagator.startGeneratingAt === null) {
+ propagator.firstTypeGuard.block.first = savedFirstInstruction;
+ }
+
+ // TODO(ngeoffray): We could avoid generating the state at the
+ // call site for non-complex bailout methods.
+ newParameters.add('state');
+
+ if (!propagator.hasComplexTypeGuards) {
+ for (String name in propagator.firstTypeGuard.sortedVariableNames) {
+ newParameters.add(', $name');
+ }
+ } else {
+ for (int i = 0; i < maxBailoutParameters; i++) {
+ newParameters.add(', env$i');
+ }
+ indent--; // Close original case.
+ indent--;
+ addIndented('}\n'); // Close 'switch'.
+ setup.add(' }\n');
+ }
}
bool visitAndOrInfo(HAndOrBlockInformation info) => false;
- bool visitIfInfo(HIfBlockInformation info) => false;
- bool visitLoopInfo(HLoopBlockInformation info) => false;
+
+ bool visitIfInfo(HIfBlockInformation info) {
+ if (info.thenGraph.start.hasGuards()) return false;
+ if (info.elseGraph.start.hasGuards()) return false;
+ return super.visitIfInfo(info);
+ }
+
+ bool visitLoopInfo(HLoopBlockInformation info) {
+ if (info.start.hasGuards()) return false;
+ if (info.loopHeader.hasGuards()) return false;
+ return super.visitLoopInfo(info);
+ }
+
bool visitTryInfo(HTryBlockInformation info) => false;
bool visitSequenceInfo(HStatementSequenceInformation info) => false;
- // If argument is a [HCheck] and it does not have a name, we try to
- // find the name of its checked input. Note that there must be a
- // name, otherwise the instruction would not be in the live
- // environment.
- HInstruction unwrap(argument) {
- while (argument is HCheck && !variableNames.hasName(argument)) {
- argument = argument.checkedInput;
- }
- assert(variableNames.hasName(argument));
- return argument;
- }
+ void visitTypeGuard(HTypeGuard node) {
+ if (!propagator.hasComplexTypeGuards) return;
- void visitTypeGuard(HTypeGuard node) {
indent--;
addIndented('case ${node.state}:\n');
indent++;
@@ -2661,9 +2685,8 @@
setup.add(' case ${node.state}:\n');
int i = 0;
- for (HInstruction input in node.inputs) {
- HInstruction instruction = unwrap(input);
- setup.add(' ${variableNames.getName(instruction)} = env$i;\n');
+ for (String name in node.sortedVariableNames) {
+ setup.add(' $name = env$i;\n');
i++;
}
if (i > maxBailoutParameters) maxBailoutParameters = i;
@@ -2686,9 +2709,7 @@
void startBailoutSwitch() {
addIndented('switch (state) {\n');
- indent++;
- addIndented('case 0:\n');
- indent++;
+ indent += 2;
}
void endBailoutSwitch() {
@@ -2698,7 +2719,6 @@
}
void beginLoop(HBasicBlock block) {
- // TODO(ngeoffray): Don't put labels on loops that don't bailout.
String newLabel = pushLabel();
if (block.hasGuards()) {
startBailoutCase(block.guards, const <HTypeGuard>[]);

Powered by Google App Engine
This is Rietveld 408576698