llvmlite 0.42.0rc1__cp311-cp311-win_amd64.whl → 0.43.0rc1__cp311-cp311-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.

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