Skip to content

Commit 6ee2a35

Browse files
committed
Implement node to get LLVM type IDs of basic types.
1 parent 7a2dc28 commit 6ee2a35

File tree

4 files changed

+184
-1
lines changed

4 files changed

+184
-1
lines changed

graalpython/com.oracle.graal.python.cext/src/capi.c

Lines changed: 57 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -199,7 +199,63 @@ initialize_type(_PyWeakref_CallableProxyType, CallableProxyType, PyWeakReference
199199

200200
POLYGLOT_DECLARE_TYPE(PyThreadState);
201201
POLYGLOT_DECLARE_TYPE(newfunc);
202-
POLYGLOT_DECLARE_TYPE(uint32_t);
202+
203+
204+
/* primitive and pointer type declarations */
205+
206+
#define REGISTER_BASIC_TYPE(typename) \
207+
POLYGLOT_DECLARE_TYPE(typename); \
208+
NO_INLINE static polyglot_typeid get_ ## typename ## _typeid(void) { \
209+
return polyglot_ ## typename ## _typeid(); \
210+
}
211+
212+
/* just a renaming to avoid name clash with Java types */
213+
typedef float float_t;
214+
typedef double double_t;
215+
216+
REGISTER_BASIC_TYPE(int64_t);
217+
REGISTER_BASIC_TYPE(int32_t);
218+
REGISTER_BASIC_TYPE(int16_t);
219+
REGISTER_BASIC_TYPE(int8_t);
220+
REGISTER_BASIC_TYPE(uint64_t);
221+
REGISTER_BASIC_TYPE(uint32_t);
222+
REGISTER_BASIC_TYPE(uint16_t);
223+
REGISTER_BASIC_TYPE(uint8_t);
224+
REGISTER_BASIC_TYPE(Py_complex);
225+
REGISTER_BASIC_TYPE(float_t);
226+
REGISTER_BASIC_TYPE(double_t);
227+
REGISTER_BASIC_TYPE(Py_ssize_t);
228+
229+
typedef int64_t* int64_ptr_t;
230+
typedef int32_t* int32_ptr_t;
231+
typedef int16_t* int16_ptr_t;
232+
typedef int8_t* int8_ptr_t;
233+
typedef char* char_ptr_t;
234+
typedef float* float_ptr_t;
235+
typedef double* double_ptr_t;
236+
typedef uint64_t* uint64_ptr_t;
237+
typedef uint32_t* uint32_ptr_t;
238+
typedef uint16_t* uint16_ptr_t;
239+
typedef uint8_t* uint8_ptr_t;
240+
typedef Py_complex* Py_complex_ptr_t;
241+
typedef void* void_ptr_t;
242+
typedef Py_ssize_t* Py_ssize_ptr_t;
243+
244+
REGISTER_BASIC_TYPE(int64_ptr_t);
245+
REGISTER_BASIC_TYPE(int32_ptr_t);
246+
REGISTER_BASIC_TYPE(int16_ptr_t);
247+
REGISTER_BASIC_TYPE(int8_ptr_t);
248+
REGISTER_BASIC_TYPE(char_ptr_t);
249+
REGISTER_BASIC_TYPE(uint64_ptr_t);
250+
REGISTER_BASIC_TYPE(uint32_ptr_t);
251+
REGISTER_BASIC_TYPE(uint16_ptr_t);
252+
REGISTER_BASIC_TYPE(uint8_ptr_t);
253+
REGISTER_BASIC_TYPE(Py_complex_ptr_t);
254+
REGISTER_BASIC_TYPE(void_ptr_t);
255+
REGISTER_BASIC_TYPE(float_ptr_t);
256+
REGISTER_BASIC_TYPE(double_ptr_t);
257+
REGISTER_BASIC_TYPE(Py_ssize_ptr_t);
258+
203259

204260
static void initialize_globals() {
205261
// register native NULL

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/CExtNodes.java

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@
7878
import com.oracle.graal.python.builtins.objects.cext.DynamicObjectNativeWrapper.PrimitiveNativeWrapper;
7979
import com.oracle.graal.python.builtins.objects.cext.DynamicObjectNativeWrapper.PythonObjectNativeWrapper;
8080
import com.oracle.graal.python.builtins.objects.cext.capi.CApiContext;
81+
import com.oracle.graal.python.builtins.objects.cext.capi.CApiContext.LLVMType;
8182
import com.oracle.graal.python.builtins.objects.cext.capi.NativeReferenceCache.ResolveNativeReferenceNode;
8283
import com.oracle.graal.python.builtins.objects.cext.capi.PyTruffleObjectFree.FreeNode;
8384
import com.oracle.graal.python.builtins.objects.cext.common.CExtAsPythonObjectNode;
@@ -3235,4 +3236,32 @@ static boolean isFallback(Object object) {
32353236
}
32363237
}
32373238

