llvmlite 0.46.0b1__cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.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.

Files changed (45) hide show
  1. llvmlite/__init__.py +11 -0
  2. llvmlite/_version.py +11 -0
  3. llvmlite/binding/__init__.py +18 -0
  4. llvmlite/binding/analysis.py +69 -0
  5. llvmlite/binding/common.py +34 -0
  6. llvmlite/binding/config.py +143 -0
  7. llvmlite/binding/context.py +31 -0
  8. llvmlite/binding/dylib.py +45 -0
  9. llvmlite/binding/executionengine.py +330 -0
  10. llvmlite/binding/ffi.py +395 -0
  11. llvmlite/binding/initfini.py +85 -0
  12. llvmlite/binding/libllvmlite.so +0 -0
  13. llvmlite/binding/linker.py +20 -0
  14. llvmlite/binding/module.py +349 -0
  15. llvmlite/binding/newpassmanagers.py +1049 -0
  16. llvmlite/binding/object_file.py +82 -0
  17. llvmlite/binding/options.py +17 -0
  18. llvmlite/binding/orcjit.py +342 -0
  19. llvmlite/binding/targets.py +462 -0
  20. llvmlite/binding/typeref.py +267 -0
  21. llvmlite/binding/value.py +632 -0
  22. llvmlite/ir/__init__.py +11 -0
  23. llvmlite/ir/_utils.py +80 -0
  24. llvmlite/ir/builder.py +1120 -0
  25. llvmlite/ir/context.py +20 -0
  26. llvmlite/ir/instructions.py +920 -0
  27. llvmlite/ir/module.py +256 -0
  28. llvmlite/ir/transforms.py +64 -0
  29. llvmlite/ir/types.py +730 -0
  30. llvmlite/ir/values.py +1217 -0
  31. llvmlite/tests/__init__.py +57 -0
  32. llvmlite/tests/__main__.py +3 -0
  33. llvmlite/tests/customize.py +407 -0
  34. llvmlite/tests/refprune_proto.py +330 -0
  35. llvmlite/tests/test_binding.py +3155 -0
  36. llvmlite/tests/test_ir.py +3095 -0
  37. llvmlite/tests/test_refprune.py +574 -0
  38. llvmlite/tests/test_valuerepr.py +60 -0
  39. llvmlite/utils.py +29 -0
  40. llvmlite-0.46.0b1.dist-info/METADATA +145 -0
  41. llvmlite-0.46.0b1.dist-info/RECORD +45 -0
  42. llvmlite-0.46.0b1.dist-info/WHEEL +6 -0
  43. llvmlite-0.46.0b1.dist-info/licenses/LICENSE +24 -0
  44. llvmlite-0.46.0b1.dist-info/licenses/LICENSE.thirdparty +225 -0
  45. llvmlite-0.46.0b1.dist-info/top_level.txt +1 -0
