| OLD | NEW |
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, 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 /** | 7 /** |
| 8 * [InvokeDynamicSpecializer] and its subclasses are helpers to | 8 * [InvokeDynamicSpecializer] and its subclasses are helpers to |
| 9 * optimize intercepted dynamic calls. It knows what input types | 9 * optimize intercepted dynamic calls. It knows what input types |
| 10 * would be beneficial for performance, and how to change a invoke | 10 * would be beneficial for performance, and how to change a invoke |
| (...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 137 | 137 |
| 138 UnaryOperation operation(ConstantSystem constantSystem) { | 138 UnaryOperation operation(ConstantSystem constantSystem) { |
| 139 return constantSystem.bitNot; | 139 return constantSystem.bitNot; |
| 140 } | 140 } |
| 141 | 141 |
| 142 HType computeDesiredTypeForInput(HInvokeDynamic instruction, | 142 HType computeDesiredTypeForInput(HInvokeDynamic instruction, |
| 143 HInstruction input, | 143 HInstruction input, |
| 144 Compiler compiler) { | 144 Compiler compiler) { |
| 145 if (input == instruction.inputs[1]) { | 145 if (input == instruction.inputs[1]) { |
| 146 HType propagatedType = instruction.instructionType; | 146 HType propagatedType = instruction.instructionType; |
| 147 if (propagatedType.isUnknown() || propagatedType.isNumber()) { | 147 if (propagatedType.canBePrimitiveNumber(compiler)) { |
| 148 return HType.INTEGER; | 148 return HType.INTEGER; |
| 149 } | 149 } |
| 150 } | 150 } |
| 151 return HType.UNKNOWN; | 151 return HType.UNKNOWN; |
| 152 } | 152 } |
| 153 | 153 |
| 154 HType computeTypeFromInputTypes(HInvokeDynamic instruction, | 154 HType computeTypeFromInputTypes(HInvokeDynamic instruction, |
| 155 Compiler compiler) { | 155 Compiler compiler) { |
| 156 // All bitwise operations on primitive types either produce an | 156 // All bitwise operations on primitive types either produce an |
| 157 // integer or throw an error. | 157 // integer or throw an error. |
| (...skipping 17 matching lines...) Expand all Loading... |
| 175 | 175 |
| 176 HType computeDesiredTypeForInput(HInvokeDynamic instruction, | 176 HType computeDesiredTypeForInput(HInvokeDynamic instruction, |
| 177 HInstruction input, | 177 HInstruction input, |
| 178 Compiler compiler) { | 178 Compiler compiler) { |
| 179 if (input == instruction.inputs[1]) { | 179 if (input == instruction.inputs[1]) { |
| 180 HType propagatedType = instruction.instructionType; | 180 HType propagatedType = instruction.instructionType; |
| 181 // If the outgoing type should be a number (integer, double or both) we | 181 // If the outgoing type should be a number (integer, double or both) we |
| 182 // want the outgoing type to be the input too. | 182 // want the outgoing type to be the input too. |
| 183 // If we don't know the outgoing type we try to make it a number. | 183 // If we don't know the outgoing type we try to make it a number. |
| 184 if (propagatedType.isNumber()) return propagatedType; | 184 if (propagatedType.isNumber()) return propagatedType; |
| 185 if (propagatedType.isUnknown()) return HType.NUMBER; | 185 if (propagatedType.canBePrimitiveNumber(compiler)) return HType.NUMBER; |
| 186 } | 186 } |
| 187 return HType.UNKNOWN; | 187 return HType.UNKNOWN; |
| 188 } | 188 } |
| 189 | 189 |
| 190 HType computeTypeFromInputTypes(HInvokeDynamic instruction, | 190 HType computeTypeFromInputTypes(HInvokeDynamic instruction, |
| 191 Compiler compiler) { | 191 Compiler compiler) { |
| 192 HType operandType = instruction.inputs[1].instructionType; | 192 HType operandType = instruction.inputs[1].instructionType; |
| 193 if (operandType.isNumber()) return operandType; | 193 if (operandType.isNumber()) return operandType; |
| 194 return instruction.instructionType; | 194 return instruction.instructionType; |
| 195 } | 195 } |
| (...skipping 25 matching lines...) Expand all Loading... |
| 221 Compiler compiler) { | 221 Compiler compiler) { |
| 222 if (input == instruction.inputs[0]) return HType.UNKNOWN; | 222 if (input == instruction.inputs[0]) return HType.UNKNOWN; |
| 223 | 223 |
| 224 HType propagatedType = instruction.instructionType; | 224 HType propagatedType = instruction.instructionType; |
| 225 // If the desired output type should be an integer we want to get two | 225 // If the desired output type should be an integer we want to get two |
| 226 // integers as arguments. | 226 // integers as arguments. |
| 227 if (propagatedType.isInteger()) return HType.INTEGER; | 227 if (propagatedType.isInteger()) return HType.INTEGER; |
| 228 // If the outgoing type should be a number we can get that if both inputs | 228 // If the outgoing type should be a number we can get that if both inputs |
| 229 // are numbers. If we don't know the outgoing type we try to make it a | 229 // are numbers. If we don't know the outgoing type we try to make it a |
| 230 // number. | 230 // number. |
| 231 if (propagatedType.isUnknown() || propagatedType.isNumber()) { | 231 if (propagatedType.canBePrimitiveNumber(compiler)) { |
| 232 return HType.NUMBER; | 232 return HType.NUMBER; |
| 233 } | 233 } |
| 234 // Even if the desired outgoing type is not a number we still want the | 234 // Even if the desired outgoing type is not a number we still want the |
| 235 // second argument to be a number if the first one is a number. This will | 235 // second argument to be a number if the first one is a number. This will |
| 236 // not help for the outgoing type, but at least the binary arithmetic | 236 // not help for the outgoing type, but at least the binary arithmetic |
| 237 // operation will not have type problems. | 237 // operation will not have type problems. |
| 238 // TODO(floitsch): normally we shouldn't request a number, but simply | 238 // TODO(floitsch): normally we shouldn't request a number, but simply |
| 239 // throw an ArgumentError if it isn't. This would be similar | 239 // throw an ArgumentError if it isn't. This would be similar |
| 240 // to the array case. | 240 // to the array case. |
| 241 HInstruction left = instruction.inputs[1]; | 241 HInstruction left = instruction.inputs[1]; |
| (...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 371 } | 371 } |
| 372 | 372 |
| 373 HType computeDesiredTypeForInput(HInvokeDynamic instruction, | 373 HType computeDesiredTypeForInput(HInvokeDynamic instruction, |
| 374 HInstruction input, | 374 HInstruction input, |
| 375 Compiler compiler) { | 375 Compiler compiler) { |
| 376 if (input == instruction.inputs[0]) return HType.UNKNOWN; | 376 if (input == instruction.inputs[0]) return HType.UNKNOWN; |
| 377 HType propagatedType = instruction.instructionType; | 377 HType propagatedType = instruction.instructionType; |
| 378 // If the outgoing type should be a number we can get that only if both | 378 // If the outgoing type should be a number we can get that only if both |
| 379 // inputs are integers. If we don't know the outgoing type we try to make | 379 // inputs are integers. If we don't know the outgoing type we try to make |
| 380 // it an integer. | 380 // it an integer. |
| 381 if (propagatedType.isUnknown() || propagatedType.isNumber()) { | 381 if (propagatedType.canBePrimitiveNumber(compiler)) { |
| 382 return HType.INTEGER; | 382 return HType.INTEGER; |
| 383 } | 383 } |
| 384 return HType.UNKNOWN; | 384 return HType.UNKNOWN; |
| 385 } | 385 } |
| 386 } | 386 } |
| 387 | 387 |
| 388 class ShiftLeftSpecializer extends BinaryBitOpSpecializer { | 388 class ShiftLeftSpecializer extends BinaryBitOpSpecializer { |
| 389 const ShiftLeftSpecializer(); | 389 const ShiftLeftSpecializer(); |
| 390 | 390 |
| 391 BinaryOperation operation(ConstantSystem constantSystem) { | 391 BinaryOperation operation(ConstantSystem constantSystem) { |
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 471 } | 471 } |
| 472 | 472 |
| 473 HType computeDesiredTypeForInput(HInvokeDynamic instruction, | 473 HType computeDesiredTypeForInput(HInvokeDynamic instruction, |
| 474 HInstruction input, | 474 HInstruction input, |
| 475 Compiler compiler) { | 475 Compiler compiler) { |
| 476 if (input == instruction.inputs[0]) return HType.UNKNOWN; | 476 if (input == instruction.inputs[0]) return HType.UNKNOWN; |
| 477 HType propagatedType = instruction.instructionType; | 477 HType propagatedType = instruction.instructionType; |
| 478 // For all relational operations except HIdentity, we expect to get numbers | 478 // For all relational operations except HIdentity, we expect to get numbers |
| 479 // only. With numbers the outgoing type is a boolean. If something else | 479 // only. With numbers the outgoing type is a boolean. If something else |
| 480 // is desired, then numbers are incorrect, though. | 480 // is desired, then numbers are incorrect, though. |
| 481 if (propagatedType.isUnknown() || propagatedType.isBoolean()) { | 481 if (propagatedType.canBePrimitiveBoolean(compiler)) { |
| 482 HInstruction left = instruction.inputs[1]; | 482 HInstruction left = instruction.inputs[1]; |
| 483 if (left.instructionType.canBePrimitiveNumber(compiler)) { | 483 if (left.instructionType.canBePrimitiveNumber(compiler)) { |
| 484 return HType.NUMBER; | 484 return HType.NUMBER; |
| 485 } | 485 } |
| 486 } | 486 } |
| 487 return HType.UNKNOWN; | 487 return HType.UNKNOWN; |
| 488 } | 488 } |
| 489 | 489 |
| 490 HInstruction tryConvertToBuiltin(HInvokeDynamic instruction) { | 490 HInstruction tryConvertToBuiltin(HInvokeDynamic instruction) { |
| 491 HInstruction left = instruction.inputs[1]; | 491 HInstruction left = instruction.inputs[1]; |
| (...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 586 const LessEqualSpecializer(); | 586 const LessEqualSpecializer(); |
| 587 | 587 |
| 588 BinaryOperation operation(ConstantSystem constantSystem) { | 588 BinaryOperation operation(ConstantSystem constantSystem) { |
| 589 return constantSystem.lessEqual; | 589 return constantSystem.lessEqual; |
| 590 } | 590 } |
| 591 | 591 |
| 592 HInstruction newBuiltinVariant(HInstruction left, HInstruction right) { | 592 HInstruction newBuiltinVariant(HInstruction left, HInstruction right) { |
| 593 return new HLessEqual(left, right); | 593 return new HLessEqual(left, right); |
| 594 } | 594 } |
| 595 } | 595 } |
| OLD | NEW |