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

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

Issue 11421056: Re-apply issue 11308169: GVN getInterceptor and use the interceptor constant when the type is known. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years 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) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, 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 ssa; 5 part of ssa;
6 6
7 abstract class OptimizationPhase { 7 abstract class OptimizationPhase {
8 String get name; 8 String get name;
9 void visitGraph(HGraph graph); 9 void visitGraph(HGraph graph);
10 } 10 }
(...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after
204 } 204 }
205 return node; 205 return node;
206 } 206 }
207 207
208 HInstruction handleInterceptorCall(HInvokeDynamic node) { 208 HInstruction handleInterceptorCall(HInvokeDynamic node) {
209 HInstruction input = node.inputs[1]; 209 HInstruction input = node.inputs[1];
210 if (input.isString(types) 210 if (input.isString(types)
211 && node.selector.name == const SourceString('toString')) { 211 && node.selector.name == const SourceString('toString')) {
212 return node.inputs[1]; 212 return node.inputs[1];
213 } 213 }
214 // Check if this call does not need to be intercepted.
215 HType type = types[input];
216 var interceptor = node.inputs[0];
217 if (node is HInvokeDynamicMethod
218 && interceptor is !HThis
219 && !type.canBePrimitive()) {
220 // If the type can be null, and the intercepted method can be in
221 // the object class, keep the interceptor.
222 if (type.canBeNull()
223 && interceptor.interceptedClasses.contains(compiler.objectClass)) {
224 return node;
225 }
226 // Change the call to a regular invoke dynamic call.
227 return new HInvokeDynamicMethod(
228 node.selector, node.inputs.getRange(1, node.inputs.length - 1));
229 }
214 return node; 230 return node;
215 } 231 }
216 232
217 bool isFixedSizeListConstructor(HInvokeStatic node) { 233 bool isFixedSizeListConstructor(HInvokeStatic node) {
218 Element element = node.target.element; 234 Element element = node.target.element;
219 return element.getEnclosingClass() == compiler.listClass 235 return element.getEnclosingClass() == compiler.listClass
220 && node.inputs.length == 2 236 && node.inputs.length == 2
221 && node.inputs[1].isInteger(types); 237 && node.inputs[1].isInteger(types);
222 } 238 }
223 239
(...skipping 19 matching lines...) Expand all
243 node.element = element; 259 node.element = element;
244 } 260 }
245 // TODO(ngeoffray): If the method has optional parameters, 261 // TODO(ngeoffray): If the method has optional parameters,
246 // we should pass the default values here. 262 // we should pass the default values here.
247 } 263 }
248 } 264 }
249 } 265 }
250 return node; 266 return node;
251 } 267 }
252 268
253 HInstruction fromInterceptorToDynamicInvocation(HInvokeStatic node, 269 /**
254 Selector selector) { 270 * Turns a primitive instruction (e.g. [HIndex], [HAdd], ...) into a
271 * [HInvokeDynamic] because we know the receiver is not a JS
272 * primitive object.
273 */
274 HInstruction fromPrimitiveInstructionToDynamicInvocation(HInvokeStatic node,
275 Selector selector) {
255 HBoundedType type = types[node.inputs[1]]; 276 HBoundedType type = types[node.inputs[1]];
256 HInvokeDynamicMethod result = new HInvokeDynamicMethod( 277 HInvokeDynamicMethod result = new HInvokeDynamicMethod(
257 selector, 278 selector,
258 node.inputs.getRange(1, node.inputs.length - 1)); 279 node.inputs.getRange(1, node.inputs.length - 1));
259 if (type.isExact()) { 280 if (type.isExact()) {
260 HBoundedType concrete = type; 281 HBoundedType concrete = type;
261 result.element = concrete.lookupMember(selector.name); 282 result.element = concrete.lookupMember(selector.name);
262 } 283 }
263 return result; 284 return result;
264 } 285 }
265 286
266 HInstruction visitIntegerCheck(HIntegerCheck node) { 287 HInstruction visitIntegerCheck(HIntegerCheck node) {
267 HInstruction value = node.value; 288 HInstruction value = node.value;
268 if (value.isInteger(types)) return value; 289 if (value.isInteger(types)) return value;
269 if (value.isConstant()) { 290 if (value.isConstant()) {
270 HConstant constantInstruction = value; 291 HConstant constantInstruction = value;
271 assert(!constantInstruction.constant.isInt()); 292 assert(!constantInstruction.constant.isInt());
272 if (!constantSystem.isInt(constantInstruction.constant)) { 293 if (!constantSystem.isInt(constantInstruction.constant)) {
273 // -0.0 is a double but will pass the runtime integer check. 294 // -0.0 is a double but will pass the runtime integer check.
274 node.alwaysFalse = true; 295 node.alwaysFalse = true;
275 } 296 }
276 } 297 }
277 return node; 298 return node;
278 } 299 }
279 300
280 301
281 HInstruction visitIndex(HIndex node) { 302 HInstruction visitIndex(HIndex node) {
282 if (!node.receiver.canBePrimitive(types)) { 303 if (!node.receiver.canBePrimitive(types)) {
283 Selector selector = new Selector.index(); 304 Selector selector = new Selector.index();
284 return fromInterceptorToDynamicInvocation(node, selector); 305 return fromPrimitiveInstructionToDynamicInvocation(node, selector);
285 } 306 }
286 return node; 307 return node;
287 } 308 }
288 309
289 HInstruction visitIndexAssign(HIndexAssign node) { 310 HInstruction visitIndexAssign(HIndexAssign node) {
290 if (!node.receiver.canBePrimitive(types)) { 311 if (!node.receiver.canBePrimitive(types)) {
291 Selector selector = new Selector.indexSet(); 312 Selector selector = new Selector.indexSet();
292 return fromInterceptorToDynamicInvocation(node, selector); 313 return fromPrimitiveInstructionToDynamicInvocation(node, selector);
293 } 314 }
294 return node; 315 return node;
295 } 316 }
296 317
297 HInstruction visitInvokeBinary(HInvokeBinary node) { 318 HInstruction visitInvokeBinary(HInvokeBinary node) {
298 HInstruction left = node.left; 319 HInstruction left = node.left;
299 HInstruction right = node.right; 320 HInstruction right = node.right;
300 BinaryOperation operation = node.operation(constantSystem); 321 BinaryOperation operation = node.operation(constantSystem);
301 if (left is HConstant && right is HConstant) { 322 if (left is HConstant && right is HConstant) {
302 HConstant op1 = left; 323 HConstant op1 = left;
303 HConstant op2 = right; 324 HConstant op2 = right;
304 Constant folded = operation.fold(op1.constant, op2.constant); 325 Constant folded = operation.fold(op1.constant, op2.constant);
305 if (folded != null) return graph.addConstant(folded); 326 if (folded != null) return graph.addConstant(folded);
306 } 327 }
307 328
308 if (!left.canBePrimitive(types) 329 if (!left.canBePrimitive(types)
309 && operation.isUserDefinable() 330 && operation.isUserDefinable()
310 // The equals operation is being optimized in visitEquals. 331 // The equals operation is being optimized in visitEquals.
311 && node is! HEquals) { 332 && node is! HEquals) {
312 Selector selector = new Selector.binaryOperator(operation.name); 333 Selector selector = new Selector.binaryOperator(operation.name);
313 return fromInterceptorToDynamicInvocation(node, selector); 334 return fromPrimitiveInstructionToDynamicInvocation(node, selector);
314 } 335 }
315 return node; 336 return node;
316 } 337 }
317 338
318 bool allUsersAreBoolifies(HInstruction instruction) { 339 bool allUsersAreBoolifies(HInstruction instruction) {
319 List<HInstruction> users = instruction.usedBy; 340 List<HInstruction> users = instruction.usedBy;
320 int length = users.length; 341 int length = users.length;
321 for (int i = 0; i < length; i++) { 342 for (int i = 0; i < length; i++) {
322 if (users[i] is! HBoolify) return false; 343 if (users[i] is! HBoolify) return false;
323 } 344 }
(...skipping 325 matching lines...) Expand 10 before | Expand all | Expand 10 after
649 for (int i = 0; i < node.inputs.length; i++) { 670 for (int i = 0; i < node.inputs.length; i++) {
650 HInstruction part = node.inputs[i]; 671 HInstruction part = node.inputs[i];
651 if (!part.isConstant()) return node; 672 if (!part.isConstant()) return node;
652 HConstant constant = part; 673 HConstant constant = part;
653 if (!constant.constant.isPrimitive()) return node; 674 if (!constant.constant.isPrimitive()) return node;
654 PrimitiveConstant primitive = constant.constant; 675 PrimitiveConstant primitive = constant.constant;
655 folded = new DartString.concat(folded, primitive.toDartString()); 676 folded = new DartString.concat(folded, primitive.toDartString());
656 } 677 }
657 return graph.addConstant(constantSystem.createString(folded, node.node)); 678 return graph.addConstant(constantSystem.createString(folded, node.node));
658 } 679 }
680
681 HInstruction visitInterceptor(HInterceptor node) {
682 if (node.isConstant()) return node;
683 HType type = types[node.inputs[0]];
684 Element constantInterceptor;
685 if (type.isInteger()) {
686 constantInterceptor = backend.intInterceptor;
687 } else if (type.isDouble()) {
688 constantInterceptor = backend.doubleInterceptor;
689 } else if (type.isBoolean()) {
690 constantInterceptor = backend.boolInterceptor;
691 } else if (type.isString()) {
692 constantInterceptor = backend.stringInterceptor;
693 } else if (type.isArray()) {
694 constantInterceptor = backend.arrayInterceptor;
695 } else if (type.isNull()) {
696 constantInterceptor = backend.nullInterceptor;
697 } else if (type.isNumber()) {
698 Set<ClassElement> intercepted = node.interceptedClasses;
699 // If the method being intercepted is not defined in [int] or
700 // [double] we can safely use the number interceptor.
701 if (!intercepted.contains(compiler.intClass)
702 && !intercepted.contains(compiler.doubleClass)) {
703 constantInterceptor = backend.numberInterceptor;
704 }
705 }
706
707 if (constantInterceptor == null) return node;
708
709 ConstantHandler handler = compiler.constantHandler;
710 return graph.addConstant(handler.compileVariable(constantInterceptor));
711 }
659 } 712 }
660 713
661 class SsaCheckInserter extends HBaseVisitor implements OptimizationPhase { 714 class SsaCheckInserter extends HBaseVisitor implements OptimizationPhase {
662 final HTypeMap types; 715 final HTypeMap types;
663 final ConstantSystem constantSystem; 716 final ConstantSystem constantSystem;
664 final Set<HInstruction> boundsChecked; 717 final Set<HInstruction> boundsChecked;
665 final WorkItem work; 718 final WorkItem work;
666 final String name = "SsaCheckInserter"; 719 final String name = "SsaCheckInserter";
667 HGraph graph; 720 HGraph graph;
668 Element lengthInterceptor; 721 Element lengthInterceptor;
(...skipping 684 matching lines...) Expand 10 before | Expand all | Expand 10 after
1353 } 1406 }
1354 1407
1355 // For other fields having setters in the generative constructor body, set 1408 // For other fields having setters in the generative constructor body, set
1356 // the type to UNKNOWN to avoid relying on the type set in the initializer 1409 // the type to UNKNOWN to avoid relying on the type set in the initializer
1357 // list. 1410 // list.
1358 allSetters.forEach((Element element) { 1411 allSetters.forEach((Element element) {
1359 backend.registerFieldConstructor(element, HType.UNKNOWN); 1412 backend.registerFieldConstructor(element, HType.UNKNOWN);
1360 }); 1413 });
1361 } 1414 }
1362 } 1415 }
OLDNEW
« no previous file with comments | « sdk/lib/_internal/compiler/implementation/ssa/nodes.dart ('k') | sdk/lib/_internal/compiler/implementation/ssa/types.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698