llvmlite 0.44.0rc2__cp310-cp310-macosx_10_14_x86_64.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 (46) hide show
  1. llvmlite/__init__.py +10 -0
  2. llvmlite/_version.py +11 -0
  3. llvmlite/binding/__init__.py +19 -0
  4. llvmlite/binding/analysis.py +69 -0
  5. llvmlite/binding/common.py +34 -0
  6. llvmlite/binding/context.py +39 -0
  7. llvmlite/binding/dylib.py +45 -0
  8. llvmlite/binding/executionengine.py +330 -0
  9. llvmlite/binding/ffi.py +395 -0
  10. llvmlite/binding/initfini.py +73 -0
  11. llvmlite/binding/libllvmlite.dylib +0 -0
  12. llvmlite/binding/linker.py +20 -0
  13. llvmlite/binding/module.py +349 -0
  14. llvmlite/binding/newpassmanagers.py +357 -0
  15. llvmlite/binding/object_file.py +82 -0
  16. llvmlite/binding/options.py +17 -0
  17. llvmlite/binding/orcjit.py +342 -0
  18. llvmlite/binding/passmanagers.py +946 -0
  19. llvmlite/binding/targets.py +520 -0
  20. llvmlite/binding/transforms.py +151 -0
  21. llvmlite/binding/typeref.py +285 -0
  22. llvmlite/binding/value.py +632 -0
  23. llvmlite/ir/__init__.py +11 -0
  24. llvmlite/ir/_utils.py +80 -0
  25. llvmlite/ir/builder.py +1120 -0
  26. llvmlite/ir/context.py +20 -0
  27. llvmlite/ir/instructions.py +920 -0
  28. llvmlite/ir/module.py +246 -0
  29. llvmlite/ir/transforms.py +64 -0
  30. llvmlite/ir/types.py +734 -0
  31. llvmlite/ir/values.py +1217 -0
  32. llvmlite/tests/__init__.py +57 -0
  33. llvmlite/tests/__main__.py +3 -0
  34. llvmlite/tests/customize.py +407 -0
  35. llvmlite/tests/refprune_proto.py +329 -0
  36. llvmlite/tests/test_binding.py +3208 -0
  37. llvmlite/tests/test_ir.py +2994 -0
  38. llvmlite/tests/test_refprune.py +730 -0
  39. llvmlite/tests/test_valuerepr.py +60 -0
  40. llvmlite/utils.py +29 -0
  41. llvmlite-0.44.0rc2.dist-info/LICENSE +24 -0
  42. llvmlite-0.44.0rc2.dist-info/LICENSE.thirdparty +225 -0
  43. llvmlite-0.44.0rc2.dist-info/METADATA +138 -0
  44. llvmlite-0.44.0rc2.dist-info/RECORD +46 -0
  45. llvmlite-0.44.0rc2.dist-info/WHEEL +5 -0
  46. llvmlite-0.44.0rc2.dist-info/top_level.txt +1 -0
