llvmlite 0.46.0b1__cp314-cp314-win_amd64.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of llvmlite might be problematic. Click here for more details.
- llvmlite/__init__.py +22 -0
- llvmlite/_version.py +11 -0
- llvmlite/binding/__init__.py +18 -0
- llvmlite/binding/analysis.py +69 -0
- llvmlite/binding/common.py +34 -0
- llvmlite/binding/config.py +143 -0
- llvmlite/binding/context.py +31 -0
- llvmlite/binding/dylib.py +45 -0
- llvmlite/binding/executionengine.py +330 -0
- llvmlite/binding/ffi.py +395 -0
- llvmlite/binding/initfini.py +85 -0
- llvmlite/binding/linker.py +20 -0
- llvmlite/binding/llvmlite.dll +0 -0
- llvmlite/binding/module.py +349 -0
- llvmlite/binding/newpassmanagers.py +1049 -0
- llvmlite/binding/object_file.py +82 -0
- llvmlite/binding/options.py +17 -0
- llvmlite/binding/orcjit.py +342 -0
- llvmlite/binding/targets.py +462 -0
- llvmlite/binding/typeref.py +267 -0
- llvmlite/binding/value.py +632 -0
- llvmlite/ir/__init__.py +11 -0
- llvmlite/ir/_utils.py +80 -0
- llvmlite/ir/builder.py +1120 -0
- llvmlite/ir/context.py +20 -0
- llvmlite/ir/instructions.py +920 -0
- llvmlite/ir/module.py +256 -0
- llvmlite/ir/transforms.py +64 -0
- llvmlite/ir/types.py +730 -0
- llvmlite/ir/values.py +1217 -0
- llvmlite/tests/__init__.py +57 -0
- llvmlite/tests/__main__.py +3 -0
- llvmlite/tests/customize.py +407 -0
- llvmlite/tests/refprune_proto.py +330 -0
- llvmlite/tests/test_binding.py +3155 -0
- llvmlite/tests/test_ir.py +3095 -0
- llvmlite/tests/test_refprune.py +574 -0
- llvmlite/tests/test_valuerepr.py +60 -0
- llvmlite/utils.py +29 -0
- llvmlite-0.46.0b1.dist-info/DELVEWHEEL +2 -0
- llvmlite-0.46.0b1.dist-info/METADATA +145 -0
- llvmlite-0.46.0b1.dist-info/RECORD +47 -0
- llvmlite-0.46.0b1.dist-info/WHEEL +5 -0
- llvmlite-0.46.0b1.dist-info/licenses/LICENSE +24 -0
- llvmlite-0.46.0b1.dist-info/licenses/LICENSE.thirdparty +225 -0
- llvmlite-0.46.0b1.dist-info/top_level.txt +1 -0
- llvmlite.libs/msvcp140-8f141b4454fa78db34bc1f28c571b4da.dll +0 -0
llvmlite/ir/types.py
ADDED
|
@@ -0,0 +1,730 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Classes that are LLVM types
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
import struct
|
|
6
|
+
|
|
7
|
+
from llvmlite import ir_layer_typed_pointers_enabled
|
|
8
|
+
from llvmlite.ir._utils import _StrCaching
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def _wrapname(x):
|
|
12
|
+
return '"{0}"'.format(x.replace('\\', '\\5c').replace('"', '\\22'))
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class Type(_StrCaching):
|
|
16
|
+
"""
|
|
17
|
+
The base class for all LLVM types.
|
|
18
|
+
"""
|
|
19
|
+
is_pointer = False
|
|
20
|
+
null = 'zeroinitializer'
|
|
21
|
+
|
|
22
|
+
def __repr__(self):
|
|
23
|
+
return "<%s %s>" % (type(self), str(self))
|
|
24
|
+
|
|
25
|
+
def _to_string(self):
|
|
26
|
+
raise NotImplementedError
|
|
27
|
+
|
|
28
|
+
def as_pointer(self, addrspace=0):
|
|
29
|
+
return PointerType(self, addrspace)
|
|
30
|
+
|
|
31
|
+
def __ne__(self, other):
|
|
32
|
+
return not (self == other)
|
|
33
|
+
|
|
34
|
+
def _get_ll_global_value_type(self, target_data, context=None):
|
|
35
|
+
"""
|
|
36
|
+
Convert this type object to an LLVM type.
|
|
37
|
+
"""
|
|
38
|
+
from llvmlite.ir import Module, GlobalVariable
|
|
39
|
+
from llvmlite.binding import parse_assembly
|
|
40
|
+
|
|
41
|
+
if context is None:
|
|
42
|
+
m = Module()
|
|
43
|
+
else:
|
|
44
|
+
m = Module(context=context)
|
|
45
|
+
foo = GlobalVariable(m, self, name="foo")
|
|
46
|
+
with parse_assembly(str(m)) as llmod:
|
|
47
|
+
return llmod.get_global_variable(foo.name).global_value_type
|
|
48
|
+
|
|
49
|
+
def get_abi_size(self, target_data, context=None):
|
|
50
|
+
"""
|
|
51
|
+
Get the ABI size of this type according to data layout *target_data*.
|
|
52
|
+
"""
|
|
53
|
+
llty = self._get_ll_global_value_type(target_data, context)
|
|
54
|
+
return target_data.get_abi_size(llty)
|
|
55
|
+
|
|
56
|
+
def get_element_offset(self, target_data, ndx, context=None):
|
|
57
|
+
llty = self._get_ll_global_value_type(target_data, context)
|
|
58
|
+
return target_data.get_element_offset(llty, ndx)
|
|
59
|
+
|
|
60
|
+
def get_abi_alignment(self, target_data, context=None):
|
|
61
|
+
"""
|
|
62
|
+
Get the minimum ABI alignment of this type according to data layout
|
|
63
|
+
*target_data*.
|
|
64
|
+
"""
|
|
65
|
+
llty = self._get_ll_global_value_type(target_data, context)
|
|
66
|
+
return target_data.get_abi_alignment(llty)
|
|
67
|
+
|
|
68
|
+
def format_constant(self, value):
|
|
69
|
+
"""
|
|
70
|
+
Format constant *value* of this type. This method may be overriden
|
|
71
|
+
by subclasses.
|
|
72
|
+
"""
|
|
73
|
+
return str(value)
|
|
74
|
+
|
|
75
|
+
def wrap_constant_value(self, value):
|
|
76
|
+
"""
|
|
77
|
+
Wrap constant *value* if necessary. This method may be overriden
|
|
78
|
+
by subclasses (especially aggregate types).
|
|
79
|
+
"""
|
|
80
|
+
return value
|
|
81
|
+
|
|
82
|
+
def __call__(self, value):
|
|
83
|
+
"""
|
|
84
|
+
Create a LLVM constant of this type with the given Python value.
|
|
85
|
+
"""
|
|
86
|
+
from llvmlite.ir import Constant
|
|
87
|
+
return Constant(self, value)
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
class MetaDataType(Type):
|
|
91
|
+
|
|
92
|
+
def _to_string(self):
|
|
93
|
+
return "metadata"
|
|
94
|
+
|
|
95
|
+
def as_pointer(self):
|
|
96
|
+
raise TypeError
|
|
97
|
+
|
|
98
|
+
def __eq__(self, other):
|
|
99
|
+
return isinstance(other, MetaDataType)
|
|
100
|
+
|
|
101
|
+
def __hash__(self):
|
|
102
|
+
return hash(MetaDataType)
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
class LabelType(Type):
|
|
106
|
+
"""
|
|
107
|
+
The label type is the type of e.g. basic blocks.
|
|
108
|
+
"""
|
|
109
|
+
|
|
110
|
+
def _to_string(self):
|
|
111
|
+
return "label"
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
class PointerType(Type):
|
|
115
|
+
"""
|
|
116
|
+
The type of all pointer values.
|
|
117
|
+
By default (without specialisation) represents an opaque pointer.
|
|
118
|
+
"""
|
|
119
|
+
is_opaque = True
|
|
120
|
+
is_pointer = True
|
|
121
|
+
null = 'null'
|
|
122
|
+
|
|
123
|
+
# Factory to create typed or opaque pointers based on `pointee'.
|
|
124
|
+
def __new__(cls, pointee=None, addrspace=0):
|
|
125
|
+
if cls is PointerType and pointee is not None:
|
|
126
|
+
return super().__new__(_TypedPointerType)
|
|
127
|
+
return super(PointerType, cls).__new__(cls)
|
|
128
|
+
|
|
129
|
+
def __init__(self, addrspace=0):
|
|
130
|
+
self.addrspace = addrspace
|
|
131
|
+
|
|
132
|
+
def _to_string(self):
|
|
133
|
+
if self.addrspace != 0:
|
|
134
|
+
return "ptr addrspace({0})".format(self.addrspace)
|
|
135
|
+
else:
|
|
136
|
+
return "ptr"
|
|
137
|
+
|
|
138
|
+
def __eq__(self, other):
|
|
139
|
+
return (isinstance(other, PointerType) and
|
|
140
|
+
self.addrspace == other.addrspace)
|
|
141
|
+
|
|
142
|
+
def __hash__(self):
|
|
143
|
+
return hash(PointerType)
|
|
144
|
+
|
|
145
|
+
@property
|
|
146
|
+
def intrinsic_name(self):
|
|
147
|
+
return 'p%d' % self.addrspace
|
|
148
|
+
|
|
149
|
+
@classmethod
|
|
150
|
+
def from_llvm(cls, typeref, ir_ctx):
|
|
151
|
+
"""
|
|
152
|
+
Create from a llvmlite.binding.TypeRef
|
|
153
|
+
"""
|
|
154
|
+
return cls()
|
|
155
|
+
|
|
156
|
+
|
|
157
|
+
class _TypedPointerType(PointerType):
|
|
158
|
+
"""
|
|
159
|
+
The type of typed pointer values. To be removed eventually.
|
|
160
|
+
"""
|
|
161
|
+
|
|
162
|
+
def __init__(self, pointee, addrspace=0):
|
|
163
|
+
super(_TypedPointerType, self).__init__(addrspace)
|
|
164
|
+
assert pointee is not None
|
|
165
|
+
assert not isinstance(pointee, VoidType)
|
|
166
|
+
self.pointee = pointee
|
|
167
|
+
self.is_opaque = False
|
|
168
|
+
|
|
169
|
+
def _to_string(self):
|
|
170
|
+
if ir_layer_typed_pointers_enabled:
|
|
171
|
+
return "{0}*".format(self.pointee) if self.addrspace == 0 else \
|
|
172
|
+
"{0} addrspace({1})*".format(self.pointee, self.addrspace)
|
|
173
|
+
return super(_TypedPointerType, self)._to_string()
|
|
174
|
+
|
|
175
|
+
# This implements ``isOpaqueOrPointeeTypeEquals''.
|
|
176
|
+
def __eq__(self, other):
|
|
177
|
+
if isinstance(other, _TypedPointerType):
|
|
178
|
+
return (self.pointee, self.addrspace) == (other.pointee,
|
|
179
|
+
other.addrspace)
|
|
180
|
+
return (isinstance(other, PointerType) and
|
|
181
|
+
self.addrspace == other.addrspace)
|
|
182
|
+
|
|
183
|
+
def __hash__(self):
|
|
184
|
+
return hash(_TypedPointerType)
|
|
185
|
+
|
|
186
|
+
def gep(self, i):
|
|
187
|
+
"""
|
|
188
|
+
Resolve the type of the i-th element (for getelementptr lookups).
|
|
189
|
+
"""
|
|
190
|
+
if not isinstance(i.type, IntType):
|
|
191
|
+
raise TypeError(i.type)
|
|
192
|
+
return self.pointee
|
|
193
|
+
|
|
194
|
+
@property
|
|
195
|
+
def intrinsic_name(self):
|
|
196
|
+
if ir_layer_typed_pointers_enabled:
|
|
197
|
+
return 'p%d%s' % (self.addrspace, self.pointee.intrinsic_name)
|
|
198
|
+
return super(_TypedPointerType, self).intrinsic_name
|
|
199
|
+
|
|
200
|
+
|
|
201
|
+
class VoidType(Type):
|
|
202
|
+
"""
|
|
203
|
+
The type for empty values (e.g. a function returning no value).
|
|
204
|
+
"""
|
|
205
|
+
|
|
206
|
+
def _to_string(self):
|
|
207
|
+
return 'void'
|
|
208
|
+
|
|
209
|
+
def __eq__(self, other):
|
|
210
|
+
return isinstance(other, VoidType)
|
|
211
|
+
|
|
212
|
+
def __hash__(self):
|
|
213
|
+
return hash(VoidType)
|
|
214
|
+
|
|
215
|
+
@classmethod
|
|
216
|
+
def from_llvm(cls, typeref, ir_ctx):
|
|
217
|
+
"""
|
|
218
|
+
Create from a llvmlite.binding.TypeRef
|
|
219
|
+
"""
|
|
220
|
+
return cls()
|
|
221
|
+
|
|
222
|
+
|
|
223
|
+
class FunctionType(Type):
|
|
224
|
+
"""
|
|
225
|
+
The type for functions.
|
|
226
|
+
"""
|
|
227
|
+
|
|
228
|
+
def __init__(self, return_type, args, var_arg=False):
|
|
229
|
+
self.return_type = return_type
|
|
230
|
+
self.args = tuple(args)
|
|
231
|
+
self.var_arg = var_arg
|
|
232
|
+
|
|
233
|
+
def _to_string(self):
|
|
234
|
+
if self.args:
|
|
235
|
+
strargs = ', '.join([str(a) for a in self.args])
|
|
236
|
+
if self.var_arg:
|
|
237
|
+
return '{0} ({1}, ...)'.format(self.return_type, strargs)
|
|
238
|
+
else:
|
|
239
|
+
return '{0} ({1})'.format(self.return_type, strargs)
|
|
240
|
+
elif self.var_arg:
|
|
241
|
+
return '{0} (...)'.format(self.return_type)
|
|
242
|
+
else:
|
|
243
|
+
return '{0} ()'.format(self.return_type)
|
|
244
|
+
|
|
245
|
+
def __eq__(self, other):
|
|
246
|
+
if isinstance(other, FunctionType):
|
|
247
|
+
return (self.return_type == other.return_type and
|
|
248
|
+
self.args == other.args and self.var_arg == other.var_arg)
|
|
249
|
+
else:
|
|
250
|
+
return False
|
|
251
|
+
|
|
252
|
+
def __hash__(self):
|
|
253
|
+
return hash(FunctionType)
|
|
254
|
+
|
|
255
|
+
@classmethod
|
|
256
|
+
def from_llvm(cls, typeref, ir_ctx):
|
|
257
|
+
"""
|
|
258
|
+
Create from a llvmlite.binding.TypeRef
|
|
259
|
+
"""
|
|
260
|
+
params = tuple(x.as_ir(ir_ctx=ir_ctx)
|
|
261
|
+
for x in typeref.get_function_parameters())
|
|
262
|
+
ret = typeref.get_function_return().as_ir(ir_ctx=ir_ctx)
|
|
263
|
+
is_vararg = typeref.is_function_vararg
|
|
264
|
+
return cls(ret, params, is_vararg)
|
|
265
|
+
|
|
266
|
+
|
|
267
|
+
class IntType(Type):
|
|
268
|
+
"""
|
|
269
|
+
The type for integers.
|
|
270
|
+
"""
|
|
271
|
+
null = '0'
|
|
272
|
+
_instance_cache = {}
|
|
273
|
+
width: int
|
|
274
|
+
|
|
275
|
+
def __new__(cls, bits):
|
|
276
|
+
# Cache all common integer types
|
|
277
|
+
if 0 <= bits <= 128:
|
|
278
|
+
try:
|
|
279
|
+
return cls._instance_cache[bits]
|
|
280
|
+
except KeyError:
|
|
281
|
+
inst = cls._instance_cache[bits] = cls.__new(bits)
|
|
282
|
+
return inst
|
|
283
|
+
return cls.__new(bits)
|
|
284
|
+
|
|
285
|
+
@classmethod
|
|
286
|
+
def __new(cls, bits):
|
|
287
|
+
assert isinstance(bits, int) and bits >= 0
|
|
288
|
+
self = super(IntType, cls).__new__(cls)
|
|
289
|
+
self.width = bits
|
|
290
|
+
return self
|
|
291
|
+
|
|
292
|
+
def __getnewargs__(self):
|
|
293
|
+
return self.width,
|
|
294
|
+
|
|
295
|
+
def __copy__(self):
|
|
296
|
+
return self
|
|
297
|
+
|
|
298
|
+
def _to_string(self):
|
|
299
|
+
return 'i%u' % (self.width,)
|
|
300
|
+
|
|
301
|
+
def __eq__(self, other):
|
|
302
|
+
if isinstance(other, IntType):
|
|
303
|
+
return self.width == other.width
|
|
304
|
+
else:
|
|
305
|
+
return False
|
|
306
|
+
|
|
307
|
+
def __hash__(self):
|
|
308
|
+
return hash(IntType)
|
|
309
|
+
|
|
310
|
+
def format_constant(self, val):
|
|
311
|
+
if isinstance(val, bool):
|
|
312
|
+
return str(val).lower()
|
|
313
|
+
else:
|
|
314
|
+
return str(val)
|
|
315
|
+
|
|
316
|
+
def wrap_constant_value(self, val):
|
|
317
|
+
if val is None:
|
|
318
|
+
return 0
|
|
319
|
+
return val
|
|
320
|
+
|
|
321
|
+
@property
|
|
322
|
+
def intrinsic_name(self):
|
|
323
|
+
return str(self)
|
|
324
|
+
|
|
325
|
+
@classmethod
|
|
326
|
+
def from_llvm(cls, typeref, ir_ctx):
|
|
327
|
+
"""
|
|
328
|
+
Create from a llvmlite.binding.TypeRef
|
|
329
|
+
"""
|
|
330
|
+
return IntType(typeref.type_width)
|
|
331
|
+
|
|
332
|
+
|
|
333
|
+
def _as_float(value):
|
|
334
|
+
"""
|
|
335
|
+
Truncate to single-precision float.
|
|
336
|
+
"""
|
|
337
|
+
return struct.unpack('f', struct.pack('f', value))[0]
|
|
338
|
+
|
|
339
|
+
|
|
340
|
+
def _as_half(value):
|
|
341
|
+
"""
|
|
342
|
+
Truncate to half-precision float.
|
|
343
|
+
"""
|
|
344
|
+
try:
|
|
345
|
+
return struct.unpack('e', struct.pack('e', value))[0]
|
|
346
|
+
except struct.error:
|
|
347
|
+
# 'e' only added in Python 3.6+
|
|
348
|
+
return _as_float(value)
|
|
349
|
+
|
|
350
|
+
|
|
351
|
+
def _format_float_as_hex(value, packfmt, unpackfmt, numdigits):
|
|
352
|
+
raw = struct.pack(packfmt, float(value))
|
|
353
|
+
intrep = struct.unpack(unpackfmt, raw)[0]
|
|
354
|
+
out = '{{0:#{0}x}}'.format(numdigits).format(intrep)
|
|
355
|
+
return out
|
|
356
|
+
|
|
357
|
+
|
|
358
|
+
def _format_double(value):
|
|
359
|
+
"""
|
|
360
|
+
Format *value* as a hexadecimal string of its IEEE double precision
|
|
361
|
+
representation.
|
|
362
|
+
"""
|
|
363
|
+
return _format_float_as_hex(value, 'd', 'Q', 16)
|
|
364
|
+
|
|
365
|
+
|
|
366
|
+
class _BaseFloatType(Type):
|
|
367
|
+
|
|
368
|
+
def __new__(cls):
|
|
369
|
+
return cls._instance_cache
|
|
370
|
+
|
|
371
|
+
def __eq__(self, other):
|
|
372
|
+
return isinstance(other, type(self))
|
|
373
|
+
|
|
374
|
+
def __hash__(self):
|
|
375
|
+
return hash(type(self))
|
|
376
|
+
|
|
377
|
+
@classmethod
|
|
378
|
+
def _create_instance(cls):
|
|
379
|
+
cls._instance_cache = super(_BaseFloatType, cls).__new__(cls)
|
|
380
|
+
|
|
381
|
+
@classmethod
|
|
382
|
+
def from_llvm(cls, typeref, ir_ctx):
|
|
383
|
+
"""
|
|
384
|
+
Create from a llvmlite.binding.TypeRef
|
|
385
|
+
"""
|
|
386
|
+
return cls()
|
|
387
|
+
|
|
388
|
+
|
|
389
|
+
class HalfType(_BaseFloatType):
|
|
390
|
+
"""
|
|
391
|
+
The type for single-precision floats.
|
|
392
|
+
"""
|
|
393
|
+
null = '0.0'
|
|
394
|
+
intrinsic_name = 'f16'
|
|
395
|
+
|
|
396
|
+
def __str__(self):
|
|
397
|
+
return 'half'
|
|
398
|
+
|
|
399
|
+
def format_constant(self, value):
|
|
400
|
+
return _format_double(_as_half(value))
|
|
401
|
+
|
|
402
|
+
|
|
403
|
+
class FloatType(_BaseFloatType):
|
|
404
|
+
"""
|
|
405
|
+
The type for single-precision floats.
|
|
406
|
+
"""
|
|
407
|
+
null = '0.0'
|
|
408
|
+
intrinsic_name = 'f32'
|
|
409
|
+
|
|
410
|
+
def __str__(self):
|
|
411
|
+
return 'float'
|
|
412
|
+
|
|
413
|
+
def format_constant(self, value):
|
|
414
|
+
return _format_double(_as_float(value))
|
|
415
|
+
|
|
416
|
+
|
|
417
|
+
class DoubleType(_BaseFloatType):
|
|
418
|
+
"""
|
|
419
|
+
The type for double-precision floats.
|
|
420
|
+
"""
|
|
421
|
+
null = '0.0'
|
|
422
|
+
intrinsic_name = 'f64'
|
|
423
|
+
|
|
424
|
+
def __str__(self):
|
|
425
|
+
return 'double'
|
|
426
|
+
|
|
427
|
+
def format_constant(self, value):
|
|
428
|
+
return _format_double(value)
|
|
429
|
+
|
|
430
|
+
|
|
431
|
+
for _cls in (HalfType, FloatType, DoubleType):
|
|
432
|
+
_cls._create_instance()
|
|
433
|
+
|
|
434
|
+
|
|
435
|
+
class _Repeat(object):
|
|
436
|
+
def __init__(self, value, size):
|
|
437
|
+
self.value = value
|
|
438
|
+
self.size = size
|
|
439
|
+
|
|
440
|
+
def __len__(self):
|
|
441
|
+
return self.size
|
|
442
|
+
|
|
443
|
+
def __getitem__(self, item):
|
|
444
|
+
if 0 <= item < self.size:
|
|
445
|
+
return self.value
|
|
446
|
+
else:
|
|
447
|
+
raise IndexError(item)
|
|
448
|
+
|
|
449
|
+
|
|
450
|
+
class VectorType(Type):
|
|
451
|
+
"""
|
|
452
|
+
The type for vectors of primitive data items (e.g. "<f32 x 4>").
|
|
453
|
+
"""
|
|
454
|
+
|
|
455
|
+
def __init__(self, element, count):
|
|
456
|
+
self.element = element
|
|
457
|
+
self.count = count
|
|
458
|
+
|
|
459
|
+
@property
|
|
460
|
+
def elements(self):
|
|
461
|
+
return _Repeat(self.element, self.count)
|
|
462
|
+
|
|
463
|
+
def __len__(self):
|
|
464
|
+
return self.count
|
|
465
|
+
|
|
466
|
+
def _to_string(self):
|
|
467
|
+
return "<%d x %s>" % (self.count, self.element)
|
|
468
|
+
|
|
469
|
+
def __eq__(self, other):
|
|
470
|
+
if isinstance(other, VectorType):
|
|
471
|
+
return self.element == other.element and self.count == other.count
|
|
472
|
+
|
|
473
|
+
def __hash__(self):
|
|
474
|
+
# TODO: why does this not take self.element/self.count into account?
|
|
475
|
+
return hash(VectorType)
|
|
476
|
+
|
|
477
|
+
def __copy__(self):
|
|
478
|
+
return self
|
|
479
|
+
|
|
480
|
+
def format_constant(self, value):
|
|
481
|
+
itemstring = ", " .join(["{0} {1}".format(x.type, x.get_reference())
|
|
482
|
+
for x in value])
|
|
483
|
+
return "<{0}>".format(itemstring)
|
|
484
|
+
|
|
485
|
+
def wrap_constant_value(self, values):
|
|
486
|
+
from . import Value, Constant
|
|
487
|
+
if not isinstance(values, (list, tuple)):
|
|
488
|
+
if isinstance(values, Constant):
|
|
489
|
+
if values.type != self.element:
|
|
490
|
+
raise TypeError("expected {} for {}".format(
|
|
491
|
+
self.element, values.type))
|
|
492
|
+
return (values, ) * self.count
|
|
493
|
+
return (Constant(self.element, values), ) * self.count
|
|
494
|
+
if len(values) != len(self):
|
|
495
|
+
raise ValueError("wrong constant size for %s: got %d elements"
|
|
496
|
+
% (self, len(values)))
|
|
497
|
+
return [Constant(ty, val) if not isinstance(val, Value) else val
|
|
498
|
+
for ty, val in zip(self.elements, values)]
|
|
499
|
+
|
|
500
|
+
@classmethod
|
|
501
|
+
def from_llvm(cls, typeref, ir_ctx):
|
|
502
|
+
"""
|
|
503
|
+
Create from a llvmlite.binding.TypeRef
|
|
504
|
+
"""
|
|
505
|
+
[elemtyperef] = typeref.elements
|
|
506
|
+
elemty = elemtyperef.as_ir(ir_ctx=ir_ctx)
|
|
507
|
+
count = typeref.element_count
|
|
508
|
+
return cls(elemty, count)
|
|
509
|
+
|
|
510
|
+
|
|
511
|
+
class Aggregate(Type):
|
|
512
|
+
"""
|
|
513
|
+
Base class for aggregate types.
|
|
514
|
+
See http://llvm.org/docs/LangRef.html#t-aggregate
|
|
515
|
+
"""
|
|
516
|
+
|
|
517
|
+
def wrap_constant_value(self, values):
|
|
518
|
+
from . import Value, Constant
|
|
519
|
+
|
|
520
|
+
if not isinstance(values, (list, tuple)):
|
|
521
|
+
return values
|
|
522
|
+
if len(values) != len(self):
|
|
523
|
+
raise ValueError("wrong constant size for %s: got %d elements"
|
|
524
|
+
% (self, len(values)))
|
|
525
|
+
return [Constant(ty, val) if not isinstance(val, Value) else val
|
|
526
|
+
for ty, val in zip(self.elements, values)]
|
|
527
|
+
|
|
528
|
+
|
|
529
|
+
class ArrayType(Aggregate):
|
|
530
|
+
"""
|
|
531
|
+
The type for fixed-size homogenous arrays (e.g. "[f32 x 3]").
|
|
532
|
+
"""
|
|
533
|
+
|
|
534
|
+
def __init__(self, element, count):
|
|
535
|
+
self.element = element
|
|
536
|
+
self.count = count
|
|
537
|
+
|
|
538
|
+
@property
|
|
539
|
+
def elements(self):
|
|
540
|
+
return _Repeat(self.element, self.count)
|
|
541
|
+
|
|
542
|
+
def __len__(self):
|
|
543
|
+
return self.count
|
|
544
|
+
|
|
545
|
+
def _to_string(self):
|
|
546
|
+
return "[%d x %s]" % (self.count, self.element)
|
|
547
|
+
|
|
548
|
+
def __eq__(self, other):
|
|
549
|
+
if isinstance(other, ArrayType):
|
|
550
|
+
return self.element == other.element and self.count == other.count
|
|
551
|
+
|
|
552
|
+
def __hash__(self):
|
|
553
|
+
return hash(ArrayType)
|
|
554
|
+
|
|
555
|
+
def gep(self, i):
|
|
556
|
+
"""
|
|
557
|
+
Resolve the type of the i-th element (for getelementptr lookups).
|
|
558
|
+
"""
|
|
559
|
+
if not isinstance(i.type, IntType):
|
|
560
|
+
raise TypeError(i.type)
|
|
561
|
+
return self.element
|
|
562
|
+
|
|
563
|
+
def format_constant(self, value):
|
|
564
|
+
itemstring = ", " .join(["{0} {1}".format(x.type, x.get_reference())
|
|
565
|
+
for x in value])
|
|
566
|
+
return "[{0}]".format(itemstring)
|
|
567
|
+
|
|
568
|
+
@classmethod
|
|
569
|
+
def from_llvm(cls, typeref, ir_ctx):
|
|
570
|
+
"""
|
|
571
|
+
Create from a llvmlite.binding.TypeRef
|
|
572
|
+
"""
|
|
573
|
+
[elemtyperef] = typeref.elements
|
|
574
|
+
elemty = elemtyperef.as_ir(ir_ctx=ir_ctx)
|
|
575
|
+
count = typeref.element_count
|
|
576
|
+
return cls(elemty, count)
|
|
577
|
+
|
|
578
|
+
|
|
579
|
+
class BaseStructType(Aggregate):
|
|
580
|
+
"""
|
|
581
|
+
The base type for heterogenous struct types.
|
|
582
|
+
"""
|
|
583
|
+
_packed = False
|
|
584
|
+
|
|
585
|
+
@property
|
|
586
|
+
def packed(self):
|
|
587
|
+
"""
|
|
588
|
+
A boolean attribute that indicates whether the structure uses
|
|
589
|
+
packed layout.
|
|
590
|
+
"""
|
|
591
|
+
return self._packed
|
|
592
|
+
|
|
593
|
+
@packed.setter
|
|
594
|
+
def packed(self, val):
|
|
595
|
+
self._packed = bool(val)
|
|
596
|
+
|
|
597
|
+
def __len__(self):
|
|
598
|
+
assert self.elements is not None
|
|
599
|
+
return len(self.elements)
|
|
600
|
+
|
|
601
|
+
def __iter__(self):
|
|
602
|
+
assert self.elements is not None
|
|
603
|
+
return iter(self.elements)
|
|
604
|
+
|
|
605
|
+
@property
|
|
606
|
+
def is_opaque(self):
|
|
607
|
+
return self.elements is None
|
|
608
|
+
|
|
609
|
+
def structure_repr(self):
|
|
610
|
+
"""
|
|
611
|
+
Return the LLVM IR for the structure representation
|
|
612
|
+
"""
|
|
613
|
+
ret = '{%s}' % ', '.join([str(x) for x in self.elements])
|
|
614
|
+
return self._wrap_packed(ret)
|
|
615
|
+
|
|
616
|
+
def format_constant(self, value):
|
|
617
|
+
itemstring = ", " .join(["{0} {1}".format(x.type, x.get_reference())
|
|
618
|
+
for x in value])
|
|
619
|
+
ret = "{{{0}}}".format(itemstring)
|
|
620
|
+
return self._wrap_packed(ret)
|
|
621
|
+
|
|
622
|
+
def gep(self, i):
|
|
623
|
+
"""
|
|
624
|
+
Resolve the type of the i-th element (for getelementptr lookups).
|
|
625
|
+
|
|
626
|
+
*i* needs to be a LLVM constant, so that the type can be determined
|
|
627
|
+
at compile-time.
|
|
628
|
+
"""
|
|
629
|
+
if not isinstance(i.type, IntType):
|
|
630
|
+
raise TypeError(i.type)
|
|
631
|
+
return self.elements[i.constant]
|
|
632
|
+
|
|
633
|
+
def _wrap_packed(self, textrepr):
|
|
634
|
+
"""
|
|
635
|
+
Internal helper to wrap textual repr of struct type into packed struct
|
|
636
|
+
"""
|
|
637
|
+
if self.packed:
|
|
638
|
+
return '<{}>'.format(textrepr)
|
|
639
|
+
else:
|
|
640
|
+
return textrepr
|
|
641
|
+
|
|
642
|
+
@classmethod
|
|
643
|
+
def from_llvm(cls, typeref, ir_ctx):
|
|
644
|
+
"""
|
|
645
|
+
Create from a llvmlite.binding.TypeRef
|
|
646
|
+
"""
|
|
647
|
+
if typeref.is_literal_struct:
|
|
648
|
+
elems = [el.as_ir(ir_ctx=ir_ctx) for el in typeref.elements]
|
|
649
|
+
return cls(elems, typeref.is_packed_struct)
|
|
650
|
+
else:
|
|
651
|
+
return ir_ctx.get_identified_type(typeref.name)
|
|
652
|
+
|
|
653
|
+
|
|
654
|
+
class LiteralStructType(BaseStructType):
|
|
655
|
+
"""
|
|
656
|
+
The type of "literal" structs, i.e. structs with a literally-defined
|
|
657
|
+
type (by contrast with IdentifiedStructType).
|
|
658
|
+
"""
|
|
659
|
+
|
|
660
|
+
null = 'zeroinitializer'
|
|
661
|
+
|
|
662
|
+
def __init__(self, elems, packed=False):
|
|
663
|
+
"""
|
|
664
|
+
*elems* is a sequence of types to be used as members.
|
|
665
|
+
*packed* controls the use of packed layout.
|
|
666
|
+
"""
|
|
667
|
+
self.elements = tuple(elems)
|
|
668
|
+
self.packed = packed
|
|
669
|
+
|
|
670
|
+
def _to_string(self):
|
|
671
|
+
return self.structure_repr()
|
|
672
|
+
|
|
673
|
+
def __eq__(self, other):
|
|
674
|
+
if isinstance(other, LiteralStructType):
|
|
675
|
+
return (self.elements == other.elements
|
|
676
|
+
and self.packed == other.packed)
|
|
677
|
+
|
|
678
|
+
def __hash__(self):
|
|
679
|
+
return hash(LiteralStructType)
|
|
680
|
+
|
|
681
|
+
|
|
682
|
+
class IdentifiedStructType(BaseStructType):
|
|
683
|
+
"""
|
|
684
|
+
A type which is a named alias for another struct type, akin to a typedef.
|
|
685
|
+
While literal struct types can be structurally equal (see
|
|
686
|
+
LiteralStructType), identified struct types are compared by name.
|
|
687
|
+
|
|
688
|
+
Do not use this directly.
|
|
689
|
+
"""
|
|
690
|
+
null = 'zeroinitializer'
|
|
691
|
+
|
|
692
|
+
def __init__(self, context, name, packed=False):
|
|
693
|
+
"""
|
|
694
|
+
*context* is a llvmlite.ir.Context.
|
|
695
|
+
*name* is the identifier for the new struct type.
|
|
696
|
+
*packed* controls the use of packed layout.
|
|
697
|
+
"""
|
|
698
|
+
assert name
|
|
699
|
+
self.context = context
|
|
700
|
+
self.name = name
|
|
701
|
+
self.elements = None
|
|
702
|
+
self.packed = packed
|
|
703
|
+
|
|
704
|
+
def _to_string(self):
|
|
705
|
+
return "%{name}".format(name=_wrapname(self.name))
|
|
706
|
+
|
|
707
|
+
def get_declaration(self):
|
|
708
|
+
"""
|
|
709
|
+
Returns the string for the declaration of the type
|
|
710
|
+
"""
|
|
711
|
+
if self.is_opaque:
|
|
712
|
+
out = "{strrep} = type opaque".format(strrep=str(self))
|
|
713
|
+
else:
|
|
714
|
+
out = "{strrep} = type {struct}".format(
|
|
715
|
+
strrep=str(self), struct=self.structure_repr())
|
|
716
|
+
return out
|
|
717
|
+
|
|
718
|
+
def __eq__(self, other):
|
|
719
|
+
if isinstance(other, IdentifiedStructType):
|
|
720
|
+
return (self.name == other.name
|
|
721
|
+
and self.packed == other.packed)
|
|
722
|
+
|
|
723
|
+
def __hash__(self):
|
|
724
|
+
return hash(IdentifiedStructType)
|
|
725
|
+
|
|
726
|
+
def set_body(self, *elems):
|
|
727
|
+
if not self.is_opaque:
|
|
728
|
+
raise RuntimeError("{name} is already defined".format(
|
|
729
|
+
name=self.name))
|
|
730
|
+
self.elements = tuple(elems)
|