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

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

Issue 48243002: When doing SSA type propagation, refine the receiver after a call. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 2 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: sdk/lib/_internal/compiler/implementation/ssa/types_propagation.dart
===================================================================
--- sdk/lib/_internal/compiler/implementation/ssa/types_propagation.dart (revision 29343)
+++ sdk/lib/_internal/compiler/implementation/ssa/types_propagation.dart (working copy)
@@ -292,8 +292,7 @@
// of [instruction] might move from number to dynamic.
pendingOptimizations.putIfAbsent(instruction, () => () {
Selector selector = instruction.selector;
- if (selector.isOperator()
- && selector.name != '==') {
+ if (selector.isOperator() && selector.name != '==') {
if (checkReceiver(instruction)) {
addAllUsersBut(instruction, instruction.inputs[1]);
}
@@ -303,6 +302,43 @@
}
});
}
+
+ HInstruction receiver = instruction.getDartReceiver(compiler);
+ HType receiverType = receiver.instructionType;
+ Selector selector = receiverType.refine(instruction.selector, compiler);
+ instruction.selector = selector;
+
+ // Try to specialize the receiver after this call.
+ if (receiver.dominatedUsers(instruction).length != 1
+ && !selector.isClosureCall()) {
+ TypeMask oldMask = receiverType.computeMask(compiler);
+ TypeMask newMask = compiler.world.allFunctions.receiverType(selector);
+ newMask = newMask.intersection(oldMask, compiler);
+
+ if (newMask != oldMask) {
+ HType newType = new HType.fromMask(newMask, compiler);
+ var next = instruction.next;
+ if (next is HTypeKnown && next.checkedInput == receiver) {
+ // We already have refined [receiver]. Check if [newHType]
+ // is actually better than the type of [next].
+ HType nextType = next.instructionType;
+ if (nextType != newType
+ && nextType.intersection(newType, compiler) == newType) {
+ next.instructionType = newType;
+ addDependentInstructionsToWorkList(next);
+ }
+ } else {
+ // Insert a refinement node after the call and update all
+ // users dominated by the call to use that node instead of
+ // [receiver].
+ HTypeKnown converted = new HTypeKnown(newType, receiver);
+ instruction.block.addBefore(instruction.next, converted);
+ receiver.replaceAllUsersDominatedBy(converted.next, converted);
+ addDependentInstructionsToWorkList(converted);
+ }
+ }
+ }
+
return instruction.specializer.computeTypeFromInputTypes(
instruction, compiler);
}

Powered by Google App Engine
This is Rietveld 408576698