@@ -0,0 +1,520 @@
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
+ # FIXME: Remove `opaque_pointers_enabled` once typed pointers are no longer
11
+ # supported.
12
+ from llvmlite import opaque_pointers_enabled
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
+ if llvm_version_major >= 15:
123
+ _object_formats = {
124
+ 0: "Unknown",
125
+ 1: "COFF",
126
+ 2: "DXContainer",
127
+ 3: "ELF",
128
+ 4: "GOFF",
129
+ 5: "MachO",
130
+ 6: "SPIRV",
131
+ 7: "Wasm",
132
+ 8: "XCOFF",
133
+ }
134
+ else:
135
+ _object_formats = {
136
+ 0: "Unknown",
137
+ 1: "COFF",
138
+ 2: "ELF",
139
+ 3: "GOFF",
140
+ 4: "MachO",
141
+ 5: "Wasm",
142
+ 6: "XCOFF",
143
+ }
144
+
145
+
146
+ def get_object_format(triple=None):
147
+ """
148
+ Get the object format for the given *triple* string (or the default
149
+ triple if omitted).
150
+ A string is returned
151
+ """
152
+ if triple is None:
153
+ triple = get_default_triple()
154
+ res = ffi.lib.LLVMPY_GetTripleObjectFormat(_encode_string(triple))
155
+ return _object_formats[res]
156
+
157
+
158
+ def create_target_data(layout):
159
+ """
160
+ Create a TargetData instance for the given *layout* string.
161
+ """
162
+ return TargetData(ffi.lib.LLVMPY_CreateTargetData(_encode_string(layout)))
163
+
164
+
165
+ class TargetData(ffi.ObjectRef):
166
+ """
167
+ A TargetData provides structured access to a data layout.
168
+ Use :func:`create_target_data` to create instances.
169
+ """
170
+
171
+ def __str__(self):
172
+ if self._closed:
173
+ return "<dead TargetData>"
174
+ with ffi.OutputString() as out:
175
+ ffi.lib.LLVMPY_CopyStringRepOfTargetData(self, out)
176
+ return str(out)
177
+
178
+ def _dispose(self):
179
+ self._capi.LLVMPY_DisposeTargetData(self)
180
+
181
+ def get_abi_size(self, ty):
182
+ """
183
+ Get ABI size of LLVM type *ty*.
184
+ """
185
+ return ffi.lib.LLVMPY_ABISizeOfType(self, ty)
186
+
187
+ def get_element_offset(self, ty, position):
188
+ """
189
+ Get byte offset of type's ty element at the given position
190
+ """
191
+
192
+ offset = ffi.lib.LLVMPY_OffsetOfElement(self, ty, position)
193
+ if offset == -1:
194
+ raise ValueError("Could not determined offset of {}th "
195
+ "element of the type '{}'. Is it a struct"
196
+ "type?".format(position, str(ty)))
197
+ return offset
198
+
199
+ def get_abi_alignment(self, ty):
200
+ """
201
+ Get minimum ABI alignment of LLVM type *ty*.
202
+ """
203
+ return ffi.lib.LLVMPY_ABIAlignmentOfType(self, ty)
204
+
205
+ def get_pointee_abi_size(self, ty):
206
+ """
207
+ Get ABI size of pointee type of LLVM pointer type *ty*.
208
+ """
209
+ if opaque_pointers_enabled:
210
+ raise RuntimeError("Cannot get pointee type in opaque pointer "
211
+ "mode.")
212
+ size = ffi.lib.LLVMPY_ABISizeOfElementType(self, ty)
213
+ if size == -1:
214
+ raise RuntimeError("Not a pointer type: %s" % (ty,))
215
+ return size
216
+
217
+ def get_pointee_abi_alignment(self, ty):
218
+ """
219
+ Get minimum ABI alignment of pointee type of LLVM pointer type *ty*.
220
+ """
221
+ if opaque_pointers_enabled:
222
+ raise RuntimeError("Cannot get pointee type in opaque pointer "
223
+ "mode.")
224
+ size = ffi.lib.LLVMPY_ABIAlignmentOfElementType(self, ty)
225
+ if size == -1:
226
+ raise RuntimeError("Not a pointer type: %s" % (ty,))
227
+ return size
228
+
229
+
230
+ RELOC = frozenset(['default', 'static', 'pic', 'dynamicnopic'])
231
+ CODEMODEL = frozenset(['default', 'jitdefault', 'small', 'kernel', 'medium',
232
+ 'large'])
233
+
234
+
235
+ class Target(ffi.ObjectRef):
236
+ _triple = ''
237
+
238
+ # No _dispose() method since LLVMGetTargetFromTriple() returns a
239
+ # persistent object.
240
+
241
+ @classmethod
242
+ def from_default_triple(cls):
243
+ """
244
+ Create a Target instance for the default triple.
245
+ """
246
+ triple = get_default_triple()
247
+ return cls.from_triple(triple)
248
+
249
+ @classmethod
250
+ def from_triple(cls, triple):
251
+ """
252
+ Create a Target instance for the given triple (a string).
253
+ """
254
+ with ffi.OutputString() as outerr:
255
+ target = ffi.lib.LLVMPY_GetTargetFromTriple(triple.encode('utf8'),
256
+ outerr)
257
+ if not target:
258
+ raise RuntimeError(str(outerr))
259
+ target = cls(target)
260
+ target._triple = triple
261
+ return target
262
+
263
+ @property
264
+ def name(self):
265
+ s = ffi.lib.LLVMPY_GetTargetName(self)
266
+ return _decode_string(s)
267
+
268
+ @property
269
+ def description(self):
270
+ s = ffi.lib.LLVMPY_GetTargetDescription(self)
271
+ return _decode_string(s)
272
+
273
+ @property
274
+ def triple(self):
275
+ return self._triple
276
+
277
+ def __str__(self):
278
+ return "<Target {0} ({1})>".format(self.name, self.description)
279
+
280
+ def create_target_machine(self, cpu='', features='',
281
+ opt=2, reloc='default', codemodel='jitdefault',
282
+ printmc=False, jit=False, abiname=''):
283
+ """
284
+ Create a new TargetMachine for this target and the given options.
285
+
286
+ Specifying codemodel='default' will result in the use of the "small"
287
+ code model. Specifying codemodel='jitdefault' will result in the code
288
+ model being picked based on platform bitness (32="small", 64="large").
289
+
290
+ The `printmc` option corresponds to llvm's `-print-machineinstrs`.
291
+
292
+ The `jit` option should be set when the target-machine is to be used
293
+ in a JIT engine.
294
+
295
+ The `abiname` option specifies the ABI. RISC-V targets with hard-float
296
+ needs to pass the ABI name to LLVM.
297
+ """
298
+ assert 0 <= opt <= 3
299
+ assert reloc in RELOC
300
+ assert codemodel in CODEMODEL
301
+ triple = self._triple
302
+ # MCJIT under Windows only supports ELF objects, see
303
+ # http://lists.llvm.org/pipermail/llvm-dev/2013-December/068341.html
304
+ # Note we still want to produce regular COFF files in AOT mode.
305
+ if os.name == 'nt' and codemodel == 'jitdefault':
306
+ triple += '-elf'
307
+ tm = ffi.lib.LLVMPY_CreateTargetMachine(self,
308
+ _encode_string(triple),
309
+ _encode_string(cpu),
310
+ _encode_string(features),
311
+ opt,
312
+ _encode_string(reloc),
313
+ _encode_string(codemodel),
314
+ int(printmc),
315
+ int(jit),
316
+ _encode_string(abiname),
317
+ )
318
+ if tm:
319
+ return TargetMachine(tm)
320
+ else:
321
+ raise RuntimeError("Cannot create target machine")
322
+
323
+
324
+ class TargetMachine(ffi.ObjectRef):
325
+
326
+ def _dispose(self):
327
+ self._capi.LLVMPY_DisposeTargetMachine(self)
328
+
329
+ def add_analysis_passes(self, pm):
330
+ """
331
+ Register analysis passes for this target machine with a pass manager.
332
+ """
333
+ ffi.lib.LLVMPY_AddAnalysisPasses(self, pm)
334
+
335
+ def set_asm_verbosity(self, verbose):
336
+ """
337
+ Set whether this target machine will emit assembly with human-readable
338
+ comments describing control flow, debug information, and so on.
339
+ """
340
+ ffi.lib.LLVMPY_SetTargetMachineAsmVerbosity(self, verbose)
341
+
342
+ def emit_object(self, module):
343
+ """
344
+ Represent the module as a code object, suitable for use with
345
+ the platform's linker. Returns a byte string.
346
+ """
347
+ return self._emit_to_memory(module, use_object=True)
348
+
349
+ def emit_assembly(self, module):
350
+ """
351
+ Return the raw assembler of the module, as a string.
352
+
353
+ llvm.initialize_native_asmprinter() must have been called first.
354
+ """
355
+ return _decode_string(self._emit_to_memory(module, use_object=False))
356
+
357
+ def _emit_to_memory(self, module, use_object=False):
358
+ """Returns bytes of object code of the module.
359
+
360
+ Args
361
+ ----
362
+ use_object : bool
363
+ Emit object code or (if False) emit assembly code.
364
+ """
365
+ with ffi.OutputString() as outerr:
366
+ mb = ffi.lib.LLVMPY_TargetMachineEmitToMemory(self, module,
367
+ int(use_object),
368
+ outerr)
369
+ if not mb:
370
+ raise RuntimeError(str(outerr))
371
+
372
+ bufptr = ffi.lib.LLVMPY_GetBufferStart(mb)
373
+ bufsz = ffi.lib.LLVMPY_GetBufferSize(mb)
374
+ try:
375
+ return string_at(bufptr, bufsz)
376
+ finally:
377
+ ffi.lib.LLVMPY_DisposeMemoryBuffer(mb)
378
+
379
+ @property
380
+ def target_data(self):
381
+ return TargetData(ffi.lib.LLVMPY_CreateTargetMachineData(self))
382
+
383
+ @property
384
+ def triple(self):
385
+ with ffi.OutputString() as out:
386
+ ffi.lib.LLVMPY_GetTargetMachineTriple(self, out)
387
+ return str(out)
388
+
389
+
390
+ def has_svml():
391
+ """
392
+ Returns True if SVML was enabled at FFI support compile time.
393
+ """
394
+ if ffi.lib.LLVMPY_HasSVMLSupport() == 0:
395
+ return False
396
+ else:
397
+ return True
398
+
399
+
400
+ # ============================================================================
401
+ # FFI
402
+
403
+ ffi.lib.LLVMPY_GetProcessTriple.argtypes = [POINTER(c_char_p)]
404
+ ffi.lib.LLVMPY_GetTripleParts.argtypes = [c_char_p, POINTER(c_char_p),
405
+ POINTER(c_char_p), POINTER(c_char_p),
406
+ POINTER(c_char_p)]
407
+
408
+ ffi.lib.LLVMPY_GetHostCPUFeatures.argtypes = [POINTER(c_char_p)]
409
+ ffi.lib.LLVMPY_GetHostCPUFeatures.restype = c_int
410
+
411
+ ffi.lib.LLVMPY_GetDefaultTargetTriple.argtypes = [POINTER(c_char_p)]
412
+
413
+ ffi.lib.LLVMPY_GetHostCPUName.argtypes = [POINTER(c_char_p)]
414
+
415
+ ffi.lib.LLVMPY_GetTripleObjectFormat.argtypes = [c_char_p]
416
+ ffi.lib.LLVMPY_GetTripleObjectFormat.restype = c_int
417
+
418
+ ffi.lib.LLVMPY_CreateTargetData.argtypes = [c_char_p]
419
+ ffi.lib.LLVMPY_CreateTargetData.restype = ffi.LLVMTargetDataRef
420
+
421
+ ffi.lib.LLVMPY_CopyStringRepOfTargetData.argtypes = [
422
+ ffi.LLVMTargetDataRef,
423
+ POINTER(c_char_p),
424
+ ]
425
+
426
+ ffi.lib.LLVMPY_DisposeTargetData.argtypes = [
427
+ ffi.LLVMTargetDataRef,
428
+ ]
429
+
430
+ ffi.lib.LLVMPY_ABISizeOfType.argtypes = [ffi.LLVMTargetDataRef,
431
+ ffi.LLVMTypeRef]
432
+ ffi.lib.LLVMPY_ABISizeOfType.restype = c_longlong
433
+
434
+ ffi.lib.LLVMPY_OffsetOfElement.argtypes = [ffi.LLVMTargetDataRef,
435
+ ffi.LLVMTypeRef,
436
+ c_int]
437
+ ffi.lib.LLVMPY_OffsetOfElement.restype = c_longlong
438
+
439
+ ffi.lib.LLVMPY_ABIAlignmentOfType.argtypes = [ffi.LLVMTargetDataRef,
440
+ ffi.LLVMTypeRef]
441
+ ffi.lib.LLVMPY_ABIAlignmentOfType.restype = c_longlong
442
+
443
+ # FIXME: Remove me once typed pointers are no longer supported.
444
+ ffi.lib.LLVMPY_ABISizeOfElementType.argtypes = [ffi.LLVMTargetDataRef,
445
+ ffi.LLVMTypeRef]
446
+ ffi.lib.LLVMPY_ABISizeOfElementType.restype = c_longlong
447
+
448
+ # FIXME: Remove me once typed pointers are no longer supported.
449
+ ffi.lib.LLVMPY_ABIAlignmentOfElementType.argtypes = [ffi.LLVMTargetDataRef,
450
+ ffi.LLVMTypeRef]
451
+ ffi.lib.LLVMPY_ABIAlignmentOfElementType.restype = c_longlong
452
+
453
+ ffi.lib.LLVMPY_GetTargetFromTriple.argtypes = [c_char_p, POINTER(c_char_p)]
454
+ ffi.lib.LLVMPY_GetTargetFromTriple.restype = ffi.LLVMTargetRef
455
+
456
+ ffi.lib.LLVMPY_GetTargetName.argtypes = [ffi.LLVMTargetRef]
457
+ ffi.lib.LLVMPY_GetTargetName.restype = c_char_p
458
+
459
+ ffi.lib.LLVMPY_GetTargetDescription.argtypes = [ffi.LLVMTargetRef]
460
+ ffi.lib.LLVMPY_GetTargetDescription.restype = c_char_p
461
+
462
+ ffi.lib.LLVMPY_CreateTargetMachine.argtypes = [
463
+ ffi.LLVMTargetRef,
464
+ # Triple
465
+ c_char_p,
466
+ # CPU
467
+ c_char_p,
468
+ # Features
469
+ c_char_p,
470
+ # OptLevel
471
+ c_int,
472
+ # Reloc
473
+ c_char_p,
474
+ # CodeModel
475
+ c_char_p,
476
+ # PrintMC
477
+ c_int,
478
+ # JIT
479
+ c_int,
480
+ # ABIName
481
+ c_char_p,
482
+ ]
483
+ ffi.lib.LLVMPY_CreateTargetMachine.restype = ffi.LLVMTargetMachineRef
484
+
485
+ ffi.lib.LLVMPY_DisposeTargetMachine.argtypes = [ffi.LLVMTargetMachineRef]
486
+
487
+ ffi.lib.LLVMPY_GetTargetMachineTriple.argtypes = [ffi.LLVMTargetMachineRef,
488
+ POINTER(c_char_p)]
489
+
490
+ ffi.lib.LLVMPY_SetTargetMachineAsmVerbosity.argtypes = [
491
+ ffi.LLVMTargetMachineRef, c_int]
492
+
493
+ ffi.lib.LLVMPY_AddAnalysisPasses.argtypes = [
494
+ ffi.LLVMTargetMachineRef,
495
+ ffi.LLVMPassManagerRef,
496
+ ]
497
+
498
+ ffi.lib.LLVMPY_TargetMachineEmitToMemory.argtypes = [
499
+ ffi.LLVMTargetMachineRef,
500
+ ffi.LLVMModuleRef,
501
+ c_int,
502
+ POINTER(c_char_p),
503
+ ]
504
+ ffi.lib.LLVMPY_TargetMachineEmitToMemory.restype = ffi.LLVMMemoryBufferRef
505
+
506
+ ffi.lib.LLVMPY_GetBufferStart.argtypes = [ffi.LLVMMemoryBufferRef]
507
+ ffi.lib.LLVMPY_GetBufferStart.restype = c_void_p
508
+
509
+ ffi.lib.LLVMPY_GetBufferSize.argtypes = [ffi.LLVMMemoryBufferRef]
510
+ ffi.lib.LLVMPY_GetBufferSize.restype = c_size_t
511
+
512
+ ffi.lib.LLVMPY_DisposeMemoryBuffer.argtypes = [ffi.LLVMMemoryBufferRef]
513
+
514
+ ffi.lib.LLVMPY_CreateTargetMachineData.argtypes = [
515
+ ffi.LLVMTargetMachineRef,
516
+ ]
517
+ ffi.lib.LLVMPY_CreateTargetMachineData.restype = ffi.LLVMTargetDataRef
518
+
519
+ ffi.lib.LLVMPY_HasSVMLSupport.argtypes = []
520
+ ffi.lib.LLVMPY_HasSVMLSupport.restype = c_int
@@ -0,0 +1,151 @@
1
+ from ctypes import c_uint, c_bool
2
+ from llvmlite.binding import ffi
3
+ from llvmlite.binding import passmanagers
4
+
5
+
6
+ def create_pass_manager_builder():
7
+ return PassManagerBuilder()
8
+
9
+
10
+ class PassManagerBuilder(ffi.ObjectRef):
11
+ __slots__ = ()
12
+
13
+ def __init__(self, ptr=None):
14
+ if ptr is None:
15
+ ptr = ffi.lib.LLVMPY_PassManagerBuilderCreate()
16
+ ffi.ObjectRef.__init__(self, ptr)
17
+
18
+ @property
19
+ def opt_level(self):
20
+ """
21
+ The general optimization level as an integer between 0 and 3.
22
+ """
23
+ return ffi.lib.LLVMPY_PassManagerBuilderGetOptLevel(self)
24
+
25
+ @opt_level.setter
26
+ def opt_level(self, level):
27
+ ffi.lib.LLVMPY_PassManagerBuilderSetOptLevel(self, level)
28
+
29
+ @property
30
+ def size_level(self):
31
+ """
32
+ Whether and how much to optimize for size. An integer between 0 and 2.
33
+ """
34
+ return ffi.lib.LLVMPY_PassManagerBuilderGetSizeLevel(self)
35
+
36
+ @size_level.setter
37
+ def size_level(self, size):
38
+ ffi.lib.LLVMPY_PassManagerBuilderSetSizeLevel(self, size)
39
+
40
+ @property
41
+ def inlining_threshold(self):
42
+ """
43
+ The integer threshold for inlining a function into another. The higher,
44
+ the more likely inlining a function is. This attribute is write-only.
45
+ """
46
+ raise NotImplementedError("inlining_threshold is write-only")
47
+
48
+ @inlining_threshold.setter
49
+ def inlining_threshold(self, threshold):
50
+ ffi.lib.LLVMPY_PassManagerBuilderUseInlinerWithThreshold(
51
+ self, threshold)
52
+
53
+ @property
54
+ def disable_unroll_loops(self):
55
+ """
56
+ If true, disable loop unrolling.
57
+ """
58
+ return ffi.lib.LLVMPY_PassManagerBuilderGetDisableUnrollLoops(self)
59
+
60
+ @disable_unroll_loops.setter
61
+ def disable_unroll_loops(self, disable=True):
62
+ ffi.lib.LLVMPY_PassManagerBuilderSetDisableUnrollLoops(self, disable)
63
+
64
+ @property
65
+ def loop_vectorize(self):
66
+ """
67
+ If true, allow vectorizing loops.
68
+ """
69
+ return ffi.lib.LLVMPY_PassManagerBuilderGetLoopVectorize(self)
70
+
71
+ @loop_vectorize.setter
72
+ def loop_vectorize(self, enable=True):
73
+ return ffi.lib.LLVMPY_PassManagerBuilderSetLoopVectorize(self, enable)
74
+
75
+ @property
76
+ def slp_vectorize(self):
77
+ """
78
+ If true, enable the "SLP vectorizer", which uses a different algorithm
79
+ from the loop vectorizer. Both may be enabled at the same time.
80
+ """
81
+ return ffi.lib.LLVMPY_PassManagerBuilderGetSLPVectorize(self)
82
+
83
+ @slp_vectorize.setter
84
+ def slp_vectorize(self, enable=True):
85
+ return ffi.lib.LLVMPY_PassManagerBuilderSetSLPVectorize(self, enable)
86
+
87
+ def _populate_module_pm(self, pm):
88
+ ffi.lib.LLVMPY_PassManagerBuilderPopulateModulePassManager(self, pm)
89
+
90
+ def _populate_function_pm(self, pm):
91
+ ffi.lib.LLVMPY_PassManagerBuilderPopulateFunctionPassManager(self, pm)
92
+
93
+ def populate(self, pm):
94
+ if isinstance(pm, passmanagers.ModulePassManager):
95
+ self._populate_module_pm(pm)
96
+ elif isinstance(pm, passmanagers.FunctionPassManager):
97
+ self._populate_function_pm(pm)
98
+ else:
99
+ raise TypeError(pm)
100
+
101
+ def _dispose(self):
102
+ self._capi.LLVMPY_PassManagerBuilderDispose(self)
103
+
104
+
105
+ # ============================================================================
106
+ # FFI
107
+
108
+ ffi.lib.LLVMPY_PassManagerBuilderCreate.restype = ffi.LLVMPassManagerBuilderRef
109
+
110
+ ffi.lib.LLVMPY_PassManagerBuilderDispose.argtypes = [
111
+ ffi.LLVMPassManagerBuilderRef,
112
+ ]
113
+
114
+ ffi.lib.LLVMPY_PassManagerBuilderPopulateModulePassManager.argtypes = [
115
+ ffi.LLVMPassManagerBuilderRef,
116
+ ffi.LLVMPassManagerRef,
117
+ ]
118
+
119
+ ffi.lib.LLVMPY_PassManagerBuilderPopulateFunctionPassManager.argtypes = [
120
+ ffi.LLVMPassManagerBuilderRef,
121
+ ffi.LLVMPassManagerRef,
122
+ ]
123
+
124
+ # Unsigned int PassManagerBuilder properties
125
+
126
+ for _func in (ffi.lib.LLVMPY_PassManagerBuilderSetOptLevel,
127
+ ffi.lib.LLVMPY_PassManagerBuilderSetSizeLevel,
128
+ ffi.lib.LLVMPY_PassManagerBuilderUseInlinerWithThreshold,
129
+ ):
130
+ _func.argtypes = [ffi.LLVMPassManagerBuilderRef, c_uint]
131
+
132
+ for _func in (ffi.lib.LLVMPY_PassManagerBuilderGetOptLevel,
133
+ ffi.lib.LLVMPY_PassManagerBuilderGetSizeLevel,
134
+ ):
135
+ _func.argtypes = [ffi.LLVMPassManagerBuilderRef]
136
+ _func.restype = c_uint
137
+
138
+ # Boolean PassManagerBuilder properties
139
+
140
+ for _func in (ffi.lib.LLVMPY_PassManagerBuilderSetDisableUnrollLoops,
141
+ ffi.lib.LLVMPY_PassManagerBuilderSetLoopVectorize,
142
+ ffi.lib.LLVMPY_PassManagerBuilderSetSLPVectorize,
143
+ ):
144
+ _func.argtypes = [ffi.LLVMPassManagerBuilderRef, c_bool]
145
+
146
+ for _func in (ffi.lib.LLVMPY_PassManagerBuilderGetDisableUnrollLoops,
147
+ ffi.lib.LLVMPY_PassManagerBuilderGetLoopVectorize,
148
+ ffi.lib.LLVMPY_PassManagerBuilderGetSLPVectorize,
149
+ ):
150
+ _func.argtypes = [ffi.LLVMPassManagerBuilderRef]
151
+ _func.restype = c_bool