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

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

Issue 10558022: Better bitwise and binary arithmetic when the left operand is known to be a number. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Cleanup HTypeConversion usage. 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/types_propagation.dart
diff --git a/lib/compiler/implementation/ssa/types_propagation.dart b/lib/compiler/implementation/ssa/types_propagation.dart
index 44dc10b5f2c5503208786e73c69b4086ffc8d375..56f43f05b8fec7c23838bc8ff7aef12804d8db7a 100644
--- a/lib/compiler/implementation/ssa/types_propagation.dart
+++ b/lib/compiler/implementation/ssa/types_propagation.dart
@@ -22,6 +22,9 @@ class SsaTypePropagator extends HGraphVisitor implements OptimizationPhase {
// Re-compute and update the type of the instruction. Returns
// whether or not the type was changed.
bool updateType(HInstruction instruction) {
+ // Visit the instruction before computing types.
+ visitInstruction(instruction);
+ // Compute old and new types.
HType oldType = instruction.propagatedType;
HType newType = computeType(instruction);
// We unconditionally replace the propagated type with the new type. The
@@ -30,6 +33,21 @@ class SsaTypePropagator extends HGraphVisitor implements OptimizationPhase {
return oldType != newType;
}
+ void visitInstruction(HInstruction instruction) {
+ if (instruction is !HBinaryArithmetic) return;
+ HInstruction left = instruction.left;
+ if (!left.isNumber()) return;
+ HInstruction right = instruction.right;
+ // TODO(floitsch): Enable this once we made it so inputs must be
+ // integers for all bitwise operations.
+ if (false && instruction is HBinaryBitOp) {
+ if (!left.isInteger()) convertInput(instruction, left, HType.INTEGER);
floitsch 2012/06/19 11:15:58 we cannot convert an input until the type-propagat
kasperl 2012/06/19 11:22:06 Yeah, that's a good point. I'll fix it and send yo
+ if (!right.isInteger()) convertInput(instruction, right, HType.INTEGER);
+ } else {
+ if (!right.isNumber()) convertInput(instruction, right, HType.NUMBER);
+ }
+ }
+
void visitGraph(HGraph graph) {
visitDominatorTree(graph);
processWorklist();
@@ -94,6 +112,62 @@ class SsaTypePropagator extends HGraphVisitor implements OptimizationPhase {
workmap[id] = instruction;
}
}
+
+ void convertInput(HInstruction instruction, HInstruction input, HType type) {
+ HTypeConversion converted =
+ new HTypeConversion.argumentTypeCheck(type, input);
+ instruction.block.addBefore(instruction, converted);
+ instruction.changeUse(input, converted);
+ replaceDominatedUses(input, converted);
+ }
+
+ // TODO(kasperl): Get rid of
+ // SsaTypeConversionInserter.changeUsesDominatedBy because this is
+ // just better.
+ void replaceDominatedUses(HInstruction instruction,
+ HInstruction replacement) {
+ // Keep track of all instructions that we have to deal with later
+ // and count the number of them that are in the current block.
+ Set<HInstruction> pending = null;
+ int pendingInCurrentBlock = 0;
+
+ // Run through all the users of the instruction and see if they
+ // are dominated or potentially dominated by the replacement.
+ HBasicBlock block = replacement.block;
+ for (int i = 0, length = instruction.usedBy.length; i < length; i++) {
+ HInstruction current = instruction.usedBy[i];
+ if (current !== replacement && block.dominates(current.block)) {
+ if (current.block === block) pendingInCurrentBlock++;
+ if (pending === null) pending = new Set<HInstruction>();
+ pending.add(current);
+ }
+ }
+
+ // If there are no pending instructions, we're done.
+ if (pending === null) return;
+
+ // Run through all the instructions before the replacement and
+ // remove them from the pending set.
+ if (pendingInCurrentBlock > 0) {
+ HInstruction current = block.first;
+ while (current !== replacement) {
+ if (pending.contains(current)) {
+ pending.remove(current);
+ if (--pendingInCurrentBlock == 0) break;
+ }
+ current = current.next;
+ }
+ }
+
+ // Run through all the pending instructions. They are the
+ // dominated users.
+ for (HInstruction current in pending) {
+ current.changeUse(instruction, replacement);
+ if (updateType(current)) {
+ addDependentInstructionsToWorkList(current);
+ }
+ }
+ }
}
class SsaSpeculativeTypePropagator extends SsaTypePropagator {
@@ -142,4 +216,7 @@ class SsaSpeculativeTypePropagator extends SsaTypePropagator {
if (!desiredType.isPrimitive()) return newType;
return newType.intersection(desiredType);
}
+
+ void visitInstruction(HInstruction instruction) { }
+
}

Powered by Google App Engine
This is Rietveld 408576698