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 |