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

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
« no previous file with comments | « lib/compiler/implementation/ssa/bailout.dart ('k') | lib/compiler/implementation/ssa/nodes.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 8591)
+++ 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(
@@ -2463,7 +2454,7 @@
int maxBailoutParameters;
- void beginGraph(HGraph graph) {}
+ HBasicBlock beginGraph(HGraph graph) => graph.entry;
void endGraph(HGraph graph) {}
void bailout(HTypeGuard guard, String reason) {
@@ -2487,10 +2478,7 @@
} 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.
@@ -2607,13 +2595,18 @@
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(),
+ newParameters = new StringBuffer(),
labels = <String>[];
String pushLabel() {
@@ -2630,38 +2623,33 @@
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);
+ 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();
- void endGraph(HGraph graph) {
- if (!graph.entry.hasGuards()) return;
- indent--; // Close original case.
- indent--;
- addIndented('}\n'); // Close 'switch'.
- setup.add(' }\n');
+ // 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');
+ return graph.entry;
+ } else {
+ // 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;
+ }
}
- bool visitAndOrInfo(HAndOrBlockInformation info) => false;
- bool visitIfInfo(HIfBlockInformation info) => false;
- bool visitLoopInfo(HLoopBlockInformation info) => false;
- 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) {
+ HInstruction unwrap(HInstruction argument) {
while (argument is HCheck && !variableNames.hasName(argument)) {
argument = argument.checkedInput;
}
@@ -2669,7 +2657,48 @@
return argument;
}
+ void endGraph(HGraph graph) {
+ // TODO(ngeoffray): We could avoid generating the state at the
+ // call site for non-complex bailout methods.
+ newParameters.add('state');
+
+ if (!propagator.hasComplexTypeGuards) {
+ propagator.firstTypeGuard.block.first = savedFirstInstruction;
+ for (HInstruction input in propagator.firstTypeGuard.inputs) {
+ input = unwrap(input);
+ newParameters.add(', ${variableNames.getName(input)}');
+ }
+ } 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) {
+ 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;
+
void visitTypeGuard(HTypeGuard node) {
+ if (!propagator.hasComplexTypeGuards) return;
+
indent--;
addIndented('case ${node.state}:\n');
indent++;
@@ -2678,8 +2707,9 @@
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');
+ input = unwrap(input);
+ String name = variableNames.getName(input);
+ setup.add(' $name = env$i;\n');
i++;
}
if (i > maxBailoutParameters) maxBailoutParameters = i;
@@ -2714,7 +2744,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>[]);
« no previous file with comments | « lib/compiler/implementation/ssa/bailout.dart ('k') | lib/compiler/implementation/ssa/nodes.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698