| 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 class SsaTypePropagator extends HBaseVisitor implements OptimizationPhase { | 7 class SsaTypePropagator extends HBaseVisitor implements OptimizationPhase { |
| 8 final Map<int, HInstruction> workmap = new Map<int, HInstruction>(); | 8 final Map<int, HInstruction> workmap = new Map<int, HInstruction>(); |
| 9 final List<int> worklist = new List<int>(); | 9 final List<int> worklist = new List<int>(); |
| 10 final Map<HInstruction, Function> pendingOptimizations = | 10 final Map<HInstruction, Function> pendingOptimizations = |
| (...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 100 HInstruction left = instruction.left; | 100 HInstruction left = instruction.left; |
| 101 HInstruction right = instruction.right; | 101 HInstruction right = instruction.right; |
| 102 JavaScriptBackend backend = compiler.backend; | 102 JavaScriptBackend backend = compiler.backend; |
| 103 if (left.isInteger(compiler) && right.isInteger(compiler)) { | 103 if (left.isInteger(compiler) && right.isInteger(compiler)) { |
| 104 return backend.intType; | 104 return backend.intType; |
| 105 } | 105 } |
| 106 if (left.isDouble(compiler)) return backend.doubleType; | 106 if (left.isDouble(compiler)) return backend.doubleType; |
| 107 return backend.numType; | 107 return backend.numType; |
| 108 } | 108 } |
| 109 | 109 |
| 110 TypeMask checkPositiveInteger(HBinaryArithmetic instruction) { |
| 111 HInstruction left = instruction.left; |
| 112 HInstruction right = instruction.right; |
| 113 JavaScriptBackend backend = compiler.backend; |
| 114 if (left.isPositiveInteger(compiler) && right.isPositiveInteger(compiler)) { |
| 115 return backend.positiveIntType; |
| 116 } |
| 117 return visitBinaryArithmetic(instruction); |
| 118 } |
| 119 |
| 120 TypeMask visitMultiply(HMultiply instruction) { |
| 121 return checkPositiveInteger(instruction); |
| 122 } |
| 123 |
| 124 TypeMask visitAdd(HAdd instruction) { |
| 125 return checkPositiveInteger(instruction); |
| 126 } |
| 127 |
| 110 TypeMask visitNegate(HNegate instruction) { | 128 TypeMask visitNegate(HNegate instruction) { |
| 111 return instruction.operand.instructionType; | 129 return instruction.operand.instructionType; |
| 112 } | 130 } |
| 113 | 131 |
| 114 TypeMask visitInstruction(HInstruction instruction) { | 132 TypeMask visitInstruction(HInstruction instruction) { |
| 115 assert(instruction.instructionType != null); | 133 assert(instruction.instructionType != null); |
| 116 return instruction.instructionType; | 134 return instruction.instructionType; |
| 117 } | 135 } |
| 118 | 136 |
| 119 TypeMask visitPhi(HPhi phi) { | 137 TypeMask visitPhi(HPhi phi) { |
| (...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 242 // We want the right error in checked mode. | 260 // We want the right error in checked mode. |
| 243 if (compiler.enableTypeAssertions) return false; | 261 if (compiler.enableTypeAssertions) return false; |
| 244 HInstruction left = instruction.inputs[1]; | 262 HInstruction left = instruction.inputs[1]; |
| 245 HInstruction right = instruction.inputs[2]; | 263 HInstruction right = instruction.inputs[2]; |
| 246 | 264 |
| 247 Selector selector = instruction.selector; | 265 Selector selector = instruction.selector; |
| 248 if (selector.isOperator() && left.isNumber(compiler)) { | 266 if (selector.isOperator() && left.isNumber(compiler)) { |
| 249 if (right.isNumber(compiler)) return false; | 267 if (right.isNumber(compiler)) return false; |
| 250 JavaScriptBackend backend = compiler.backend; | 268 JavaScriptBackend backend = compiler.backend; |
| 251 TypeMask type = right.isIntegerOrNull(compiler) | 269 TypeMask type = right.isIntegerOrNull(compiler) |
| 252 ? backend.intType | 270 ? right.instructionType.nonNullable() |
| 253 : backend.numType; | 271 : backend.numType; |
| 254 // TODO(ngeoffray): Some number operations don't have a builtin | 272 // TODO(ngeoffray): Some number operations don't have a builtin |
| 255 // variant and will do the check in their method anyway. We | 273 // variant and will do the check in their method anyway. We |
| 256 // still add a check because it allows to GVN these operations, | 274 // still add a check because it allows to GVN these operations, |
| 257 // but we should find a better way. | 275 // but we should find a better way. |
| 258 convertInput(instruction, | 276 convertInput(instruction, |
| 259 right, | 277 right, |
| 260 type, | 278 type, |
| 261 HTypeConversion.ARGUMENT_TYPE_CHECK); | 279 HTypeConversion.ARGUMENT_TYPE_CHECK); |
| 262 return true; | 280 return true; |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 329 instruction.block.addBefore(instruction.next, converted); | 347 instruction.block.addBefore(instruction.next, converted); |
| 330 receiver.replaceAllUsersDominatedBy(converted.next, converted); | 348 receiver.replaceAllUsersDominatedBy(converted.next, converted); |
| 331 addDependentInstructionsToWorkList(converted); | 349 addDependentInstructionsToWorkList(converted); |
| 332 } | 350 } |
| 333 } | 351 } |
| 334 | 352 |
| 335 return instruction.specializer.computeTypeFromInputTypes( | 353 return instruction.specializer.computeTypeFromInputTypes( |
| 336 instruction, compiler); | 354 instruction, compiler); |
| 337 } | 355 } |
| 338 } | 356 } |
| OLD | NEW |