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

Side by Side Diff: pkg/compiler/lib/src/cps_ir/backward_null_check_remover.dart

Issue 1743283002: dart2js cps: Use definitions by default, not references. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Fix doc comments and long lines Created 4 years, 9 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 unified diff | Download patch
OLDNEW
1 library dart2js.cps_ir.backward_null_check_remover; 1 library dart2js.cps_ir.backward_null_check_remover;
2 2
3 import 'cps_ir_nodes.dart'; 3 import 'cps_ir_nodes.dart';
4 import 'optimizers.dart'; 4 import 'optimizers.dart';
5 import '../common/names.dart'; 5 import '../common/names.dart';
6 import '../universe/selector.dart'; 6 import '../universe/selector.dart';
7 import 'type_mask_system.dart'; 7 import 'type_mask_system.dart';
8 import 'cps_fragment.dart'; 8 import 'cps_fragment.dart';
9 9
10 /// Removes null checks that are follwed by another instruction that will 10 /// Removes null checks that are follwed by another instruction that will
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
43 /// The [nullCheckedValue] at the entry point of a continuation. 43 /// The [nullCheckedValue] at the entry point of a continuation.
44 final Map<Continuation, Primitive> nullCheckedValueAt = 44 final Map<Continuation, Primitive> nullCheckedValueAt =
45 <Continuation, Primitive>{}; 45 <Continuation, Primitive>{};
46 46
47 BackwardNullCheckRemover(this.typeSystem); 47 BackwardNullCheckRemover(this.typeSystem);
48 48
49 void rewrite(FunctionDefinition node) { 49 void rewrite(FunctionDefinition node) {
50 BlockVisitor.traverseInPostOrder(node, this); 50 BlockVisitor.traverseInPostOrder(node, this);
51 } 51 }
52 52
53 /// Returns a reference to an operand of [prim], where [prim] throws if null 53 /// Returns an operand of [prim] that throws if null is passed into it.
54 /// is passed into that operand. 54 Primitive getNullCheckedOperand(Primitive prim) {
55 Reference<Primitive> getNullCheckedOperand(Primitive prim) {
56 if (prim is ReceiverCheck) return prim.value; 55 if (prim is ReceiverCheck) return prim.value;
57 if (prim is GetLength) return prim.object; 56 if (prim is GetLength) return prim.object;
58 if (prim is GetField) return prim.object; 57 if (prim is GetField) return prim.object;
59 if (prim is GetIndex) return prim.object; 58 if (prim is GetIndex) return prim.object;
60 if (prim is SetField) return prim.object; 59 if (prim is SetField) return prim.object;
61 if (prim is SetIndex) return prim.object; 60 if (prim is SetIndex) return prim.object;
62 if (prim is InvokeMethod && !selectorsOnNull.contains(prim.selector)) { 61 if (prim is InvokeMethod && !selectorsOnNull.contains(prim.selector)) {
63 return prim.dartReceiverReference; 62 return prim.dartReceiver;
64 } 63 }
65 if (prim is ForeignCode) { 64 if (prim is ForeignCode) {
66 return prim.isNullGuardOnNullFirstArgument() ? prim.arguments[0] : null; 65 return prim.isNullGuardOnNullFirstArgument() ? prim.argument(0) : null;
67 } 66 }
68 return null; 67 return null;
69 } 68 }
70 69
71 /// It has been determined that the null check in [prim] made redundant by 70 /// It has been determined that the null check in [prim] made redundant by
72 /// [newNullCheck]. Eliminate [prim] if it is not needed any more. 71 /// [newNullCheck]. Eliminate [prim] if it is not needed any more.
73 void tryEliminateRedundantNullCheck(Primitive prim, Primitive newNullCheck) { 72 void tryEliminateRedundantNullCheck(Primitive prim, Primitive newNullCheck) {
74 if (prim is ReceiverCheck && prim.isNullCheck) { 73 if (prim is ReceiverCheck && prim.isNullCheck) {
75 Primitive value = prim.value.definition; 74 Primitive value = prim.value;
76 LetPrim let = prim.parent; 75 LetPrim let = prim.parent;
77 prim..replaceUsesWith(value)..destroy(); 76 prim..replaceUsesWith(value)..destroy();
78 let.remove(); 77 let.remove();
79 } else if (prim is GetLength || prim is GetField || prim is GetIndex) { 78 } else if (prim is GetLength || prim is GetField || prim is GetIndex) {
80 if (prim.hasNoRefinedUses) { 79 if (prim.hasNoRefinedUses) {
81 destroyRefinementsOfDeadPrimitive(prim); 80 destroyRefinementsOfDeadPrimitive(prim);
82 LetPrim let = prim.parent; 81 LetPrim let = prim.parent;
83 prim..destroy(); 82 prim..destroy();
84 let.remove(); 83 let.remove();
85 } 84 }
86 } 85 }
87 } 86 }
88 87
89 /// True if [prim] can be moved above a null check. This is safe if [prim] 88 /// True if [prim] can be moved above a null check. This is safe if [prim]
90 /// cannot throw or have side effects and does not carry any path-sensitive 89 /// cannot throw or have side effects and does not carry any path-sensitive
91 /// type information, such as [Refinement] nodes do. 90 /// type information, such as [Refinement] nodes do.
92 // 91 //
93 // TODO(asgerf): This prevents elimination of the .length created for a bounds 92 // TODO(asgerf): This prevents elimination of the .length created for a bounds
94 // check, because there is a refinement node below it. To handle this, we 93 // check, because there is a refinement node below it. To handle this, we
95 // would have to relocate the [Refinement] node below the new null check. 94 // would have to relocate the [Refinement] node below the new null check.
96 bool canMoveAboveNullCheck(Primitive prim) { 95 bool canMoveAboveNullCheck(Primitive prim) {
97 return prim.isSafeForReordering; 96 return prim.isSafeForReordering;
98 } 97 }
99 98
100 void visitLetPrim(LetPrim node) { 99 void visitLetPrim(LetPrim node) {
101 Primitive prim = node.primitive; 100 Primitive prim = node.primitive;
102 Primitive receiver = getNullCheckedOperand(prim)?.definition; 101 Primitive receiver = getNullCheckedOperand(prim);
103 if (receiver != null) { 102 if (receiver != null) {
104 if (nullCheckedValue != null && receiver.sameValue(nullCheckedValue)) { 103 if (nullCheckedValue != null && receiver.sameValue(nullCheckedValue)) {
105 tryEliminateRedundantNullCheck(prim, nullCheckedValue); 104 tryEliminateRedundantNullCheck(prim, nullCheckedValue);
106 } 105 }
107 nullCheckedValue = receiver; 106 nullCheckedValue = receiver;
108 } else if (!canMoveAboveNullCheck(prim)) { 107 } else if (!canMoveAboveNullCheck(prim)) {
109 nullCheckedValue = null; 108 nullCheckedValue = null;
110 } 109 }
111 } 110 }
112 111
113 void visitContinuation(Continuation cont) { 112 void visitContinuation(Continuation cont) {
114 if (nullCheckedValue != null) { 113 if (nullCheckedValue != null) {
115 nullCheckedValueAt[cont] = nullCheckedValue; 114 nullCheckedValueAt[cont] = nullCheckedValue;
116 nullCheckedValue = null; 115 nullCheckedValue = null;
117 } 116 }
118 } 117 }
119 118
120 void visitLetHandler(LetHandler node) { 119 void visitLetHandler(LetHandler node) {
121 nullCheckedValue = null; 120 nullCheckedValue = null;
122 } 121 }
123 122
124 visitInvokeContinuation(InvokeContinuation node) { 123 visitInvokeContinuation(InvokeContinuation node) {
125 if (!node.isRecursive) { 124 if (!node.isRecursive) {
126 nullCheckedValue = nullCheckedValueAt[node.continuation.definition]; 125 nullCheckedValue = nullCheckedValueAt[node.continuation];
127 } 126 }
128 } 127 }
129 } 128 }
OLDNEW
« no previous file with comments | « no previous file | pkg/compiler/lib/src/cps_ir/bounds_checker.dart » ('j') | pkg/compiler/lib/src/cps_ir/bounds_checker.dart » ('J')

Powered by Google App Engine
This is Rietveld 408576698