Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(31)

Side by Side Diff: sdk/lib/_internal/compiler/implementation/ssa/invoke_dynamic_specializers.dart

Issue 85663003: We can actually map the Dart shift right to the JavaScript one under certain conditions. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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
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
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 }
OLDNEW
« no previous file with comments | « sdk/lib/_internal/compiler/implementation/ssa/codegen.dart ('k') | sdk/lib/_internal/compiler/implementation/ssa/nodes.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698