| 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 182 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 193 block.remove(instruction); | 193 block.remove(instruction); |
| 194 } | 194 } |
| 195 instruction = next; | 195 instruction = next; |
| 196 } | 196 } |
| 197 } | 197 } |
| 198 | 198 |
| 199 HInstruction visitInstruction(HInstruction node) { | 199 HInstruction visitInstruction(HInstruction node) { |
| 200 return node; | 200 return node; |
| 201 } | 201 } |
| 202 | 202 |
| 203 ConstantValue getConstantFromType(HInstruction node) { | |
| 204 if (node.isValue() && !node.canBeNull()) { | |
| 205 ValueTypeMask valueMask = node.instructionType; | |
| 206 if (valueMask.value.isBool) { | |
| 207 return valueMask.value; | |
| 208 } | |
| 209 // TODO(het): consider supporting other values (short strings?) | |
| 210 } | |
| 211 return null; | |
| 212 } | |
| 213 | |
| 214 void propagateConstantValueToUses(HInstruction known) { | |
| 215 if (known.usedBy.isEmpty) return; | |
| 216 ConstantValue value = getConstantFromType(known); | |
| 217 if (value != null) { | |
| 218 for (HInstruction user in known.usedBy.toList()) { | |
| 219 user.changeUse(known, graph.addConstant(value, compiler)); | |
| 220 } | |
| 221 } | |
| 222 } | |
| 223 | |
| 224 HInstruction visitParameterValue(HParameterValue node) { | |
| 225 propagateConstantValueToUses(node); | |
| 226 return node; | |
| 227 } | |
| 228 | |
| 229 HInstruction visitBoolify(HBoolify node) { | 203 HInstruction visitBoolify(HBoolify node) { |
| 230 List<HInstruction> inputs = node.inputs; | 204 List<HInstruction> inputs = node.inputs; |
| 231 assert(inputs.length == 1); | 205 assert(inputs.length == 1); |
| 232 HInstruction input = inputs[0]; | 206 HInstruction input = inputs[0]; |
| 233 if (input.isBoolean(compiler)) return input; | 207 if (input.isBoolean(compiler)) return input; |
| 234 | 208 |
| 235 // If the code is unreachable, remove the HBoolify. This can happen when | 209 // If the code is unreachable, remove the HBoolify. This can happen when |
| 236 // there is a throw expression in a short-circuit conditional. Removing the | 210 // there is a throw expression in a short-circuit conditional. Removing the |
| 237 // unreachable HBoolify makes it easier to reconstruct the short-circuit | 211 // unreachable HBoolify makes it easier to reconstruct the short-circuit |
| 238 // operation. | 212 // operation. |
| (...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 391 if (selector.applies(backend.jsIndexableLength, world)) { | 365 if (selector.applies(backend.jsIndexableLength, world)) { |
| 392 HInstruction optimized = tryOptimizeLengthInterceptedGetter(node); | 366 HInstruction optimized = tryOptimizeLengthInterceptedGetter(node); |
| 393 if (optimized != null) return optimized; | 367 if (optimized != null) return optimized; |
| 394 } | 368 } |
| 395 } | 369 } |
| 396 | 370 |
| 397 return node; | 371 return node; |
| 398 } | 372 } |
| 399 | 373 |
| 400 HInstruction visitInvokeDynamicMethod(HInvokeDynamicMethod node) { | 374 HInstruction visitInvokeDynamicMethod(HInvokeDynamicMethod node) { |
| 401 propagateConstantValueToUses(node); | |
| 402 if (node.isInterceptedCall) { | 375 if (node.isInterceptedCall) { |
| 403 HInstruction folded = handleInterceptedCall(node); | 376 HInstruction folded = handleInterceptedCall(node); |
| 404 if (folded != node) return folded; | 377 if (folded != node) return folded; |
| 405 } | 378 } |
| 406 | 379 |
| 407 TypeMask receiverType = node.getDartReceiver(compiler).instructionType; | 380 TypeMask receiverType = node.getDartReceiver(compiler).instructionType; |
| 408 Element element = | 381 Element element = |
| 409 compiler.world.locateSingleElement(node.selector, receiverType); | 382 compiler.world.locateSingleElement(node.selector, receiverType); |
| 410 // TODO(ngeoffray): Also fold if it's a getter or variable. | 383 // TODO(ngeoffray): Also fold if it's a getter or variable. |
| 411 if (element != null | 384 if (element != null |
| (...skipping 414 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 826 instruction = node.index; | 799 instruction = node.index; |
| 827 int index = instruction.constant.primitiveValue; | 800 int index = instruction.constant.primitiveValue; |
| 828 if (index >= 0 && index < entries.length) { | 801 if (index >= 0 && index < entries.length) { |
| 829 return graph.addConstant(entries[index], compiler); | 802 return graph.addConstant(entries[index], compiler); |
| 830 } | 803 } |
| 831 } | 804 } |
| 832 return node; | 805 return node; |
| 833 } | 806 } |
| 834 | 807 |
| 835 HInstruction visitInvokeDynamicGetter(HInvokeDynamicGetter node) { | 808 HInstruction visitInvokeDynamicGetter(HInvokeDynamicGetter node) { |
| 836 propagateConstantValueToUses(node); | |
| 837 if (node.isInterceptedCall) { | 809 if (node.isInterceptedCall) { |
| 838 HInstruction folded = handleInterceptedCall(node); | 810 HInstruction folded = handleInterceptedCall(node); |
| 839 if (folded != node) return folded; | 811 if (folded != node) return folded; |
| 840 } | 812 } |
| 841 HInstruction receiver = node.getDartReceiver(compiler); | 813 HInstruction receiver = node.getDartReceiver(compiler); |
| 842 Element field = findConcreteFieldForDynamicAccess( | 814 Element field = findConcreteFieldForDynamicAccess( |
| 843 receiver, node.selector); | 815 receiver, node.selector); |
| 844 if (field == null) return node; | 816 if (field == null) return node; |
| 845 return directFieldGet(receiver, field); | 817 return directFieldGet(receiver, field); |
| 846 } | 818 } |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 888 HTypeConversion.CHECKED_MODE_CHECK); | 860 HTypeConversion.CHECKED_MODE_CHECK); |
| 889 if (other != value) { | 861 if (other != value) { |
| 890 node.block.addBefore(node, other); | 862 node.block.addBefore(node, other); |
| 891 value = other; | 863 value = other; |
| 892 } | 864 } |
| 893 } | 865 } |
| 894 return new HFieldSet(field, receiver, value); | 866 return new HFieldSet(field, receiver, value); |
| 895 } | 867 } |
| 896 | 868 |
| 897 HInstruction visitInvokeStatic(HInvokeStatic node) { | 869 HInstruction visitInvokeStatic(HInvokeStatic node) { |
| 898 propagateConstantValueToUses(node); | |
| 899 if (node.element == backend.getCheckConcurrentModificationError()) { | 870 if (node.element == backend.getCheckConcurrentModificationError()) { |
| 900 if (node.inputs.length == 2) { | 871 if (node.inputs.length == 2) { |
| 901 HInstruction firstArgument = node.inputs[0]; | 872 HInstruction firstArgument = node.inputs[0]; |
| 902 if (firstArgument is HConstant) { | 873 if (firstArgument is HConstant) { |
| 903 HConstant constant = firstArgument; | 874 HConstant constant = firstArgument; |
| 904 if (constant.constant.isTrue) return constant; | 875 if (constant.constant.isTrue) return constant; |
| 905 } | 876 } |
| 906 } | 877 } |
| 907 } | 878 } |
| 908 return node; | 879 return node; |
| (...skipping 419 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1328 } | 1299 } |
| 1329 | 1300 |
| 1330 void visitIf(HIf instruction) { | 1301 void visitIf(HIf instruction) { |
| 1331 HInstruction condition = instruction.condition; | 1302 HInstruction condition = instruction.condition; |
| 1332 if (condition.isConstant()) { | 1303 if (condition.isConstant()) { |
| 1333 if (condition.isConstantTrue()) { | 1304 if (condition.isConstantTrue()) { |
| 1334 markBlockLive(instruction.thenBlock); | 1305 markBlockLive(instruction.thenBlock); |
| 1335 } else { | 1306 } else { |
| 1336 markBlockLive(instruction.elseBlock); | 1307 markBlockLive(instruction.elseBlock); |
| 1337 } | 1308 } |
| 1309 } else if (condition.isValue()) { |
| 1310 ValueTypeMask valueType = condition.instructionType; |
| 1311 if (valueType.value == true) { |
| 1312 markBlockLive(instruction.thenBlock); |
| 1313 } else { |
| 1314 markBlockLive(instruction.elseBlock); |
| 1315 } |
| 1338 } else { | 1316 } else { |
| 1339 visitControlFlow(instruction); | 1317 visitControlFlow(instruction); |
| 1340 } | 1318 } |
| 1341 } | 1319 } |
| 1342 | 1320 |
| 1343 void visitSwitch(HSwitch node) { | 1321 void visitSwitch(HSwitch node) { |
| 1344 if (node.expression.isInteger(compiler)) { | 1322 if (node.expression.isInteger(compiler)) { |
| 1345 Range switchRange = ranges[node.expression]; | 1323 Range switchRange = ranges[node.expression]; |
| 1346 if (switchRange != null && | 1324 if (switchRange != null && |
| 1347 switchRange.lower is IntValue && | 1325 switchRange.lower is IntValue && |
| (...skipping 1033 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2381 | 2359 |
| 2382 keyedValues.forEach((receiver, values) { | 2360 keyedValues.forEach((receiver, values) { |
| 2383 result.keyedValues[receiver] = | 2361 result.keyedValues[receiver] = |
| 2384 new Map<HInstruction, HInstruction>.from(values); | 2362 new Map<HInstruction, HInstruction>.from(values); |
| 2385 }); | 2363 }); |
| 2386 | 2364 |
| 2387 result.nonEscapingReceivers.addAll(nonEscapingReceivers); | 2365 result.nonEscapingReceivers.addAll(nonEscapingReceivers); |
| 2388 return result; | 2366 return result; |
| 2389 } | 2367 } |
| 2390 } | 2368 } |
| OLD | NEW |