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

Side by Side Diff: pkg/compiler/lib/src/tree_ir/optimization/copy_propagator.dart

Issue 958603002: Added VariableUse expression to tree IR. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Comments Created 5 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 | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 part of tree_ir.optimization; 5 part of tree_ir.optimization;
6 6
7 /// Eliminates moving assignments, such as w := v, by assigning directly to w 7 /// Eliminates moving assignments, such as w := v, by assigning directly to w
8 /// at the definition of v. 8 /// at the definition of v.
9 /// 9 ///
10 /// This compensates for suboptimal register allocation, and merges closure 10 /// This compensates for suboptimal register allocation, and merges closure
11 /// variables with local temporaries that were left behind when translating 11 /// variables with local temporaries that were left behind when translating
12 /// out of CPS (where closure variables live in a separate space). 12 /// out of CPS (where closure variables live in a separate space).
13 class CopyPropagator extends RecursiveVisitor with PassMixin { 13 class CopyPropagator extends RecursiveVisitor with PassMixin {
14 14
15 /// After visitStatement returns, [move] maps a variable v to an 15 /// After visitStatement returns, [move] maps a variable v to an
16 /// assignment A of form w := v, under the following conditions: 16 /// assignment A of form w := v, under the following conditions:
17 /// - there are no uses of w before A 17 /// - there are no reads or writes of w before A
18 /// - A is the only use of v 18 /// - A is the only use of v
19 Map<Variable, Assign> move = <Variable, Assign>{}; 19 Map<Variable, Assign> move = <Variable, Assign>{};
20 20
21 /// Like [move], except w is the key instead of v. 21 /// Like [move], except w is the key instead of v.
22 Map<Variable, Assign> inverseMove = <Variable, Assign>{}; 22 Map<Variable, Assign> inverseMove = <Variable, Assign>{};
23 23
24 ExecutableElement currentElement; 24 ExecutableElement currentElement;
25 25
26 void rewriteExecutableDefinition(ExecutableDefinition root) { 26 void rewriteExecutableDefinition(ExecutableDefinition root) {
27 currentElement = root.element; 27 currentElement = root.element;
(...skipping 16 matching lines...) Expand all
44 // } 44 // }
45 45
46 // Variables must not occur more than once in the parameter list, so 46 // Variables must not occur more than once in the parameter list, so
47 // invalidate all moving assignments that would propagate a parameter 47 // invalidate all moving assignments that would propagate a parameter
48 // into another parameter. For example: 48 // into another parameter. For example:
49 // foo(x,y) { 49 // foo(x,y) {
50 // y = x; 50 // y = x;
51 // BODY 51 // BODY
52 // } 52 // }
53 // Cannot declare function as foo(x,x)! 53 // Cannot declare function as foo(x,x)!
54 node.parameters.forEach(visitVariable); 54 node.parameters.forEach(invalidateMovingAssignment);
55 55
56 // Now do the propagation. 56 // Now do the propagation.
57 for (int i = 0; i < node.parameters.length; i++) { 57 for (int i = 0; i < node.parameters.length; i++) {
58 Variable param = node.parameters[i]; 58 Variable param = node.parameters[i];
59 Variable replacement = copyPropagateVariable(param); 59 Variable replacement = copyPropagateVariable(param);
60 replacement.element = param.element; // Preserve parameter name. 60 replacement.element = param.element; // Preserve parameter name.
61 node.parameters[i] = replacement; 61 node.parameters[i] = replacement;
62 } 62 }
63 } 63 }
64 64
(...skipping 15 matching lines...) Expand all
80 // } 80 // }
81 81
82 // Variables must not occur more than once in the parameter list, so 82 // Variables must not occur more than once in the parameter list, so
83 // invalidate all moving assignments that would propagate a parameter 83 // invalidate all moving assignments that would propagate a parameter
84 // into another parameter. For example: 84 // into another parameter. For example:
85 // foo(x,y) { 85 // foo(x,y) {
86 // y = x; 86 // y = x;
87 // BODY 87 // BODY
88 // } 88 // }
89 // Cannot declare function as foo(x,x)! 89 // Cannot declare function as foo(x,x)!
90 node.parameters.forEach(visitVariable); 90 node.parameters.forEach(invalidateMovingAssignment);
91 91
92 // Now do the propagation. 92 // Now do the propagation.
93 for (int i = 0; i < node.parameters.length; i++) { 93 for (int i = 0; i < node.parameters.length; i++) {
94 Variable param = node.parameters[i]; 94 Variable param = node.parameters[i];
95 Variable replacement = copyPropagateVariable(param); 95 Variable replacement = copyPropagateVariable(param);
96 replacement.element = param.element; // Preserve parameter name. 96 replacement.element = param.element; // Preserve parameter name.
97 node.parameters[i] = replacement; 97 node.parameters[i] = replacement;
98 } 98 }
99 99
100 } 100 }
101 101
102 102
103 Statement visitBasicBlock(Statement node) { 103 Statement visitBasicBlock(Statement node) {
104 node = visitStatement(node); 104 node = visitStatement(node);
105 move.clear(); 105 move.clear();
106 inverseMove.clear(); 106 inverseMove.clear();
107 return node; 107 return node;
108 } 108 }
109 109
110 void visitVariable(Variable variable) { 110 /// Remove an assignment of form [w] := v from the move maps.
111 // We have found a use of w. 111 void invalidateMovingAssignment(Variable w) {
112 // Remove assignments of form w := v from the move maps. 112 Assign movingAssignment = inverseMove.remove(w);
113 Assign movingAssignment = inverseMove.remove(variable);
114 if (movingAssignment != null) { 113 if (movingAssignment != null) {
115 move.remove(movingAssignment.definition); 114 VariableUse def = movingAssignment.definition;
115 move.remove(def.variable);
116 } 116 }
117 } 117 }
118 118
119 /** 119 /**
120 * Called when a definition of [v] is encountered. 120 * Called when a definition of [v] is encountered.
121 * Attempts to propagate the assignment through a moving assignment. 121 * Attempts to propagate the assignment through a moving assignment.
122 * Returns the variable to be assigned into, defaulting to [v] itself if 122 * Returns the variable to be assigned into, defaulting to [v] itself if
123 * no optimization could be performed. 123 * no optimization could be performed.
124 */ 124 */
125 Variable copyPropagateVariable(Variable v) { 125 Variable copyPropagateVariable(Variable v) {
126 Assign movingAssign = move[v]; 126 Assign movingAssign = move[v];
127 if (movingAssign != null) { 127 if (movingAssign != null) {
128 // We found the pattern: 128 // We found the pattern:
129 // v := EXPR 129 // v := EXPR
130 // BLOCK (does not use w) 130 // BLOCK (does not use w)
131 // w := v (only use of v) 131 // w := v (only use of v)
132 // 132 //
133 // Rewrite to: 133 // Rewrite to:
134 // w := EXPR 134 // w := EXPR
135 // BLOCK 135 // BLOCK
136 // w := w (to be removed later) 136 // w := w (to be removed later)
137 Variable w = movingAssign.variable; 137 Variable w = movingAssign.variable;
138 138
139 // Make w := w. 139 // Make w := w.
140 // We can't remove the statement from here because we don't have 140 // We can't remove the statement from here because we don't have
141 // parent pointers. So just make it a no-op so it can be removed later. 141 // parent pointers. So just make it a no-op so it can be removed later.
142 movingAssign.definition = w; 142 movingAssign.definition = new VariableUse(w);
143 143
144 // The intermediate variable 'v' should now be orphaned, so don't bother 144 // The intermediate variable 'v' should now be orphaned, so don't bother
145 // updating its read/write counters. 145 // updating its read/write counters.
146 // Due to the nop trick, the variable 'w' now has one additional read
147 // and write.
148 ++w.writeCount;
149 ++w.readCount;
150 146
151 // Make w := EXPR 147 // Make w := EXPR
148 ++w.writeCount;
152 return w; 149 return w;
153 } 150 }
154 return v; 151 return v;
155 } 152 }
156 153
157 Statement visitAssign(Assign node) { 154 Statement visitAssign(Assign node) {
158 node.next = visitStatement(node.next); 155 node.next = visitStatement(node.next);
159 node.variable = copyPropagateVariable(node.variable); 156 node.variable = copyPropagateVariable(node.variable);
157
158 // If a moving assignment w := v exists later, and we assign to w here,
159 // the moving assignment is no longer a candidate for copy propagation.
160 invalidateMovingAssignment(node.variable);
161
160 visitExpression(node.definition); 162 visitExpression(node.definition);
161 visitVariable(node.variable);
162 163
163 // If this is a moving assignment w := v, with this being the only use of v, 164 // If this is a moving assignment w := v, with this being the only use of v,
164 // try to propagate it backwards. Do not propagate assignments where w 165 // try to propagate it backwards. Do not propagate assignments where w
165 // is from an outer function scope. 166 // is from an outer function scope.
166 if (node.definition is Variable) { 167 if (node.definition is VariableUse) {
167 Variable def = node.definition; 168 VariableUse definition = node.definition;
168 if (def.readCount == 1 && 169 if (definition.variable.readCount == 1 &&
169 node.variable.host == currentElement) { 170 node.variable.host == currentElement) {
170 move[node.definition] = node; 171 move[definition.variable] = node;
171 inverseMove[node.variable] = node; 172 inverseMove[node.variable] = node;
172 } 173 }
173 } 174 }
174 175
175 return node; 176 return node;
176 } 177 }
177 178
178 Statement visitLabeledStatement(LabeledStatement node) { 179 Statement visitLabeledStatement(LabeledStatement node) {
179 node.next = visitBasicBlock(node.next); 180 node.next = visitBasicBlock(node.next);
180 node.body = visitStatement(node.body); 181 node.body = visitStatement(node.body);
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
233 234
234 void visitFunctionExpression(FunctionExpression node) { 235 void visitFunctionExpression(FunctionExpression node) {
235 new CopyPropagator().rewrite(node.definition); 236 new CopyPropagator().rewrite(node.definition);
236 } 237 }
237 238
238 void visitFieldInitializer(FieldInitializer node) { 239 void visitFieldInitializer(FieldInitializer node) {
239 visitStatement(node.body); 240 visitStatement(node.body);
240 } 241 }
241 242
242 } 243 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698