llvmlite 0.46.0b1__cp314-cp314-macosx_11_0_universal2.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 (45) hide show
  1. llvmlite/__init__.py +11 -0
  2. llvmlite/_version.py +11 -0
  3. llvmlite/binding/__init__.py +18 -0
  4. llvmlite/binding/analysis.py +69 -0
  5. llvmlite/binding/common.py +34 -0
  6. llvmlite/binding/config.py +143 -0
  7. llvmlite/binding/context.py +31 -0
  8. llvmlite/binding/dylib.py +45 -0
  9. llvmlite/binding/executionengine.py +330 -0
  10. llvmlite/binding/ffi.py +395 -0
  11. llvmlite/binding/initfini.py +85 -0
  12. llvmlite/binding/libllvmlite.dylib +0 -0
  13. llvmlite/binding/linker.py +20 -0
  14. llvmlite/binding/module.py +349 -0
  15. llvmlite/binding/newpassmanagers.py +1049 -0
  16. llvmlite/binding/object_file.py +82 -0
  17. llvmlite/binding/options.py +17 -0
  18. llvmlite/binding/orcjit.py +342 -0
  19. llvmlite/binding/targets.py +462 -0
  20. llvmlite/binding/typeref.py +267 -0
  21. llvmlite/binding/value.py +632 -0
  22. llvmlite/ir/__init__.py +11 -0
  23. llvmlite/ir/_utils.py +80 -0
  24. llvmlite/ir/builder.py +1120 -0
  25. llvmlite/ir/context.py +20 -0
  26. llvmlite/ir/instructions.py +920 -0
  27. llvmlite/ir/module.py +256 -0
  28. llvmlite/ir/transforms.py +64 -0
  29. llvmlite/ir/types.py +730 -0
  30. llvmlite/ir/values.py +1217 -0
  31. llvmlite/tests/__init__.py +57 -0
  32. llvmlite/tests/__main__.py +3 -0
  33. llvmlite/tests/customize.py +407 -0
  34. llvmlite/tests/refprune_proto.py +330 -0
  35. llvmlite/tests/test_binding.py +3155 -0
  36. llvmlite/tests/test_ir.py +3095 -0
  37. llvmlite/tests/test_refprune.py +574 -0
  38. llvmlite/tests/test_valuerepr.py +60 -0
  39. llvmlite/utils.py +29 -0
  40. llvmlite-0.46.0b1.dist-info/METADATA +145 -0
  41. llvmlite-0.46.0b1.dist-info/RECORD +45 -0
  42. llvmlite-0.46.0b1.dist-info/WHEEL +5 -0
  43. llvmlite-0.46.0b1.dist-info/licenses/LICENSE +24 -0
  44. llvmlite-0.46.0b1.dist-info/licenses/LICENSE.thirdparty +225 -0
  45. llvmlite-0.46.0b1.dist-info/top_level.txt +1 -0
