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

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

Issue 1750583002: Revert "dart2js cps: Refactor tracking of side effects." (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: 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
« no previous file with comments | « pkg/compiler/lib/src/cps_ir/gvn.dart ('k') | pkg/compiler/lib/src/cps_ir/type_propagation.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.loop_effects; 1 library dart2js.cps_ir.loop_effects;
2 2
3 import 'cps_ir_nodes.dart'; 3 import 'cps_ir_nodes.dart';
4 import 'loop_hierarchy.dart'; 4 import 'loop_hierarchy.dart';
5 import '../universe/side_effects.dart';
6 import '../elements/elements.dart';
5 import '../world.dart'; 7 import '../world.dart';
6 import 'effects.dart';
7 8
8 /// Determines the side effects that may occur in each loop. 9 /// Determines which the [SideEffects] that may occur during each loop in
10 /// a given function, in addition to whether the loop may change the length
11 /// of an indexable object.
12 ///
13 /// TODO(asgerf): Make length a flag on [SideEffects] for better precision and
14 /// so we don't need to special case the length in this class.
9 class LoopSideEffects extends TrampolineRecursiveVisitor { 15 class LoopSideEffects extends TrampolineRecursiveVisitor {
10 LoopHierarchy loopHierarchy; 16 LoopHierarchy loopHierarchy;
11 final World world; 17 final World world;
12 final Map<Continuation, List<Continuation>> exitContinuations = {}; 18 final Map<Continuation, List<Continuation>> exitContinuations = {};
13 final Map<Continuation, int> loopSideEffects = {}; 19 final Map<Continuation, SideEffects> loopSideEffects = {};
20 final Set<Continuation> loopsChangingLength = new Set<Continuation>();
14 Continuation currentLoopHeader; 21 Continuation currentLoopHeader;
22 SideEffects currentLoopSideEffects = new SideEffects.empty();
23 bool currentLoopChangesLength = false;
15 24
16 LoopSideEffects(FunctionDefinition node, this.world, {this.loopHierarchy}) { 25 LoopSideEffects(FunctionDefinition node, this.world, {this.loopHierarchy}) {
17 if (loopHierarchy == null) { 26 if (loopHierarchy == null) {
18 loopHierarchy = new LoopHierarchy(node); 27 loopHierarchy = new LoopHierarchy(node);
19 } 28 }
20 visit(node); 29 visit(node);
21 } 30 }
22 31
23 /// Returns the accumulated effects and dependencies on all paths from the 32 /// Returns the accumulated effects and dependencies on all paths from the
24 /// loop entry to any recursive invocation of the loop. 33 /// loop entry to any recursive invocation of the loop.
25 int getSideEffectsInLoop(Continuation loop) { 34 SideEffects getSideEffectsInLoop(Continuation loop) {
26 return loopSideEffects[loop]; 35 return loopSideEffects[loop];
27 } 36 }
28 37
29 /// True if the length of an indexable object may change between the loop 38 /// True if the length of an indexable object may change between the loop
30 /// entry and a recursive invocation of the loop. 39 /// entry and a recursive invocation of the loop.
31 bool changesIndexableLength(Continuation loop) { 40 bool loopChangesLength(Continuation loop) {
32 return loopSideEffects[loop] & Effects.changesIndexableLength != 0; 41 return loopsChangingLength.contains(loop);
33 } 42 }
34 43
35 @override 44 @override
36 Expression traverseContinuation(Continuation cont) { 45 Expression traverseContinuation(Continuation cont) {
37 if (cont.isRecursive) { 46 if (cont.isRecursive) {
38 loopSideEffects[cont] = Effects.none; 47 SideEffects oldEffects = currentLoopSideEffects;
48 bool oldChangesLength = currentLoopChangesLength;
49 loopSideEffects[cont] = currentLoopSideEffects = new SideEffects.empty();
39 exitContinuations[cont] = <Continuation>[]; 50 exitContinuations[cont] = <Continuation>[];
40 pushAction(() { 51 pushAction(() {
41 if (currentLoopHeader != null) { 52 oldEffects.add(currentLoopSideEffects);
42 loopSideEffects[currentLoopHeader] |= loopSideEffects[cont]; 53 if (currentLoopChangesLength) {
54 loopsChangingLength.add(cont);
43 } 55 }
56 currentLoopChangesLength = currentLoopChangesLength || oldChangesLength;
57 currentLoopSideEffects = oldEffects;
44 exitContinuations[cont].forEach(push); 58 exitContinuations[cont].forEach(push);
45 }); 59 });
46 } 60 }
47 Continuation oldLoopHeader = currentLoopHeader; 61 Continuation oldLoopHeader = currentLoopHeader;
48 currentLoopHeader = loopHierarchy.getLoopHeader(cont); 62 currentLoopHeader = loopHierarchy.getLoopHeader(cont);
49 pushAction(() { 63 pushAction(() {
50 currentLoopHeader = oldLoopHeader; 64 currentLoopHeader = oldLoopHeader;
51 }); 65 });
52 return cont.body; 66 return cont.body;
53 } 67 }
54 68
55 @override 69 @override
56 Expression traverseLetHandler(LetHandler node) { 70 Expression traverseLetHandler(LetHandler node) {
57 enqueueContinuation(node.handler); 71 enqueueContinuation(node.handler);
58 return node.body; 72 return node.body;
59 } 73 }
60 74
61 @override 75 @override
62 Expression traverseLetCont(LetCont node) { 76 Expression traverseLetCont(LetCont node) {
63 node.continuations.forEach(enqueueContinuation); 77 node.continuations.forEach(enqueueContinuation);
64 return node.body; 78 return node.body;
65 } 79 }
66 80
67 @override
68 Expression traverseLetPrim(LetPrim node) {
69 if (currentLoopHeader != null) {
70 loopSideEffects[currentLoopHeader] |= node.primitive.effects;
71 }
72 return node.body;
73 }
74
75 void enqueueContinuation(Continuation cont) { 81 void enqueueContinuation(Continuation cont) {
76 Continuation loop = loopHierarchy.getEnclosingLoop(cont); 82 Continuation loop = loopHierarchy.getEnclosingLoop(cont);
77 if (loop == currentLoopHeader) { 83 if (loop == currentLoopHeader) {
78 push(cont); 84 push(cont);
79 } else { 85 } else {
80 // Multiple loops can be exited at once. 86 // Multiple loops can be exited at once.
81 // Register as an exit from the outermost loop being exited. 87 // Register as an exit from the outermost loop being exited.
82 Continuation inner = currentLoopHeader; 88 Continuation inner = currentLoopHeader;
83 Continuation outer = loopHierarchy.getEnclosingLoop(currentLoopHeader); 89 Continuation outer = loopHierarchy.getEnclosingLoop(currentLoopHeader);
84 while (outer != loop) { 90 while (outer != loop) {
85 if (inner == null) { 91 if (inner == null) {
86 // The shrinking reductions pass must run before any pass that relies 92 // The shrinking reductions pass must run before any pass that relies
87 // on computing loop side effects. 93 // on computing loop side effects.
88 world.compiler.reporter.internalError(null, 94 world.compiler.reporter.internalError(null,
89 'Unreachable continuations must be removed before computing ' 95 'Unreachable continuations must be removed before computing '
90 'loop side effects.'); 96 'loop side effects.');
91 } 97 }
92 inner = outer; 98 inner = outer;
93 outer = loopHierarchy.getEnclosingLoop(outer); 99 outer = loopHierarchy.getEnclosingLoop(outer);
94 } 100 }
95 exitContinuations[inner].add(cont); 101 exitContinuations[inner].add(cont);
96 } 102 }
97 } 103 }
104
105 void addSideEffects(SideEffects effects) {
106 currentLoopSideEffects.add(effects);
107 if (effects.changesIndex()) {
108 currentLoopChangesLength = true;
109 }
110 }
111
112 void addAllSideEffects() {
113 currentLoopSideEffects.setAllSideEffects();
114 currentLoopSideEffects.setDependsOnSomething();
115 currentLoopChangesLength = true;
116 }
117
118 void visitInvokeMethod(InvokeMethod node) {
119 addSideEffects(world.getSideEffectsOfSelector(node.selector, node.mask));
120 }
121
122 void visitInvokeStatic(InvokeStatic node) {
123 addSideEffects(world.getSideEffectsOfElement(node.target));
124 }
125
126 void visitInvokeMethodDirectly(InvokeMethodDirectly node) {
127 FunctionElement target = node.target;
128 if (target is ConstructorBodyElement) {
129 ConstructorBodyElement body = target;
130 target = body.constructor;
131 }
132 addSideEffects(world.getSideEffectsOfElement(target));
133 }
134
135 void visitInvokeConstructor(InvokeConstructor node) {
136 addSideEffects(world.getSideEffectsOfElement(node.target));
137 }
138
139 void visitSetStatic(SetStatic node) {
140 currentLoopSideEffects.setChangesStaticProperty();
141 }
142
143 void visitGetStatic(GetStatic node) {
144 currentLoopSideEffects.setDependsOnStaticPropertyStore();
145 }
146
147 void visitGetField(GetField node) {
148 currentLoopSideEffects.setDependsOnInstancePropertyStore();
149 }
150
151 void visitSetField(SetField node) {
152 currentLoopSideEffects.setChangesInstanceProperty();
153 }
154
155 void visitGetIndex(GetIndex node) {
156 currentLoopSideEffects.setDependsOnIndexStore();
157 }
158
159 void visitSetIndex(SetIndex node) {
160 // Set the change index flag without setting the change length flag.
161 currentLoopSideEffects.setChangesIndex();
162 }
163
164 void visitForeignCode(ForeignCode node) {
165 addSideEffects(node.nativeBehavior.sideEffects);
166 }
167
168 void visitGetLazyStatic(GetLazyStatic node) {
169 // TODO(asgerf): How do we get the side effects of a lazy field initializer?
170 addAllSideEffects();
171 }
172
173 void visitAwait(Await node) {
174 addAllSideEffects();
175 }
176
177 void visitYield(Yield node) {
178 addAllSideEffects();
179 }
180
181 void visitApplyBuiltinMethod(ApplyBuiltinMethod node) {
182 currentLoopSideEffects.setChangesIndex();
183 currentLoopChangesLength = true; // Push and pop.
184 }
98 } 185 }
OLDNEW
« no previous file with comments | « pkg/compiler/lib/src/cps_ir/gvn.dart ('k') | pkg/compiler/lib/src/cps_ir/type_propagation.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698