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 202 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
213 } | 213 } |
214 return null; | 214 return null; |
215 } | 215 } |
216 | 216 |
217 void clearAllSideEffects(HInstruction instruction) { | 217 void clearAllSideEffects(HInstruction instruction) { |
218 instruction.sideEffects.clearAllSideEffects(); | 218 instruction.sideEffects.clearAllSideEffects(); |
219 instruction.sideEffects.clearAllDependencies(); | 219 instruction.sideEffects.clearAllDependencies(); |
220 instruction.setUseGvn(); | 220 instruction.setUseGvn(); |
221 } | 221 } |
222 | 222 |
| 223 bool inputsArePositiveIntegers(HInstruction instruction, Compiler compiler) { |
| 224 HInstruction left = instruction.inputs[1]; |
| 225 HInstruction right = instruction.inputs[2]; |
| 226 JavaScriptBackend backend = compiler.backend; |
| 227 return left.isPositiveIntegerOrNull(compiler) |
| 228 && right.isPositiveIntegerOrNull(compiler); |
| 229 } |
| 230 |
223 HInstruction newBuiltinVariant(HInvokeDynamic instruction, Compiler compiler); | 231 HInstruction newBuiltinVariant(HInvokeDynamic instruction, Compiler compiler); |
224 } | 232 } |
225 | 233 |
226 class AddSpecializer extends BinaryArithmeticSpecializer { | 234 class AddSpecializer extends BinaryArithmeticSpecializer { |
227 const AddSpecializer(); | 235 const AddSpecializer(); |
228 | 236 |
| 237 TypeMask computeTypeFromInputTypes(HInvokeDynamic instruction, |
| 238 Compiler compiler) { |
| 239 if (inputsArePositiveIntegers(instruction, compiler)) { |
| 240 JavaScriptBackend backend = compiler.backend; |
| 241 return backend.positiveIntType; |
| 242 } |
| 243 return super.computeTypeFromInputTypes(instruction, compiler); |
| 244 } |
| 245 |
229 BinaryOperation operation(ConstantSystem constantSystem) { | 246 BinaryOperation operation(ConstantSystem constantSystem) { |
230 return constantSystem.add; | 247 return constantSystem.add; |
231 } | 248 } |
232 | 249 |
233 HInstruction newBuiltinVariant(HInvokeDynamic instruction, | 250 HInstruction newBuiltinVariant(HInvokeDynamic instruction, |
234 Compiler compiler) { | 251 Compiler compiler) { |
235 return new HAdd( | 252 return new HAdd( |
236 instruction.inputs[1], instruction.inputs[2], | 253 instruction.inputs[1], instruction.inputs[2], |
237 instruction.selector, computeTypeFromInputTypes(instruction, compiler)); | 254 instruction.selector, computeTypeFromInputTypes(instruction, compiler)); |
238 } | 255 } |
(...skipping 21 matching lines...) Expand all Loading... |
260 JavaScriptBackend backend = compiler.backend; | 277 JavaScriptBackend backend = compiler.backend; |
261 return new HDivide( | 278 return new HDivide( |
262 instruction.inputs[1], instruction.inputs[2], | 279 instruction.inputs[1], instruction.inputs[2], |
263 instruction.selector, backend.doubleType); | 280 instruction.selector, backend.doubleType); |
264 } | 281 } |
265 } | 282 } |
266 | 283 |
267 class ModuloSpecializer extends BinaryArithmeticSpecializer { | 284 class ModuloSpecializer extends BinaryArithmeticSpecializer { |
268 const ModuloSpecializer(); | 285 const ModuloSpecializer(); |
269 | 286 |
| 287 TypeMask computeTypeFromInputTypes(HInvokeDynamic instruction, |
| 288 Compiler compiler) { |
| 289 if (inputsArePositiveIntegers(instruction, compiler)) { |
| 290 JavaScriptBackend backend = compiler.backend; |
| 291 return backend.positiveIntType; |
| 292 } |
| 293 return super.computeTypeFromInputTypes(instruction, compiler); |
| 294 } |
| 295 |
270 BinaryOperation operation(ConstantSystem constantSystem) { | 296 BinaryOperation operation(ConstantSystem constantSystem) { |
271 return constantSystem.modulo; | 297 return constantSystem.modulo; |
272 } | 298 } |
273 | 299 |
274 HInstruction newBuiltinVariant(HInvokeDynamic instruction, | 300 HInstruction newBuiltinVariant(HInvokeDynamic instruction, |
275 Compiler compiler) { | 301 Compiler compiler) { |
276 // Modulo cannot be mapped to the native operator (different semantics). | 302 // Modulo cannot be mapped to the native operator (different semantics). |
277 return null; | 303 return null; |
278 } | 304 } |
279 } | 305 } |
280 | 306 |
281 class MultiplySpecializer extends BinaryArithmeticSpecializer { | 307 class MultiplySpecializer extends BinaryArithmeticSpecializer { |
282 const MultiplySpecializer(); | 308 const MultiplySpecializer(); |
283 | 309 |
284 BinaryOperation operation(ConstantSystem constantSystem) { | 310 BinaryOperation operation(ConstantSystem constantSystem) { |
285 return constantSystem.multiply; | 311 return constantSystem.multiply; |
286 } | 312 } |
287 | 313 |
| 314 TypeMask computeTypeFromInputTypes(HInvokeDynamic instruction, |
| 315 Compiler compiler) { |
| 316 if (inputsArePositiveIntegers(instruction, compiler)) { |
| 317 JavaScriptBackend backend = compiler.backend; |
| 318 return backend.positiveIntType; |
| 319 } |
| 320 return super.computeTypeFromInputTypes(instruction, compiler); |
| 321 } |
| 322 |
288 HInstruction newBuiltinVariant(HInvokeDynamic instruction, | 323 HInstruction newBuiltinVariant(HInvokeDynamic instruction, |
289 Compiler compiler) { | 324 Compiler compiler) { |
290 return new HMultiply( | 325 return new HMultiply( |
291 instruction.inputs[1], instruction.inputs[2], | 326 instruction.inputs[1], instruction.inputs[2], |
292 instruction.selector, computeTypeFromInputTypes(instruction, compiler)); | 327 instruction.selector, computeTypeFromInputTypes(instruction, compiler)); |
293 } | 328 } |
294 } | 329 } |
295 | 330 |
296 class SubtractSpecializer extends BinaryArithmeticSpecializer { | 331 class SubtractSpecializer extends BinaryArithmeticSpecializer { |
297 const SubtractSpecializer(); | 332 const SubtractSpecializer(); |
(...skipping 10 matching lines...) Expand all Loading... |
308 } | 343 } |
309 } | 344 } |
310 | 345 |
311 class TruncatingDivideSpecializer extends BinaryArithmeticSpecializer { | 346 class TruncatingDivideSpecializer extends BinaryArithmeticSpecializer { |
312 const TruncatingDivideSpecializer(); | 347 const TruncatingDivideSpecializer(); |
313 | 348 |
314 BinaryOperation operation(ConstantSystem constantSystem) { | 349 BinaryOperation operation(ConstantSystem constantSystem) { |
315 return constantSystem.truncatingDivide; | 350 return constantSystem.truncatingDivide; |
316 } | 351 } |
317 | 352 |
| 353 TypeMask computeTypeFromInputTypes(HInvokeDynamic instruction, |
| 354 Compiler compiler) { |
| 355 if (inputsArePositiveIntegers(instruction, compiler)) { |
| 356 JavaScriptBackend backend = compiler.backend; |
| 357 return backend.positiveIntType; |
| 358 } |
| 359 return super.computeTypeFromInputTypes(instruction, compiler); |
| 360 } |
| 361 |
318 HInstruction newBuiltinVariant(HInvokeDynamic instruction, | 362 HInstruction newBuiltinVariant(HInvokeDynamic instruction, |
319 Compiler compiler) { | 363 Compiler compiler) { |
320 // Truncating divide does not have a JS equivalent. | 364 // Truncating divide does not have a JS equivalent. |
321 return null; | 365 return null; |
322 } | 366 } |
323 } | 367 } |
324 | 368 |
325 abstract class BinaryBitOpSpecializer extends BinaryArithmeticSpecializer { | 369 abstract class BinaryBitOpSpecializer extends BinaryArithmeticSpecializer { |
326 const BinaryBitOpSpecializer(); | 370 const BinaryBitOpSpecializer(); |
327 | 371 |
(...skipping 13 matching lines...) Expand all Loading... |
341 if (!instruction.isConstantInteger()) return false; | 385 if (!instruction.isConstantInteger()) return false; |
342 HConstant rightConstant = instruction; | 386 HConstant rightConstant = instruction; |
343 IntConstant intConstant = rightConstant.constant; | 387 IntConstant intConstant = rightConstant.constant; |
344 int count = intConstant.value; | 388 int count = intConstant.value; |
345 return count >= 0 && count <= 31; | 389 return count >= 0 && count <= 31; |
346 } | 390 } |
347 | 391 |
348 bool isPositive(HInstruction instruction, Compiler compiler) { | 392 bool isPositive(HInstruction instruction, Compiler compiler) { |
349 // TODO: We should use the value range analysis. Currently, ranges | 393 // TODO: We should use the value range analysis. Currently, ranges |
350 // are discarded just after the analysis. | 394 // are discarded just after the analysis. |
351 return instruction.isUInt32(compiler); | 395 return instruction.isPositiveInteger(compiler); |
352 } | 396 } |
353 } | 397 } |
354 | 398 |
355 class ShiftLeftSpecializer extends BinaryBitOpSpecializer { | 399 class ShiftLeftSpecializer extends BinaryBitOpSpecializer { |
356 const ShiftLeftSpecializer(); | 400 const ShiftLeftSpecializer(); |
357 | 401 |
358 BinaryOperation operation(ConstantSystem constantSystem) { | 402 BinaryOperation operation(ConstantSystem constantSystem) { |
359 return constantSystem.shiftLeft; | 403 return constantSystem.shiftLeft; |
360 } | 404 } |
361 | 405 |
(...skipping 263 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
625 } | 669 } |
626 | 670 |
627 HInstruction newBuiltinVariant(HInvokeDynamic instruction, | 671 HInstruction newBuiltinVariant(HInvokeDynamic instruction, |
628 Compiler compiler) { | 672 Compiler compiler) { |
629 JavaScriptBackend backend = compiler.backend; | 673 JavaScriptBackend backend = compiler.backend; |
630 return new HLessEqual( | 674 return new HLessEqual( |
631 instruction.inputs[1], instruction.inputs[2], | 675 instruction.inputs[1], instruction.inputs[2], |
632 instruction.selector, backend.boolType); | 676 instruction.selector, backend.boolType); |
633 } | 677 } |
634 } | 678 } |
OLD | NEW |