3239+
@GenerateUncached
3240+
public abstract static class GetLLVMType extends Node {
3241+
public abstract TruffleObject execute(LLVMType llvmType);
3242+
3243+
@Specialization(guards = "llvmType == cachedType", limit = "typeCount()")
3244+
static TruffleObject doGeneric(@SuppressWarnings("unused") LLVMType llvmType,
3245+
@Cached("llvmType") LLVMType cachedType,
3246+
@CachedContext(PythonLanguage.class) PythonContext context) {
3247+
3248+
CApiContext cApiContext = context.getCApiContext();
3249+
TruffleObject llvmTypeID = cApiContext.getLLVMTypeID(cachedType);
3250+
3251+
// TODO(fa): get rid of lazy initialization for better sharing
3252+
if (llvmTypeID == null) {
3253+
CompilerDirectives.transferToInterpreterAndInvalidate();
3254+
String getterFunctionName = LLVMType.getGetterFunctionName(llvmType);
3255+
llvmTypeID = (TruffleObject) PCallCapiFunction.getUncached().call(getterFunctionName);
3256+
cApiContext.setLLVMTypeID(cachedType, llvmTypeID);
3257+
}
3258+
return llvmTypeID;
3259+
}
3260+
3261+
static int typeCount() {
3262+
CompilerAsserts.neverPartOfCompilation();
3263+
return LLVMType.values().length;
3264+
}
3265+
}
3266+
32383267
}

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/NativeCAPISymbols.java

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@
4646
import com.oracle.truffle.api.nodes.ExplodeLoop;
4747
import com.oracle.truffle.api.nodes.ExplodeLoop.LoopExplosionKind;
4848

