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

Unified Diff: lib/compiler/implementation/ssa/bailout.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/bailout.dart
===================================================================
--- lib/compiler/implementation/ssa/bailout.dart (revision 8532)
+++ lib/compiler/implementation/ssa/bailout.dart (working copy)
@@ -26,7 +26,11 @@
}
void add(HInstruction instruction) {
- if (!instruction.isCodeMotionInvariant()) {
+ // We don't need to an code motion invariant instructions in the
kasperl 2012/06/12 12:18:40 need to an code?
ngeoffray 2012/06/12 12:28:18 Done.
+ // live set except for parameters that are not 'this' ('this' is
kasperl 2012/06/12 12:18:40 ('this' is -> , which is
ngeoffray 2012/06/12 12:28:18 Done.
+ // always passed as the receiver).
+ if (!instruction.isCodeMotionInvariant()
floitsch 2012/06/12 15:01:17 Explain that this is, because we generate these at
+ || (instruction is HParameterValue && instruction is !HThis)) {
lives.add(instruction);
} else {
for (int i = 0, len = instruction.inputs.length; i < len; i++) {
@@ -199,13 +203,33 @@
HType speculativeType = instruction.propagatedType;
if (shouldInsertTypeGuard(instruction)) {
List<HInstruction> inputs = <HInstruction>[instruction];
- HTypeGuard guard = new HTypeGuard(speculativeType, stateId++, inputs);
+ HInstruction insertionPoint;
+ if (instruction is HPhi) {
+ insertionPoint = instruction.block.first;
+ } else if (instruction is HParameterValue) {
+ // We insert the type guard at the end of the entry block
+ // because if a parameter is live, it must be kept in the live
+ // environment. Not doing so would mean we could visit a
+ // parameter and remove it from the environment before
+ // visiting a type guard.
+ insertionPoint = instruction.block.last;
+ } else {
+ insertionPoint = instruction.next;
+ }
+ int state;
kasperl 2012/06/12 12:18:40 I would move 'int state' down below the comment.
ngeoffray 2012/06/12 12:28:18 Done.
+ // If the previous instruction is also a type guard, then both
+ // guards have the same environment, and can therefore share the
+ // same state id.
+ if (insertionPoint.previous is HTypeGuard) {
+ HTypeGuard other = insertionPoint.previous;
+ state = other.state;
+ } else {
+ state = stateId++;
+ }
+ HTypeGuard guard = new HTypeGuard(speculativeType, state, inputs);
guard.propagatedType = speculativeType;
work.guards.add(guard);
instruction.block.rewrite(instruction, guard);
- HInstruction insertionPoint = (instruction is HPhi)
- ? instruction.block.first
- : instruction.next;
insertionPoint.block.addBefore(insertionPoint, guard);
}
}
@@ -340,17 +364,39 @@
final Compiler compiler;
final List<HBasicBlock> blocks;
final List<HLabeledBlockInformation> labeledBlockInformations;
+ final Set<HInstruction> generateAtUseSite;
+ final VariableNames variableNames;
SubGraph subGraph;
- SsaBailoutPropagator(Compiler this.compiler)
+ /**
+ * If set to true, the graph has either multiple bailouts in
+ * different places, or a bailout inside an if or a loop. For such a
+ * graph, the code generator will emit a generic switch.
+ */
+ bool hasComplexTypeGuards = false;
+
+ /**
+ * The first type guard in the graph.
+ */
+ HTypeGuard firstTypeGuard;
+
+ /**
+ * If set, it is the first block in the graph where we generate
+ * code. Blocks before this one are dead code in the bailout
+ * version.
+ */
+ HBasicBlock startGeneratingAt;
+
kasperl 2012/06/12 12:18:40 Remove one newline here.
ngeoffray 2012/06/12 12:28:18 Done.
+
+ SsaBailoutPropagator(this.compiler,
+ this.generateAtUseSite,
+ this.variableNames)
: blocks = <HBasicBlock>[],
labeledBlockInformations = <HLabeledBlockInformation>[];
void visitGraph(HGraph graph) {
subGraph = new SubGraph(graph.entry, graph.exit);
- blocks.addLast(graph.entry);
visitBasicBlock(graph.entry);
- blocks.removeLast();
if (!blocks.isEmpty()) {
compiler.internalError('Bailout propagation',
node: compiler.currentElement.parseNode(compiler));
@@ -363,7 +409,8 @@
if (block.isLoopHeader()) {
blocks.addLast(block);
- } else if (block.isLabeledBlock() && blocks.last() !== block) {
+ } else if (block.isLabeledBlock()
+ && (blocks.isEmpty() || blocks.last() !== block)) {
HLabeledBlockInformation info = block.blockFlow.body;
visitStatements(info.body);
return;
@@ -460,9 +507,45 @@
}
}
+ // 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;
+ }
+
visitTypeGuard(HTypeGuard guard) {
- blocks.forEach((HBasicBlock block) {
- block.guards.add(guard);
- });
+ // Sort the names of all type guards, to be able to merge
kasperl 2012/06/12 12:18:40 to be able to -> so we can
ngeoffray 2012/06/12 12:28:18 Done.
+ // guards that have the same state id.
+ List<String> names = <String>[];
+ for (HInstruction input in guard.inputs) {
+ HInstruction instruction = unwrap(input);
+ names.add(variableNames.getName(instruction));
+ }
+ names.sort((a, b) => a.compareTo(b));
+ guard.sortedVariableNames = names;
+
+ if (firstTypeGuard === null || firstTypeGuard.state === guard.state) {
+ firstTypeGuard = guard;
+ if (!blocks.isEmpty()) {
+ hasComplexTypeGuards = true;
+ // We start generating at the first block that has control
+ // flow.
+ startGeneratingAt = blocks[0];
+ blocks.forEach((HBasicBlock block) {
+ block.guards.add(guard);
+ });
+ }
+ } else {
+ hasComplexTypeGuards = true;
+ blocks.forEach((HBasicBlock block) {
+ block.guards.add(guard);
+ });
+ }
}
}
« no previous file with comments | « no previous file | lib/compiler/implementation/ssa/codegen.dart » ('j') | lib/compiler/implementation/ssa/codegen.dart » ('J')

Powered by Google App Engine
This is Rietveld 408576698