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

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

Issue 12211013: Allow intercepted calls to have typed selectors. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 10 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) 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 167 matching lines...) Expand 10 before | Expand all | Expand 10 after
178 } 178 }
179 179
180 HInstruction visitInstruction(HInstruction node) { 180 HInstruction visitInstruction(HInstruction node) {
181 return node; 181 return node;
182 } 182 }
183 183
184 HInstruction visitBoolify(HBoolify node) { 184 HInstruction visitBoolify(HBoolify node) {
185 List<HInstruction> inputs = node.inputs; 185 List<HInstruction> inputs = node.inputs;
186 assert(inputs.length == 1); 186 assert(inputs.length == 1);
187 HInstruction input = inputs[0]; 187 HInstruction input = inputs[0];
188 if (input.isBoolean(types)) return input; 188 HType type = types[input];
189 if (type.isBoolean()) return input;
189 // All values !== true are boolified to false. 190 // All values !== true are boolified to false.
190 DartType type = types[input].computeType(compiler); 191 if (!type.isBooleanOrNull() && !type.isUnknown()) {
191 if (type != null && !identical(type.element, compiler.boolClass)) {
192 return graph.addConstantBool(false, constantSystem); 192 return graph.addConstantBool(false, constantSystem);
193 } 193 }
194 return node; 194 return node;
195 } 195 }
196 196
197 HInstruction visitNot(HNot node) { 197 HInstruction visitNot(HNot node) {
198 List<HInstruction> inputs = node.inputs; 198 List<HInstruction> inputs = node.inputs;
199 assert(inputs.length == 1); 199 assert(inputs.length == 1);
200 HInstruction input = inputs[0]; 200 HInstruction input = inputs[0];
201 if (input is HConstant) { 201 if (input is HConstant) {
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
272 272
273 // Try converting the instruction to a builtin instruction. 273 // Try converting the instruction to a builtin instruction.
274 HInstruction instruction = 274 HInstruction instruction =
275 node.specializer.tryConvertToBuiltin(node, types); 275 node.specializer.tryConvertToBuiltin(node, types);
276 if (instruction != null) return instruction; 276 if (instruction != null) return instruction;
277 277
278 // Check if this call does not need to be intercepted. 278 // Check if this call does not need to be intercepted.
279 HInstruction input = node.inputs[1]; 279 HInstruction input = node.inputs[1];
280 HType type = types[input]; 280 HType type = types[input];
281 var interceptor = node.inputs[0]; 281 var interceptor = node.inputs[0];
282
283 if (interceptor.isConstant() && selector.isCall()) {
284 DartType type = types[interceptor].computeType(compiler);
285 node.element = type.element.lookupSelector(selector);
286 }
287
282 if (interceptor is !HThis && !type.canBePrimitive()) { 288 if (interceptor is !HThis && !type.canBePrimitive()) {
283 // If the type can be null, and the intercepted method can be in 289 // If the type can be null, and the intercepted method can be in
284 // the object class, keep the interceptor. 290 // the object class, keep the interceptor.
285 if (type.canBeNull()) { 291 if (type.canBeNull()) {
286 Set<ClassElement> interceptedClasses; 292 Set<ClassElement> interceptedClasses;
287 if (interceptor is HInterceptor) { 293 if (interceptor is HInterceptor) {
288 interceptedClasses = interceptor.interceptedClasses; 294 interceptedClasses = interceptor.interceptedClasses;
289 } else if (node is HOneShotInterceptor) { 295 } else if (node is HOneShotInterceptor) {
290 var oneShotInterceptor = node; 296 var oneShotInterceptor = node;
291 interceptedClasses = oneShotInterceptor.interceptedClasses; 297 interceptedClasses = oneShotInterceptor.interceptedClasses;
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
324 } 330 }
325 } else if (selector.applies(backend.jsStringConcat, compiler)) { 331 } else if (selector.applies(backend.jsStringConcat, compiler)) {
326 if (node.inputs[2].isString(types)) { 332 if (node.inputs[2].isString(types)) {
327 target = backend.jsStringConcat; 333 target = backend.jsStringConcat;
328 } 334 }
329 } else if (selector.applies(backend.jsStringToString, compiler)) { 335 } else if (selector.applies(backend.jsStringToString, compiler)) {
330 return input; 336 return input;
331 } 337 }
332 } 338 }
333 if (target != null) { 339 if (target != null) {
340 // TODO(ngeoffray): There is a strong dependency between codegen
341 // and this optimization that the dynamic invoke does not need an
342 // interceptor. We currently need to keep a
343 // HInvokeDynamicMethod and not create a HForeign because
344 // HForeign is too opaque for the SssaCheckInserter (that adds a
345 // bounds check on removeLast). Once we start inlining, the
346 // bounds check will become explicit, so we won't need this
347 // optimization.
334 HInvokeDynamicMethod result = new HInvokeDynamicMethod( 348 HInvokeDynamicMethod result = new HInvokeDynamicMethod(
335 node.selector, node.inputs.getRange(1, node.inputs.length - 1)); 349 node.selector, node.inputs.getRange(1, node.inputs.length - 1));
336 result.element = target; 350 result.element = target;
337 return result; 351 return result;
338 } 352 }
339 } else if (selector.isGetter()) { 353 } else if (selector.isGetter()) {
340 if (selector.applies(backend.jsArrayLength, compiler)) { 354 if (selector.applies(backend.jsArrayLength, compiler)) {
341 return optimizeLengthInterceptedGetter(node); 355 return optimizeLengthInterceptedGetter(node);
342 } 356 }
343 } 357 }
(...skipping 461 matching lines...) Expand 10 before | Expand all | Expand 10 after
805 HInstruction index = node.index; 819 HInstruction index = node.index;
806 if (!node.index.isInteger(types)) { 820 if (!node.index.isInteger(types)) {
807 index = insertIntegerCheck(node, index); 821 index = insertIntegerCheck(node, index);
808 } 822 }
809 index = insertBoundsCheck(node, node.receiver, index); 823 index = insertBoundsCheck(node, node.receiver, index);
810 node.changeUse(node.index, index); 824 node.changeUse(node.index, index);
811 } 825 }
812 826
813 void visitInvokeDynamicMethod(HInvokeDynamicMethod node) { 827 void visitInvokeDynamicMethod(HInvokeDynamicMethod node) {
814 Element element = node.element; 828 Element element = node.element;
829 if (node.isInterceptorCall) return;
815 if (element != backend.jsArrayRemoveLast) return; 830 if (element != backend.jsArrayRemoveLast) return;
816 if (boundsChecked.contains(node)) return; 831 if (boundsChecked.contains(node)) return;
817 insertBoundsCheck( 832 insertBoundsCheck(
818 node, node.receiver, graph.addConstantInt(0, backend.constantSystem)); 833 node, node.receiver, graph.addConstantInt(0, backend.constantSystem));
819 } 834 }
820 } 835 }
821 836
822 class SsaDeadCodeEliminator extends HGraphVisitor implements OptimizationPhase { 837 class SsaDeadCodeEliminator extends HGraphVisitor implements OptimizationPhase {
823 final HTypeMap types; 838 final HTypeMap types;
824 final String name = "SsaDeadCodeEliminator"; 839 final String name = "SsaDeadCodeEliminator";
(...skipping 695 matching lines...) Expand 10 before | Expand all | Expand 10 after
1520 HBasicBlock block = user.block; 1535 HBasicBlock block = user.block;
1521 block.addAfter(user, interceptor); 1536 block.addAfter(user, interceptor);
1522 block.rewrite(user, interceptor); 1537 block.rewrite(user, interceptor);
1523 block.remove(user); 1538 block.remove(user);
1524 1539
1525 // The interceptor will be removed in the dead code elimination 1540 // The interceptor will be removed in the dead code elimination
1526 // phase. Note that removing it here would not work because of how 1541 // phase. Note that removing it here would not work because of how
1527 // the [visitBasicBlock] is implemented. 1542 // the [visitBasicBlock] is implemented.
1528 } 1543 }
1529 } 1544 }
OLDNEW
« no previous file with comments | « sdk/lib/_internal/compiler/implementation/ssa/codegen.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