llvmlite/ir/values.py ADDED
@@ -0,0 +1,1217 @@
1
+ """
2
+ Classes that are LLVM values: Value, Constant...
3
+ Instructions are in the instructions module.
4
+ """
5
+
6
+ import functools
7
+ import string
8
+ import re
9
+ from types import MappingProxyType
10
+
11
+ from llvmlite.ir import values, types, _utils
12
+ from llvmlite.ir._utils import (_StrCaching, _StringReferenceCaching,
13
+ _HasMetadata)
14
+
15
+ _VALID_CHARS = (frozenset(map(ord, string.ascii_letters)) |
16
+ frozenset(map(ord, string.digits)) |
17
+ frozenset(map(ord, ' !#$%&\'()*+,-./:;<=>?@[]^_`{|}~')))
18
+
19
+ _SIMPLE_IDENTIFIER_RE = re.compile(r"[-a-zA-Z$._][-a-zA-Z$._0-9]*$")
20
+
21
+ _CMP_MAP = {
22
+ '>': 'gt',
23
+ '<': 'lt',
24
+ '==': 'eq',
25
+ '!=': 'ne',
26
+ '>=': 'ge',
27
+ '<=': 'le',
28
+ }
29
+
30
+
31
+ def _escape_string(text, _map={}):
32
+ """
33
+ Escape the given bytestring for safe use as a LLVM array constant.
34
+ Any unicode string input is first encoded with utf8 into bytes.
35
+ """
36
+ if isinstance(text, str):
37
+ text = text.encode()
38
+ assert isinstance(text, (bytes, bytearray))
39
+
40
+ if not _map:
41
+ for ch in range(256):
42
+ if ch in _VALID_CHARS:
43
+ _map[ch] = chr(ch)
44
+ else:
45
+ _map[ch] = '\\%02x' % ch
46
+
47
+ buf = [_map[ch] for ch in text]
48
+ return ''.join(buf)
49
+
50
+
51
+ def _binop(opname):
52
+ def wrap(fn):
53
+ @functools.wraps(fn)
54
+ def wrapped(lhs, rhs):
55
+ if lhs.type != rhs.type:
56
+ raise ValueError("Operands must be the same type, got (%s, %s)"
57
+ % (lhs.type, rhs.type))
58
+
59
+ fmt = "{0} ({1} {2}, {3} {4})".format(opname,
60
+ lhs.type, lhs.get_reference(),
61
+ rhs.type, rhs.get_reference())
62
+ return FormattedConstant(lhs.type, fmt)
63
+
64
+ return wrapped
65
+ return wrap
66
+
67
+
68
+ def _castop(opname):
69
+ def wrap(fn):
70
+ @functools.wraps(fn)
71
+ def wrapped(self, typ):
72
+ fn(self, typ)
73
+ if typ == self.type:
74
+ return self
75
+
76
+ op = "{0} ({1} {2} to {3})".format(opname, self.type,
77
+ self.get_reference(), typ)
78
+ return FormattedConstant(typ, op)
79
+
80
+ return wrapped
81
+ return wrap
82
+
83
+
84
+ class _ConstOpMixin(object):
85
+ """
86
+ A mixin defining constant operations, for use in constant-like classes.
87
+ """
88
+
89
+ #
90
+ # Arithmetic APIs
91
+ #
92
+
93
+ @_binop('shl')
94
+ def shl(self, other):
95
+ """
96
+ Left integer shift:
97
+ lhs << rhs
98
+ """
99
+
100
+ @_binop('lshr')
101
+ def lshr(self, other):
102
+ """
103
+ Logical (unsigned) right integer shift:
104
+ lhs >> rhs
105
+ """
106
+
107
+ @_binop('ashr')
108
+ def ashr(self, other):
109
+ """
110
+ Arithmetic (signed) right integer shift:
111
+ lhs >> rhs
112
+ """
113
+
114
+ @_binop('add')
115
+ def add(self, other):
116
+ """
117
+ Integer addition:
118
+ lhs + rhs
119
+ """
120
+
121
+ @_binop('fadd')
122
+ def fadd(self, other):
123
+ """
124
+ Floating-point addition:
125
+ lhs + rhs
126
+ """
127
+
128
+ @_binop('sub')
129
+ def sub(self, other):
130
+ """
131
+ Integer subtraction:
132
+ lhs - rhs
133
+ """
134
+
135
+ @_binop('fsub')
136
+ def fsub(self, other):
137
+ """
138
+ Floating-point subtraction:
139
+ lhs - rhs
140
+ """
141
+
142
+ @_binop('mul')
143
+ def mul(self, other):
144
+ """
145
+ Integer multiplication:
146
+ lhs * rhs
147
+ """
148
+
149
+ @_binop('fmul')
150
+ def fmul(self, other):
151
+ """
152
+ Floating-point multiplication:
153
+ lhs * rhs
154
+ """
155
+
156
+ @_binop('udiv')
157
+ def udiv(self, other):
158
+ """
159
+ Unsigned integer division:
160
+ lhs / rhs
161
+ """
162
+
163
+ @_binop('sdiv')
164
+ def sdiv(self, other):
165
+ """
166
+ Signed integer division:
167
+ lhs / rhs
168
+ """
169
+
170
+ @_binop('fdiv')
171
+ def fdiv(self, other):
172
+ """
173
+ Floating-point division:
174
+ lhs / rhs
175
+ """
176
+
177
+ @_binop('urem')
178
+ def urem(self, other):
179
+ """
180
+ Unsigned integer remainder:
181
+ lhs % rhs
182
+ """
183
+
184
+ @_binop('srem')
185
+ def srem(self, other):
186
+ """
187
+ Signed integer remainder:
188
+ lhs % rhs
189
+ """
190
+
191
+ @_binop('frem')
192
+ def frem(self, other):
193
+ """
194
+ Floating-point remainder:
195
+ lhs % rhs
196
+ """
197
+
198
+ @_binop('or')
199
+ def or_(self, other):
200
+ """
201
+ Bitwise integer OR:
202
+ lhs | rhs
203
+ """
204
+
205
+ @_binop('and')
206
+ def and_(self, other):
207
+ """
208
+ Bitwise integer AND:
209
+ lhs & rhs
210
+ """
211
+
212
+ @_binop('xor')
213
+ def xor(self, other):
214
+ """
215
+ Bitwise integer XOR:
216
+ lhs ^ rhs
217
+ """
218
+
219
+ def _cmp(self, prefix, sign, cmpop, other):
220
+ ins = prefix + 'cmp'
221
+ try:
222
+ op = _CMP_MAP[cmpop]
223
+ except KeyError:
224
+ raise ValueError("invalid comparison %r for %s" % (cmpop, ins))
225
+
226
+ if not (prefix == 'i' and cmpop in ('==', '!=')):
227
+ op = sign + op
228
+
229
+ if self.type != other.type:
230
+ raise ValueError("Operands must be the same type, got (%s, %s)"
231
+ % (self.type, other.type))
232
+
233
+ fmt = "{0} {1} ({2} {3}, {4} {5})".format(
234
+ ins, op,
235
+ self.type, self.get_reference(),
236
+ other.type, other.get_reference())
237
+
238
+ return FormattedConstant(types.IntType(1), fmt)
239
+
240
+ def icmp_signed(self, cmpop, other):
241
+ """
242
+ Signed integer comparison:
243
+ lhs <cmpop> rhs
244
+
245
+ where cmpop can be '==', '!=', '<', '<=', '>', '>='
246
+ """
247
+ return self._cmp('i', 's', cmpop, other)
248
+
249
+ def icmp_unsigned(self, cmpop, other):
250
+ """
251
+ Unsigned integer (or pointer) comparison:
252
+ lhs <cmpop> rhs
253
+
254
+ where cmpop can be '==', '!=', '<', '<=', '>', '>='
255
+ """
256
+ return self._cmp('i', 'u', cmpop, other)
257
+
258
+ def fcmp_ordered(self, cmpop, other):
259
+ """
260
+ Floating-point ordered comparison:
261
+ lhs <cmpop> rhs
262
+
263
+ where cmpop can be '==', '!=', '<', '<=', '>', '>=', 'ord', 'uno'
264
+ """
265
+ return self._cmp('f', 'o', cmpop, other)
266
+
267
+ def fcmp_unordered(self, cmpop, other):
268
+ """
269
+ Floating-point unordered comparison:
270
+ lhs <cmpop> rhs
271
+
272
+ where cmpop can be '==', '!=', '<', '<=', '>', '>=', 'ord', 'uno'
273
+ """
274
+ return self._cmp('f', 'u', cmpop, other)
275
+
276
+ #
277
+ # Unary APIs
278
+ #
279
+
280
+ def not_(self):
281
+ """
282
+ Bitwise integer complement:
283
+ ~value
284
+ """
285
+ if isinstance(self.type, types.VectorType):
286
+ rhs = values.Constant(self.type, (-1,) * self.type.count)
287
+ else:
288
+ rhs = values.Constant(self.type, -1)
289
+
290
+ return self.xor(rhs)
291
+
292
+ def neg(self):
293
+ """
294
+ Integer negative:
295
+ -value
296
+ """
297
+ zero = values.Constant(self.type, 0)
298
+ return zero.sub(self)
299
+
300
+ def fneg(self):
301
+ """
302
+ Floating-point negative:
303
+ -value
304
+ """
305
+ fmt = "fneg ({0} {1})".format(self.type, self.get_reference())
306
+ return FormattedConstant(self.type, fmt)
307
+
308
+ #
309
+ # Cast APIs
310
+ #
311
+
312
+ @_castop('trunc')
313
+ def trunc(self, typ):
314
+ """
315
+ Truncating integer downcast to a smaller type.
316
+ """
317
+
318
+ @_castop('zext')
319
+ def zext(self, typ):
320
+ """
321
+ Zero-extending integer upcast to a larger type
322
+ """
323
+
324
+ @_castop('sext')
325
+ def sext(self, typ):
326
+ """
327
+ Sign-extending integer upcast to a larger type.
328
+ """
329
+
330
+ @_castop('fptrunc')
331
+ def fptrunc(self, typ):
332
+ """
333
+ Floating-point downcast to a less precise type.
334
+ """
335
+
336
+ @_castop('fpext')
337
+ def fpext(self, typ):
338
+ """
339
+ Floating-point upcast to a more precise type.
340
+ """
341
+
342
+ @_castop('bitcast')
343
+ def bitcast(self, typ):
344
+ """
345
+ Pointer cast to a different pointer type.
346
+ """
347
+
348
+ @_castop('fptoui')
349
+ def fptoui(self, typ):
350
+ """
351
+ Convert floating-point to unsigned integer.
352
+ """
353
+
354
+ @_castop('uitofp')
355
+ def uitofp(self, typ):
356
+ """
357
+ Convert unsigned integer to floating-point.
358
+ """
359
+
360
+ @_castop('fptosi')
361
+ def fptosi(self, typ):
362
+ """
363
+ Convert floating-point to signed integer.
364
+ """
365
+
366
+ @_castop('sitofp')
367
+ def sitofp(self, typ):
368
+ """
369
+ Convert signed integer to floating-point.
370
+ """
371
+
372
+ @_castop('ptrtoint')
373
+ def ptrtoint(self, typ):
374
+ """
375
+ Cast pointer to integer.
376
+ """
377
+ if not isinstance(self.type, types.PointerType):
378
+ msg = "can only call ptrtoint() on pointer type, not '%s'"
379
+ raise TypeError(msg % (self.type,))
380
+ if not isinstance(typ, types.IntType):
381
+ raise TypeError("can only ptrtoint() to integer type, not '%s'"
382
+ % (typ,))
383
+
384
+ @_castop('inttoptr')
385
+ def inttoptr(self, typ):
386
+ """
387
+ Cast integer to pointer.
388
+ """
389
+ if not isinstance(self.type, types.IntType):
390
+ msg = "can only call inttoptr() on integer constants, not '%s'"
391
+ raise TypeError(msg % (self.type,))
392
+ if not isinstance(typ, types.PointerType):
393
+ raise TypeError("can only inttoptr() to pointer type, not '%s'"
394
+ % (typ,))
395
+
396
+ def gep(self, indices):
397
+ """
398
+ Call getelementptr on this pointer constant.
399
+ """
400
+ if not isinstance(self.type, types.PointerType):
401
+ raise TypeError("can only call gep() on pointer constants, not '%s'"
402
+ % (self.type,))
403
+
404
+ outtype = self.type
405
+ for i in indices:
406
+ outtype = outtype.gep(i)
407
+
408
+ strindices = ["{0} {1}".format(idx.type, idx.get_reference())
409
+ for idx in indices]
410
+
411
+ op = "getelementptr ({0}, {1} {2}, {3})".format(
412
+ self.type.pointee, self.type,
413
+ self.get_reference(), ', '.join(strindices))
414
+ return FormattedConstant(outtype.as_pointer(self.addrspace), op)
415
+
416
+
417
+ class Value(object):
418
+ """
419
+ The base class for all values.
420
+ """
421
+
422
+ def __repr__(self):
423
+ return "<ir.%s type='%s' ...>" % (self.__class__.__name__, self.type,)
424
+
425
+
426
+ class _Undefined(object):
427
+ """
428
+ 'undef': a value for undefined values.
429
+ """
430
+ def __new__(cls):
431
+ try:
432
+ return Undefined
433
+ except NameError:
434
+ return object.__new__(_Undefined)
435
+
436
+
437
+ Undefined = _Undefined()
438
+
439
+
440
+ class Constant(_StrCaching, _StringReferenceCaching, _ConstOpMixin, Value):
441
+ """
442
+ A constant LLVM value.
443
+ """
444
+
445
+ def __init__(self, typ, constant):
446
+ assert isinstance(typ, types.Type)
447
+ assert not isinstance(typ, types.VoidType)
448
+ self.type = typ
449
+ constant = typ.wrap_constant_value(constant)
450
+ self.constant = constant
451
+
452
+ def _to_string(self):
453
+ return '{0} {1}'.format(self.type, self.get_reference())
454
+
455
+ def _get_reference(self):
456
+ if self.constant is None:
457
+ val = self.type.null
458
+
459
+ elif self.constant is Undefined:
460
+ val = "undef"
461
+
462
+ elif isinstance(self.constant, bytearray):
463
+ val = 'c"{0}"'.format(_escape_string(self.constant))
464
+
465
+ else:
466
+ val = self.type.format_constant(self.constant)
467
+
468
+ return val
469
+
470
+ @classmethod
471
+ def literal_array(cls, elems):
472
+ """
473
+ Construct a literal array constant made of the given members.
474
+ """
475
+ tys = [el.type for el in elems]
476
+ if len(tys) == 0:
477
+ raise ValueError("need at least one element")
478
+ ty = tys[0]
479
+ for other in tys:
480
+ if ty != other:
481
+ raise TypeError("all elements must have the same type")
482
+ return cls(types.ArrayType(ty, len(elems)), elems)
483
+
484
+ @classmethod
485
+ def literal_struct(cls, elems, packed=False):
486
+ """
487
+ Construct a literal structure constant made of the given members.
488
+ """
489
+ tys = [el.type for el in elems]
490
+ return cls(types.LiteralStructType(tys, packed), elems)
491
+
492
+ @property
493
+ def addrspace(self):
494
+ if not isinstance(self.type, types.PointerType):
495
+ raise TypeError("Only pointer constant have address spaces")
496
+ return self.type.addrspace
497
+
498
+ def __eq__(self, other):
499
+ if isinstance(other, Constant):
500
+ return str(self) == str(other)
501
+ else:
502
+ return False
503
+
504
+ def __ne__(self, other):
505
+ return not self.__eq__(other)
506
+
507
+ def __hash__(self):
508
+ return hash(str(self))
509
+
510
+ def __repr__(self):
511
+ return "<ir.Constant type='%s' value=%r>" % (self.type, self.constant)
512
+
513
+
514
+ class FormattedConstant(Constant):
515
+ """
516
+ A constant with an already formatted IR representation.
517
+ """
518
+
519
+ def __init__(self, typ, constant):
520
+ assert isinstance(constant, str)
521
+ Constant.__init__(self, typ, constant)
522
+
523
+ def _to_string(self):
524
+ return self.constant
525
+
526
+ def _get_reference(self):
527
+ return self.constant
528
+
529
+
530
+ class NamedValue(_StrCaching, _StringReferenceCaching, Value):
531
+ """
532
+ The base class for named values.
533
+ """
534
+ name_prefix = '%'
535
+ deduplicate_name = True
536
+
537
+ def __init__(self, parent, type, name):
538
+ assert parent is not None
539
+ assert isinstance(type, types.Type)
540
+ self.parent = parent
541
+ self.type = type
542
+ self._set_name(name)
543
+
544
+ def _to_string(self):
545
+ buf = []
546
+ if not isinstance(self.type, types.VoidType):
547
+ buf.append("{0} = ".format(self.get_reference()))
548
+ self.descr(buf)
549
+ return "".join(buf).rstrip()
550
+
551
+ def descr(self, buf):
552
+ raise NotImplementedError
553
+
554
+ def _get_name(self):
555
+ return self._name
556
+
557
+ def _set_name(self, name):
558
+ name = self.parent.scope.register(name,
559
+ deduplicate=self.deduplicate_name)
560
+ self._name = name
561
+
562
+ name = property(_get_name, _set_name)
563
+
564
+ def _get_reference(self):
565
+ name = self.name
566
+ # Quote and escape value name
567
+ if '\\' in name or '"' in name:
568
+ name = name.replace('\\', '\\5c').replace('"', '\\22')
569
+ return '{0}"{1}"'.format(self.name_prefix, name)
570
+
571
+ def __repr__(self):
572
+ return "<ir.%s %r of type '%s'>" % (
573
+ self.__class__.__name__, self.name, self.type)
574
+
575
+ @property
576
+ def function_type(self):
577
+ ty = self.type
578
+ if isinstance(ty, types.PointerType):
579
+ ty = self.type.pointee
580
+ if isinstance(ty, types.FunctionType):
581
+ return ty
582
+ else:
583
+ raise TypeError("Not a function: {0}".format(self.type))
584
+
585
+
586
+ class MetaDataString(NamedValue):
587
+ """
588
+ A metadata string, i.e. a constant string used as a value in a metadata
589
+ node.
590
+ """
591
+
592
+ def __init__(self, parent, string):
593
+ super(MetaDataString, self).__init__(parent,
594
+ types.MetaDataType(),
595
+ name="")
596
+ self.string = string
597
+
598
+ def descr(self, buf):
599
+ buf += (self.get_reference(), "\n")
600
+
601
+ def _get_reference(self):
602
+ return '!"{0}"'.format(_escape_string(self.string))
603
+
604
+ _to_string = _get_reference
605
+
606
+ def __eq__(self, other):
607
+ if isinstance(other, MetaDataString):
608
+ return self.string == other.string
609
+ else:
610
+ return False
611
+
612
+ def __ne__(self, other):
613
+ return not self.__eq__(other)
614
+
615
+ def __hash__(self):
616
+ return hash(self.string)
617
+
618
+
619
+ class MetaDataArgument(_StrCaching, _StringReferenceCaching, Value):
620
+ """
621
+ An argument value to a function taking metadata arguments.
622
+ This can wrap any other kind of LLVM value.
623
+
624
+ Do not instantiate directly, Builder.call() will create these
625
+ automatically.
626
+ """
627
+
628
+ def __init__(self, value):
629
+ assert isinstance(value, Value)
630
+ assert not isinstance(value.type, types.MetaDataType)
631
+ self.type = types.MetaDataType()
632
+ self.wrapped_value = value
633
+
634
+ def _get_reference(self):
635
+ # e.g. "i32* %2"
636
+ return "{0} {1}".format(self.wrapped_value.type,
637
+ self.wrapped_value.get_reference())
638
+
639
+ _to_string = _get_reference
640
+
641
+
642
+ class NamedMetaData(object):
643
+ """
644
+ A named metadata node.
645
+
646
+ Do not instantiate directly, use Module.add_named_metadata() instead.
647
+ """
648
+
649
+ def __init__(self, parent):
650
+ self.parent = parent
651
+ self.operands = []
652
+
653
+ def add(self, md):
654
+ self.operands.append(md)
655
+
656
+
657
+ class MDValue(NamedValue):
658
+ """
659
+ A metadata node's value, consisting of a sequence of elements ("operands").
660
+
661
+ Do not instantiate directly, use Module.add_metadata() instead.
662
+ """
663
+ name_prefix = '!'
664
+
665
+ def __init__(self, parent, values, name):
666
+ super(MDValue, self).__init__(parent,
667
+ types.MetaDataType(),
668
+ name=name)
669
+ self.operands = tuple(values)
670
+ parent.metadata.append(self)
671
+
672
+ def descr(self, buf):
673
+ operands = []
674
+ for op in self.operands:
675
+ if isinstance(op.type, types.MetaDataType):
676
+ if isinstance(op, Constant) and op.constant is None:
677
+ operands.append("null")
678
+ else:
679
+ operands.append(op.get_reference())
680
+ else:
681
+ operands.append("{0} {1}".format(op.type, op.get_reference()))
682
+ operands = ', '.join(operands)
683
+ buf += ("!{{ {0} }}".format(operands), "\n")
684
+
685
+ def _get_reference(self):
686
+ return self.name_prefix + str(self.name)
687
+
688
+ def __eq__(self, other):
689
+ if isinstance(other, MDValue):
690
+ return self.operands == other.operands
691
+ else:
692
+ return False
693
+
694
+ def __ne__(self, other):
695
+ return not self.__eq__(other)
696
+
697
+ def __hash__(self):
698
+ return hash(self.operands)
699
+
700
+
701
+ class DIToken:
702
+ """
703
+ A debug information enumeration value that should appear bare in
704
+ the emitted metadata.
705
+
706
+ Use this to wrap known constants, e.g. the DW_* enumerations.
707
+ """
708
+
709
+ def __init__(self, value):
710
+ self.value = value
711
+
712
+
713
+ class DIValue(NamedValue):
714
+ """
715
+ A debug information descriptor, containing key-value pairs.
716
+
717
+ Do not instantiate directly, use Module.add_debug_info() instead.
718
+ """
719
+ name_prefix = '!'
720
+
721
+ def __init__(self, parent, is_distinct, kind, operands, name):
722
+ super(DIValue, self).__init__(parent,
723
+ types.MetaDataType(),
724
+ name=name)
725
+ self.is_distinct = is_distinct
726
+ self.kind = kind
727
+ self.operands = tuple(operands)
728
+ parent.metadata.append(self)
729
+
730
+ def descr(self, buf):
731
+ if self.is_distinct:
732
+ buf += ("distinct ",)
733
+ operands = []
734
+ for key, value in self.operands:
735
+ if value is None:
736
+ strvalue = "null"
737
+ elif value is True:
738
+ strvalue = "true"
739
+ elif value is False:
740
+ strvalue = "false"
741
+ elif isinstance(value, DIToken):
742
+ strvalue = value.value
743
+ elif isinstance(value, str):
744
+ strvalue = '"{}"'.format(_escape_string(value))
745
+ elif isinstance(value, int):
746
+ strvalue = str(value)
747
+ elif isinstance(value, NamedValue):
748
+ strvalue = value.get_reference()
749
+ else:
750
+ raise TypeError("invalid operand type for debug info: %r"
751
+ % (value,))
752
+ operands.append("{0}: {1}".format(key, strvalue))
753
+ operands = ', '.join(operands)
754
+ buf += ("!", self.kind, "(", operands, ")\n")
755
+
756
+ def _get_reference(self):
757
+ return self.name_prefix + str(self.name)
758
+
759
+ def __eq__(self, other):
760
+ if isinstance(other, DIValue):
761
+ return self.is_distinct == other.is_distinct and \
762
+ self.kind == other.kind and \
763
+ self.operands == other.operands
764
+ else:
765
+ return False
766
+
767
+ def __ne__(self, other):
768
+ return not self.__eq__(other)
769
+
770
+ def __hash__(self):
771
+ return hash((self.is_distinct, self.kind, self.operands))
772
+
773
+
774
+ class GlobalValue(NamedValue, _ConstOpMixin, _HasMetadata):
775
+ """
776
+ A global value.
777
+ """
778
+ name_prefix = '@'
779
+ deduplicate_name = False
780
+
781
+ def __init__(self, *args, **kwargs):
782
+ super(GlobalValue, self).__init__(*args, **kwargs)
783
+ self.linkage = ''
784
+ self.storage_class = ''
785
+ self.section = ''
786
+ self.metadata = {}
787
+
788
+
789
+ class GlobalVariable(GlobalValue):
790
+ """
791
+ A global variable.
792
+ """
793
+
794
+ def __init__(self, module, typ, name, addrspace=0):
795
+ assert isinstance(typ, types.Type)
796
+ super(GlobalVariable, self).__init__(module, typ.as_pointer(addrspace),
797
+ name=name)
798
+ self.value_type = typ
799
+ self.initializer = None
800
+ self.unnamed_addr = False
801
+ self.global_constant = False
802
+ self.addrspace = addrspace
803
+ self.align = None
804
+ self.parent.add_global(self)
805
+
806
+ def descr(self, buf):
807
+ if self.global_constant:
808
+ kind = 'constant'
809
+ else:
810
+ kind = 'global'
811
+
812
+ if not self.linkage:
813
+ # Default to external linkage
814
+ linkage = 'external' if self.initializer is None else ''
815
+ else:
816
+ linkage = self.linkage
817
+
818
+ if linkage:
819
+ buf.append(linkage + " ")
820
+ if self.storage_class:
821
+ buf.append(self.storage_class + " ")
822
+ if self.unnamed_addr:
823
+ buf.append("unnamed_addr ")
824
+ if self.addrspace != 0:
825
+ buf.append('addrspace({0:d}) '.format(self.addrspace))
826
+
827
+ buf.append("{kind} {type}" .format(kind=kind, type=self.value_type))
828
+
829
+ if self.initializer is not None:
830
+ if self.initializer.type != self.value_type:
831
+ raise TypeError("got initializer of type %s "
832
+ "for global value type %s"
833
+ % (self.initializer.type, self.value_type))
834
+ buf.append(" " + self.initializer.get_reference())
835
+ elif linkage not in ('external', 'extern_weak'):
836
+ # emit 'undef' for non-external linkage GV
837
+ buf.append(" " + self.value_type(Undefined).get_reference())
838
+
839
+ if self.section:
840
+ buf.append(", section \"%s\"" % (self.section,))
841
+
842
+ if self.align is not None:
843
+ buf.append(", align %d" % (self.align,))
844
+
845
+ if self.metadata:
846
+ buf.append(self._stringify_metadata(leading_comma=True))
847
+
848
+ buf.append("\n")
849
+
850
+
851
+ class AttributeSet(set):
852
+ """A set of string attribute.
853
+ Only accept items listed in *_known*.
854
+
855
+ Properties:
856
+ * Iterate in sorted order
857
+ """
858
+ _known = ()
859
+
860
+ def __init__(self, args=()):
861
+ super().__init__()
862
+ if isinstance(args, str):
863
+ args = [args]
864
+ for name in args:
865
+ self.add(name)
866
+
867
+ def _expand(self, name, typ):
868
+ return name
869
+
870
+ def add(self, name):
871
+ if name not in self._known:
872
+ raise ValueError('unknown attr {!r} for {}'.format(name, self))
873
+ return super(AttributeSet, self).add(name)
874
+
875
+ def _to_list(self, typ):
876
+ return [self._expand(i, typ) for i in sorted(self)]
877
+
878
+
879
+ class FunctionAttributes(AttributeSet):
880
+ _known = frozenset([
881
+ 'argmemonly', 'alwaysinline', 'builtin', 'cold', 'convergent',
882
+ 'inaccessiblememonly', 'inaccessiblemem_or_argmemonly', 'inlinehint',
883
+ 'jumptable', 'minsize', 'naked', 'nobuiltin', 'noduplicate',
884
+ 'noimplicitfloat', 'noinline', 'nonlazybind', 'norecurse',
885
+ 'noredzone', 'noreturn', 'nounwind', 'optnone', 'optsize',
886
+ 'readnone', 'readonly', 'returns_twice', 'sanitize_address',
887
+ 'sanitize_memory', 'sanitize_thread', 'ssp',
888
+ 'sspreg', 'sspstrong', 'uwtable'])
889
+
890
+ def __init__(self, args=()):
891
+ self._alignstack = 0
892
+ self._personality = None
893
+ super(FunctionAttributes, self).__init__(args)
894
+
895
+ def add(self, name):
896
+ if ((name == 'alwaysinline' and 'noinline' in self) or
897
+ (name == 'noinline' and 'alwaysinline' in self)):
898
+ raise ValueError("Can't have alwaysinline and noinline")
899
+
900
+ super().add(name)
901
+
902
+ @property
903
+ def alignstack(self):
904
+ return self._alignstack
905
+
906
+ @alignstack.setter
907
+ def alignstack(self, val):
908
+ assert val >= 0
909
+ self._alignstack = val
910
+
911
+ @property
912
+ def personality(self):
913
+ return self._personality
914
+
915
+ @personality.setter
916
+ def personality(self, val):
917
+ assert val is None or isinstance(val, GlobalValue)
918
+ self._personality = val
919
+
920
+ def _to_list(self, ret_type):
921
+ attrs = super()._to_list(ret_type)
922
+ if self.alignstack:
923
+ attrs.append('alignstack({0:d})'.format(self.alignstack))
924
+ if self.personality:
925
+ attrs.append('personality {persty} {persfn}'.format(
926
+ persty=self.personality.type,
927
+ persfn=self.personality.get_reference()))
928
+ return attrs
929
+
930
+
931
+ class Function(GlobalValue):
932
+ """Represent a LLVM Function but does uses a Module as parent.
933
+ Global Values are stored as a set of dependencies (attribute `depends`).
934
+ """
935
+
936
+ def __init__(self, module, ftype, name):
937
+ assert isinstance(ftype, types.Type)
938
+ super(Function, self).__init__(module, ftype.as_pointer(), name=name)
939
+ self.ftype = ftype
940
+ self.scope = _utils.NameScope()
941
+ self.blocks = []
942
+ self.attributes = FunctionAttributes()
943
+ self.args = tuple([Argument(self, t)
944
+ for t in ftype.args])
945
+ self.return_value = ReturnValue(self, ftype.return_type)
946
+ self.parent.add_global(self)
947
+ self.calling_convention = ''
948
+
949
+ @property
950
+ def module(self):
951
+ return self.parent
952
+
953
+ @property
954
+ def entry_basic_block(self):
955
+ return self.blocks[0]
956
+
957
+ @property
958
+ def basic_blocks(self):
959
+ return self.blocks
960
+
961
+ def append_basic_block(self, name=''):
962
+ blk = Block(parent=self, name=name)
963
+ self.blocks.append(blk)
964
+ return blk
965
+
966
+ def insert_basic_block(self, before, name=''):
967
+ """Insert block before
968
+ """
969
+ blk = Block(parent=self, name=name)
970
+ self.blocks.insert(before, blk)
971
+ return blk
972
+
973
+ def descr_prototype(self, buf):
974
+ """
975
+ Describe the prototype ("head") of the function.
976
+ """
977
+ state = "define" if self.blocks else "declare"
978
+ ret = self.return_value
979
+ args = ", ".join(str(a) for a in self.args)
980
+ name = self.get_reference()
981
+ attrs = ' ' + ' '.join(self.attributes._to_list(
982
+ self.ftype.return_type)) if self.attributes else ''
983
+ if any(self.args):
984
+ vararg = ', ...' if self.ftype.var_arg else ''
985
+ else:
986
+ vararg = '...' if self.ftype.var_arg else ''
987
+ linkage = self.linkage
988
+ cconv = self.calling_convention
989
+ prefix = " ".join(str(x) for x in [state, linkage, cconv, ret] if x)
990
+ metadata = self._stringify_metadata()
991
+ metadata = ' {}'.format(metadata) if metadata else ''
992
+ section = ' section "{}"'.format(self.section) if self.section else ''
993
+ pt_str = "{prefix} {name}({args}{vararg}){attrs}{section}{metadata}\n"
994
+ prototype = pt_str.format(prefix=prefix, name=name, args=args,
995
+ vararg=vararg, attrs=attrs, section=section,
996
+ metadata=metadata)
997
+ buf.append(prototype)
998
+
999
+ def descr_body(self, buf):
1000
+ """
1001
+ Describe of the body of the function.
1002
+ """
1003
+ for blk in self.blocks:
1004
+ blk.descr(buf)
1005
+
1006
+ def descr(self, buf):
1007
+ self.descr_prototype(buf)
1008
+ if self.blocks:
1009
+ buf.append("{\n")
1010
+ self.descr_body(buf)
1011
+ buf.append("}\n")
1012
+
1013
+ def __str__(self):
1014
+ buf = []
1015
+ self.descr(buf)
1016
+ return "".join(buf)
1017
+
1018
+ @property
1019
+ def is_declaration(self):
1020
+ return len(self.blocks) == 0
1021
+
1022
+
1023
+ class ArgumentAttributes(AttributeSet):
1024
+ # List from
1025
+ # https://releases.llvm.org/14.0.0/docs/LangRef.html#parameter-attributes
1026
+ _known = MappingProxyType({
1027
+ # True (emit type),
1028
+ # False (emit name only)
1029
+ 'byref': True,
1030
+ 'byval': True,
1031
+ 'elementtype': True,
1032
+ 'immarg': False,
1033
+ 'inalloca': True,
1034
+ 'inreg': False,
1035
+ 'nest': False,
1036
+ 'noalias': False,
1037
+ 'nocapture': False,
1038
+ 'nofree': False,
1039
+ 'nonnull': False,
1040
+ 'noundef': False,
1041
+ 'preallocated': True,
1042
+ 'returned': False,
1043
+ 'signext': False,
1044
+ 'sret': True,
1045
+ 'swiftasync': False,
1046
+ 'swifterror': False,
1047
+ 'swiftself': False,
1048
+ 'zeroext': False,
1049
+ })
1050
+
1051
+ def __init__(self, args=()):
1052
+ self._align = 0
1053
+ self._dereferenceable = 0
1054
+ self._dereferenceable_or_null = 0
1055
+ super(ArgumentAttributes, self).__init__(args)
1056
+
1057
+ def _expand(self, name, typ):
1058
+ requires_type = self._known.get(name)
1059
+ if requires_type:
1060
+ return f"{name}({typ.pointee})"
1061
+ else:
1062
+ return name
1063
+
1064
+ @property
1065
+ def align(self):
1066
+ return self._align
1067
+
1068
+ @align.setter
1069
+ def align(self, val):
1070
+ assert isinstance(val, int) and val >= 0
1071
+ self._align = val
1072
+
1073
+ @property
1074
+ def dereferenceable(self):
1075
+ return self._dereferenceable
1076
+
1077
+ @dereferenceable.setter
1078
+ def dereferenceable(self, val):
1079
+ assert isinstance(val, int) and val >= 0
1080
+ self._dereferenceable = val
1081
+
1082
+ @property
1083
+ def dereferenceable_or_null(self):
1084
+ return self._dereferenceable_or_null
1085
+
1086
+ @dereferenceable_or_null.setter
1087
+ def dereferenceable_or_null(self, val):
1088
+ assert isinstance(val, int) and val >= 0
1089
+ self._dereferenceable_or_null = val
1090
+
1091
+ def _to_list(self, typ):
1092
+ attrs = super()._to_list(typ)
1093
+ if self.align:
1094
+ attrs.append('align {0:d}'.format(self.align))
1095
+ if self.dereferenceable:
1096
+ attrs.append('dereferenceable({0:d})'.format(self.dereferenceable))
1097
+ if self.dereferenceable_or_null:
1098
+ dref = 'dereferenceable_or_null({0:d})'
1099
+ attrs.append(dref.format(self.dereferenceable_or_null))
1100
+ return attrs
1101
+
1102
+
1103
+ class _BaseArgument(NamedValue):
1104
+ def __init__(self, parent, typ, name=''):
1105
+ assert isinstance(typ, types.Type)
1106
+ super(_BaseArgument, self).__init__(parent, typ, name=name)
1107
+ self.parent = parent
1108
+ self.attributes = ArgumentAttributes()
1109
+
1110
+ def __repr__(self):
1111
+ return "<ir.%s %r of type %s>" % (self.__class__.__name__, self.name,
1112
+ self.type)
1113
+
1114
+ def add_attribute(self, attr):
1115
+ self.attributes.add(attr)
1116
+
1117
+
1118
+ class Argument(_BaseArgument):
1119
+ """
1120
+ The specification of a function argument.
1121
+ """
1122
+
1123
+ def __str__(self):
1124
+ attrs = self.attributes._to_list(self.type)
1125
+ if attrs:
1126
+ return "{0} {1} {2}".format(self.type, ' '.join(attrs),
1127
+ self.get_reference())
1128
+ else:
1129
+ return "{0} {1}".format(self.type, self.get_reference())
1130
+
1131
+
1132
+ class ReturnValue(_BaseArgument):
1133
+ """
1134
+ The specification of a function's return value.
1135
+ """
1136
+
1137
+ def __str__(self):
1138
+ attrs = self.attributes._to_list(self.type)
1139
+ if attrs:
1140
+ return "{0} {1}".format(' '.join(attrs), self.type)
1141
+ else:
1142
+ return str(self.type)
1143
+
1144
+
1145
+ class Block(NamedValue):
1146
+ """
1147
+ A LLVM IR basic block. A basic block is a sequence of
1148
+ instructions whose execution always goes from start to end. That
1149
+ is, a control flow instruction (branch) can only appear as the
1150
+ last instruction, and incoming branches can only jump to the first
1151
+ instruction.
1152
+ """
1153
+
1154
+ def __init__(self, parent, name=''):
1155
+ super(Block, self).__init__(parent, types.LabelType(), name=name)
1156
+ self.scope = parent.scope
1157
+ self.instructions = []
1158
+ self.terminator = None
1159
+
1160
+ @property
1161
+ def is_terminated(self):
1162
+ return self.terminator is not None
1163
+
1164
+ @property
1165
+ def function(self):
1166
+ return self.parent
1167
+
1168
+ @property
1169
+ def module(self):
1170
+ return self.parent.module
1171
+
1172
+ def descr(self, buf):
1173
+ buf.append("{0}:\n".format(self._format_name()))
1174
+ buf += [" {0}\n".format(instr) for instr in self.instructions]
1175
+
1176
+ def replace(self, old, new):
1177
+ """Replace an instruction"""
1178
+ if old.type != new.type:
1179
+ raise TypeError("new instruction has a different type")
1180
+ pos = self.instructions.index(old)
1181
+ self.instructions.remove(old)
1182
+ self.instructions.insert(pos, new)
1183
+
1184
+ for bb in self.parent.basic_blocks:
1185
+ for instr in bb.instructions:
1186
+ instr.replace_usage(old, new)
1187
+
1188
+ def _format_name(self):
1189
+ # Per the LLVM Language Ref on identifiers, names matching the following
1190
+ # regex do not need to be quoted: [%@][-a-zA-Z$._][-a-zA-Z$._0-9]*
1191
+ # Otherwise, the identifier must be quoted and escaped.
1192
+ name = self.name
1193
+ if not _SIMPLE_IDENTIFIER_RE.match(name):
1194
+ name = name.replace('\\', '\\5c').replace('"', '\\22')
1195
+ name = '"{0}"'.format(name)
1196
+ return name
1197
+
1198
+
1199
+ class BlockAddress(Value):
1200
+ """
1201
+ The address of a basic block.
1202
+ """
1203
+
1204
+ def __init__(self, function, basic_block):
1205
+ assert isinstance(function, Function)
1206
+ assert isinstance(basic_block, Block)
1207
+ self.type = types.IntType(8).as_pointer()
1208
+ self.function = function
1209
+ self.basic_block = basic_block
1210
+
1211
+ def __str__(self):
1212
+ return '{0} {1}'.format(self.type, self.get_reference())
1213
+
1214
+ def get_reference(self):
1215
+ return "blockaddress({0}, {1})".format(
1216
+ self.function.get_reference(),
1217
+ self.basic_block.get_reference())