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 |