49+
@SuppressWarnings("unused")
4950
public abstract class NativeCAPISymbols {
5051

5152
public static final String FUN_NATIVE_LONG_TO_JAVA = "native_long_to_java";
@@ -101,6 +102,33 @@ public abstract class NativeCAPISymbols {
101102
public static final String FUN_TRUFFLE_CANNOT_BE_HANDLE = "truffle_cannot_be_handle";
102103
public static final String FUN_GET_LONG_BITS_PER_DIGIT = "get_long_bits_in_digit";
103104
public static final String FUN_BULK_SUBREF = "PyTruffle_bulk_SUBREF";
105+
private static final String FUN_GET_INT8_T_TYPEID = "get_int8_t_typeid";
106+
private static final String FUN_GET_INT16_T_TYPEID = "get_int16_t_typeid";
107+
private static final String FUN_GET_INT32_T_TYPEID = "get_int32_t_typeid";
108+
private static final String FUN_GET_INT64_T_TYPEID = "get_int64_t_typeid";
109+
private static final String FUN_GET_UINT8_T_TYPEID = "get_uint8_t_typeid";
110+
private static final String FUN_GET_UINT16_T_TYPEID = "get_uint16_t_typeid";
111+
private static final String FUN_GET_UINT32_T_TYPEID = "get_uint32_t_typeid";
112+
private static final String FUN_GET_UINT64_T_TYPEID = "get_uint64_t_typeid";
113+
private static final String FUN_GET_PY_COMPLEX_TYPEID = "get_Py_complex_typeid";
114+
private static final String FUN_GET_FLOAT_T_TYPEID = "get_float_t_typeid";
115+
private static final String FUN_GET_DOUBLE_T_TYPEID = "get_double_t_typeid";
116+
private static final String FUN_GET_PY_SSIZE_T_TYPEID = "get_Py_ssize_t_typeid";
117+
private static final String FUN_GET_VOID_PTR_T_TYPEID = "get_void_ptr_t_typeid";
118+
private static final String FUN_GET_CHAR_PTR_T_TYPEID = "get_char_ptr_t_typeid";
119+
private static final String FUN_GET_INT8_PTR_T_TYPEID = "get_int8_ptr_t_typeid";
120+
private static final String FUN_GET_INT16_PTR_T_TYPEID = "get_int16_ptr_t_typeid";
121+
private static final String FUN_GET_INT32_PTR_T_TYPEID = "get_int32_ptr_t_typeid";
122+
private static final String FUN_GET_INT64_PTR_T_TYPEID = "get_int64_ptr_t_typeid";
123+
private static final String FUN_GET_UINT8_PTR_T_TYPEID = "get_uint8_ptr_t_typeid";
124+
private static final String FUN_GET_UINT16_PTR_T_TYPEID = "get_uint16_ptr_t_typeid";
125+
private static final String FUN_GET_UINT32_PTR_T_TYPEID = "get_uint32_ptr_t_typeid";
126+
private static final String FUN_GET_UINT64_PTR_T_TYPEID = "get_uint64_ptr_t_typeid";
127+
private static final String FUN_GET_PY_COMPLEX_PTR_T_TYPEID = "get_Py_complex_ptr_t_typeid";
128+
private static final String FUN_GET_FLOAT_PTR_T_TYPEID = "get_float_ptr_t_typeid";
129+
private static final String FUN_GET_DOUBLE_PTR_T_TYPEID = "get_double_ptr_t_typeid";
130+
private static final String FUN_GET_PY_SSIZE_PTR_T_TYPEID = "get_Py_ssize_ptr_t_typeid";
131+
104132

105133
@CompilationFinal(dimensions = 1) private static final String[] values;
106134
static {

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/capi/CApiContext.java

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,9 @@ public final class CApiContext extends CExtContext {
130130
*/
131131
@CompilationFinal private int pyLongBitsInDigit = -1;
132132

133+
/** Cache for polyglot types of primitive and pointer types. */
134+
@CompilationFinal(dimensions = 1) private final TruffleObject[] llvmTypeCache;
135+
133136
public CApiContext(PythonContext context, Object hpyLibrary) {
134137
super(context, hpyLibrary, CAPIConversionNodeSupplier.INSTANCE);
135138
nativeObjectsQueue = new ReferenceQueue<>();
@@ -139,6 +142,9 @@ public CApiContext(PythonContext context, Object hpyLibrary) {
139142
int nullID = nativeObjectWrapperList.reserve();
140143
assert nullID == 0;
141144

145+
// initialize primitive and pointer type cache
146+
llvmTypeCache = new TruffleObject[LLVMType.values().length];
147+
142148
// initialize primitive native wrapper cache
143149
primitiveNativeWrapperCache = new PrimitiveNativeWrapper[262];
144150
for (int i = 0; i < primitiveNativeWrapperCache.length; i++) {
@@ -180,6 +186,14 @@ public int getPyLongBitsInDigit() {
180186
return pyLongBitsInDigit;
181187
}
182188

189+
public TruffleObject getLLVMTypeID(LLVMType llvmType) {
190+
return llvmTypeCache[llvmType.ordinal()];
191+
}
192+
193+
public void setLLVMTypeID(LLVMType llvmType, TruffleObject llvmTypeId) {
194+
llvmTypeCache[llvmType.ordinal()] = llvmTypeId;
195+
}
196+
183197
@TruffleBoundary
184198
public static Object asHex(Object ptr) {
185199
if (ptr instanceof Number) {
@@ -711,4 +725,60 @@ public long getId() {
711725
}
712726
}
713727

728+
/**
729+
* Enum of basic C types. These type names need to stay in sync with the declarations in
730+
* 'capi.c'.
731+
*/
732+
public enum LLVMType {
733+
int8_t,
734+
int16_t,
735+
int32_t,
736+
int64_t,
737+
uint8_t,
738+
uint16_t,
739+
uint32_t,
740+
uint64_t,
741+
float_t,
742+
double_t,
743+
Py_ssize_t,
744+
Py_complex,
745+
void_ptr_t,
746+
char_ptr_t,
747+
int8_ptr_t,
748+
int16_ptr_t,
749+
int32_ptr_t,
750+
int64_ptr_t,
751+
uint8_ptr_t,
752+
uint16_ptr_t,
753+
uint32_ptr_t,
754+
uint64_ptr_t,
755+
Py_complex_ptr_t,
756+
float_ptr_t,
757+
double_ptr_t,
758+
Py_ssize_ptr_t;
759+
760+
public static String getGetterFunctionName(LLVMType llvmType) {
761+
CompilerAsserts.neverPartOfCompilation();
762+
return "get_" + llvmType.name() + "_typeid()";
763+
}
764+
765+
public static boolean isPointerToPrimitive(LLVMType llvmType) {
766+
switch (llvmType) {
767+
case int8_ptr_t:
768+
case int16_ptr_t:
769+
case int32_ptr_t:
770+
case int64_ptr_t:
771+
case uint8_ptr_t:
772+
case uint16_ptr_t:
773+
case uint32_ptr_t:
774+
case uint64_ptr_t:
775+
case float_ptr_t:
776+
case double_ptr_t:
777+
case char_ptr_t:
778+
return true;
779+
}
780+
return false;
781+
}
782+
}
783+
714784
}

0 commit comments

Comments
 (0)