| 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 249 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 260 } | 260 } |
| 261 | 261 |
| 262 bool isBuiltin(HInvokeDynamicMethod instruction, HTypeMap types) { | 262 bool isBuiltin(HInvokeDynamicMethod instruction, HTypeMap types) { |
| 263 return instruction.inputs[1].isNumber(types) | 263 return instruction.inputs[1].isNumber(types) |
| 264 && instruction.inputs[2].isNumber(types); | 264 && instruction.inputs[2].isNumber(types); |
| 265 } | 265 } |
| 266 | 266 |
| 267 HInstruction tryConvertToBuiltin(HInvokeDynamicMethod instruction, | 267 HInstruction tryConvertToBuiltin(HInvokeDynamicMethod instruction, |
| 268 HTypeMap types) { | 268 HTypeMap types) { |
| 269 if (isBuiltin(instruction, types)) { | 269 if (isBuiltin(instruction, types)) { |
| 270 return newBuiltinVariant(instruction.inputs[1], instruction.inputs[2]); | 270 HInstruction builtin = |
| 271 newBuiltinVariant(instruction.inputs[1], instruction.inputs[2]); |
| 272 if (builtin != null) return builtin; |
| 273 // Even if there is no builtin equivalent instruction, we know |
| 274 // the instruction does not have any side effect, and that it |
| 275 // can be GVN'ed. |
| 276 instruction.clearAllSideEffects(); |
| 277 instruction.clearAllDependencies(); |
| 278 instruction.setUseGvn(); |
| 271 } | 279 } |
| 272 return null; | 280 return null; |
| 273 } | 281 } |
| 274 | 282 |
| 275 HInstruction newBuiltinVariant(HInstruction left, HInstruction right); | 283 HInstruction newBuiltinVariant(HInstruction left, HInstruction right); |
| 276 } | 284 } |
| 277 | 285 |
| 278 class AddSpecializer extends BinaryArithmeticSpecializer { | 286 class AddSpecializer extends BinaryArithmeticSpecializer { |
| 279 const AddSpecializer(); | 287 const AddSpecializer(); |
| 280 | 288 |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 318 } | 326 } |
| 319 } | 327 } |
| 320 | 328 |
| 321 class ModuloSpecializer extends BinaryArithmeticSpecializer { | 329 class ModuloSpecializer extends BinaryArithmeticSpecializer { |
| 322 const ModuloSpecializer(); | 330 const ModuloSpecializer(); |
| 323 | 331 |
| 324 BinaryOperation operation(ConstantSystem constantSystem) { | 332 BinaryOperation operation(ConstantSystem constantSystem) { |
| 325 return constantSystem.modulo; | 333 return constantSystem.modulo; |
| 326 } | 334 } |
| 327 | 335 |
| 328 HInstruction tryConvertToBuiltin(HInvokeDynamicMethod instruction, | 336 HInstruction newBuiltinVariant(HInstruction left, HInstruction right) { |
| 329 HTypeMap types) { | |
| 330 // Modulo cannot be mapped to the native operator (different semantics). | 337 // Modulo cannot be mapped to the native operator (different semantics). |
| 331 return null; | 338 return null; |
| 332 } | 339 } |
| 333 | |
| 334 HInstruction newBuiltinVariant(HInstruction left, HInstruction right) { | |
| 335 throw 'Modulo has no builtin variant'; | |
| 336 } | |
| 337 } | 340 } |
| 338 | 341 |
| 339 class MultiplySpecializer extends BinaryArithmeticSpecializer { | 342 class MultiplySpecializer extends BinaryArithmeticSpecializer { |
| 340 const MultiplySpecializer(); | 343 const MultiplySpecializer(); |
| 341 | 344 |
| 342 BinaryOperation operation(ConstantSystem constantSystem) { | 345 BinaryOperation operation(ConstantSystem constantSystem) { |
| 343 return constantSystem.multiply; | 346 return constantSystem.multiply; |
| 344 } | 347 } |
| 345 | 348 |
| 346 HInstruction newBuiltinVariant(HInstruction left, HInstruction right) { | 349 HInstruction newBuiltinVariant(HInstruction left, HInstruction right) { |
| (...skipping 13 matching lines...) Expand all Loading... |
| 360 } | 363 } |
| 361 } | 364 } |
| 362 | 365 |
| 363 class TruncatingDivideSpecializer extends BinaryArithmeticSpecializer { | 366 class TruncatingDivideSpecializer extends BinaryArithmeticSpecializer { |
| 364 const TruncatingDivideSpecializer(); | 367 const TruncatingDivideSpecializer(); |
| 365 | 368 |
| 366 BinaryOperation operation(ConstantSystem constantSystem) { | 369 BinaryOperation operation(ConstantSystem constantSystem) { |
| 367 return constantSystem.truncatingDivide; | 370 return constantSystem.truncatingDivide; |
| 368 } | 371 } |
| 369 | 372 |
| 370 HInstruction tryConvertToBuiltin(HInvokeDynamicMethod instruction, | 373 HInstruction newBuiltinVariant(HInstruction left, HInstruction right) { |
| 371 HTypeMap types) { | |
| 372 // Truncating divide does not have a JS equivalent. | 374 // Truncating divide does not have a JS equivalent. |
| 373 return null; | 375 return null; |
| 374 } | 376 } |
| 375 | |
| 376 HInstruction newBuiltinVariant(HInstruction left, HInstruction right) { | |
| 377 throw 'Truncating divide has no builtin variant'; | |
| 378 } | |
| 379 } | 377 } |
| 380 | 378 |
| 381 abstract class BinaryBitOpSpecializer extends BinaryArithmeticSpecializer { | 379 abstract class BinaryBitOpSpecializer extends BinaryArithmeticSpecializer { |
| 382 const BinaryBitOpSpecializer(); | 380 const BinaryBitOpSpecializer(); |
| 383 | 381 |
| 384 HType computeTypeFromInputTypes(HInvokeDynamicMethod instruction, | 382 HType computeTypeFromInputTypes(HInvokeDynamicMethod instruction, |
| 385 HTypeMap types, | 383 HTypeMap types, |
| 386 Compiler compiler) { | 384 Compiler compiler) { |
| 387 // All bitwise operations on primitive types either produce an | 385 // All bitwise operations on primitive types either produce an |
| 388 // integer or throw an error. | 386 // integer or throw an error. |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 429 } | 427 } |
| 430 | 428 |
| 431 HInstruction newBuiltinVariant(HInstruction left, HInstruction right) { | 429 HInstruction newBuiltinVariant(HInstruction left, HInstruction right) { |
| 432 return new HShiftLeft(left, right); | 430 return new HShiftLeft(left, right); |
| 433 } | 431 } |
| 434 } | 432 } |
| 435 | 433 |
| 436 class ShiftRightSpecializer extends BinaryBitOpSpecializer { | 434 class ShiftRightSpecializer extends BinaryBitOpSpecializer { |
| 437 const ShiftRightSpecializer(); | 435 const ShiftRightSpecializer(); |
| 438 | 436 |
| 439 HInstruction tryConvertToBuiltin(HInvokeDynamicMethod instruction, | 437 HInstruction newBuiltinVariant(HInstruction left, HInstruction right) { |
| 440 HTypeMap types) { | |
| 441 // Shift right cannot be mapped to the native operator easily. | 438 // Shift right cannot be mapped to the native operator easily. |
| 442 return null; | 439 return null; |
| 443 } | 440 } |
| 444 | 441 |
| 445 HInstruction newBuiltinVariant(HInstruction left, HInstruction right) { | |
| 446 throw 'Shift right has no builtin variant'; | |
| 447 } | |
| 448 | |
| 449 BinaryOperation operation(ConstantSystem constantSystem) { | 442 BinaryOperation operation(ConstantSystem constantSystem) { |
| 450 return constantSystem.shiftRight; | 443 return constantSystem.shiftRight; |
| 451 } | 444 } |
| 452 } | 445 } |
| 453 | 446 |
| 454 class BitOrSpecializer extends BinaryBitOpSpecializer { | 447 class BitOrSpecializer extends BinaryBitOpSpecializer { |
| 455 const BitOrSpecializer(); | 448 const BitOrSpecializer(); |
| 456 | 449 |
| 457 BinaryOperation operation(ConstantSystem constantSystem) { | 450 BinaryOperation operation(ConstantSystem constantSystem) { |
| 458 return constantSystem.bitOr; | 451 return constantSystem.bitOr; |
| (...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 618 const LessEqualSpecializer(); | 611 const LessEqualSpecializer(); |
| 619 | 612 |
| 620 BinaryOperation operation(ConstantSystem constantSystem) { | 613 BinaryOperation operation(ConstantSystem constantSystem) { |
| 621 return constantSystem.lessEqual; | 614 return constantSystem.lessEqual; |
| 622 } | 615 } |
| 623 | 616 |
| 624 HInstruction newBuiltinVariant(HInstruction left, HInstruction right) { | 617 HInstruction newBuiltinVariant(HInstruction left, HInstruction right) { |
| 625 return new HLessEqual(left, right); | 618 return new HLessEqual(left, right); |
| 626 } | 619 } |
| 627 } | 620 } |
| OLD | NEW |