llvmlite 0.43.0rc1__cp312-cp312-macosx_11_0_arm64.whl → 0.44.0rc2__cp312-cp312-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.

@@ -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]
@@ -431,9 +431,17 @@ class CastInstr(Instruction):
431
431
 
432
432
  class LoadInstr(Instruction):
433
433
 
434
- def __init__(self, parent, ptr, name=''):
435
- super(LoadInstr, self).__init__(parent, ptr.type.pointee, "load",
436
- [ptr], name=name)
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
- val.type.pointee,
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
- super(LoadAtomicInstr, self).__init__(parent, ptr.type.pointee,
478
- "load atomic", [ptr], name=name)
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
- val.type.pointee,
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.type.pointee))
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
- typ = ptr.type
535
- lasttyp = None
536
- lastaddrspace = 0
537
- for i in indices:
538
- lasttyp, typ = typ, typ.gep(i)
539
- # inherit the addrspace from the last seen pointer
540
- if isinstance(lasttyp, types.PointerType):
541
- lastaddrspace = lasttyp.addrspace
542
-
543
- if (not isinstance(typ, types.PointerType) and
544
- isinstance(lasttyp, types.PointerType)):
545
- typ = lasttyp
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
- typ = typ.as_pointer(lastaddrspace)
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.pointer.type.pointee,
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 _get_ll_pointer_type(self, target_data, context=None):
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).type
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._get_ll_pointer_type(target_data, context)
53
- return target_data.get_pointee_abi_size(llty)
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._get_ll_pointer_type(target_data, context)
61
- return target_data.get_pointee_abi_alignment(llty)
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
- def __init__(self, pointee, addrspace=0):
117
- assert not isinstance(pointee, VoidType)
118
- self.pointee = pointee
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 "{0} addrspace({1})*".format(self.pointee, self.addrspace)
136
+ return "ptr addrspace({0})".format(self.addrspace)
124
137
  else:
125
- return "{0}*".format(self.pointee)
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, PointerType):
173
+ if isinstance(other, _TypedPointerType):
129
174
  return (self.pointee, self.addrspace) == (other.pointee,
130
175
  other.addrspace)
131
- else:
132
- return False
176
+ return isinstance(other, PointerType)
133
177
 
134
178
  def __hash__(self):
135
- return hash(PointerType)
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):