@@ -0,0 +1,462 @@
1
+ import os
2
+ from ctypes import (POINTER, c_char_p, c_longlong, c_int, c_size_t,
3
+ c_void_p, string_at)
4
+
5
+ from llvmlite.binding import ffi
6
+ from llvmlite.binding.initfini import llvm_version_info
7
+ from llvmlite.binding.common import _decode_string, _encode_string
8
+ from collections import namedtuple
9
+
10
+ # import for backward compatible API, `has_svml` is now in config module.
11
+ from llvmlite.binding.config import _has_svml as has_svml # noqa: F401
12
+
13
+
14
+ Triple = namedtuple('Triple', ['Arch', 'SubArch', 'Vendor',
15
+ 'OS', 'Env', 'ObjectFormat'])
16
+
17
+
18
+ def get_process_triple():
19
+ """
20
+ Return a target triple suitable for generating code for the current process.
21
+ An example when the default triple from ``get_default_triple()`` is not be
22
+ suitable is when LLVM is compiled for 32-bit but the process is executing
23
+ in 64-bit mode.
24
+ """
25
+ with ffi.OutputString() as out:
26
+ ffi.lib.LLVMPY_GetProcessTriple(out)
27
+ return str(out)
28
+
29
+
30
+ def get_triple_parts(triple: str):
31
+ """
32
+ Return a tuple of the parts of the given triple.
33
+ """
34
+ with ffi.OutputString() as arch, \
35
+ ffi.OutputString() as vendor, \
36
+ ffi.OutputString() as os, ffi.OutputString() as env:
37
+ ffi.lib.LLVMPY_GetTripleParts(triple.encode('utf8'),
38
+ arch, vendor, os, env)
39
+ arch = str(arch)
40
+ subarch = ''
41
+ for _str in triple.split('-'):
42
+ if _str.startswith(arch):
43
+ subarch = _str[len(arch):]
44
+ break
45
+ return Triple(arch, subarch, str(vendor), str(os),
46
+ str(env), get_object_format(triple))
47
+
48
+
49
+ class FeatureMap(dict):
50
+ """
51
+ Maps feature name to a boolean indicating the availability of the feature.
52
+ Extends ``dict`` to add `.flatten()` method.
53
+ """
54
+
55
+ def flatten(self, sort=True):
56
+ """
57
+ Args
58
+ ----
59
+ sort: bool
60
+ Optional. If True, the features are sorted by name; otherwise,
61
+ the ordering is unstable between python session due to hash
62
+ randomization. Defaults to True.
63
+
64
+ Returns a string suitable for use as the ``features`` argument to
65
+ ``Target.create_target_machine()``.
66
+
67
+ """
68
+ iterator = sorted(self.items()) if sort else iter(self.items())
69
+ flag_map = {True: '+', False: '-'}
70
+ return ','.join('{0}{1}'.format(flag_map[v], k)
71
+ for k, v in iterator)
72
+
73
+
74
+ def get_host_cpu_features():
75
+ """
76
+ Returns a dictionary-like object indicating the CPU features for current
77
+ architecture and whether they are enabled for this CPU. The key-value pairs
78
+ are the feature name as string and a boolean indicating whether the feature
79
+ is available. The returned value is an instance of ``FeatureMap`` class,
80
+ which adds a new method ``.flatten()`` for returning a string suitable for
81
+ use as the "features" argument to ``Target.create_target_machine()``.
82
+
83
+ If LLVM has not implemented this feature or it fails to get the information,
84
+ this function will raise a RuntimeError exception.
85
+ """
86
+ with ffi.OutputString() as out:
87
+ outdict = FeatureMap()
88
+ if not ffi.lib.LLVMPY_GetHostCPUFeatures(out):
89
+ return outdict
90
+ flag_map = {'+': True, '-': False}
91
+ content = str(out)
92
+ if content: # protect against empty string
93
+ for feat in content.split(','):
94
+ if feat: # protect against empty feature
95
+ outdict[feat[1:]] = flag_map[feat[0]]
96
+ return outdict
97
+
98
+
99
+ def get_default_triple():
100
+ """
101
+ Return the default target triple LLVM is configured to produce code for.
102
+ """
103
+ with ffi.OutputString() as out:
104
+ ffi.lib.LLVMPY_GetDefaultTargetTriple(out)
105
+ return str(out)
106
+
107
+
108
+ def get_host_cpu_name():
109
+ """
110
+ Get the name of the host's CPU, suitable for using with
111
+ :meth:`Target.create_target_machine()`.
112
+ """
113
+ with ffi.OutputString() as out:
114
+ ffi.lib.LLVMPY_GetHostCPUName(out)
115
+ return str(out)
116
+
117
+
118
+ # Adapted from https://github.com/llvm/llvm-project/blob/release/15.x/llvm/include/llvm/ADT/Triple.h#L269 # noqa
119
+ llvm_version_major = llvm_version_info[0]
120
+
121
+
122
+ _object_formats = {
123
+ 0: "Unknown",
124
+ 1: "COFF",
125
+ 2: "DXContainer",
126
+ 3: "ELF",
127
+ 4: "GOFF",
128
+ 5: "MachO",
129
+ 6: "SPIRV",
130
+ 7: "Wasm",
131
+ 8: "XCOFF",
132
+ }
133
+
134
+
135
+ def get_object_format(triple=None):
136
+ """
137
+ Get the object format for the given *triple* string (or the default
138
+ triple if omitted).
139
+ A string is returned
140
+ """
141
+ if triple is None:
142
+ triple = get_default_triple()
143
+ res = ffi.lib.LLVMPY_GetTripleObjectFormat(_encode_string(triple))
144
+ return _object_formats[res]
145
+
146
+
147
+ def create_target_data(layout):
148
+ """
149
+ Create a TargetData instance for the given *layout* string.
150
+ """
151
+ return TargetData(ffi.lib.LLVMPY_CreateTargetData(_encode_string(layout)))
152
+
153
+
154
+ class TargetData(ffi.ObjectRef):
155
+ """
156
+ A TargetData provides structured access to a data layout.
157
+ Use :func:`create_target_data` to create instances.
158
+ """
159
+
160
+ def __str__(self):
161
+ if self._closed:
162
+ return "<dead TargetData>"
163
+ with ffi.OutputString() as out:
164
+ ffi.lib.LLVMPY_CopyStringRepOfTargetData(self, out)
165
+ return str(out)
166
+
167
+ def _dispose(self):
168
+ self._capi.LLVMPY_DisposeTargetData(self)
169
+
170
+ def get_abi_size(self, ty):
171
+ """
172
+ Get ABI size of LLVM type *ty*.
173
+ """
174
+ return ffi.lib.LLVMPY_ABISizeOfType(self, ty)
175
+
176
+ def get_element_offset(self, ty, position):
177
+ """
178
+ Get byte offset of type's ty element at the given position
179
+ """
180
+
181
+ offset = ffi.lib.LLVMPY_OffsetOfElement(self, ty, position)
182
+ if offset == -1:
183
+ raise ValueError("Could not determined offset of {}th "
184
+ "element of the type '{}'. Is it a struct"
185
+ "type?".format(position, str(ty)))
186
+ return offset
187
+
188
+ def get_abi_alignment(self, ty):
189
+ """
190
+ Get minimum ABI alignment of LLVM type *ty*.
191
+ """
192
+ return ffi.lib.LLVMPY_ABIAlignmentOfType(self, ty)
193
+
194
+
195
+ RELOC = frozenset(['default', 'static', 'pic', 'dynamicnopic'])
196
+ CODEMODEL = frozenset(['default', 'jitdefault', 'small', 'kernel', 'medium',
197
+ 'large'])
198
+
199
+
200
+ class Target(ffi.ObjectRef):
201
+ _triple = ''
202
+
203
+ # No _dispose() method since LLVMGetTargetFromTriple() returns a
204
+ # persistent object.
205
+
206
+ @classmethod
207
+ def from_default_triple(cls):
208
+ """
209
+ Create a Target instance for the default triple.
210
+ """
211
+ triple = get_default_triple()
212
+ return cls.from_triple(triple)
213
+
214
+ @classmethod
215
+ def from_triple(cls, triple):
216
+ """
217
+ Create a Target instance for the given triple (a string).
218
+ """
219
+ with ffi.OutputString() as outerr:
220
+ target = ffi.lib.LLVMPY_GetTargetFromTriple(triple.encode('utf8'),
221
+ outerr)
222
+ if not target:
223
+ raise RuntimeError(str(outerr))
224
+ target = cls(target)
225
+ target._triple = triple
226
+ return target
227
+
228
+ @property
229
+ def name(self):
230
+ s = ffi.lib.LLVMPY_GetTargetName(self)
231
+ return _decode_string(s)
232
+
233
+ @property
234
+ def description(self):
235
+ s = ffi.lib.LLVMPY_GetTargetDescription(self)
236
+ return _decode_string(s)
237
+
238
+ @property
239
+ def triple(self):
240
+ return self._triple
241
+
242
+ def __str__(self):
243
+ return "<Target {0} ({1})>".format(self.name, self.description)
244
+
245
+ def create_target_machine(self, cpu='', features='',
246
+ opt=2, reloc='default', codemodel='jitdefault',
247
+ printmc=False, jit=False, abiname=''):
248
+ """
249
+ Create a new TargetMachine for this target and the given options.
250
+
251
+ Specifying codemodel='default' will result in the use of the "small"
252
+ code model. Specifying codemodel='jitdefault' will result in the code
253
+ model being picked based on platform bitness (32="small", 64="large").
254
+
255
+ The `printmc` option corresponds to llvm's `-print-machineinstrs`.
256
+
257
+ The `jit` option should be set when the target-machine is to be used
258
+ in a JIT engine.
259
+
260
+ The `abiname` option specifies the ABI. RISC-V targets with hard-float
261
+ needs to pass the ABI name to LLVM.
262
+ """
263
+ assert 0 <= opt <= 3
264
+ assert reloc in RELOC
265
+ assert codemodel in CODEMODEL
266
+ triple = self._triple
267
+ # MCJIT under Windows only supports ELF objects, see
268
+ # http://lists.llvm.org/pipermail/llvm-dev/2013-December/068341.html
269
+ # Note we still want to produce regular COFF files in AOT mode.
270
+ if os.name == 'nt' and codemodel == 'jitdefault':
271
+ triple += '-elf'
272
+ tm = ffi.lib.LLVMPY_CreateTargetMachine(self,
273
+ _encode_string(triple),
274
+ _encode_string(cpu),
275
+ _encode_string(features),
276
+ opt,
277
+ _encode_string(reloc),
278
+ _encode_string(codemodel),
279
+ int(printmc),
280
+ int(jit),
281
+ _encode_string(abiname),
282
+ )
283
+ if tm:
284
+ return TargetMachine(tm)
285
+ else:
286
+ raise RuntimeError("Cannot create target machine")
287
+
288
+
289
+ class TargetMachine(ffi.ObjectRef):
290
+
291
+ def _dispose(self):
292
+ self._capi.LLVMPY_DisposeTargetMachine(self)
293
+
294
+ def add_analysis_passes(self, pm):
295
+ """
296
+ Register analysis passes for this target machine with a pass manager.
297
+ """
298
+ ffi.lib.LLVMPY_AddAnalysisPasses(self, pm)
299
+
300
+ def set_asm_verbosity(self, verbose):
301
+ """
302
+ Set whether this target machine will emit assembly with human-readable
303
+ comments describing control flow, debug information, and so on.
304
+ """
305
+ ffi.lib.LLVMPY_SetTargetMachineAsmVerbosity(self, verbose)
306
+
307
+ def emit_object(self, module):
308
+ """
309
+ Represent the module as a code object, suitable for use with
310
+ the platform's linker. Returns a byte string.
311
+ """
312
+ return self._emit_to_memory(module, use_object=True)
313
+
314
+ def emit_assembly(self, module):
315
+ """
316
+ Return the raw assembler of the module, as a string.
317
+
318
+ llvm.initialize_native_asmprinter() must have been called first.
319
+ """
320
+ return _decode_string(self._emit_to_memory(module, use_object=False))
321
+
322
+ def _emit_to_memory(self, module, use_object=False):
323
+ """Returns bytes of object code of the module.
324
+
325
+ Args
326
+ ----
327
+ use_object : bool
328
+ Emit object code or (if False) emit assembly code.
329
+ """
330
+ with ffi.OutputString() as outerr:
331
+ mb = ffi.lib.LLVMPY_TargetMachineEmitToMemory(self, module,
332
+ int(use_object),
333
+ outerr)
334
+ if not mb:
335
+ raise RuntimeError(str(outerr))
336
+
337
+ bufptr = ffi.lib.LLVMPY_GetBufferStart(mb)
338
+ bufsz = ffi.lib.LLVMPY_GetBufferSize(mb)
339
+ try:
340
+ return string_at(bufptr, bufsz)
341
+ finally:
342
+ ffi.lib.LLVMPY_DisposeMemoryBuffer(mb)
343
+
344
+ @property
345
+ def target_data(self):
346
+ return TargetData(ffi.lib.LLVMPY_CreateTargetMachineData(self))
347
+
348
+ @property
349
+ def triple(self):
350
+ with ffi.OutputString() as out:
351
+ ffi.lib.LLVMPY_GetTargetMachineTriple(self, out)
352
+ return str(out)
353
+
354
+
355
+ # ============================================================================
356
+ # FFI
357
+
358
+ ffi.lib.LLVMPY_GetProcessTriple.argtypes = [POINTER(c_char_p)]
359
+ ffi.lib.LLVMPY_GetTripleParts.argtypes = [c_char_p, POINTER(c_char_p),
360
+ POINTER(c_char_p), POINTER(c_char_p),
361
+ POINTER(c_char_p)]
362
+
363
+ ffi.lib.LLVMPY_GetHostCPUFeatures.argtypes = [POINTER(c_char_p)]
364
+ ffi.lib.LLVMPY_GetHostCPUFeatures.restype = c_int
365
+
366
+ ffi.lib.LLVMPY_GetDefaultTargetTriple.argtypes = [POINTER(c_char_p)]
367
+
368
+ ffi.lib.LLVMPY_GetHostCPUName.argtypes = [POINTER(c_char_p)]
369
+
370
+ ffi.lib.LLVMPY_GetTripleObjectFormat.argtypes = [c_char_p]
371
+ ffi.lib.LLVMPY_GetTripleObjectFormat.restype = c_int
372
+
373
+ ffi.lib.LLVMPY_CreateTargetData.argtypes = [c_char_p]
374
+ ffi.lib.LLVMPY_CreateTargetData.restype = ffi.LLVMTargetDataRef
375
+
376
+ ffi.lib.LLVMPY_CopyStringRepOfTargetData.argtypes = [
377
+ ffi.LLVMTargetDataRef,
378
+ POINTER(c_char_p),
379
+ ]
380
+
381
+ ffi.lib.LLVMPY_DisposeTargetData.argtypes = [
382
+ ffi.LLVMTargetDataRef,
383
+ ]
384
+
385
+ ffi.lib.LLVMPY_ABISizeOfType.argtypes = [ffi.LLVMTargetDataRef,
386
+ ffi.LLVMTypeRef]
387
+ ffi.lib.LLVMPY_ABISizeOfType.restype = c_longlong
388
+
389
+ ffi.lib.LLVMPY_OffsetOfElement.argtypes = [ffi.LLVMTargetDataRef,
390
+ ffi.LLVMTypeRef,
391
+ c_int]
392
+ ffi.lib.LLVMPY_OffsetOfElement.restype = c_longlong
393
+
394
+ ffi.lib.LLVMPY_ABIAlignmentOfType.argtypes = [ffi.LLVMTargetDataRef,
395
+ ffi.LLVMTypeRef]
396
+ ffi.lib.LLVMPY_ABIAlignmentOfType.restype = c_longlong
397
+
398
+ ffi.lib.LLVMPY_GetTargetFromTriple.argtypes = [c_char_p, POINTER(c_char_p)]
399
+ ffi.lib.LLVMPY_GetTargetFromTriple.restype = ffi.LLVMTargetRef
400
+
401
+ ffi.lib.LLVMPY_GetTargetName.argtypes = [ffi.LLVMTargetRef]
402
+ ffi.lib.LLVMPY_GetTargetName.restype = c_char_p
403
+
404
+ ffi.lib.LLVMPY_GetTargetDescription.argtypes = [ffi.LLVMTargetRef]
405
+ ffi.lib.LLVMPY_GetTargetDescription.restype = c_char_p
406
+
407
+ ffi.lib.LLVMPY_CreateTargetMachine.argtypes = [
408
+ ffi.LLVMTargetRef,
409
+ # Triple
410
+ c_char_p,
411
+ # CPU
412
+ c_char_p,
413
+ # Features
414
+ c_char_p,
415
+ # OptLevel
416
+ c_int,
417
+ # Reloc
418
+ c_char_p,
419
+ # CodeModel
420
+ c_char_p,
421
+ # PrintMC
422
+ c_int,
423
+ # JIT
424
+ c_int,
425
+ # ABIName
426
+ c_char_p,
427
+ ]
428
+ ffi.lib.LLVMPY_CreateTargetMachine.restype = ffi.LLVMTargetMachineRef
429
+
430
+ ffi.lib.LLVMPY_DisposeTargetMachine.argtypes = [ffi.LLVMTargetMachineRef]
431
+
432
+ ffi.lib.LLVMPY_GetTargetMachineTriple.argtypes = [ffi.LLVMTargetMachineRef,
433
+ POINTER(c_char_p)]
434
+
435
+ ffi.lib.LLVMPY_SetTargetMachineAsmVerbosity.argtypes = [
436
+ ffi.LLVMTargetMachineRef, c_int]
437
+
438
+ ffi.lib.LLVMPY_AddAnalysisPasses.argtypes = [
439
+ ffi.LLVMTargetMachineRef,
440
+ ffi.LLVMPassManagerRef,
441
+ ]
442
+
443
+ ffi.lib.LLVMPY_TargetMachineEmitToMemory.argtypes = [
444
+ ffi.LLVMTargetMachineRef,
445
+ ffi.LLVMModuleRef,
446
+ c_int,
447
+ POINTER(c_char_p),
448
+ ]
449
+ ffi.lib.LLVMPY_TargetMachineEmitToMemory.restype = ffi.LLVMMemoryBufferRef
450
+
451
+ ffi.lib.LLVMPY_GetBufferStart.argtypes = [ffi.LLVMMemoryBufferRef]
452
+ ffi.lib.LLVMPY_GetBufferStart.restype = c_void_p
453
+
454
+ ffi.lib.LLVMPY_GetBufferSize.argtypes = [ffi.LLVMMemoryBufferRef]
455
+ ffi.lib.LLVMPY_GetBufferSize.restype = c_size_t
456
+
457
+ ffi.lib.LLVMPY_DisposeMemoryBuffer.argtypes = [ffi.LLVMMemoryBufferRef]
458
+
459
+ ffi.lib.LLVMPY_CreateTargetMachineData.argtypes = [
460
+ ffi.LLVMTargetMachineRef,
461
+ ]
462
+ ffi.lib.LLVMPY_CreateTargetMachineData.restype = ffi.LLVMTargetDataRef