83
83
import com .oracle .graal .python .nodes .util .CastToIndexNode ;
84
84
import com .oracle .graal .python .runtime .exception .PythonErrorType ;
85
85
import com .oracle .truffle .api .CompilerDirectives ;
86
+ import com .oracle .truffle .api .CompilerDirectives .CompilationFinal ;
86
87
import com .oracle .truffle .api .CompilerDirectives .TruffleBoundary ;
87
88
import com .oracle .truffle .api .dsl .Cached ;
88
89
import com .oracle .truffle .api .dsl .Fallback ;
@@ -613,6 +614,7 @@ PNotImplemented doGeneric(Object left, Object right) {
613
614
@ GenerateNodeFactory
614
615
@ TypeSystemReference (PythonArithmeticTypes .class )
615
616
abstract static class MulNode extends PythonBinaryBuiltinNode {
617
+ @ CompilationFinal private ConditionProfile isBigIntPowerOfTwo = ConditionProfile .createBinaryProfile ();
616
618
617
619
@ Specialization (rewriteOn = ArithmeticException .class )
618
620
int doII (int x , int y ) throws ArithmeticException {
@@ -637,27 +639,40 @@ PInt doLLOvf(long x, long y) {
637
639
if (((ax | ay ) >>> 31 != 0 )) {
638
640
int leadingZeros = Long .numberOfLeadingZeros (ax ) + Long .numberOfLeadingZeros (ay );
639
641
if (leadingZeros < 66 ) {
640
- return factory ().createInt (op (BigInteger .valueOf (x ), BigInteger .valueOf (y )));
642
+ return factory ().createInt (mul (BigInteger .valueOf (x ), BigInteger .valueOf (y )));
641
643
}
642
644
}
643
645
return factory ().createInt (r );
644
646
}
645
647
646
648
@ Specialization
647
649
PInt doPIntLong (PInt left , long right ) {
648
- return factory ().createInt (op (left .getValue (), BigInteger .valueOf (right )));
650
+ return factory ().createInt (mul (left .getValue (), BigInteger .valueOf (right )));
649
651
}
650
652
651
653
@ Specialization
652
654
PInt doPIntPInt (PInt left , PInt right ) {
653
- return factory ().createInt (op (left .getValue (), right .getValue ()));
655
+ return factory ().createInt (mul (left .getValue (), right .getValue ()));
656
+ }
657
+
658
+ BigInteger mul (BigInteger a , BigInteger b ) {
659
+ if (isBigIntPowerOfTwo .profile (b .and (b .subtract (BigInteger .ONE )).equals (BigInteger .ZERO ))) {
660
+ return bigIntegerShift (a , b .getLowestSetBit ());
661
+ } else {
662
+ return bigIntegerMul (a , b );
663
+ }
654
664
}
655
665
656
666
@ TruffleBoundary
657
- BigInteger op (BigInteger a , BigInteger b ) {
667
+ BigInteger bigIntegerMul (BigInteger a , BigInteger b ) {
658
668
return a .multiply (b );
659
669
}
660
670
671
+ @ TruffleBoundary
672
+ BigInteger bigIntegerShift (BigInteger a , int n ) {
673
+ return a .shiftLeft (n );
674
+ }
675
+
661
676
@ SuppressWarnings ("unused" )
662
677
@ Fallback
663
678
PNotImplemented doGeneric (Object left , Object right ) {
0 commit comments