Skip to content

Commit f7aebb3

Browse files
committed
[GR-52250] Fix host inlining of Float comparison operations.
PullRequest: graalpython/3210
2 parents e5bb3c2 + 146c339 commit f7aebb3

File tree

7 files changed

+47
-5
lines changed

7 files changed

+47
-5
lines changed

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/bytes/ByteArrayBuiltins.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,7 @@
109109
import com.oracle.graal.python.runtime.sequence.storage.ByteSequenceStorage;
110110
import com.oracle.graal.python.runtime.sequence.storage.SequenceStorage;
111111
import com.oracle.graal.python.util.ComparisonOp;
112+
import com.oracle.truffle.api.HostCompilerDirectives.InliningCutoff;
112113
import com.oracle.truffle.api.dsl.Bind;
113114
import com.oracle.truffle.api.dsl.Cached;
114115
import com.oracle.truffle.api.dsl.Cached.Exclusive;
@@ -867,6 +868,7 @@ static boolean cmp(Node inliningTarget, PByteArray self, PBytesLike other, Compa
867868
}
868869

869870
@Specialization(guards = {"check.execute(inliningTarget, self)", "acquireLib.hasBuffer(other)"}, limit = "3")
871+
@InliningCutoff
870872
static Object cmp(VirtualFrame frame, Node inliningTarget, Object self, Object other, ComparisonOp op,
871873
@Cached("createFor(this)") IndirectCallData indirectCallData,
872874
@SuppressWarnings("unused") @Exclusive @Cached PyByteArrayCheckNode check,
@@ -893,6 +895,7 @@ static Object cmp(VirtualFrame frame, Node inliningTarget, Object self, Object o
893895
}
894896

895897
@Specialization(guards = "!check.execute(inliningTarget, self)")
898+
@InliningCutoff
896899
@SuppressWarnings("unused")
897900
static Object error(VirtualFrame frame, Node inliningTarget, Object self, Object other, ComparisonOp op,
898901
@Shared @Cached PyByteArrayCheckNode check,

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/common/SequenceStorageNodes.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1720,6 +1720,7 @@ static byte[] doGenericLenCached(Node inliningTarget, SequenceStorage s,
17201720
}
17211721

17221722
@Specialization(replaces = "doGenericLenCached")
1723+
@InliningCutoff
17231724
static byte[] doGeneric(Node inliningTarget, SequenceStorage s,
17241725
@Shared("getItemNode") @Cached GetItemScalarNode getItemNode,
17251726
@Shared @Cached CastToJavaByteNode castToByteNode) {

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/floats/FloatBuiltins.java

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@
8686
import com.oracle.graal.python.builtins.objects.PNotImplemented;
8787
import com.oracle.graal.python.builtins.objects.common.FormatNodeBase;
8888
import com.oracle.graal.python.builtins.objects.floats.FloatBuiltinsClinicProviders.FormatNodeClinicProviderGen;
89+
import com.oracle.graal.python.builtins.objects.floats.FloatUtils.PFloatUnboxing;
8990
import com.oracle.graal.python.builtins.objects.ints.PInt;
9091
import com.oracle.graal.python.builtins.objects.tuple.PTuple;
9192
import com.oracle.graal.python.lib.PyFloatCheckNode;
@@ -106,6 +107,7 @@
106107
import com.oracle.graal.python.nodes.truffle.PythonArithmeticTypes;
107108
import com.oracle.graal.python.nodes.util.CannotCastException;
108109
import com.oracle.graal.python.nodes.util.CastToJavaDoubleNode;
110+
import com.oracle.graal.python.runtime.exception.PException;
109111
import com.oracle.graal.python.runtime.exception.PythonErrorType;
110112
import com.oracle.graal.python.runtime.formatting.FloatFormatter;
111113
import com.oracle.graal.python.runtime.formatting.InternalFormat;
@@ -147,10 +149,15 @@ private static double castToDoubleChecked(Node inliningTarget, Object obj, CastT
147149
try {
148150
return cast.execute(inliningTarget, obj);
149151
} catch (CannotCastException e) {
150-
throw PRaiseNode.getUncached().raise(TypeError, ErrorMessages.DESCRIPTOR_REQUIRES_S_OBJ_RECEIVED_P, "float", obj);
152+
throw raiseWrongSelf(obj);
151153
}
152154
}
153155

156+
@InliningCutoff
157+
private static PException raiseWrongSelf(Object obj) {
158+
throw PRaiseNode.getUncached().raise(TypeError, ErrorMessages.DESCRIPTOR_REQUIRES_S_OBJ_RECEIVED_P, "float", obj);
159+
}
160+
154161
@GenerateCached(false)
155162
abstract static class AbstractNumericUnaryBuiltin extends PythonUnaryBuiltinNode {
156163
protected abstract Object op(double num);
@@ -733,6 +740,7 @@ private static BigInteger toBigInteger(double d) {
733740

734741
@GenerateInline
735742
@GenerateCached(false)
743+
@TypeSystemReference(PFloatUnboxing.class)
736744
public abstract static class ComparisonHelperNode extends Node {
737745

738746
@FunctionalInterface
@@ -753,6 +761,7 @@ static boolean doDI(double a, int b, Op op) {
753761
}
754762

755763
@Specialization(guards = "check.execute(inliningTarget, bObj)", replaces = "doDD", limit = "1")
764+
@InliningCutoff
756765
static boolean doOO(Node inliningTarget, Object aObj, Object bObj, Op op,
757766
@SuppressWarnings("unused") @Cached PyFloatCheckNode check,
758767
@Exclusive @Cached CastToJavaDoubleNode cast) {
@@ -762,13 +771,15 @@ static boolean doOO(Node inliningTarget, Object aObj, Object bObj, Op op,
762771
}
763772

764773
@Specialization(replaces = "doDI")
774+
@InliningCutoff
765775
static boolean doOI(Node inliningTarget, Object aObj, int b, Op op,
766776
@Shared @Cached CastToJavaDoubleNode cast) {
767777
double a = castToDoubleChecked(inliningTarget, aObj, cast);
768778
return op.compute(a, b);
769779
}
770780

771781
@Specialization
782+
@InliningCutoff
772783
static boolean doOL(Node inliningTarget, Object aObj, long b, Op op,
773784
@Exclusive @Cached CastToJavaDoubleNode cast,
774785
@Cached InlinedConditionProfile longFitsToDoubleProfile) {
@@ -777,13 +788,15 @@ static boolean doOL(Node inliningTarget, Object aObj, long b, Op op,
777788
}
778789

779790
@Specialization
791+
@InliningCutoff
780792
static boolean doOPInt(Node inliningTarget, Object aObj, PInt b, Op op,
781793
@Shared @Cached CastToJavaDoubleNode cast) {
782794
double a = castToDoubleChecked(inliningTarget, aObj, cast);
783795
return op.compute(compareDoubleToLargeInt(a, b), 0.0);
784796
}
785797

786798
@Specialization
799+
@InliningCutoff
787800
static boolean doOB(Node inliningTarget, Object aObj, boolean b, Op op,
788801
@Shared @Cached CastToJavaDoubleNode cast) {
789802
double a = castToDoubleChecked(inliningTarget, aObj, cast);

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/floats/FloatUtils.java

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2020, 2021, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* The Universal Permissive License (UPL), Version 1.0
@@ -44,6 +44,8 @@
4444

4545
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
4646
import com.oracle.truffle.api.CompilerDirectives.ValueType;
47+
import com.oracle.truffle.api.dsl.ImplicitCast;
48+
import com.oracle.truffle.api.dsl.TypeSystem;
4749

4850
/**
4951
* Contains helper methods for parsing float numbers in float() and complex() constructors.
@@ -241,4 +243,18 @@ public static double parseValidString(String substr) {
241243
}
242244
return d;
243245
}
246+
247+
/**
248+
* Unboxes {@link PFloat}. Use only in situations where this is correct behavior.
249+
*/
250+
@TypeSystem
251+
public static class PFloatUnboxing {
252+
@ImplicitCast
253+
public static double PFloatToDouble(PFloat value) {
254+
// NOTE: That's correct because we just use it in arithmetic operations where CPython
255+
// also access the value ('f_val') directly. So, even if the object is subclassed, it
256+
// is ignored.
257+
return value.getValue();
258+
}
259+
}
244260
}

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyFloatCheckNode.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2023, 2024, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* The Universal Permissive License (UPL), Version 1.0
@@ -44,6 +44,7 @@
4444
import com.oracle.graal.python.builtins.objects.cext.PythonAbstractNativeObject;
4545
import com.oracle.graal.python.builtins.objects.floats.PFloat;
4646
import com.oracle.graal.python.nodes.object.BuiltinClassProfiles.IsBuiltinObjectProfile;
47+
import com.oracle.truffle.api.HostCompilerDirectives.InliningCutoff;
4748
import com.oracle.truffle.api.dsl.Cached;
4849
import com.oracle.truffle.api.dsl.Fallback;
4950
import com.oracle.truffle.api.dsl.GenerateCached;
@@ -73,6 +74,7 @@ static boolean doPFloat(@SuppressWarnings("unused") PFloat obj) {
7374
}
7475

7576
@Specialization
77+
@InliningCutoff
7678
static boolean doNative(PythonAbstractNativeObject object,
7779
@Cached(inline = false) IsBuiltinObjectProfile check) {
7880
return check.profileObjectCached(object, PythonBuiltinClassType.PFloat);

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/util/CastToJavaByteNode.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2019, 2023, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2019, 2024, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* The Universal Permissive License (UPL), Version 1.0
@@ -47,6 +47,7 @@
4747
import com.oracle.graal.python.nodes.PNodeWithContext;
4848
import com.oracle.graal.python.nodes.PRaiseNode;
4949
import com.oracle.graal.python.util.OverflowException;
50+
import com.oracle.truffle.api.HostCompilerDirectives.InliningCutoff;
5051
import com.oracle.truffle.api.dsl.Cached;
5152
import com.oracle.truffle.api.dsl.Cached.Shared;
5253
import com.oracle.truffle.api.dsl.GenerateCached;
@@ -91,6 +92,7 @@ static byte fromPInt(PInt x) {
9192
}
9293

9394
@Specialization(replaces = "fromInt")
95+
@InliningCutoff
9496
static byte fromIntErr(Node inliningTarget, int x,
9597
@Shared("raiseNode") @Cached PRaiseNode.Lazy raiseNode) {
9698
try {
@@ -101,6 +103,7 @@ static byte fromIntErr(Node inliningTarget, int x,
101103
}
102104

103105
@Specialization(replaces = "fromLong")
106+
@InliningCutoff
104107
static byte fromLongErr(Node inliningTarget, long x,
105108
@Shared("raiseNode") @Cached PRaiseNode.Lazy raiseNode) {
106109
try {
@@ -111,6 +114,7 @@ static byte fromLongErr(Node inliningTarget, long x,
111114
}
112115

113116
@Specialization(replaces = "fromPInt")
117+
@InliningCutoff
114118
static byte fromPIntErr(Node inliningTarget, PInt x,
115119
@Shared("raiseNode") @Cached PRaiseNode.Lazy raiseNode) {
116120
try {

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/util/CastToJavaDoubleNode.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* The Universal Permissive License (UPL), Version 1.0
@@ -52,6 +52,7 @@
5252
import com.oracle.graal.python.nodes.object.GetClassNode.GetPythonObjectClassNode;
5353
import com.oracle.graal.python.nodes.truffle.PythonArithmeticTypes;
5454
import com.oracle.truffle.api.CompilerDirectives;
55+
import com.oracle.truffle.api.HostCompilerDirectives.InliningCutoff;
5556
import com.oracle.truffle.api.dsl.Cached;
5657
import com.oracle.truffle.api.dsl.GenerateCached;
5758
import com.oracle.truffle.api.dsl.GenerateInline;
@@ -114,6 +115,7 @@ static double doPBCT(@SuppressWarnings("unused") PythonBuiltinClassType object)
114115
}
115116

116117
@Specialization
118+
@InliningCutoff
117119
static double doNativeObject(Node inliningTarget, PythonAbstractNativeObject x,
118120
@Cached GetPythonObjectClassNode getClassNode,
119121
@Cached(inline = false) IsSubtypeNode isSubtypeNode,
@@ -144,6 +146,7 @@ public static Double doInterop(Object obj,
144146
}
145147

146148
@Specialization(guards = "!isNumber(obj)")
149+
@InliningCutoff
147150
static double doGeneric(Object obj,
148151
@CachedLibrary(limit = "3") InteropLibrary interopLibrary) {
149152
Double d = doInterop(obj, interopLibrary);

0 commit comments

Comments
 (0)