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

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

Issue 1668913002: dart2js cps: More aggressive operator specialization. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Update test expectations Created 4 years, 10 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
« no previous file with comments | « no previous file | pkg/compiler/lib/src/cps_ir/cps_ir_nodes.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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
11 /// perform the same check. 11 /// perform the same check.
12 /// 12 ///
13 /// For example: 13 /// For example:
14 /// 14 ///
15 /// x.toString; // NullCheck instruction 15 /// x.toString; // NullCheck instruction
16 /// print(x.length); 16 /// print(x.length);
17 /// 17 ///
18 /// ==> 18 /// ==>
19 /// 19 ///
20 /// print(x.length); 20 /// print(x.length);
21 /// 21 ///
22 /// `x.length` will throw when x is null, so the original [NullCheck] is not 22 /// `x.length` will throw when x is null, so the original [ReceiverCheck] is not
23 /// needed. This changes the error message, but at least for now we are 23 /// needed. This changes the error message, but at least for now we are
24 /// willing to accept this. 24 /// willing to accept this.
25 /// 25 ///
26 /// Note that code motion may not occur after this pass, since the [NullCheck] 26 /// Note that code motion may not occur after this pass, since the [ReceiverChec k]
27 /// nodes are not there to restrict it. 27 /// nodes are not there to restrict it.
28 // 28 //
29 // TODO(asgerf): It would be nice with a clear specification of when we allow 29 // TODO(asgerf): It would be nice with a clear specification of when we allow
30 // the wording of error message to change. E.g. "toString" is already pretty 30 // the wording of error message to change. E.g. "toString" is already pretty
31 // bad so changing that should be ok, but changing a field access is not as 31 // bad so changing that should be ok, but changing a field access is not as
32 // clear. 32 // clear.
33 // 33 //
34 class BackwardNullCheckRemover extends BlockVisitor implements Pass { 34 class BackwardNullCheckRemover extends BlockVisitor implements Pass {
35 String get passName => 'Backward null-check remover'; 35 String get passName => 'Backward null-check remover';
36 36
37 final TypeMaskSystem typeSystem; 37 final TypeMaskSystem typeSystem;
38 38
39 /// When the analysis of an expression completes, [nullCheckValue] refers to 39 /// When the analysis of an expression completes, [nullCheckValue] refers to
40 /// a value that is checked in the beginning of that expression. 40 /// a value that is checked in the beginning of that expression.
41 Primitive nullCheckedValue; 41 Primitive nullCheckedValue;
42 42
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 a reference to an operand of [prim], where [prim] throws if null
54 /// is passed into that operand. 54 /// is passed into that operand.
55 Reference<Primitive> getNullCheckedOperand(Primitive prim) { 55 Reference<Primitive> getNullCheckedOperand(Primitive prim) {
56 if (prim is NullCheck) return prim.value; 56 if (prim is ReceiverCheck) return prim.value;
57 if (prim is GetLength) return prim.object; 57 if (prim is GetLength) return prim.object;
58 if (prim is GetField) return prim.object; 58 if (prim is GetField) return prim.object;
59 if (prim is GetIndex) return prim.object; 59 if (prim is GetIndex) return prim.object;
60 if (prim is SetField) return prim.object; 60 if (prim is SetField) return prim.object;
61 if (prim is SetIndex) return prim.object; 61 if (prim is SetIndex) return prim.object;
62 if (prim is InvokeMethod && !selectorsOnNull.contains(prim.selector)) { 62 if (prim is InvokeMethod && !selectorsOnNull.contains(prim.selector)) {
63 return prim.dartReceiverReference; 63 return prim.dartReceiverReference;
64 } 64 }
65 if (prim is ForeignCode) { 65 if (prim is ForeignCode) {
66 return prim.isNullGuardOnNullFirstArgument() ? prim.arguments[0] : null; 66 return prim.isNullGuardOnNullFirstArgument() ? prim.arguments[0] : null;
67 } 67 }
68 return null; 68 return null;
69 } 69 }
70 70
71 /// It has been determined that the null check in [prim] made redundant by 71 /// It has been determined that the null check in [prim] made redundant by
72 /// [newNullCheck]. Eliminate [prim] if it is not needed any more. 72 /// [newNullCheck]. Eliminate [prim] if it is not needed any more.
73 void tryEliminateRedundantNullCheck(Primitive prim, Primitive newNullCheck) { 73 void tryEliminateRedundantNullCheck(Primitive prim, Primitive newNullCheck) {
74 if (prim is NullCheck) { 74 if (prim is ReceiverCheck && prim.isNullCheck) {
75 Primitive value = prim.value.definition; 75 Primitive value = prim.value.definition;
76 LetPrim let = prim.parent; 76 LetPrim let = prim.parent;
77 prim..replaceUsesWith(value)..destroy(); 77 prim..replaceUsesWith(value)..destroy();
78 let.remove(); 78 let.remove();
79 } else if (prim is GetLength || prim is GetField || prim is GetIndex) { 79 } else if (prim is GetLength || prim is GetField || prim is GetIndex) {
80 if (prim.hasNoRefinedUses) { 80 if (prim.hasNoRefinedUses) {
81 destroyRefinementsOfDeadPrimitive(prim); 81 destroyRefinementsOfDeadPrimitive(prim);
82 LetPrim let = prim.parent; 82 LetPrim let = prim.parent;
83 prim..destroy(); 83 prim..destroy();
84 let.remove(); 84 let.remove();
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
120 void visitLetHandler(LetHandler node) { 120 void visitLetHandler(LetHandler node) {
121 nullCheckedValue = null; 121 nullCheckedValue = null;
122 } 122 }
123 123
124 visitInvokeContinuation(InvokeContinuation node) { 124 visitInvokeContinuation(InvokeContinuation node) {
125 if (!node.isRecursive) { 125 if (!node.isRecursive) {
126 nullCheckedValue = nullCheckedValueAt[node.continuation.definition]; 126 nullCheckedValue = nullCheckedValueAt[node.continuation.definition];
127 } 127 }
128 } 128 }
129 } 129 }
OLDNEW
« no previous file with comments | « no previous file | pkg/compiler/lib/src/cps_ir/cps_ir_nodes.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698