| OLD | NEW |
| 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 212 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 223 && interceptor.interceptedClasses.contains(compiler.objectClass)) { | 223 && interceptor.interceptedClasses.contains(compiler.objectClass)) { |
| 224 return node; | 224 return node; |
| 225 } | 225 } |
| 226 // Change the call to a regular invoke dynamic call. | 226 // Change the call to a regular invoke dynamic call. |
| 227 return new HInvokeDynamicMethod( | 227 return new HInvokeDynamicMethod( |
| 228 node.selector, node.inputs.getRange(1, node.inputs.length - 1)); | 228 node.selector, node.inputs.getRange(1, node.inputs.length - 1)); |
| 229 } | 229 } |
| 230 | 230 |
| 231 Selector selector = node.selector; | 231 Selector selector = node.selector; |
| 232 | 232 |
| 233 if (node.isIndexOperatorOnIndexablePrimitive(types)) { | 233 // TODO(ngeoffray): Move this logic into a separate class. |
| 234 return new HIndex(node.inputs[1], node.inputs[2]); | 234 if (selector.kind == SelectorKind.INDEX |
| 235 && input.isIndexablePrimitive(types)) { |
| 236 if (selector.name == const SourceString('[]')) { |
| 237 return new HIndex(node.inputs[1], node.inputs[2]); |
| 238 } else if (input.isMutableArray(types)) { |
| 239 assert(selector.name == const SourceString('[]=')); |
| 240 return new HIndexAssign(node.inputs[1], node.inputs[2], node.inputs[3]); |
| 241 } |
| 242 } else if (selector.kind == SelectorKind.OPERATOR) { |
| 243 if (selector.name == const SourceString('-')) { |
| 244 if (input.isNumber(types)) { |
| 245 return new HNegate(input); |
| 246 } |
| 247 } else if (selector.name == const SourceString('~')) { |
| 248 if (input.isNumber(types)) { |
| 249 return new HBitNot(input); |
| 250 } |
| 251 } |
| 235 } | 252 } |
| 236 | 253 |
| 237 SourceString selectorName = selector.name; | 254 SourceString selectorName = selector.name; |
| 238 Element target; | 255 Element target; |
| 239 if (input.isExtendableArray(types)) { | 256 if (input.isExtendableArray(types)) { |
| 240 if (selectorName == backend.jsArrayRemoveLast.name | 257 if (selectorName == backend.jsArrayRemoveLast.name |
| 241 && selector.argumentCount == 0) { | 258 && selector.argumentCount == 0) { |
| 242 target = backend.jsArrayRemoveLast; | 259 target = backend.jsArrayRemoveLast; |
| 243 } else if (selectorName == backend.jsArrayAdd.name | 260 } else if (selectorName == backend.jsArrayAdd.name |
| 244 && selector.argumentCount == 1 | 261 && selector.argumentCount == 1 |
| (...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 343 HConstant constantInstruction = value; | 360 HConstant constantInstruction = value; |
| 344 assert(!constantInstruction.constant.isInt()); | 361 assert(!constantInstruction.constant.isInt()); |
| 345 if (!constantSystem.isInt(constantInstruction.constant)) { | 362 if (!constantSystem.isInt(constantInstruction.constant)) { |
| 346 // -0.0 is a double but will pass the runtime integer check. | 363 // -0.0 is a double but will pass the runtime integer check. |
| 347 node.alwaysFalse = true; | 364 node.alwaysFalse = true; |
| 348 } | 365 } |
| 349 } | 366 } |
| 350 return node; | 367 return node; |
| 351 } | 368 } |
| 352 | 369 |
| 353 HInstruction visitIndexAssign(HIndexAssign node) { | |
| 354 if (!node.receiver.canBePrimitive(types)) { | |
| 355 Selector selector = new Selector.indexSet(); | |
| 356 return fromPrimitiveInstructionToDynamicInvocation(node, selector); | |
| 357 } | |
| 358 return node; | |
| 359 } | |
| 360 | |
| 361 HInstruction visitInvokeBinary(HInvokeBinary node) { | 370 HInstruction visitInvokeBinary(HInvokeBinary node) { |
| 362 HInstruction left = node.left; | 371 HInstruction left = node.left; |
| 363 HInstruction right = node.right; | 372 HInstruction right = node.right; |
| 364 BinaryOperation operation = node.operation(constantSystem); | 373 BinaryOperation operation = node.operation(constantSystem); |
| 365 if (left is HConstant && right is HConstant) { | 374 if (left is HConstant && right is HConstant) { |
| 366 HConstant op1 = left; | 375 HConstant op1 = left; |
| 367 HConstant op2 = right; | 376 HConstant op2 = right; |
| 368 Constant folded = operation.fold(op1.constant, op2.constant); | 377 Constant folded = operation.fold(op1.constant, op2.constant); |
| 369 if (folded != null) return graph.addConstant(folded); | 378 if (folded != null) return graph.addConstant(folded); |
| 370 } | 379 } |
| (...skipping 454 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 825 | 834 |
| 826 void visitIndexAssign(HIndexAssign node) { | 835 void visitIndexAssign(HIndexAssign node) { |
| 827 if (!node.receiver.isMutableArray(types)) return; | 836 if (!node.receiver.isMutableArray(types)) return; |
| 828 if (boundsChecked.contains(node)) return; | 837 if (boundsChecked.contains(node)) return; |
| 829 HInstruction index = node.index; | 838 HInstruction index = node.index; |
| 830 if (!node.index.isInteger(types)) { | 839 if (!node.index.isInteger(types)) { |
| 831 index = insertIntegerCheck(node, index); | 840 index = insertIntegerCheck(node, index); |
| 832 } | 841 } |
| 833 index = insertBoundsCheck(node, node.receiver, index); | 842 index = insertBoundsCheck(node, node.receiver, index); |
| 834 node.changeUse(node.index, index); | 843 node.changeUse(node.index, index); |
| 835 assert(node.isBuiltin(types)); | |
| 836 } | 844 } |
| 837 | 845 |
| 838 void visitInvokeDynamicMethod(HInvokeDynamicMethod node) { | 846 void visitInvokeDynamicMethod(HInvokeDynamicMethod node) { |
| 839 Element element = node.element; | 847 Element element = node.element; |
| 840 if (element != backend.jsArrayRemoveLast) return; | 848 if (element != backend.jsArrayRemoveLast) return; |
| 841 if (boundsChecked.contains(node)) return; | 849 if (boundsChecked.contains(node)) return; |
| 842 insertBoundsCheck( | 850 insertBoundsCheck( |
| 843 node, node.receiver, graph.addConstantInt(0, backend.constantSystem)); | 851 node, node.receiver, graph.addConstantInt(0, backend.constantSystem)); |
| 844 } | 852 } |
| 845 } | 853 } |
| (...skipping 640 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1486 HInstruction receiver = interceptor.receiver; | 1494 HInstruction receiver = interceptor.receiver; |
| 1487 for (var user in receiver.usedBy) { | 1495 for (var user in receiver.usedBy) { |
| 1488 if (user is HInterceptor && interceptor.dominates(user)) { | 1496 if (user is HInterceptor && interceptor.dominates(user)) { |
| 1489 user.interceptedClasses = interceptor.interceptedClasses; | 1497 user.interceptedClasses = interceptor.interceptedClasses; |
| 1490 } | 1498 } |
| 1491 } | 1499 } |
| 1492 } | 1500 } |
| 1493 | 1501 |
| 1494 // TODO(ngeoffray): Also implement it for non-intercepted calls. | 1502 // TODO(ngeoffray): Also implement it for non-intercepted calls. |
| 1495 } | 1503 } |
| OLD | NEW |