| 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 node) { |
| 215 if (node.usedBy.isEmpty) return; |
| 216 ConstantValue value = getConstantFromType(node); |
| 217 if (value != null) { |
| 218 HConstant constant = graph.addConstant(value, compiler); |
| 219 for (HInstruction user in node.usedBy.toList()) { |
| 220 user.changeUse(node, constant); |
| 221 } |
| 222 } |
| 223 } |
| 224 |
| 225 HInstruction visitParameterValue(HParameterValue node) { |
| 226 // It is possible for the parameter value to be assigned to in the function |
| 227 // body. If that happens then we should not forward the constant value to |
| 228 // its uses since since the uses reachable from the assignment may have |
| 229 // values in addition to the constant passed to the function. |
| 230 if (node.usedBy.any((user) => |
| 231 user is HLocalSet && identical(user.local, node))) { |
| 232 return node; |
| 233 } |
| 234 propagateConstantValueToUses(node); |
| 235 return node; |
| 236 } |
| 237 |
| 203 HInstruction visitBoolify(HBoolify node) { | 238 HInstruction visitBoolify(HBoolify node) { |
| 204 List<HInstruction> inputs = node.inputs; | 239 List<HInstruction> inputs = node.inputs; |
| 205 assert(inputs.length == 1); | 240 assert(inputs.length == 1); |
| 206 HInstruction input = inputs[0]; | 241 HInstruction input = inputs[0]; |
| 207 if (input.isBoolean(compiler)) return input; | 242 if (input.isBoolean(compiler)) return input; |
| 208 | 243 |
| 209 // If the code is unreachable, remove the HBoolify. This can happen when | 244 // If the code is unreachable, remove the HBoolify. This can happen when |
| 210 // there is a throw expression in a short-circuit conditional. Removing the | 245 // there is a throw expression in a short-circuit conditional. Removing the |
| 211 // unreachable HBoolify makes it easier to reconstruct the short-circuit | 246 // unreachable HBoolify makes it easier to reconstruct the short-circuit |
| 212 // operation. | 247 // operation. |
| (...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 365 if (selector.applies(backend.jsIndexableLength, world)) { | 400 if (selector.applies(backend.jsIndexableLength, world)) { |
| 366 HInstruction optimized = tryOptimizeLengthInterceptedGetter(node); | 401 HInstruction optimized = tryOptimizeLengthInterceptedGetter(node); |
| 367 if (optimized != null) return optimized; | 402 if (optimized != null) return optimized; |
| 368 } | 403 } |
| 369 } | 404 } |
| 370 | 405 |
| 371 return node; | 406 return node; |
| 372 } | 407 } |
| 373 | 408 |
| 374 HInstruction visitInvokeDynamicMethod(HInvokeDynamicMethod node) { | 409 HInstruction visitInvokeDynamicMethod(HInvokeDynamicMethod node) { |
| 410 propagateConstantValueToUses(node); |
| 375 if (node.isInterceptedCall) { | 411 if (node.isInterceptedCall) { |
| 376 HInstruction folded = handleInterceptedCall(node); | 412 HInstruction folded = handleInterceptedCall(node); |
| 377 if (folded != node) return folded; | 413 if (folded != node) return folded; |
| 378 } | 414 } |
| 379 | 415 |
| 380 TypeMask receiverType = node.getDartReceiver(compiler).instructionType; | 416 TypeMask receiverType = node.getDartReceiver(compiler).instructionType; |
| 381 Element element = | 417 Element element = |
| 382 compiler.world.locateSingleElement(node.selector, receiverType); | 418 compiler.world.locateSingleElement(node.selector, receiverType); |
| 383 // TODO(ngeoffray): Also fold if it's a getter or variable. | 419 // TODO(ngeoffray): Also fold if it's a getter or variable. |
| 384 if (element != null | 420 if (element != null |
| (...skipping 414 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 799 instruction = node.index; | 835 instruction = node.index; |
| 800 int index = instruction.constant.primitiveValue; | 836 int index = instruction.constant.primitiveValue; |
| 801 if (index >= 0 && index < entries.length) { | 837 if (index >= 0 && index < entries.length) { |
| 802 return graph.addConstant(entries[index], compiler); | 838 return graph.addConstant(entries[index], compiler); |
| 803 } | 839 } |
| 804 } | 840 } |
| 805 return node; | 841 return node; |
| 806 } | 842 } |
| 807 | 843 |
| 808 HInstruction visitInvokeDynamicGetter(HInvokeDynamicGetter node) { | 844 HInstruction visitInvokeDynamicGetter(HInvokeDynamicGetter node) { |
| 845 propagateConstantValueToUses(node); |
| 809 if (node.isInterceptedCall) { | 846 if (node.isInterceptedCall) { |
| 810 HInstruction folded = handleInterceptedCall(node); | 847 HInstruction folded = handleInterceptedCall(node); |
| 811 if (folded != node) return folded; | 848 if (folded != node) return folded; |
| 812 } | 849 } |
| 813 HInstruction receiver = node.getDartReceiver(compiler); | 850 HInstruction receiver = node.getDartReceiver(compiler); |
| 814 Element field = findConcreteFieldForDynamicAccess( | 851 Element field = findConcreteFieldForDynamicAccess( |
| 815 receiver, node.selector); | 852 receiver, node.selector); |
| 816 if (field == null) return node; | 853 if (field == null) return node; |
| 817 return directFieldGet(receiver, field); | 854 return directFieldGet(receiver, field); |
| 818 } | 855 } |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 860 HTypeConversion.CHECKED_MODE_CHECK); | 897 HTypeConversion.CHECKED_MODE_CHECK); |
| 861 if (other != value) { | 898 if (other != value) { |
| 862 node.block.addBefore(node, other); | 899 node.block.addBefore(node, other); |
| 863 value = other; | 900 value = other; |
| 864 } | 901 } |
| 865 } | 902 } |
| 866 return new HFieldSet(field, receiver, value); | 903 return new HFieldSet(field, receiver, value); |
| 867 } | 904 } |
| 868 | 905 |
| 869 HInstruction visitInvokeStatic(HInvokeStatic node) { | 906 HInstruction visitInvokeStatic(HInvokeStatic node) { |
| 907 propagateConstantValueToUses(node); |
| 870 if (node.element == backend.getCheckConcurrentModificationError()) { | 908 if (node.element == backend.getCheckConcurrentModificationError()) { |
| 871 if (node.inputs.length == 2) { | 909 if (node.inputs.length == 2) { |
| 872 HInstruction firstArgument = node.inputs[0]; | 910 HInstruction firstArgument = node.inputs[0]; |
| 873 if (firstArgument is HConstant) { | 911 if (firstArgument is HConstant) { |
| 874 HConstant constant = firstArgument; | 912 HConstant constant = firstArgument; |
| 875 if (constant.constant.isTrue) return constant; | 913 if (constant.constant.isTrue) return constant; |
| 876 } | 914 } |
| 877 } | 915 } |
| 878 } | 916 } |
| 879 return node; | 917 return node; |
| (...skipping 419 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1299 } | 1337 } |
| 1300 | 1338 |
| 1301 void visitIf(HIf instruction) { | 1339 void visitIf(HIf instruction) { |
| 1302 HInstruction condition = instruction.condition; | 1340 HInstruction condition = instruction.condition; |
| 1303 if (condition.isConstant()) { | 1341 if (condition.isConstant()) { |
| 1304 if (condition.isConstantTrue()) { | 1342 if (condition.isConstantTrue()) { |
| 1305 markBlockLive(instruction.thenBlock); | 1343 markBlockLive(instruction.thenBlock); |
| 1306 } else { | 1344 } else { |
| 1307 markBlockLive(instruction.elseBlock); | 1345 markBlockLive(instruction.elseBlock); |
| 1308 } | 1346 } |
| 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 } | |
| 1316 } else { | 1347 } else { |
| 1317 visitControlFlow(instruction); | 1348 visitControlFlow(instruction); |
| 1318 } | 1349 } |
| 1319 } | 1350 } |
| 1320 | 1351 |
| 1321 void visitSwitch(HSwitch node) { | 1352 void visitSwitch(HSwitch node) { |
| 1322 if (node.expression.isInteger(compiler)) { | 1353 if (node.expression.isInteger(compiler)) { |
| 1323 Range switchRange = ranges[node.expression]; | 1354 Range switchRange = ranges[node.expression]; |
| 1324 if (switchRange != null && | 1355 if (switchRange != null && |
| 1325 switchRange.lower is IntValue && | 1356 switchRange.lower is IntValue && |
| (...skipping 1033 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2359 | 2390 |
| 2360 keyedValues.forEach((receiver, values) { | 2391 keyedValues.forEach((receiver, values) { |
| 2361 result.keyedValues[receiver] = | 2392 result.keyedValues[receiver] = |
| 2362 new Map<HInstruction, HInstruction>.from(values); | 2393 new Map<HInstruction, HInstruction>.from(values); |
| 2363 }); | 2394 }); |
| 2364 | 2395 |
| 2365 result.nonEscapingReceivers.addAll(nonEscapingReceivers); | 2396 result.nonEscapingReceivers.addAll(nonEscapingReceivers); |
| 2366 return result; | 2397 return result; |
| 2367 } | 2398 } |
| 2368 } | 2399 } |
| OLD | NEW |