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

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: 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
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
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 void visitVariable(Variable variable) {
111 // We have found a use of w. 111 // We have found a use of w.
112 // Remove assignments of form w := v from the move maps. 112 // Remove assignments of form w := v from the move maps.
Kevin Millikin (Google) 2015/02/26 12:43:18 It looks like we remove variable's that are read a
asgerf 2015/02/27 12:05:19 Completely agree.
113 Assign movingAssignment = inverseMove.remove(variable); 113 Assign movingAssignment = inverseMove.remove(variable);
114 if (movingAssignment != null) { 114 if (movingAssignment != null) {
115 move.remove(movingAssignment.definition); 115 VariableUse def = movingAssignment.definition;
116 move.remove(def.variable);
116 } 117 }
117 } 118 }
118 119
119 /** 120 /**
120 * Called when a definition of [v] is encountered. 121 * Called when a definition of [v] is encountered.
121 * Attempts to propagate the assignment through a moving assignment. 122 * Attempts to propagate the assignment through a moving assignment.
122 * Returns the variable to be assigned into, defaulting to [v] itself if 123 * Returns the variable to be assigned into, defaulting to [v] itself if
123 * no optimization could be performed. 124 * no optimization could be performed.
124 */ 125 */
125 Variable copyPropagateVariable(Variable v) { 126 Variable copyPropagateVariable(Variable v) {
126 Assign movingAssign = move[v]; 127 Assign movingAssign = move[v];
127 if (movingAssign != null) { 128 if (movingAssign != null) {
128 // We found the pattern: 129 // We found the pattern:
129 // v := EXPR 130 // v := EXPR
130 // BLOCK (does not use w) 131 // BLOCK (does not use w)
131 // w := v (only use of v) 132 // w := v (only use of v)
132 // 133 //
133 // Rewrite to: 134 // Rewrite to:
134 // w := EXPR 135 // w := EXPR
135 // BLOCK 136 // BLOCK
136 // w := w (to be removed later) 137 // w := w (to be removed later)
137 Variable w = movingAssign.variable; 138 Variable w = movingAssign.variable;
138 139
139 // Make w := w. 140 // Make w := w.
140 // We can't remove the statement from here because we don't have 141 // 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. 142 // parent pointers. So just make it a no-op so it can be removed later.
142 movingAssign.definition = w; 143 movingAssign.definition = new VariableUse(w);
143 144
144 // The intermediate variable 'v' should now be orphaned, so don't bother 145 // The intermediate variable 'v' should now be orphaned, so don't bother
145 // updating its read/write counters. 146 // updating its read/write counters.
146 // Due to the nop trick, the variable 'w' now has one additional read 147 // Due to the nop trick, the variable 'w' now has one additional write.
Kevin Millikin (Google) 2015/02/26 12:43:18 'The nop trick' is a bit confusing. Isn't the ext
asgerf 2015/02/27 12:05:19 Yeah, that's why I moved it closer to the return.
Kevin Millikin (Google) 2015/02/27 12:17:18 I'm on the fence. It's definitely a downside of t
147 // and write.
148 ++w.writeCount;
149 ++w.readCount;
150 148
151 // Make w := EXPR 149 // Make w := EXPR
150 ++w.writeCount;
152 return w; 151 return w;
153 } 152 }
154 return v; 153 return v;
155 } 154 }
156 155
157 Statement visitAssign(Assign node) { 156 Statement visitAssign(Assign node) {
158 node.next = visitStatement(node.next); 157 node.next = visitStatement(node.next);
159 node.variable = copyPropagateVariable(node.variable); 158 node.variable = copyPropagateVariable(node.variable);
160 visitExpression(node.definition); 159 visitExpression(node.definition);
161 visitVariable(node.variable); 160 visitVariable(node.variable);
162 161
163 // If this is a moving assignment w := v, with this being the only use of v, 162 // 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 163 // try to propagate it backwards. Do not propagate assignments where w
165 // is from an outer function scope. 164 // is from an outer function scope.
166 if (node.definition is Variable) { 165 if (node.definition is VariableUse) {
167 Variable def = node.definition; 166 VariableUse definition = node.definition;
168 if (def.readCount == 1 && 167 if (definition.variable.readCount == 1 &&
169 node.variable.host == currentElement) { 168 node.variable.host == currentElement) {
170 move[node.definition] = node; 169 move[definition.variable] = node;
171 inverseMove[node.variable] = node; 170 inverseMove[node.variable] = node;
172 } 171 }
173 } 172 }
174 173
175 return node; 174 return node;
176 } 175 }
177 176
178 Statement visitLabeledStatement(LabeledStatement node) { 177 Statement visitLabeledStatement(LabeledStatement node) {
179 node.next = visitBasicBlock(node.next); 178 node.next = visitBasicBlock(node.next);
180 node.body = visitStatement(node.body); 179 node.body = visitStatement(node.body);
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
233 232
234 void visitFunctionExpression(FunctionExpression node) { 233 void visitFunctionExpression(FunctionExpression node) {
235 new CopyPropagator().rewrite(node.definition); 234 new CopyPropagator().rewrite(node.definition);
236 } 235 }
237 236
238 void visitFieldInitializer(FieldInitializer node) { 237 void visitFieldInitializer(FieldInitializer node) {
239 visitStatement(node.body); 238 visitStatement(node.body);
240 } 239 }
241 240
242 } 241 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698