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

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
« no previous file with comments | « lib/compiler/implementation/ssa/nodes.dart ('k') | lib/compiler/implementation/ssa/types.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 // 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 133 matching lines...) Expand 10 before | Expand all | Expand 10 after
144 if (operand is HConstant) { 144 if (operand is HConstant) {
145 UnaryOperation operation = node.operation; 145 UnaryOperation operation = node.operation;
146 HConstant receiver = operand; 146 HConstant receiver = operand;
147 Constant folded = operation.fold(receiver.constant); 147 Constant folded = operation.fold(receiver.constant);
148 if (folded !== null) return graph.addConstant(folded); 148 if (folded !== null) return graph.addConstant(folded);
149 } 149 }
150 return node; 150 return node;
151 } 151 }
152 152
153 HInstruction visitInvokeInterceptor(HInvokeInterceptor node) { 153 HInstruction visitInvokeInterceptor(HInvokeInterceptor node) {
154 if (node.name == const SourceString('length') && 154 if (node.isLengthGetter()) {
155 node.inputs[1].isConstantString()) { 155 HInstruction input = node.inputs[1];
156 HConstant input = node.inputs[1]; 156 if (input.isConstantString()) {
157 StringConstant constant = input.constant; 157 StringConstant constant = input.constant;
158 DartString string = constant.value; 158 return graph.addConstantInt(constant.length);
159 return graph.addConstantInt(string.length); 159 } else if (input.isConstantList()) {
160 ListConstant constant = input.constant;
161 return graph.addConstantInt(constant.length);
162 } else if (input.isConstantMap()) {
163 MapConstant constant = input.constant;
164 return graph.addConstantInt(constant.length);
165 }
166 }
167 return node;
168 }
169
170 HInstruction visitInvokeDynamic(HInvokeDynamic node) {
171 HType receiverType = node.receiver.propagatedType;
172 if (receiverType.isNonPrimitive()) {
173 HNonPrimitiveType type = receiverType;
174 Element element = type.lookupMember(node.name);
175 // TODO(ngeoffray): Also fold if it's a getter or variable.
176 if (element != null && element.isFunction()) {
177 FunctionElement method = element;
178 FunctionParameters parameters = method.computeParameters(compiler);
179 if (node.selector.applies(parameters)) {
180 if (parameters.optionalParameterCount == 0) {
181 node.element = element;
182 }
183 // TODO(ngeoffray): If the method has optional parameters,
184 // we should pass the default values here.
185 }
186 }
187 }
188 return node;
189 }
190
191 HInstruction fromInterceptorToDynamicInvocation(
192 HInvokeStatic node, SourceString methodName) {
193 HNonPrimitiveType type = node.inputs[1].propagatedType;
194 Element element = type.lookupMember(methodName);
195 HInvokeDynamicMethod result = new HInvokeDynamicMethod(
196 node.selector,
197 methodName,
198 node.inputs.getRange(1, node.inputs.length - 1));
199 result.element = element;
200 return result;
201 }
202
203 HInstruction visitIndex(HIndex node) {
204 if (node.receiver.isNonPrimitive()) {
205 SourceString methodName = Elements.constructOperatorName(
206 const SourceString('operator'), const SourceString('[]'));
207 return fromInterceptorToDynamicInvocation(node, methodName);
208 }
209 return node;
210 }
211
212 HInstruction visitIndexAssign(HIndexAssign node) {
213 if (node.receiver.isNonPrimitive()) {
214 SourceString methodName = Elements.constructOperatorName(
215 const SourceString('operator'), const SourceString('[]='));
216 return fromInterceptorToDynamicInvocation(node, methodName);
160 } 217 }
161 return node; 218 return node;
162 } 219 }
163 220
164 HInstruction visitInvokeBinary(HInvokeBinary node) { 221 HInstruction visitInvokeBinary(HInvokeBinary node) {
165 HInstruction left = node.left; 222 HInstruction left = node.left;
166 HInstruction right = node.right; 223 HInstruction right = node.right;
167 if (left is HConstant && right is HConstant) { 224 if (left is HConstant && right is HConstant) {
168 BinaryOperation operation = node.operation; 225 BinaryOperation operation = node.operation;
169 HConstant op1 = left; 226 HConstant op1 = left;
170 HConstant op2 = right; 227 HConstant op2 = right;
171 Constant folded = operation.fold(op1.constant, op2.constant); 228 Constant folded = operation.fold(op1.constant, op2.constant);
172 if (folded !== null) return graph.addConstant(folded); 229 if (folded !== null) return graph.addConstant(folded);
173 } 230 }
231
232 if (left.isNonPrimitive() && node.operation.isUserDefinable()) {
233 SourceString methodName = Elements.constructOperatorName(
234 const SourceString('operator'), node.operation.name);
235 return fromInterceptorToDynamicInvocation(node, methodName);
236 }
174 return node; 237 return node;
175 } 238 }
176 239
177 HInstruction visitEquals(HEquals node) { 240 HInstruction visitEquals(HEquals node) {
178 HInstruction left = node.left; 241 HInstruction left = node.left;
179 HInstruction right = node.right; 242 HInstruction right = node.right;
180 if (!left.isConstant() && right.isConstantNull()) { 243
181 // TODO(floitsch): cache interceptors. 244 if (left.isConstant() && right.isConstant()) {
182 HStatic target = new HStatic( 245 return visitInvokeBinary(node);
183 compiler.builder.interceptors.getEqualsNullInterceptor());
184 node.block.addBefore(node,target);
185 return new HEquals(target, node.left, node.right);
186 } 246 }
247
248 if (right.isConstantNull()) {
249 if (left.propagatedType.isUseful()) {
250 return graph.addConstantBool(false);
251 } else {
252 // TODO(floitsch): cache interceptors.
253 HStatic target = new HStatic(
254 compiler.builder.interceptors.getEqualsNullInterceptor());
255 node.block.addBefore(node,target);
256 return new HEquals(target, node.left, node.right);
257 }
258 }
259
260 if (left.isNonPrimitive()) {
261 // If the left-hand side is guaranteed to be a non-primitive
262 // type and and it does not define operator==, we can just emit
263 // an identity check.
264 HNonPrimitiveType type = left.propagatedType;
265 Element element = type.lookupMember(Namer.OPERATOR_EQUALS);
266 if (element === null) {
267 // TODO(floitsch): cache interceptors.
268 HStatic target = new HStatic(
269 compiler.builder.interceptors.getTripleEqualsInterceptor());
270 return new HIdentity(target, left, right);
271 }
272 }
273
187 // All other cases are dealt with by the [visitInvokeBinary]. 274 // All other cases are dealt with by the [visitInvokeBinary].
188 return visitInvokeBinary(node); 275 return visitInvokeBinary(node);
189 } 276 }
190 277
191 HInstruction visitTypeGuard(HTypeGuard node) { 278 HInstruction visitTypeGuard(HTypeGuard node) {
192 HInstruction value = node.guarded; 279 HInstruction value = node.guarded;
193 HType combinedType = value.propagatedType.combine(node.propagatedType); 280 HType combinedType = value.propagatedType.combine(node.propagatedType);
194 return (combinedType == value.propagatedType) ? value : node; 281 return (combinedType == value.propagatedType) ? value : node;
195 } 282 }
196 283
(...skipping 520 matching lines...) Expand 10 before | Expand all | Expand 10 after
717 } 804 }
718 } 805 }
719 if (!canBeMoved) continue; 806 if (!canBeMoved) continue;
720 807
721 // This is safe because we are running after GVN. 808 // This is safe because we are running after GVN.
722 // TODO(ngeoffray): ensure GVN has been run. 809 // TODO(ngeoffray): ensure GVN has been run.
723 set_.add(current); 810 set_.add(current);
724 } 811 }
725 } 812 }
726 } 813 }
OLDNEW
« no previous file with comments | « lib/compiler/implementation/ssa/nodes.dart ('k') | lib/compiler/implementation/ssa/types.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698