llvmlite 0.46.0b1__cp314-cp314-win_amd64.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of llvmlite might be problematic. Click here for more details.
- llvmlite/__init__.py +22 -0
- llvmlite/_version.py +11 -0
- llvmlite/binding/__init__.py +18 -0
- llvmlite/binding/analysis.py +69 -0
- llvmlite/binding/common.py +34 -0
- llvmlite/binding/config.py +143 -0
- llvmlite/binding/context.py +31 -0
- llvmlite/binding/dylib.py +45 -0
- llvmlite/binding/executionengine.py +330 -0
- llvmlite/binding/ffi.py +395 -0
- llvmlite/binding/initfini.py +85 -0
- llvmlite/binding/linker.py +20 -0
- llvmlite/binding/llvmlite.dll +0 -0
- llvmlite/binding/module.py +349 -0
- llvmlite/binding/newpassmanagers.py +1049 -0
- llvmlite/binding/object_file.py +82 -0
- llvmlite/binding/options.py +17 -0
- llvmlite/binding/orcjit.py +342 -0
- llvmlite/binding/targets.py +462 -0
- llvmlite/binding/typeref.py +267 -0
- llvmlite/binding/value.py +632 -0
- llvmlite/ir/__init__.py +11 -0
- llvmlite/ir/_utils.py +80 -0
- llvmlite/ir/builder.py +1120 -0
- llvmlite/ir/context.py +20 -0
- llvmlite/ir/instructions.py +920 -0
- llvmlite/ir/module.py +256 -0
- llvmlite/ir/transforms.py +64 -0
- llvmlite/ir/types.py +730 -0
- llvmlite/ir/values.py +1217 -0
- llvmlite/tests/__init__.py +57 -0
- llvmlite/tests/__main__.py +3 -0
- llvmlite/tests/customize.py +407 -0
- llvmlite/tests/refprune_proto.py +330 -0
- llvmlite/tests/test_binding.py +3155 -0
- llvmlite/tests/test_ir.py +3095 -0
- llvmlite/tests/test_refprune.py +574 -0
- llvmlite/tests/test_valuerepr.py +60 -0
- llvmlite/utils.py +29 -0
- llvmlite-0.46.0b1.dist-info/DELVEWHEEL +2 -0
- llvmlite-0.46.0b1.dist-info/METADATA +145 -0
- llvmlite-0.46.0b1.dist-info/RECORD +47 -0
- llvmlite-0.46.0b1.dist-info/WHEEL +5 -0
- llvmlite-0.46.0b1.dist-info/licenses/LICENSE +24 -0
- llvmlite-0.46.0b1.dist-info/licenses/LICENSE.thirdparty +225 -0
- llvmlite-0.46.0b1.dist-info/top_level.txt +1 -0
- llvmlite.libs/msvcp140-8f141b4454fa78db34bc1f28c571b4da.dll +0 -0
|
@@ -0,0 +1,330 @@
|
|
|
1
|
+
import platform
|
|
2
|
+
from ctypes import (POINTER, c_char_p, c_bool, c_void_p,
|
|
3
|
+
c_int, c_uint64, c_size_t, CFUNCTYPE, string_at, cast,
|
|
4
|
+
py_object, Structure)
|
|
5
|
+
|
|
6
|
+
from llvmlite.binding import ffi, targets, object_file
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
# Just check these weren't optimized out of the DLL.
|
|
10
|
+
ffi.lib.LLVMPY_LinkInMCJIT
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def create_mcjit_compiler(module, target_machine, use_lmm=None):
|
|
14
|
+
"""
|
|
15
|
+
Create a MCJIT ExecutionEngine from the given *module* and
|
|
16
|
+
*target_machine*.
|
|
17
|
+
|
|
18
|
+
*lmm* controls whether the llvmlite memory manager is used. If not supplied,
|
|
19
|
+
the default choice for the platform will be used (``True`` on 64-bit ARM
|
|
20
|
+
systems, ``False`` otherwise).
|
|
21
|
+
"""
|
|
22
|
+
if use_lmm is None:
|
|
23
|
+
use_lmm = platform.machine() in ('arm64', 'aarch64')
|
|
24
|
+
|
|
25
|
+
with ffi.OutputString() as outerr:
|
|
26
|
+
engine = ffi.lib.LLVMPY_CreateMCJITCompiler(
|
|
27
|
+
module, target_machine, use_lmm, outerr)
|
|
28
|
+
if not engine:
|
|
29
|
+
raise RuntimeError(str(outerr))
|
|
30
|
+
|
|
31
|
+
target_machine._owned = True
|
|
32
|
+
return ExecutionEngine(engine, module=module)
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
def check_jit_execution():
|
|
36
|
+
"""
|
|
37
|
+
Check the system allows execution of in-memory JITted functions.
|
|
38
|
+
An exception is raised otherwise.
|
|
39
|
+
"""
|
|
40
|
+
errno = ffi.lib.LLVMPY_TryAllocateExecutableMemory()
|
|
41
|
+
if errno != 0:
|
|
42
|
+
raise OSError(errno,
|
|
43
|
+
"cannot allocate executable memory. "
|
|
44
|
+
"This may be due to security restrictions on your "
|
|
45
|
+
"system, such as SELinux or similar mechanisms."
|
|
46
|
+
)
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
class ExecutionEngine(ffi.ObjectRef):
|
|
50
|
+
"""An ExecutionEngine owns all Modules associated with it.
|
|
51
|
+
Deleting the engine will remove all associated modules.
|
|
52
|
+
It is an error to delete the associated modules.
|
|
53
|
+
"""
|
|
54
|
+
_object_cache = None
|
|
55
|
+
|
|
56
|
+
def __init__(self, ptr, module):
|
|
57
|
+
"""
|
|
58
|
+
Module ownership is transferred to the EE
|
|
59
|
+
"""
|
|
60
|
+
self._modules = set([module])
|
|
61
|
+
self._td = None
|
|
62
|
+
module._owned = True
|
|
63
|
+
ffi.ObjectRef.__init__(self, ptr)
|
|
64
|
+
|
|
65
|
+
def get_function_address(self, name):
|
|
66
|
+
"""
|
|
67
|
+
Return the address of the function named *name* as an integer.
|
|
68
|
+
|
|
69
|
+
It's a fatal error in LLVM if the symbol of *name* doesn't exist.
|
|
70
|
+
"""
|
|
71
|
+
return ffi.lib.LLVMPY_GetFunctionAddress(self, name.encode("ascii"))
|
|
72
|
+
|
|
73
|
+
def get_global_value_address(self, name):
|
|
74
|
+
"""
|
|
75
|
+
Return the address of the global value named *name* as an integer.
|
|
76
|
+
|
|
77
|
+
It's a fatal error in LLVM if the symbol of *name* doesn't exist.
|
|
78
|
+
"""
|
|
79
|
+
return ffi.lib.LLVMPY_GetGlobalValueAddress(self, name.encode("ascii"))
|
|
80
|
+
|
|
81
|
+
def add_global_mapping(self, gv, addr):
|
|
82
|
+
ffi.lib.LLVMPY_AddGlobalMapping(self, gv, addr)
|
|
83
|
+
|
|
84
|
+
def add_module(self, module):
|
|
85
|
+
"""
|
|
86
|
+
Ownership of module is transferred to the execution engine
|
|
87
|
+
"""
|
|
88
|
+
if module in self._modules:
|
|
89
|
+
raise KeyError("module already added to this engine")
|
|
90
|
+
ffi.lib.LLVMPY_AddModule(self, module)
|
|
91
|
+
module._owned = True
|
|
92
|
+
self._modules.add(module)
|
|
93
|
+
|
|
94
|
+
def finalize_object(self):
|
|
95
|
+
"""
|
|
96
|
+
Make sure all modules owned by the execution engine are fully processed
|
|
97
|
+
and "usable" for execution.
|
|
98
|
+
"""
|
|
99
|
+
ffi.lib.LLVMPY_FinalizeObject(self)
|
|
100
|
+
|
|
101
|
+
def run_static_constructors(self):
|
|
102
|
+
"""
|
|
103
|
+
Run static constructors which initialize module-level static objects.
|
|
104
|
+
"""
|
|
105
|
+
ffi.lib.LLVMPY_RunStaticConstructors(self)
|
|
106
|
+
|
|
107
|
+
def run_static_destructors(self):
|
|
108
|
+
"""
|
|
109
|
+
Run static destructors which perform module-level cleanup of static
|
|
110
|
+
resources.
|
|
111
|
+
"""
|
|
112
|
+
ffi.lib.LLVMPY_RunStaticDestructors(self)
|
|
113
|
+
|
|
114
|
+
def remove_module(self, module):
|
|
115
|
+
"""
|
|
116
|
+
Ownership of module is returned
|
|
117
|
+
"""
|
|
118
|
+
with ffi.OutputString() as outerr:
|
|
119
|
+
if ffi.lib.LLVMPY_RemoveModule(self, module, outerr):
|
|
120
|
+
raise RuntimeError(str(outerr))
|
|
121
|
+
self._modules.remove(module)
|
|
122
|
+
module._owned = False
|
|
123
|
+
|
|
124
|
+
@property
|
|
125
|
+
def target_data(self):
|
|
126
|
+
"""
|
|
127
|
+
The TargetData for this execution engine.
|
|
128
|
+
"""
|
|
129
|
+
if self._td is not None:
|
|
130
|
+
return self._td
|
|
131
|
+
ptr = ffi.lib.LLVMPY_GetExecutionEngineTargetData(self)
|
|
132
|
+
self._td = targets.TargetData(ptr)
|
|
133
|
+
self._td._owned = True
|
|
134
|
+
return self._td
|
|
135
|
+
|
|
136
|
+
def enable_jit_events(self):
|
|
137
|
+
"""
|
|
138
|
+
Enable JIT events for profiling of generated code.
|
|
139
|
+
Return value indicates whether connection to profiling tool
|
|
140
|
+
was successful.
|
|
141
|
+
"""
|
|
142
|
+
ret = ffi.lib.LLVMPY_EnableJITEvents(self)
|
|
143
|
+
return ret
|
|
144
|
+
|
|
145
|
+
def _find_module_ptr(self, module_ptr):
|
|
146
|
+
"""
|
|
147
|
+
Find the ModuleRef corresponding to the given pointer.
|
|
148
|
+
"""
|
|
149
|
+
ptr = cast(module_ptr, c_void_p).value
|
|
150
|
+
for module in self._modules:
|
|
151
|
+
if cast(module._ptr, c_void_p).value == ptr:
|
|
152
|
+
return module
|
|
153
|
+
return None
|
|
154
|
+
|
|
155
|
+
def add_object_file(self, obj_file):
|
|
156
|
+
"""
|
|
157
|
+
Add object file to the jit. object_file can be instance of
|
|
158
|
+
:class:ObjectFile or a string representing file system path
|
|
159
|
+
"""
|
|
160
|
+
if isinstance(obj_file, str):
|
|
161
|
+
obj_file = object_file.ObjectFileRef.from_path(obj_file)
|
|
162
|
+
|
|
163
|
+
ffi.lib.LLVMPY_MCJITAddObjectFile(self, obj_file)
|
|
164
|
+
|
|
165
|
+
def set_object_cache(self, notify_func=None, getbuffer_func=None):
|
|
166
|
+
"""
|
|
167
|
+
Set the object cache "notifyObjectCompiled" and "getBuffer"
|
|
168
|
+
callbacks to the given Python functions.
|
|
169
|
+
"""
|
|
170
|
+
self._object_cache_notify = notify_func
|
|
171
|
+
self._object_cache_getbuffer = getbuffer_func
|
|
172
|
+
# Lifetime of the object cache is managed by us.
|
|
173
|
+
self._object_cache = _ObjectCacheRef(self)
|
|
174
|
+
# Note this doesn't keep a reference to self, to avoid reference
|
|
175
|
+
# cycles.
|
|
176
|
+
ffi.lib.LLVMPY_SetObjectCache(self, self._object_cache)
|
|
177
|
+
|
|
178
|
+
def _raw_object_cache_notify(self, data):
|
|
179
|
+
"""
|
|
180
|
+
Low-level notify hook.
|
|
181
|
+
"""
|
|
182
|
+
if self._object_cache_notify is None:
|
|
183
|
+
return
|
|
184
|
+
module_ptr = data.contents.module_ptr
|
|
185
|
+
buf_ptr = data.contents.buf_ptr
|
|
186
|
+
buf_len = data.contents.buf_len
|
|
187
|
+
buf = string_at(buf_ptr, buf_len)
|
|
188
|
+
module = self._find_module_ptr(module_ptr)
|
|
189
|
+
if module is None:
|
|
190
|
+
# The LLVM EE should only give notifications for modules
|
|
191
|
+
# known by us.
|
|
192
|
+
raise RuntimeError("object compilation notification "
|
|
193
|
+
"for unknown module %s" % (module_ptr,))
|
|
194
|
+
self._object_cache_notify(module, buf)
|
|
195
|
+
|
|
196
|
+
def _raw_object_cache_getbuffer(self, data):
|
|
197
|
+
"""
|
|
198
|
+
Low-level getbuffer hook.
|
|
199
|
+
"""
|
|
200
|
+
if self._object_cache_getbuffer is None:
|
|
201
|
+
return
|
|
202
|
+
module_ptr = data.contents.module_ptr
|
|
203
|
+
module = self._find_module_ptr(module_ptr)
|
|
204
|
+
if module is None:
|
|
205
|
+
# The LLVM EE should only give notifications for modules
|
|
206
|
+
# known by us.
|
|
207
|
+
raise RuntimeError("object compilation notification "
|
|
208
|
+
"for unknown module %s" % (module_ptr,))
|
|
209
|
+
|
|
210
|
+
buf = self._object_cache_getbuffer(module)
|
|
211
|
+
if buf is not None:
|
|
212
|
+
# Create a copy, which will be freed by the caller
|
|
213
|
+
data[0].buf_ptr = ffi.lib.LLVMPY_CreateByteString(buf, len(buf))
|
|
214
|
+
data[0].buf_len = len(buf)
|
|
215
|
+
|
|
216
|
+
def _dispose(self):
|
|
217
|
+
# The modules will be cleaned up by the EE
|
|
218
|
+
for mod in self._modules:
|
|
219
|
+
mod.detach()
|
|
220
|
+
if self._td is not None:
|
|
221
|
+
self._td.detach()
|
|
222
|
+
self._modules.clear()
|
|
223
|
+
self._object_cache = None
|
|
224
|
+
self._capi.LLVMPY_DisposeExecutionEngine(self)
|
|
225
|
+
|
|
226
|
+
|
|
227
|
+
class _ObjectCacheRef(ffi.ObjectRef):
|
|
228
|
+
"""
|
|
229
|
+
Internal: an ObjectCache instance for use within an ExecutionEngine.
|
|
230
|
+
"""
|
|
231
|
+
|
|
232
|
+
def __init__(self, obj):
|
|
233
|
+
ptr = ffi.lib.LLVMPY_CreateObjectCache(_notify_c_hook,
|
|
234
|
+
_getbuffer_c_hook,
|
|
235
|
+
obj)
|
|
236
|
+
ffi.ObjectRef.__init__(self, ptr)
|
|
237
|
+
|
|
238
|
+
def _dispose(self):
|
|
239
|
+
self._capi.LLVMPY_DisposeObjectCache(self)
|
|
240
|
+
|
|
241
|
+
|
|
242
|
+
# ============================================================================
|
|
243
|
+
# FFI
|
|
244
|
+
|
|
245
|
+
|
|
246
|
+
ffi.lib.LLVMPY_CreateMCJITCompiler.argtypes = [
|
|
247
|
+
ffi.LLVMModuleRef,
|
|
248
|
+
ffi.LLVMTargetMachineRef,
|
|
249
|
+
c_bool,
|
|
250
|
+
POINTER(c_char_p),
|
|
251
|
+
]
|
|
252
|
+
ffi.lib.LLVMPY_CreateMCJITCompiler.restype = ffi.LLVMExecutionEngineRef
|
|
253
|
+
|
|
254
|
+
ffi.lib.LLVMPY_RemoveModule.argtypes = [
|
|
255
|
+
ffi.LLVMExecutionEngineRef,
|
|
256
|
+
ffi.LLVMModuleRef,
|
|
257
|
+
POINTER(c_char_p),
|
|
258
|
+
]
|
|
259
|
+
ffi.lib.LLVMPY_RemoveModule.restype = c_bool
|
|
260
|
+
|
|
261
|
+
ffi.lib.LLVMPY_AddModule.argtypes = [
|
|
262
|
+
ffi.LLVMExecutionEngineRef,
|
|
263
|
+
ffi.LLVMModuleRef
|
|
264
|
+
]
|
|
265
|
+
|
|
266
|
+
ffi.lib.LLVMPY_AddGlobalMapping.argtypes = [ffi.LLVMExecutionEngineRef,
|
|
267
|
+
ffi.LLVMValueRef,
|
|
268
|
+
c_void_p]
|
|
269
|
+
|
|
270
|
+
ffi.lib.LLVMPY_FinalizeObject.argtypes = [ffi.LLVMExecutionEngineRef]
|
|
271
|
+
|
|
272
|
+
ffi.lib.LLVMPY_GetExecutionEngineTargetData.argtypes = [
|
|
273
|
+
ffi.LLVMExecutionEngineRef
|
|
274
|
+
]
|
|
275
|
+
ffi.lib.LLVMPY_GetExecutionEngineTargetData.restype = ffi.LLVMTargetDataRef
|
|
276
|
+
|
|
277
|
+
ffi.lib.LLVMPY_TryAllocateExecutableMemory.argtypes = []
|
|
278
|
+
ffi.lib.LLVMPY_TryAllocateExecutableMemory.restype = c_int
|
|
279
|
+
|
|
280
|
+
ffi.lib.LLVMPY_GetFunctionAddress.argtypes = [
|
|
281
|
+
ffi.LLVMExecutionEngineRef,
|
|
282
|
+
c_char_p
|
|
283
|
+
]
|
|
284
|
+
ffi.lib.LLVMPY_GetFunctionAddress.restype = c_uint64
|
|
285
|
+
|
|
286
|
+
ffi.lib.LLVMPY_GetGlobalValueAddress.argtypes = [
|
|
287
|
+
ffi.LLVMExecutionEngineRef,
|
|
288
|
+
c_char_p
|
|
289
|
+
]
|
|
290
|
+
ffi.lib.LLVMPY_GetGlobalValueAddress.restype = c_uint64
|
|
291
|
+
|
|
292
|
+
ffi.lib.LLVMPY_MCJITAddObjectFile.argtypes = [
|
|
293
|
+
ffi.LLVMExecutionEngineRef,
|
|
294
|
+
ffi.LLVMObjectFileRef
|
|
295
|
+
]
|
|
296
|
+
|
|
297
|
+
|
|
298
|
+
class _ObjectCacheData(Structure):
|
|
299
|
+
_fields_ = [
|
|
300
|
+
('module_ptr', ffi.LLVMModuleRef),
|
|
301
|
+
('buf_ptr', c_void_p),
|
|
302
|
+
('buf_len', c_size_t),
|
|
303
|
+
]
|
|
304
|
+
|
|
305
|
+
|
|
306
|
+
_ObjectCacheNotifyFunc = CFUNCTYPE(None, py_object,
|
|
307
|
+
POINTER(_ObjectCacheData))
|
|
308
|
+
_ObjectCacheGetBufferFunc = CFUNCTYPE(None, py_object,
|
|
309
|
+
POINTER(_ObjectCacheData))
|
|
310
|
+
|
|
311
|
+
# XXX The ctypes function wrappers are created at the top-level, otherwise
|
|
312
|
+
# there are issues when creating CFUNCTYPEs in child processes on CentOS 5
|
|
313
|
+
# 32 bits.
|
|
314
|
+
_notify_c_hook = _ObjectCacheNotifyFunc(
|
|
315
|
+
ExecutionEngine._raw_object_cache_notify)
|
|
316
|
+
_getbuffer_c_hook = _ObjectCacheGetBufferFunc(
|
|
317
|
+
ExecutionEngine._raw_object_cache_getbuffer)
|
|
318
|
+
|
|
319
|
+
ffi.lib.LLVMPY_CreateObjectCache.argtypes = [_ObjectCacheNotifyFunc,
|
|
320
|
+
_ObjectCacheGetBufferFunc,
|
|
321
|
+
py_object]
|
|
322
|
+
ffi.lib.LLVMPY_CreateObjectCache.restype = ffi.LLVMObjectCacheRef
|
|
323
|
+
|
|
324
|
+
ffi.lib.LLVMPY_DisposeObjectCache.argtypes = [ffi.LLVMObjectCacheRef]
|
|
325
|
+
|
|
326
|
+
ffi.lib.LLVMPY_SetObjectCache.argtypes = [ffi.LLVMExecutionEngineRef,
|
|
327
|
+
ffi.LLVMObjectCacheRef]
|
|
328
|
+
|
|
329
|
+
ffi.lib.LLVMPY_CreateByteString.restype = c_void_p
|
|
330
|
+
ffi.lib.LLVMPY_CreateByteString.argtypes = [c_void_p, c_size_t]
|