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 190 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
201 } | 201 } |
202 | 202 |
203 HInstruction tryConvertToBuiltin(HInvokeDynamic instruction, | 203 HInstruction tryConvertToBuiltin(HInvokeDynamic instruction, |
204 Compiler compiler) { | 204 Compiler compiler) { |
205 if (isBuiltin(instruction, compiler)) { | 205 if (isBuiltin(instruction, compiler)) { |
206 HInstruction builtin = newBuiltinVariant(instruction, compiler); | 206 HInstruction builtin = newBuiltinVariant(instruction, compiler); |
207 if (builtin != null) return builtin; | 207 if (builtin != null) return builtin; |
208 // Even if there is no builtin equivalent instruction, we know | 208 // Even if there is no builtin equivalent instruction, we know |
209 // the instruction does not have any side effect, and that it | 209 // the instruction does not have any side effect, and that it |
210 // can be GVN'ed. | 210 // can be GVN'ed. |
211 instruction.sideEffects.clearAllSideEffects(); | 211 clearAllSideEffects(instruction); |
212 instruction.sideEffects.clearAllDependencies(); | |
213 instruction.setUseGvn(); | |
214 } | 212 } |
215 return null; | 213 return null; |
216 } | 214 } |
215 | |
216 bool clearAllSideEffects(HInstruction instruction) { | |
kasperl
2013/11/26 08:29:29
bool -> void
ngeoffray
2013/11/26 08:36:35
Done.
| |
217 instruction.sideEffects.clearAllSideEffects(); | |
218 instruction.sideEffects.clearAllDependencies(); | |
219 instruction.setUseGvn(); | |
220 } | |
217 | 221 |
218 HInstruction newBuiltinVariant(HInvokeDynamic instruction, Compiler compiler); | 222 HInstruction newBuiltinVariant(HInvokeDynamic instruction, Compiler compiler); |
219 } | 223 } |
220 | 224 |
221 class AddSpecializer extends BinaryArithmeticSpecializer { | 225 class AddSpecializer extends BinaryArithmeticSpecializer { |
222 const AddSpecializer(); | 226 const AddSpecializer(); |
223 | 227 |
224 BinaryOperation operation(ConstantSystem constantSystem) { | 228 BinaryOperation operation(ConstantSystem constantSystem) { |
225 return constantSystem.add; | 229 return constantSystem.add; |
226 } | 230 } |
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
324 Compiler compiler) { | 328 Compiler compiler) { |
325 // All bitwise operations on primitive types either produce an | 329 // All bitwise operations on primitive types either produce an |
326 // integer or throw an error. | 330 // integer or throw an error. |
327 HInstruction left = instruction.inputs[1]; | 331 HInstruction left = instruction.inputs[1]; |
328 JavaScriptBackend backend = compiler.backend; | 332 JavaScriptBackend backend = compiler.backend; |
329 if (left.isPrimitiveOrNull(compiler)) { | 333 if (left.isPrimitiveOrNull(compiler)) { |
330 return backend.intType; | 334 return backend.intType; |
331 } | 335 } |
332 return super.computeTypeFromInputTypes(instruction, compiler); | 336 return super.computeTypeFromInputTypes(instruction, compiler); |
333 } | 337 } |
338 | |
339 bool argumentLessThan32(HInstruction instruction) { | |
340 if (!instruction.isConstantInteger()) return false; | |
341 HConstant rightConstant = instruction; | |
342 IntConstant intConstant = rightConstant.constant; | |
343 int count = intConstant.value; | |
344 return count >= 0 && count <= 31; | |
345 } | |
346 | |
347 bool isPositive(HInstruction instruction) { | |
348 return instruction is HBinaryBitOp; | |
kasperl
2013/11/26 08:29:29
No way of using value range information here? Add
ngeoffray
2013/11/26 08:36:35
I have added a TODO for the range analysis. I have
| |
349 } | |
334 } | 350 } |
335 | 351 |
336 class ShiftLeftSpecializer extends BinaryBitOpSpecializer { | 352 class ShiftLeftSpecializer extends BinaryBitOpSpecializer { |
337 const ShiftLeftSpecializer(); | 353 const ShiftLeftSpecializer(); |
338 | 354 |
339 BinaryOperation operation(ConstantSystem constantSystem) { | 355 BinaryOperation operation(ConstantSystem constantSystem) { |
340 return constantSystem.shiftLeft; | 356 return constantSystem.shiftLeft; |
341 } | 357 } |
342 | 358 |
343 HInstruction tryConvertToBuiltin(HInvokeDynamic instruction, | 359 HInstruction tryConvertToBuiltin(HInvokeDynamic instruction, |
344 Compiler compiler) { | 360 Compiler compiler) { |
345 HInstruction left = instruction.inputs[1]; | 361 HInstruction left = instruction.inputs[1]; |
346 HInstruction right = instruction.inputs[2]; | 362 HInstruction right = instruction.inputs[2]; |
347 if (!left.isNumber(compiler)) return null; | 363 if (left.isNumber(compiler)) { |
348 if (argumentLessThan32(right)) { | 364 if (argumentLessThan32(right)) { |
349 return newBuiltinVariant(instruction, compiler); | 365 return newBuiltinVariant(instruction, compiler); |
366 } | |
367 // Even if there is no builtin equivalent instruction, we know | |
368 // the instruction does not have any side effect, and that it | |
369 // can be GVN'ed. | |
370 clearAllSideEffects(instruction); | |
350 } | 371 } |
351 return null; | 372 return null; |
352 } | 373 } |
353 | 374 |
354 HInstruction newBuiltinVariant(HInvokeDynamic instruction, | 375 HInstruction newBuiltinVariant(HInvokeDynamic instruction, |
355 Compiler compiler) { | 376 Compiler compiler) { |
356 JavaScriptBackend backend = compiler.backend; | 377 JavaScriptBackend backend = compiler.backend; |
357 return new HShiftLeft( | 378 return new HShiftLeft( |
358 instruction.inputs[1], instruction.inputs[2], | 379 instruction.inputs[1], instruction.inputs[2], |
359 instruction.selector, backend.intType); | 380 instruction.selector, backend.intType); |
360 } | 381 } |
361 | |
362 bool argumentLessThan32(HInstruction instruction) { | |
363 if (!instruction.isConstantInteger()) return false; | |
364 HConstant rightConstant = instruction; | |
365 IntConstant intConstant = rightConstant.constant; | |
366 int count = intConstant.value; | |
367 return count >= 0 && count <= 31; | |
368 } | |
369 } | 382 } |
370 | 383 |
371 class ShiftRightSpecializer extends BinaryBitOpSpecializer { | 384 class ShiftRightSpecializer extends BinaryBitOpSpecializer { |
372 const ShiftRightSpecializer(); | 385 const ShiftRightSpecializer(); |
373 | 386 |
374 HInstruction newBuiltinVariant(HInvokeDynamic instruction, | 387 HInstruction tryConvertToBuiltin(HInvokeDynamic instruction, |
375 Compiler compiler) { | 388 Compiler compiler) { |
376 // Shift right cannot be mapped to the native operator easily. | 389 HInstruction left = instruction.inputs[1]; |
390 HInstruction right = instruction.inputs[2]; | |
391 if (left.isNumber(compiler)) { | |
392 if (argumentLessThan32(right) && isPositive(left)) { | |
393 return newBuiltinVariant(instruction, compiler); | |
394 } | |
395 // Even if there is no builtin equivalent instruction, we know | |
396 // the instruction does not have any side effect, and that it | |
397 // can be GVN'ed. | |
398 clearAllSideEffects(instruction); | |
399 } | |
377 return null; | 400 return null; |
378 } | 401 } |
379 | 402 |
403 HInstruction newBuiltinVariant(HInvokeDynamic instruction, | |
404 Compiler compiler) { | |
405 JavaScriptBackend backend = compiler.backend; | |
406 return new HShiftRight( | |
407 instruction.inputs[1], instruction.inputs[2], | |
408 instruction.selector, backend.intType); | |
409 } | |
410 | |
380 BinaryOperation operation(ConstantSystem constantSystem) { | 411 BinaryOperation operation(ConstantSystem constantSystem) { |
381 return constantSystem.shiftRight; | 412 return constantSystem.shiftRight; |
382 } | 413 } |
383 } | 414 } |
384 | 415 |
385 class BitOrSpecializer extends BinaryBitOpSpecializer { | 416 class BitOrSpecializer extends BinaryBitOpSpecializer { |
386 const BitOrSpecializer(); | 417 const BitOrSpecializer(); |
387 | 418 |
388 BinaryOperation operation(ConstantSystem constantSystem) { | 419 BinaryOperation operation(ConstantSystem constantSystem) { |
389 return constantSystem.bitOr; | 420 return constantSystem.bitOr; |
(...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
549 } | 580 } |
550 | 581 |
551 HInstruction newBuiltinVariant(HInvokeDynamic instruction, | 582 HInstruction newBuiltinVariant(HInvokeDynamic instruction, |
552 Compiler compiler) { | 583 Compiler compiler) { |
553 JavaScriptBackend backend = compiler.backend; | 584 JavaScriptBackend backend = compiler.backend; |
554 return new HLessEqual( | 585 return new HLessEqual( |
555 instruction.inputs[1], instruction.inputs[2], | 586 instruction.inputs[1], instruction.inputs[2], |
556 instruction.selector, backend.boolType); | 587 instruction.selector, backend.boolType); |
557 } | 588 } |
558 } | 589 } |
OLD | NEW |