llvmlite 0.43.0rc1__cp310-cp310-macosx_11_0_arm64.whl → 0.44.0rc2__cp310-cp310-macosx_11_0_arm64.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 +7 -0
- llvmlite/_version.py +2 -2
- llvmlite/binding/__init__.py +1 -0
- llvmlite/binding/context.py +12 -2
- llvmlite/binding/ffi.py +6 -1
- llvmlite/binding/libllvmlite.dylib +0 -0
- llvmlite/binding/newpassmanagers.py +357 -0
- llvmlite/binding/passmanagers.py +25 -18
- llvmlite/binding/targets.py +75 -5
- llvmlite/binding/typeref.py +88 -1
- llvmlite/binding/value.py +14 -0
- llvmlite/ir/builder.py +8 -7
- llvmlite/ir/context.py +2 -2
- llvmlite/ir/instructions.py +52 -25
- llvmlite/ir/types.py +137 -17
- llvmlite/ir/values.py +2 -2
- llvmlite/tests/test_binding.py +663 -40
- llvmlite/tests/test_ir.py +411 -146
- llvmlite/tests/test_refprune.py +179 -6
- {llvmlite-0.43.0rc1.dist-info → llvmlite-0.44.0rc2.dist-info}/METADATA +7 -6
- llvmlite-0.44.0rc2.dist-info/RECORD +46 -0
- {llvmlite-0.43.0rc1.dist-info → llvmlite-0.44.0rc2.dist-info}/WHEEL +1 -1
- llvmlite-0.43.0rc1.dist-info/RECORD +0 -45
- {llvmlite-0.43.0rc1.dist-info → llvmlite-0.44.0rc2.dist-info}/LICENSE +0 -0
- {llvmlite-0.43.0rc1.dist-info → llvmlite-0.44.0rc2.dist-info}/LICENSE.thirdparty +0 -0
- {llvmlite-0.43.0rc1.dist-info → llvmlite-0.44.0rc2.dist-info}/top_level.txt +0 -0
llvmlite/binding/typeref.py
CHANGED
|
@@ -1,8 +1,12 @@
|
|
|
1
|
-
from ctypes import c_int, c_bool, c_void_p, c_uint64
|
|
1
|
+
from ctypes import c_int, c_bool, c_void_p, c_uint64, c_uint, POINTER
|
|
2
2
|
import enum
|
|
3
3
|
|
|
4
|
+
from llvmlite import ir
|
|
4
5
|
from llvmlite.binding import ffi
|
|
5
6
|
|
|
7
|
+
# FIXME: Remove `opaque_pointers_enabled' when TP's are removed.
|
|
8
|
+
from llvmlite import opaque_pointers_enabled
|
|
9
|
+
|
|
6
10
|
|
|
7
11
|
class TypeKind(enum.IntEnum):
|
|
8
12
|
# The LLVMTypeKind enum from llvm-c/Core.h
|
|
@@ -29,6 +33,21 @@ class TypeKind(enum.IntEnum):
|
|
|
29
33
|
x86_amx = 19
|
|
30
34
|
|
|
31
35
|
|
|
36
|
+
_TypeKindToIRType = {
|
|
37
|
+
# All TypeKind here must have a TypeRef.as_ir() implementation
|
|
38
|
+
TypeKind.void: ir.VoidType,
|
|
39
|
+
TypeKind.half: ir.HalfType,
|
|
40
|
+
TypeKind.float: ir.FloatType,
|
|
41
|
+
TypeKind.double: ir.DoubleType,
|
|
42
|
+
TypeKind.integer: ir.IntType,
|
|
43
|
+
TypeKind.function: ir.FunctionType,
|
|
44
|
+
TypeKind.pointer: ir.PointerType,
|
|
45
|
+
TypeKind.array: ir.ArrayType,
|
|
46
|
+
TypeKind.vector: ir.VectorType,
|
|
47
|
+
TypeKind.struct: ir.LiteralStructType,
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
|
|
32
51
|
class TypeRef(ffi.ObjectRef):
|
|
33
52
|
"""A weak reference to a LLVM type
|
|
34
53
|
"""
|
|
@@ -67,6 +86,13 @@ class TypeRef(ffi.ObjectRef):
|
|
|
67
86
|
"""
|
|
68
87
|
return ffi.lib.LLVMPY_TypeIsVector(self)
|
|
69
88
|
|
|
89
|
+
@property
|
|
90
|
+
def is_function(self):
|
|
91
|
+
"""
|
|
92
|
+
Returns true if the type is a function type.
|
|
93
|
+
"""
|
|
94
|
+
return ffi.lib.LLVMPY_TypeIsFunction(self)
|
|
95
|
+
|
|
70
96
|
@property
|
|
71
97
|
def is_function_vararg(self):
|
|
72
98
|
"""
|
|
@@ -82,8 +108,11 @@ class TypeRef(ffi.ObjectRef):
|
|
|
82
108
|
"""
|
|
83
109
|
Returns iterator over enclosing types
|
|
84
110
|
"""
|
|
111
|
+
if self.is_pointer and opaque_pointers_enabled:
|
|
112
|
+
raise ValueError("Type {} doesn't contain elements.".format(self))
|
|
85
113
|
return _TypeListIterator(ffi.lib.LLVMPY_ElementIter(self))
|
|
86
114
|
|
|
115
|
+
# FIXME: Remove me once typed pointers support is removed.
|
|
87
116
|
@property
|
|
88
117
|
def element_type(self):
|
|
89
118
|
"""
|
|
@@ -129,6 +158,41 @@ class TypeRef(ffi.ObjectRef):
|
|
|
129
158
|
"""
|
|
130
159
|
return TypeKind(ffi.lib.LLVMPY_GetTypeKind(self))
|
|
131
160
|
|
|
161
|
+
@property
|
|
162
|
+
def is_packed_struct(self):
|
|
163
|
+
return ffi.lib.LLVMPY_IsPackedStruct(self)
|
|
164
|
+
|
|
165
|
+
@property
|
|
166
|
+
def is_literal_struct(self):
|
|
167
|
+
return ffi.lib.LLVMPY_IsLiteralStruct(self)
|
|
168
|
+
|
|
169
|
+
@property
|
|
170
|
+
def is_opaque_struct(self):
|
|
171
|
+
return ffi.lib.LLVMPY_IsOpaqueStruct(self)
|
|
172
|
+
|
|
173
|
+
def get_function_parameters(self) -> tuple["TypeRef"]:
|
|
174
|
+
nparams = ffi.lib.LLVMPY_CountParamTypes(self)
|
|
175
|
+
if nparams > 0:
|
|
176
|
+
out_buffer = (ffi.LLVMTypeRef * nparams)(None)
|
|
177
|
+
ffi.lib.LLVMPY_GetParamTypes(self, out_buffer)
|
|
178
|
+
return tuple(map(TypeRef, out_buffer))
|
|
179
|
+
else:
|
|
180
|
+
return ()
|
|
181
|
+
|
|
182
|
+
def get_function_return(self) -> "TypeRef":
|
|
183
|
+
return TypeRef(ffi.lib.LLVMPY_GetReturnType(self))
|
|
184
|
+
|
|
185
|
+
def as_ir(self, ir_ctx: ir.Context) -> ir.Type:
|
|
186
|
+
"""Convert into a ``llvmlite.ir.Type``.
|
|
187
|
+
"""
|
|
188
|
+
try:
|
|
189
|
+
cls = _TypeKindToIRType[self.type_kind]
|
|
190
|
+
except KeyError:
|
|
191
|
+
msg = f"as_ir() unsupported for TypeRef of {self.type_kind}"
|
|
192
|
+
raise TypeError(msg)
|
|
193
|
+
else:
|
|
194
|
+
return cls.from_llvm(self, ir_ctx)
|
|
195
|
+
|
|
132
196
|
def __str__(self):
|
|
133
197
|
return ffi.ret_string(ffi.lib.LLVMPY_PrintType(self))
|
|
134
198
|
|
|
@@ -162,6 +226,7 @@ class _TypeListIterator(_TypeIterator):
|
|
|
162
226
|
ffi.lib.LLVMPY_PrintType.argtypes = [ffi.LLVMTypeRef]
|
|
163
227
|
ffi.lib.LLVMPY_PrintType.restype = c_void_p
|
|
164
228
|
|
|
229
|
+
# FIXME: Remove me once typed pointers support is removed.
|
|
165
230
|
ffi.lib.LLVMPY_GetElementType.argtypes = [ffi.LLVMTypeRef]
|
|
166
231
|
ffi.lib.LLVMPY_GetElementType.restype = ffi.LLVMTypeRef
|
|
167
232
|
|
|
@@ -177,6 +242,28 @@ ffi.lib.LLVMPY_TypeIsVector.restype = c_bool
|
|
|
177
242
|
ffi.lib.LLVMPY_TypeIsStruct.argtypes = [ffi.LLVMTypeRef]
|
|
178
243
|
ffi.lib.LLVMPY_TypeIsStruct.restype = c_bool
|
|
179
244
|
|
|
245
|
+
ffi.lib.LLVMPY_TypeIsFunction.argtypes = [ffi.LLVMTypeRef]
|
|
246
|
+
ffi.lib.LLVMPY_TypeIsFunction.restype = c_bool
|
|
247
|
+
|
|
248
|
+
ffi.lib.LLVMPY_IsPackedStruct.argtypes = [ffi.LLVMTypeRef]
|
|
249
|
+
ffi.lib.LLVMPY_IsPackedStruct.restype = c_bool
|
|
250
|
+
|
|
251
|
+
ffi.lib.LLVMPY_IsOpaqueStruct.argtypes = [ffi.LLVMTypeRef]
|
|
252
|
+
ffi.lib.LLVMPY_IsOpaqueStruct.restype = c_bool
|
|
253
|
+
|
|
254
|
+
ffi.lib.LLVMPY_IsLiteralStruct.argtypes = [ffi.LLVMTypeRef]
|
|
255
|
+
ffi.lib.LLVMPY_IsLiteralStruct.restype = c_bool
|
|
256
|
+
|
|
257
|
+
ffi.lib.LLVMPY_GetReturnType.argtypes = [ffi.LLVMTypeRef]
|
|
258
|
+
ffi.lib.LLVMPY_GetReturnType.restype = ffi.LLVMTypeRef
|
|
259
|
+
|
|
260
|
+
ffi.lib.LLVMPY_CountParamTypes.argtypes = [ffi.LLVMTypeRef]
|
|
261
|
+
ffi.lib.LLVMPY_CountParamTypes.restype = c_uint
|
|
262
|
+
|
|
263
|
+
ffi.lib.LLVMPY_GetParamTypes.argtypes = [ffi.LLVMTypeRef,
|
|
264
|
+
POINTER(ffi.LLVMTypeRef)]
|
|
265
|
+
ffi.lib.LLVMPY_GetParamTypes.restype = None
|
|
266
|
+
|
|
180
267
|
ffi.lib.LLVMPY_IsFunctionVararg.argtypes = [ffi.LLVMTypeRef]
|
|
181
268
|
ffi.lib.LLVMPY_IsFunctionVararg.restype = c_bool
|
|
182
269
|
|
llvmlite/binding/value.py
CHANGED
|
@@ -217,6 +217,17 @@ class ValueRef(ffi.ObjectRef):
|
|
|
217
217
|
# XXX what does this return?
|
|
218
218
|
return TypeRef(ffi.lib.LLVMPY_TypeOf(self))
|
|
219
219
|
|
|
220
|
+
@property
|
|
221
|
+
def global_value_type(self):
|
|
222
|
+
"""
|
|
223
|
+
Uses ``LLVMGlobalGetValueType()``.
|
|
224
|
+
Needed for opaque pointers in globals.
|
|
225
|
+
> For globals, use getValueType().
|
|
226
|
+
See https://llvm.org/docs/OpaquePointers.html#migration-instructions
|
|
227
|
+
"""
|
|
228
|
+
assert self.is_global or self.is_function
|
|
229
|
+
return TypeRef(ffi.lib.LLVMPY_GlobalGetValueType(self))
|
|
230
|
+
|
|
220
231
|
@property
|
|
221
232
|
def is_declaration(self):
|
|
222
233
|
"""
|
|
@@ -505,6 +516,9 @@ ffi.lib.LLVMPY_SetValueName.argtypes = [ffi.LLVMValueRef, c_char_p]
|
|
|
505
516
|
ffi.lib.LLVMPY_TypeOf.argtypes = [ffi.LLVMValueRef]
|
|
506
517
|
ffi.lib.LLVMPY_TypeOf.restype = ffi.LLVMTypeRef
|
|
507
518
|
|
|
519
|
+
ffi.lib.LLVMPY_GlobalGetValueType.argtypes = [ffi.LLVMValueRef]
|
|
520
|
+
ffi.lib.LLVMPY_GlobalGetValueType.restype = ffi.LLVMTypeRef
|
|
521
|
+
|
|
508
522
|
ffi.lib.LLVMPY_GetTypeName.argtypes = [ffi.LLVMTypeRef]
|
|
509
523
|
ffi.lib.LLVMPY_GetTypeName.restype = c_void_p
|
|
510
524
|
|
llvmlite/ir/builder.py
CHANGED
|
@@ -753,7 +753,7 @@ class IRBuilder(object):
|
|
|
753
753
|
self._insert(al)
|
|
754
754
|
return al
|
|
755
755
|
|
|
756
|
-
def load(self, ptr, name='', align=None):
|
|
756
|
+
def load(self, ptr, name='', align=None, typ=None):
|
|
757
757
|
"""
|
|
758
758
|
Load value from pointer, with optional guaranteed alignment:
|
|
759
759
|
name = *ptr
|
|
@@ -761,7 +761,7 @@ class IRBuilder(object):
|
|
|
761
761
|
if not isinstance(ptr.type, types.PointerType):
|
|
762
762
|
msg = "cannot load from value of type %s (%r): not a pointer"
|
|
763
763
|
raise TypeError(msg % (ptr.type, str(ptr)))
|
|
764
|
-
ld = instructions.LoadInstr(self.block, ptr, name)
|
|
764
|
+
ld = instructions.LoadInstr(self.block, ptr, name, typ=typ)
|
|
765
765
|
ld.align = align
|
|
766
766
|
self._insert(ld)
|
|
767
767
|
return ld
|
|
@@ -774,7 +774,7 @@ class IRBuilder(object):
|
|
|
774
774
|
if not isinstance(ptr.type, types.PointerType):
|
|
775
775
|
msg = "cannot store to value of type %s (%r): not a pointer"
|
|
776
776
|
raise TypeError(msg % (ptr.type, str(ptr)))
|
|
777
|
-
if ptr.type.pointee != value.type:
|
|
777
|
+
if not ptr.type.is_opaque and ptr.type.pointee != value.type:
|
|
778
778
|
raise TypeError("cannot store %s to %s: mismatching types"
|
|
779
779
|
% (value.type, ptr.type))
|
|
780
780
|
st = instructions.StoreInstr(self.block, value, ptr)
|
|
@@ -782,7 +782,7 @@ class IRBuilder(object):
|
|
|
782
782
|
self._insert(st)
|
|
783
783
|
return st
|
|
784
784
|
|
|
785
|
-
def load_atomic(self, ptr, ordering, align, name=''):
|
|
785
|
+
def load_atomic(self, ptr, ordering, align, name='', typ=None):
|
|
786
786
|
"""
|
|
787
787
|
Load value from pointer, with optional guaranteed alignment:
|
|
788
788
|
name = *ptr
|
|
@@ -791,7 +791,7 @@ class IRBuilder(object):
|
|
|
791
791
|
msg = "cannot load from value of type %s (%r): not a pointer"
|
|
792
792
|
raise TypeError(msg % (ptr.type, str(ptr)))
|
|
793
793
|
ld = instructions.LoadAtomicInstr(
|
|
794
|
-
self.block, ptr, ordering, align, name)
|
|
794
|
+
self.block, ptr, ordering, align, name, typ=typ)
|
|
795
795
|
self._insert(ld)
|
|
796
796
|
return ld
|
|
797
797
|
|
|
@@ -919,13 +919,14 @@ class IRBuilder(object):
|
|
|
919
919
|
|
|
920
920
|
# GEP APIs
|
|
921
921
|
|
|
922
|
-
def gep(self, ptr, indices, inbounds=False, name=''):
|
|
922
|
+
def gep(self, ptr, indices, inbounds=False, name='', source_etype=None):
|
|
923
923
|
"""
|
|
924
924
|
Compute effective address (getelementptr):
|
|
925
925
|
name = getelementptr ptr, <indices...>
|
|
926
926
|
"""
|
|
927
927
|
instr = instructions.GEPInstr(self.block, ptr, indices,
|
|
928
|
-
inbounds=inbounds, name=name
|
|
928
|
+
inbounds=inbounds, name=name,
|
|
929
|
+
source_etype=source_etype)
|
|
929
930
|
self._insert(instr)
|
|
930
931
|
return instr
|
|
931
932
|
|
llvmlite/ir/context.py
CHANGED
|
@@ -7,10 +7,10 @@ class Context(object):
|
|
|
7
7
|
self.scope = _utils.NameScope()
|
|
8
8
|
self.identified_types = {}
|
|
9
9
|
|
|
10
|
-
def get_identified_type(self, name):
|
|
10
|
+
def get_identified_type(self, name, packed=False):
|
|
11
11
|
if name not in self.identified_types:
|
|
12
12
|
self.scope.register(name)
|
|
13
|
-
ty = types.IdentifiedStructType(self, name)
|
|
13
|
+
ty = types.IdentifiedStructType(self, name, packed)
|
|
14
14
|
self.identified_types[name] = ty
|
|
15
15
|
else:
|
|
16
16
|
ty = self.identified_types[name]
|
llvmlite/ir/instructions.py
CHANGED
|
@@ -431,9 +431,17 @@ class CastInstr(Instruction):
|
|
|
431
431
|
|
|
432
432
|
class LoadInstr(Instruction):
|
|
433
433
|
|
|
434
|
-
def __init__(self, parent, ptr, name=''):
|
|
435
|
-
|
|
436
|
-
|
|
434
|
+
def __init__(self, parent, ptr, name='', typ=None):
|
|
435
|
+
if typ is None:
|
|
436
|
+
if isinstance(ptr, AllocaInstr):
|
|
437
|
+
typ = ptr.allocated_type
|
|
438
|
+
# For compatibility with typed pointers. Eventually this should
|
|
439
|
+
# probably be removed (when typed pointers are fully removed).
|
|
440
|
+
elif not ptr.type.is_opaque:
|
|
441
|
+
typ = ptr.type.pointee
|
|
442
|
+
else:
|
|
443
|
+
raise ValueError("Load lacks type.")
|
|
444
|
+
super(LoadInstr, self).__init__(parent, typ, "load", [ptr], name=name)
|
|
437
445
|
self.align = None
|
|
438
446
|
|
|
439
447
|
def descr(self, buf):
|
|
@@ -443,7 +451,7 @@ class LoadInstr(Instruction):
|
|
|
443
451
|
else:
|
|
444
452
|
align = ''
|
|
445
453
|
buf.append("load {0}, {1} {2}{3}{4}\n".format(
|
|
446
|
-
|
|
454
|
+
self.type,
|
|
447
455
|
val.type,
|
|
448
456
|
val.get_reference(),
|
|
449
457
|
align,
|
|
@@ -473,16 +481,25 @@ class StoreInstr(Instruction):
|
|
|
473
481
|
|
|
474
482
|
|
|
475
483
|
class LoadAtomicInstr(Instruction):
|
|
476
|
-
def __init__(self, parent, ptr, ordering, align, name=''):
|
|
477
|
-
|
|
478
|
-
|
|
484
|
+
def __init__(self, parent, ptr, ordering, align, name='', typ=None):
|
|
485
|
+
if typ is None:
|
|
486
|
+
if isinstance(ptr, AllocaInstr):
|
|
487
|
+
typ = ptr.allocated_type
|
|
488
|
+
# For compatibility with typed pointers. Eventually this should
|
|
489
|
+
# probably be removed (when typed pointers are fully removed).
|
|
490
|
+
elif not ptr.type.is_opaque:
|
|
491
|
+
typ = ptr.type.pointee
|
|
492
|
+
else:
|
|
493
|
+
raise ValueError("Load atomic lacks type.")
|
|
494
|
+
super(LoadAtomicInstr, self).__init__(parent, typ, "load atomic",
|
|
495
|
+
[ptr], name=name)
|
|
479
496
|
self.ordering = ordering
|
|
480
497
|
self.align = align
|
|
481
498
|
|
|
482
499
|
def descr(self, buf):
|
|
483
500
|
[val] = self.operands
|
|
484
501
|
buf.append("load atomic {0}, {1} {2} {3}, align {4}{5}\n".format(
|
|
485
|
-
|
|
502
|
+
self.type,
|
|
486
503
|
val.type,
|
|
487
504
|
val.get_reference(),
|
|
488
505
|
self.ordering,
|
|
@@ -516,10 +533,11 @@ class AllocaInstr(Instruction):
|
|
|
516
533
|
operands = [count] if count else ()
|
|
517
534
|
super(AllocaInstr, self).__init__(parent, typ.as_pointer(), "alloca",
|
|
518
535
|
operands, name)
|
|
536
|
+
self.allocated_type = typ
|
|
519
537
|
self.align = None
|
|
520
538
|
|
|
521
539
|
def descr(self, buf):
|
|
522
|
-
buf.append("{0} {1}".format(self.opname, self.
|
|
540
|
+
buf.append("{0} {1}".format(self.opname, self.allocated_type))
|
|
523
541
|
if self.operands:
|
|
524
542
|
op, = self.operands
|
|
525
543
|
buf.append(", {0} {1}".format(op.type, op.get_reference()))
|
|
@@ -530,22 +548,31 @@ class AllocaInstr(Instruction):
|
|
|
530
548
|
|
|
531
549
|
|
|
532
550
|
class GEPInstr(Instruction):
|
|
533
|
-
def __init__(self, parent, ptr, indices, inbounds, name
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
551
|
+
def __init__(self, parent, ptr, indices, inbounds, name,
|
|
552
|
+
source_etype=None):
|
|
553
|
+
if source_etype is not None:
|
|
554
|
+
typ = ptr.type
|
|
555
|
+
self.source_etype = source_etype
|
|
556
|
+
# For compatibility with typed pointers. Eventually this should
|
|
557
|
+
# probably be removed (when typed pointers are fully removed).
|
|
558
|
+
elif not ptr.type.is_opaque:
|
|
559
|
+
typ = ptr.type
|
|
560
|
+
lasttyp = None
|
|
561
|
+
lastaddrspace = 0
|
|
562
|
+
for i in indices:
|
|
563
|
+
lasttyp, typ = typ, typ.gep(i)
|
|
564
|
+
# inherit the addrspace from the last seen pointer
|
|
565
|
+
if isinstance(lasttyp, types.PointerType):
|
|
566
|
+
lastaddrspace = lasttyp.addrspace
|
|
567
|
+
|
|
568
|
+
if (not isinstance(typ, types.PointerType) and
|
|
569
|
+
isinstance(lasttyp, types.PointerType)):
|
|
570
|
+
typ = lasttyp
|
|
571
|
+
else:
|
|
572
|
+
typ = typ.as_pointer(lastaddrspace)
|
|
573
|
+
self.source_etype = ptr.type.pointee
|
|
546
574
|
else:
|
|
547
|
-
|
|
548
|
-
|
|
575
|
+
raise ValueError("GEP lacks type.")
|
|
549
576
|
super(GEPInstr, self).__init__(parent, typ, "getelementptr",
|
|
550
577
|
[ptr] + list(indices), name=name)
|
|
551
578
|
self.pointer = ptr
|
|
@@ -558,7 +585,7 @@ class GEPInstr(Instruction):
|
|
|
558
585
|
op = "getelementptr inbounds" if self.inbounds else "getelementptr"
|
|
559
586
|
buf.append("{0} {1}, {2} {3}, {4} {5}\n".format(
|
|
560
587
|
op,
|
|
561
|
-
self.
|
|
588
|
+
self.source_etype,
|
|
562
589
|
self.pointer.type,
|
|
563
590
|
self.pointer.get_reference(),
|
|
564
591
|
', '.join(indices),
|
llvmlite/ir/types.py
CHANGED
|
@@ -6,6 +6,9 @@ import struct
|
|
|
6
6
|
|
|
7
7
|
from llvmlite.ir._utils import _StrCaching
|
|
8
8
|
|
|
9
|
+
# FIXME: Remove me once typed pointers are no longer supported.
|
|
10
|
+
from llvmlite import opaque_pointers_enabled
|
|
11
|
+
|
|
9
12
|
|
|
10
13
|
def _wrapname(x):
|
|
11
14
|
return '"{0}"'.format(x.replace('\\', '\\5c').replace('"', '\\22'))
|
|
@@ -30,7 +33,7 @@ class Type(_StrCaching):
|
|
|
30
33
|
def __ne__(self, other):
|
|
31
34
|
return not (self == other)
|
|
32
35
|
|
|
33
|
-
def
|
|
36
|
+
def _get_ll_global_value_type(self, target_data, context=None):
|
|
34
37
|
"""
|
|
35
38
|
Convert this type object to an LLVM type.
|
|
36
39
|
"""
|
|
@@ -43,22 +46,26 @@ class Type(_StrCaching):
|
|
|
43
46
|
m = Module(context=context)
|
|
44
47
|
foo = GlobalVariable(m, self, name="foo")
|
|
45
48
|
with parse_assembly(str(m)) as llmod:
|
|
46
|
-
return llmod.get_global_variable(foo.name).
|
|
49
|
+
return llmod.get_global_variable(foo.name).global_value_type
|
|
47
50
|
|
|
48
51
|
def get_abi_size(self, target_data, context=None):
|
|
49
52
|
"""
|
|
50
53
|
Get the ABI size of this type according to data layout *target_data*.
|
|
51
54
|
"""
|
|
52
|
-
llty = self.
|
|
53
|
-
return target_data.
|
|
55
|
+
llty = self._get_ll_global_value_type(target_data, context)
|
|
56
|
+
return target_data.get_abi_size(llty)
|
|
57
|
+
|
|
58
|
+
def get_element_offset(self, target_data, ndx, context=None):
|
|
59
|
+
llty = self._get_ll_global_value_type(target_data, context)
|
|
60
|
+
return target_data.get_element_offset(llty, ndx)
|
|
54
61
|
|
|
55
62
|
def get_abi_alignment(self, target_data, context=None):
|
|
56
63
|
"""
|
|
57
64
|
Get the minimum ABI alignment of this type according to data layout
|
|
58
65
|
*target_data*.
|
|
59
66
|
"""
|
|
60
|
-
llty = self.
|
|
61
|
-
return target_data.
|
|
67
|
+
llty = self._get_ll_global_value_type(target_data, context)
|
|
68
|
+
return target_data.get_abi_alignment(llty)
|
|
62
69
|
|
|
63
70
|
def format_constant(self, value):
|
|
64
71
|
"""
|
|
@@ -109,30 +116,67 @@ class LabelType(Type):
|
|
|
109
116
|
class PointerType(Type):
|
|
110
117
|
"""
|
|
111
118
|
The type of all pointer values.
|
|
119
|
+
By default (without specialisation) represents an opaque pointer.
|
|
112
120
|
"""
|
|
121
|
+
is_opaque = True
|
|
113
122
|
is_pointer = True
|
|
114
123
|
null = 'null'
|
|
115
124
|
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
125
|
+
# Factory to create typed or opaque pointers based on `pointee'.
|
|
126
|
+
def __new__(cls, pointee=None, addrspace=0):
|
|
127
|
+
if cls is PointerType and pointee is not None:
|
|
128
|
+
return super().__new__(_TypedPointerType)
|
|
129
|
+
return super(PointerType, cls).__new__(cls)
|
|
130
|
+
|
|
131
|
+
def __init__(self, addrspace=0):
|
|
119
132
|
self.addrspace = addrspace
|
|
120
133
|
|
|
121
134
|
def _to_string(self):
|
|
122
135
|
if self.addrspace != 0:
|
|
123
|
-
return "
|
|
136
|
+
return "ptr addrspace({0})".format(self.addrspace)
|
|
124
137
|
else:
|
|
125
|
-
return "
|
|
138
|
+
return "ptr"
|
|
139
|
+
|
|
140
|
+
def __hash__(self):
|
|
141
|
+
return hash(PointerType)
|
|
142
|
+
|
|
143
|
+
@classmethod
|
|
144
|
+
def from_llvm(cls, typeref, ir_ctx):
|
|
145
|
+
"""
|
|
146
|
+
Create from a llvmlite.binding.TypeRef
|
|
147
|
+
"""
|
|
148
|
+
if not opaque_pointers_enabled:
|
|
149
|
+
return _TypedPointerType.from_llvm(typeref, ir_ctx)
|
|
150
|
+
return cls()
|
|
151
|
+
|
|
152
|
+
|
|
153
|
+
class _TypedPointerType(PointerType):
|
|
154
|
+
"""
|
|
155
|
+
The type of typed pointer values. To be removed eventually.
|
|
156
|
+
"""
|
|
157
|
+
|
|
158
|
+
def __init__(self, pointee, addrspace=0):
|
|
159
|
+
super(_TypedPointerType, self).__init__(addrspace)
|
|
160
|
+
assert pointee is not None
|
|
161
|
+
assert not isinstance(pointee, VoidType)
|
|
162
|
+
self.pointee = pointee
|
|
163
|
+
self.is_opaque = False
|
|
164
|
+
|
|
165
|
+
def _to_string(self):
|
|
166
|
+
if not opaque_pointers_enabled:
|
|
167
|
+
return "{0}*".format(self.pointee) if self.addrspace == 0 else \
|
|
168
|
+
"{0} addrspace({1})*".format(self.pointee, self.addrspace)
|
|
169
|
+
return super(_TypedPointerType, self)._to_string()
|
|
126
170
|
|
|
171
|
+
# This implements ``isOpaqueOrPointeeTypeEquals''.
|
|
127
172
|
def __eq__(self, other):
|
|
128
|
-
if isinstance(other,
|
|
173
|
+
if isinstance(other, _TypedPointerType):
|
|
129
174
|
return (self.pointee, self.addrspace) == (other.pointee,
|
|
130
175
|
other.addrspace)
|
|
131
|
-
|
|
132
|
-
return False
|
|
176
|
+
return isinstance(other, PointerType)
|
|
133
177
|
|
|
134
178
|
def __hash__(self):
|
|
135
|
-
return hash(
|
|
179
|
+
return hash(_TypedPointerType)
|
|
136
180
|
|
|
137
181
|
def gep(self, i):
|
|
138
182
|
"""
|
|
@@ -146,6 +190,17 @@ class PointerType(Type):
|
|
|
146
190
|
def intrinsic_name(self):
|
|
147
191
|
return 'p%d%s' % (self.addrspace, self.pointee.intrinsic_name)
|
|
148
192
|
|
|
193
|
+
@classmethod
|
|
194
|
+
def from_llvm(cls, typeref, ir_ctx):
|
|
195
|
+
"""
|
|
196
|
+
Create from a llvmlite.binding.TypeRef
|
|
197
|
+
"""
|
|
198
|
+
assert not opaque_pointers_enabled
|
|
199
|
+
# opaque pointer will change this
|
|
200
|
+
[pointee] = typeref.elements
|
|
201
|
+
# addrspace is not handled
|
|
202
|
+
return cls(pointee.as_ir(ir_ctx=ir_ctx))
|
|
203
|
+
|
|
149
204
|
|
|
150
205
|
class VoidType(Type):
|
|
151
206
|
"""
|
|
@@ -161,6 +216,13 @@ class VoidType(Type):
|
|
|
161
216
|
def __hash__(self):
|
|
162
217
|
return hash(VoidType)
|
|
163
218
|
|
|
219
|
+
@classmethod
|
|
220
|
+
def from_llvm(cls, typeref, ir_ctx):
|
|
221
|
+
"""
|
|
222
|
+
Create from a llvmlite.binding.TypeRef
|
|
223
|
+
"""
|
|
224
|
+
return cls()
|
|
225
|
+
|
|
164
226
|
|
|
165
227
|
class FunctionType(Type):
|
|
166
228
|
"""
|
|
@@ -194,6 +256,17 @@ class FunctionType(Type):
|
|
|
194
256
|
def __hash__(self):
|
|
195
257
|
return hash(FunctionType)
|
|
196
258
|
|
|
259
|
+
@classmethod
|
|
260
|
+
def from_llvm(cls, typeref, ir_ctx):
|
|
261
|
+
"""
|
|
262
|
+
Create from a llvmlite.binding.TypeRef
|
|
263
|
+
"""
|
|
264
|
+
params = tuple(x.as_ir(ir_ctx=ir_ctx)
|
|
265
|
+
for x in typeref.get_function_parameters())
|
|
266
|
+
ret = typeref.get_function_return().as_ir(ir_ctx=ir_ctx)
|
|
267
|
+
is_vararg = typeref.is_function_vararg
|
|
268
|
+
return cls(ret, params, is_vararg)
|
|
269
|
+
|
|
197
270
|
|
|
198
271
|
class IntType(Type):
|
|
199
272
|
"""
|
|
@@ -253,6 +326,13 @@ class IntType(Type):
|
|
|
253
326
|
def intrinsic_name(self):
|
|
254
327
|
return str(self)
|
|
255
328
|
|
|
329
|
+
@classmethod
|
|
330
|
+
def from_llvm(cls, typeref, ir_ctx):
|
|
331
|
+
"""
|
|
332
|
+
Create from a llvmlite.binding.TypeRef
|
|
333
|
+
"""
|
|
334
|
+
return IntType(typeref.type_width)
|
|
335
|
+
|
|
256
336
|
|
|
257
337
|
def _as_float(value):
|
|
258
338
|
"""
|
|
@@ -302,6 +382,13 @@ class _BaseFloatType(Type):
|
|
|
302
382
|
def _create_instance(cls):
|
|
303
383
|
cls._instance_cache = super(_BaseFloatType, cls).__new__(cls)
|
|
304
384
|
|
|
385
|
+
@classmethod
|
|
386
|
+
def from_llvm(cls, typeref, ir_ctx):
|
|
387
|
+
"""
|
|
388
|
+
Create from a llvmlite.binding.TypeRef
|
|
389
|
+
"""
|
|
390
|
+
return cls()
|
|
391
|
+
|
|
305
392
|
|
|
306
393
|
class HalfType(_BaseFloatType):
|
|
307
394
|
"""
|
|
@@ -414,6 +501,16 @@ class VectorType(Type):
|
|
|
414
501
|
return [Constant(ty, val) if not isinstance(val, Value) else val
|
|
415
502
|
for ty, val in zip(self.elements, values)]
|
|
416
503
|
|
|
504
|
+
@classmethod
|
|
505
|
+
def from_llvm(cls, typeref, ir_ctx):
|
|
506
|
+
"""
|
|
507
|
+
Create from a llvmlite.binding.TypeRef
|
|
508
|
+
"""
|
|
509
|
+
[elemtyperef] = typeref.elements
|
|
510
|
+
elemty = elemtyperef.as_ir(ir_ctx=ir_ctx)
|
|
511
|
+
count = typeref.element_count
|
|
512
|
+
return cls(elemty, count)
|
|
513
|
+
|
|
417
514
|
|
|
418
515
|
class Aggregate(Type):
|
|
419
516
|
"""
|
|
@@ -472,6 +569,16 @@ class ArrayType(Aggregate):
|
|
|
472
569
|
for x in value])
|
|
473
570
|
return "[{0}]".format(itemstring)
|
|
474
571
|
|
|
572
|
+
@classmethod
|
|
573
|
+
def from_llvm(cls, typeref, ir_ctx):
|
|
574
|
+
"""
|
|
575
|
+
Create from a llvmlite.binding.TypeRef
|
|
576
|
+
"""
|
|
577
|
+
[elemtyperef] = typeref.elements
|
|
578
|
+
elemty = elemtyperef.as_ir(ir_ctx=ir_ctx)
|
|
579
|
+
count = typeref.element_count
|
|
580
|
+
return cls(elemty, count)
|
|
581
|
+
|
|
475
582
|
|
|
476
583
|
class BaseStructType(Aggregate):
|
|
477
584
|
"""
|
|
@@ -536,6 +643,17 @@ class BaseStructType(Aggregate):
|
|
|
536
643
|
else:
|
|
537
644
|
return textrepr
|
|
538
645
|
|
|
646
|
+
@classmethod
|
|
647
|
+
def from_llvm(cls, typeref, ir_ctx):
|
|
648
|
+
"""
|
|
649
|
+
Create from a llvmlite.binding.TypeRef
|
|
650
|
+
"""
|
|
651
|
+
if typeref.is_literal_struct:
|
|
652
|
+
elems = [el.as_ir(ir_ctx=ir_ctx) for el in typeref.elements]
|
|
653
|
+
return cls(elems, typeref.is_packed_struct)
|
|
654
|
+
else:
|
|
655
|
+
return ir_ctx.get_identified_type(typeref.name)
|
|
656
|
+
|
|
539
657
|
|
|
540
658
|
class LiteralStructType(BaseStructType):
|
|
541
659
|
"""
|
|
@@ -558,7 +676,8 @@ class LiteralStructType(BaseStructType):
|
|
|
558
676
|
|
|
559
677
|
def __eq__(self, other):
|
|
560
678
|
if isinstance(other, LiteralStructType):
|
|
561
|
-
return self.elements == other.elements
|
|
679
|
+
return (self.elements == other.elements
|
|
680
|
+
and self.packed == other.packed)
|
|
562
681
|
|
|
563
682
|
def __hash__(self):
|
|
564
683
|
return hash(LiteralStructType)
|
|
@@ -602,7 +721,8 @@ class IdentifiedStructType(BaseStructType):
|
|
|
602
721
|
|
|
603
722
|
def __eq__(self, other):
|
|
604
723
|
if isinstance(other, IdentifiedStructType):
|
|
605
|
-
return self.name == other.name
|
|
724
|
+
return (self.name == other.name
|
|
725
|
+
and self.packed == other.packed)
|
|
606
726
|
|
|
607
727
|
def __hash__(self):
|
|
608
728
|
return hash(IdentifiedStructType)
|
llvmlite/ir/values.py
CHANGED
|
@@ -482,12 +482,12 @@ class Constant(_StrCaching, _StringReferenceCaching, _ConstOpMixin, Value):
|
|
|
482
482
|
return cls(types.ArrayType(ty, len(elems)), elems)
|
|
483
483
|
|
|
484
484
|
@classmethod
|
|
485
|
-
def literal_struct(cls, elems):
|
|
485
|
+
def literal_struct(cls, elems, packed=False):
|
|
486
486
|
"""
|
|
487
487
|
Construct a literal structure constant made of the given members.
|
|
488
488
|
"""
|
|
489
489
|
tys = [el.type for el in elems]
|
|
490
|
-
return cls(types.LiteralStructType(tys), elems)
|
|
490
|
+
return cls(types.LiteralStructType(tys, packed), elems)
|
|
491
491
|
|
|
492
492
|
@property
|
|
493
493
|
def addrspace(self):
|