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

Side by Side Diff: lib/compiler/implementation/ssa/optimize.dart

Issue 10119010: Start propagating non-primitive types in the backend, and fold instructions that know about the typ… (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years, 8 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) 2011, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2011, 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 interface OptimizationPhase { 5 interface OptimizationPhase {
6 String get name(); 6 String get name();
7 void visitGraph(HGraph graph); 7 void visitGraph(HGraph graph);
8 } 8 }
9 9
10 class SsaOptimizerTask extends CompilerTask { 10 class SsaOptimizerTask extends CompilerTask {
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after
140 if (operand is HConstant) { 140 if (operand is HConstant) {
141 UnaryOperation operation = node.operation; 141 UnaryOperation operation = node.operation;
142 HConstant receiver = operand; 142 HConstant receiver = operand;
143 Constant folded = operation.fold(receiver.constant); 143 Constant folded = operation.fold(receiver.constant);
144 if (folded !== null) return graph.addConstant(folded); 144 if (folded !== null) return graph.addConstant(folded);
145 } 145 }
146 return node; 146 return node;
147 } 147 }
148 148
149 HInstruction visitInvokeInterceptor(HInvokeInterceptor node) { 149 HInstruction visitInvokeInterceptor(HInvokeInterceptor node) {
150 if (node.name == const SourceString('length') && 150 if (node.isLengthGetter()) {
151 node.inputs[1].isConstantString()) { 151 HInstruction input = node.inputs[1];
152 HConstant input = node.inputs[1]; 152 if (input.isConstantString()) {
153 StringConstant constant = input.constant; 153 StringConstant constant = input.constant;
154 DartString string = constant.value; 154 return graph.addConstantInt(constant.length);
155 return graph.addConstantInt(string.length); 155 } else if (input.isConstantList()) {
156 ListConstant constant = input.constant;
157 return graph.addConstantInt(constant.length);
158 } else if (input.isConstantMap()) {
159 MapConstant constant = input.constant;
160 return graph.addConstantInt(constant.length);
161 }
162 }
163 return node;
164 }
165
166 HInstruction visitInvokeDynamic(HInvokeDynamic node) {
167 HType receiverType = node.receiver.propagatedType;
168 if (receiverType.isNonPrimitive()) {
169 HNonPrimitiveType type = receiverType;
170 Element element = type.lookupMember(node.name);
171 // TODO(ngeoffray): Also fold if it's a getter or variable.
172 if (element != null && element.isFunction()) {
173 FunctionElement method = element;
174 FunctionParameters parameters = method.computeParameters(compiler);
175 if (node.selector.applies(parameters)) {
floitsch 2012/04/18 19:18:48 Even if the function doesn't apply we should set t
ngeoffray 2012/04/19 08:09:33 Why? There is no need to compile the function sinc
176 if (parameters.optionalParameterCount == 0) {
177 node.element = element;
178 }
179 // TODO(ngeoffray): If the method has optional parameters,
180 // we should pass the default values here.
181 }
182 }
183 }
184 return node;
185 }
186
187 HInstruction visitIndex(HIndex node) {
kasperl 2012/04/19 06:46:19 This looks like this could be refactored with a he
ngeoffray 2012/04/19 08:09:33 Done.
188 if (node.receiver.isNonPrimitive()) {
189 return new HInvokeDynamicMethod(
190 node.selector,
191 Elements.constructOperatorName(
192 const SourceString('operator'),
193 const SourceString('[]')),
194 node.inputs.getRange(1, node.inputs.length - 1));
195 }
196 return node;
197 }
198
199 HInstruction visitIndexAssign(HIndexAssign node) {
200 if (node.receiver.isNonPrimitive()) {
201 return new HInvokeDynamicMethod(
202 node.selector,
203 Elements.constructOperatorName(
204 const SourceString('operator'),
205 const SourceString('[]=')),
206 node.inputs.getRange(1, node.inputs.length - 1));
156 } 207 }
157 return node; 208 return node;
158 } 209 }
159 210
160 HInstruction visitInvokeBinary(HInvokeBinary node) { 211 HInstruction visitInvokeBinary(HInvokeBinary node) {
161 HInstruction left = node.left; 212 HInstruction left = node.left;
162 HInstruction right = node.right; 213 HInstruction right = node.right;
163 if (left is HConstant && right is HConstant) { 214 if (left is HConstant && right is HConstant) {
164 BinaryOperation operation = node.operation; 215 BinaryOperation operation = node.operation;
165 HConstant op1 = left; 216 HConstant op1 = left;
166 HConstant op2 = right; 217 HConstant op2 = right;
167 Constant folded = operation.fold(op1.constant, op2.constant); 218 Constant folded = operation.fold(op1.constant, op2.constant);
168 if (folded !== null) return graph.addConstant(folded); 219 if (folded !== null) return graph.addConstant(folded);
169 } 220 }
221
222 if (left.isNonPrimitive() && node.operation.isUserDefinable()) {
223 return new HInvokeDynamicMethod(
224 node.selector,
225 Elements.constructOperatorName(
226 const SourceString('operator'),
227 node.operation.name),
228 node.inputs.getRange(1, node.inputs.length - 1));
229 }
170 return node; 230 return node;
171 } 231 }
172 232
173 HInstruction visitEquals(HEquals node) { 233 HInstruction visitEquals(HEquals node) {
174 HInstruction left = node.left; 234 HInstruction left = node.left;
175 HInstruction right = node.right; 235 HInstruction right = node.right;
176 if (!left.isConstant() && right.isConstantNull()) { 236 if (!left.isConstant() && right.isConstantNull()) {
177 // TODO(floitsch): cache interceptors. 237 // TODO(floitsch): cache interceptors.
178 HStatic target = new HStatic( 238 HStatic target = new HStatic(
179 compiler.builder.interceptors.getEqualsNullInterceptor()); 239 compiler.builder.interceptors.getEqualsNullInterceptor());
180 node.block.addBefore(node,target); 240 node.block.addBefore(node,target);
181 return new HEquals(target, node.left, node.right); 241 return new HEquals(target, node.left, node.right);
182 } 242 }
243
244 if (left.isNonPrimitive()) {
kasperl 2012/04/19 06:46:19 Add a comment here that explains what this does. E
245 HNonPrimitiveType type = left.propagatedType;
246 Element element = type.lookupMember(Namer.OPERATOR_EQUALS);
247 if (element === null) {
248 // TODO(floitsch): cache interceptors.
249 HStatic target = new HStatic(
250 compiler.builder.interceptors.getTripleEqualsInterceptor());
251 return new HIdentity(target, left, right);
252 }
253 }
254
183 // All other cases are dealt with by the [visitInvokeBinary]. 255 // All other cases are dealt with by the [visitInvokeBinary].
184 return visitInvokeBinary(node); 256 return visitInvokeBinary(node);
185 } 257 }
186 258
187 HInstruction visitTypeGuard(HTypeGuard node) { 259 HInstruction visitTypeGuard(HTypeGuard node) {
188 HInstruction value = node.guarded; 260 HInstruction value = node.guarded;
189 HType combinedType = value.propagatedType.combine(node.propagatedType); 261 HType combinedType = value.propagatedType.combine(node.propagatedType);
190 return (combinedType == value.propagatedType) ? value : node; 262 return (combinedType == value.propagatedType) ? value : node;
191 } 263 }
192 264
(...skipping 520 matching lines...) Expand 10 before | Expand all | Expand 10 after
713 } 785 }
714 } 786 }
715 if (!canBeMoved) continue; 787 if (!canBeMoved) continue;
716 788
717 // This is safe because we are running after GVN. 789 // This is safe because we are running after GVN.
718 // TODO(ngeoffray): ensure GVN has been run. 790 // TODO(ngeoffray): ensure GVN has been run.
719 set_.add(current); 791 set_.add(current);
720 } 792 }
721 } 793 }
722 } 794 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698