llvmlite 0.46.0b1__cp312-cp312-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
@@ -0,0 +1,574 @@
1
+ import unittest
2
+ from collections import defaultdict
3
+ from llvmlite import ir
4
+ from llvmlite import binding as llvm
5
+ from llvmlite.tests import TestCase
6
+
7
+ import llvmlite.tests.refprune_proto as proto
8
+
9
+
10
+ def _iterate_cases(generate_test):
11
+ def wrap(fn):
12
+ def wrapped(self):
13
+ return generate_test(self, fn)
14
+ wrapped.__doc__ = f"generated test for {fn.__module__}.{fn.__name__}"
15
+ return wrapped
16
+
17
+ for k, case_fn in proto.__dict__.items():
18
+ if k.startswith('case'):
19
+ yield f'test_{k}', wrap(case_fn)
20
+
21
+
22
+ class PassManagerMixin():
23
+
24
+ def pb(self):
25
+ llvm.initialize_native_target()
26
+ tm = llvm.Target.from_default_triple().create_target_machine()
27
+ pto = llvm.create_pipeline_tuning_options(speed_level=0, size_level=0)
28
+ return llvm.create_pass_builder(tm, pto)
29
+
30
+
31
+ class TestRefPrunePrototype(TestCase):
32
+ """
33
+ Test that the prototype is working.
34
+ """
35
+ def generate_test(self, case_gen):
36
+ nodes, edges, expected = case_gen()
37
+ got = proto.FanoutAlgorithm(nodes, edges).run()
38
+ self.assertEqual(expected, got)
39
+
40
+ # Generate tests
41
+ for name, case in _iterate_cases(generate_test):
42
+ locals()[name] = case
43
+
44
+
45
+ ptr_ty = ir.IntType(8).as_pointer()
46
+
47
+
48
+ class TestRefPrunePass(TestCase, PassManagerMixin):
49
+ """
50
+ Test that the C++ implementation matches the expected behavior as for
51
+ the prototype.
52
+
53
+ This generates a LLVM module for each test case, runs the pruner and checks
54
+ that the expected results are achieved.
55
+ """
56
+
57
+ def make_incref(self, m):
58
+ fnty = ir.FunctionType(ir.VoidType(), [ptr_ty])
59
+ return ir.Function(m, fnty, name='NRT_incref')
60
+
61
+ def make_decref(self, m):
62
+ fnty = ir.FunctionType(ir.VoidType(), [ptr_ty])
63
+ return ir.Function(m, fnty, name='NRT_decref')
64
+
65
+ def make_switcher(self, m):
66
+ fnty = ir.FunctionType(ir.IntType(32), ())
67
+ return ir.Function(m, fnty, name='switcher')
68
+
69
+ def make_brancher(self, m):
70
+ fnty = ir.FunctionType(ir.IntType(1), ())
71
+ return ir.Function(m, fnty, name='brancher')
72
+
73
+ def generate_ir(self, nodes, edges):
74
+ # Build LLVM module for the CFG
75
+ m = ir.Module()
76
+
77
+ incref_fn = self.make_incref(m)
78
+ decref_fn = self.make_decref(m)
79
+ switcher_fn = self.make_switcher(m)
80
+ brancher_fn = self.make_brancher(m)
81
+
82
+ fnty = ir.FunctionType(ir.VoidType(), [ptr_ty])
83
+ fn = ir.Function(m, fnty, name='main')
84
+ [ptr] = fn.args
85
+ ptr.name = 'mem'
86
+ # populate the BB nodes
87
+ bbmap = {}
88
+ for bb in edges:
89
+ bbmap[bb] = fn.append_basic_block(bb)
90
+ # populate the BB
91
+ builder = ir.IRBuilder()
92
+ for bb, jump_targets in edges.items():
93
+ builder.position_at_end(bbmap[bb])
94
+ # Insert increfs and decrefs
95
+ for action in nodes[bb]:
96
+ if action == 'incref':
97
+ builder.call(incref_fn, [ptr])
98
+ elif action == 'decref':
99
+ builder.call(decref_fn, [ptr])
100
+ else:
101
+ raise AssertionError('unreachable')
102
+
103
+ # Insert the terminator.
104
+ # Switch base on the number of jump targets.
105
+ n_targets = len(jump_targets)
106
+ if n_targets == 0:
107
+ builder.ret_void()
108
+ elif n_targets == 1:
109
+ [dst] = jump_targets
110
+ builder.branch(bbmap[dst])
111
+ elif n_targets == 2:
112
+ [left, right] = jump_targets
113
+ sel = builder.call(brancher_fn, ())
114
+ builder.cbranch(sel, bbmap[left], bbmap[right])
115
+ elif n_targets > 2:
116
+ sel = builder.call(switcher_fn, ())
117
+ [head, *tail] = jump_targets
118
+
119
+ sw = builder.switch(sel, default=bbmap[head])
120
+ for i, dst in enumerate(tail):
121
+ sw.add_case(sel.type(i), bbmap[dst])
122
+ else:
123
+ raise AssertionError('unreachable')
124
+
125
+ return m
126
+
127
+ def apply_refprune(self, irmod):
128
+ mod = llvm.parse_assembly(str(irmod))
129
+ pb = self.pb()
130
+ pm = pb.getModulePassManager()
131
+ pm.add_refprune_pass()
132
+ pm.run(mod, pb)
133
+ return mod
134
+
135
+ def check(self, mod, expected, nodes):
136
+ # preprocess incref/decref locations
137
+
138
+ # LLVM >= 18 adds an extra empty block "LoopExit" which causes
139
+ # regular dict to throw KeyError
140
+ d = defaultdict(lambda: defaultdict(int))
141
+
142
+ for k, vs in nodes.items():
143
+ n_incref = vs.count('incref')
144
+ n_decref = vs.count('decref')
145
+ d[k] = {'incref': n_incref, 'decref': n_decref}
146
+ for k, stats in d.items():
147
+ if expected.get(k):
148
+ stats['incref'] -= 1
149
+ for dec_bb in expected[k]:
150
+ d[dec_bb]['decref'] -= 1
151
+
152
+ # find the main function
153
+ for f in mod.functions:
154
+ if f.name == 'main':
155
+ break
156
+
157
+ # check each BB
158
+ for bb in f.blocks:
159
+ stats = d[bb.name]
160
+ text = str(bb)
161
+ n_incref = text.count('NRT_incref')
162
+ n_decref = text.count('NRT_decref')
163
+ self.assertEqual(stats['incref'], n_incref, msg=f'BB {bb}')
164
+ self.assertEqual(stats['decref'], n_decref, msg=f'BB {bb}')
165
+
166
+ def generate_test(self, case_gen):
167
+ nodes, edges, expected = case_gen()
168
+ irmod = self.generate_ir(nodes, edges)
169
+ outmod = self.apply_refprune(irmod)
170
+ self.check(outmod, expected, nodes)
171
+
172
+ # Generate tests
173
+ for name, case in _iterate_cases(generate_test):
174
+ locals()[name] = case
175
+
176
+
177
+ class BaseTestByIR(TestCase, PassManagerMixin):
178
+ refprune_bitmask = 0
179
+
180
+ prologue = r"""
181
+ declare void @NRT_incref(i8* %ptr)
182
+ declare void @NRT_decref(i8* %ptr)
183
+ """
184
+
185
+ def check(self, irmod, subgraph_limit=None):
186
+ mod = llvm.parse_assembly(f"{self.prologue}\n{irmod}")
187
+ pb = self.pb()
188
+ pm = pb.getModulePassManager()
189
+ if subgraph_limit is None:
190
+ pm.add_refprune_pass(self.refprune_bitmask)
191
+ else:
192
+ pm.add_refprune_pass(self.refprune_bitmask,
193
+ subgraph_limit=subgraph_limit)
194
+ before = llvm.dump_refprune_stats()
195
+ pm.run(mod, pb)
196
+ after = llvm.dump_refprune_stats()
197
+ return mod, after - before
198
+
199
+
200
+ class TestPerBB(BaseTestByIR):
201
+ refprune_bitmask = llvm.RefPruneSubpasses.PER_BB
202
+
203
+ per_bb_ir_1 = r"""
204
+ define void @main(i8* %ptr) {
205
+ call void @NRT_incref(i8* %ptr)
206
+ call void @NRT_decref(i8* %ptr)
207
+ ret void
208
+ }
209
+ """
210
+
211
+ def test_per_bb_1(self):
212
+ mod, stats = self.check(self.per_bb_ir_1)
213
+ self.assertEqual(stats.basicblock, 2)
214
+
215
+ per_bb_ir_2 = r"""
216
+ define void @main(i8* %ptr) {
217
+ call void @NRT_incref(i8* %ptr)
218
+ call void @NRT_incref(i8* %ptr)
219
+ call void @NRT_incref(i8* %ptr)
220
+ call void @NRT_decref(i8* %ptr)
221
+ call void @NRT_decref(i8* %ptr)
222
+ ret void
223
+ }
224
+ """
225
+
226
+ def test_per_bb_2(self):
227
+ mod, stats = self.check(self.per_bb_ir_2)
228
+ self.assertEqual(stats.basicblock, 4)
229
+ # not pruned
230
+ self.assertIn("call void @NRT_incref(ptr %ptr)", str(mod))
231
+
232
+ per_bb_ir_3 = r"""
233
+ define void @main(ptr %ptr, ptr %other) {
234
+ call void @NRT_incref(ptr %ptr)
235
+ call void @NRT_incref(ptr %ptr)
236
+ call void @NRT_decref(ptr %ptr)
237
+ call void @NRT_decref(ptr %other)
238
+ ret void
239
+ }
240
+ """
241
+
242
+ def test_per_bb_3(self):
243
+ mod, stats = self.check(self.per_bb_ir_3)
244
+ self.assertEqual(stats.basicblock, 2)
245
+ # not pruned
246
+ self.assertIn("call void @NRT_decref(ptr %other)", str(mod))
247
+
248
+ per_bb_ir_4 = r"""
249
+ ; reordered
250
+ define void @main(ptr %ptr, ptr %other) {
251
+ call void @NRT_incref(ptr %ptr)
252
+ call void @NRT_decref(ptr %ptr)
253
+ call void @NRT_decref(ptr %ptr)
254
+ call void @NRT_decref(ptr %other)
255
+ call void @NRT_incref(ptr %ptr)
256
+ ret void
257
+ }
258
+ """
259
+
260
+ def test_per_bb_4(self):
261
+ mod, stats = self.check(self.per_bb_ir_4)
262
+ self.assertEqual(stats.basicblock, 4)
263
+ # not pruned
264
+ self.assertIn("call void @NRT_decref(ptr %other)", str(mod))
265
+
266
+
267
+ class TestDiamond(BaseTestByIR):
268
+ refprune_bitmask = llvm.RefPruneSubpasses.DIAMOND
269
+
270
+ per_diamond_1 = r"""
271
+ define void @main(i8* %ptr) {
272
+ bb_A:
273
+ call void @NRT_incref(i8* %ptr)
274
+ br label %bb_B
275
+ bb_B:
276
+ call void @NRT_decref(i8* %ptr)
277
+ ret void
278
+ }
279
+ """
280
+
281
+ def test_per_diamond_1(self):
282
+ mod, stats = self.check(self.per_diamond_1)
283
+ self.assertEqual(stats.diamond, 2)
284
+
285
+ per_diamond_2 = r"""
286
+ define void @main(i8* %ptr, i1 %cond) {
287
+ bb_A:
288
+ call void @NRT_incref(i8* %ptr)
289
+ br i1 %cond, label %bb_B, label %bb_C
290
+ bb_B:
291
+ br label %bb_D
292
+ bb_C:
293
+ br label %bb_D
294
+ bb_D:
295
+ call void @NRT_decref(i8* %ptr)
296
+ ret void
297
+ }
298
+ """
299
+
300
+ def test_per_diamond_2(self):
301
+ mod, stats = self.check(self.per_diamond_2)
302
+ self.assertEqual(stats.diamond, 2)
303
+
304
+ per_diamond_3 = r"""
305
+ define void @main(i8* %ptr, i1 %cond) {
306
+ bb_A:
307
+ call void @NRT_incref(i8* %ptr)
308
+ br i1 %cond, label %bb_B, label %bb_C
309
+ bb_B:
310
+ br label %bb_D
311
+ bb_C:
312
+ call void @NRT_decref(i8* %ptr) ; reject because of decref in diamond
313
+ br label %bb_D
314
+ bb_D:
315
+ call void @NRT_decref(i8* %ptr)
316
+ ret void
317
+ }
318
+ """
319
+
320
+ def test_per_diamond_3(self):
321
+ mod, stats = self.check(self.per_diamond_3)
322
+ self.assertEqual(stats.diamond, 0)
323
+
324
+ per_diamond_4 = r"""
325
+ define void @main(i8* %ptr, i1 %cond) {
326
+ bb_A:
327
+ call void @NRT_incref(i8* %ptr)
328
+ br i1 %cond, label %bb_B, label %bb_C
329
+ bb_B:
330
+ call void @NRT_incref(i8* %ptr) ; extra incref will not affect prune
331
+ br label %bb_D
332
+ bb_C:
333
+ br label %bb_D
334
+ bb_D:
335
+ call void @NRT_decref(i8* %ptr)
336
+ ret void
337
+ }
338
+ """
339
+
340
+ def test_per_diamond_4(self):
341
+ mod, stats = self.check(self.per_diamond_4)
342
+ self.assertEqual(stats.diamond, 2)
343
+
344
+ per_diamond_5 = r"""
345
+ define void @main(i8* %ptr, i1 %cond) {
346
+ bb_A:
347
+ call void @NRT_incref(i8* %ptr)
348
+ call void @NRT_incref(i8* %ptr)
349
+ br i1 %cond, label %bb_B, label %bb_C
350
+ bb_B:
351
+ br label %bb_D
352
+ bb_C:
353
+ br label %bb_D
354
+ bb_D:
355
+ call void @NRT_decref(i8* %ptr)
356
+ call void @NRT_decref(i8* %ptr)
357
+ ret void
358
+ }
359
+ """
360
+
361
+ def test_per_diamond_5(self):
362
+ mod, stats = self.check(self.per_diamond_5)
363
+ self.assertEqual(stats.diamond, 4)
364
+
365
+
366
+ class TestFanout(BaseTestByIR):
367
+ """More complex cases are tested in TestRefPrunePass
368
+ """
369
+
370
+ refprune_bitmask = llvm.RefPruneSubpasses.FANOUT
371
+
372
+ fanout_1 = r"""
373
+ define void @main(i8* %ptr, i1 %cond) {
374
+ bb_A:
375
+ call void @NRT_incref(i8* %ptr)
376
+ br i1 %cond, label %bb_B, label %bb_C
377
+ bb_B:
378
+ call void @NRT_decref(i8* %ptr)
379
+ ret void
380
+ bb_C:
381
+ call void @NRT_decref(i8* %ptr)
382
+ ret void
383
+ }
384
+ """
385
+
386
+ def test_fanout_1(self):
387
+ mod, stats = self.check(self.fanout_1)
388
+ self.assertEqual(stats.fanout, 3)
389
+
390
+ fanout_2 = r"""
391
+ define void @main(i8* %ptr, i1 %cond, i8** %excinfo) {
392
+ bb_A:
393
+ call void @NRT_incref(i8* %ptr)
394
+ br i1 %cond, label %bb_B, label %bb_C
395
+ bb_B:
396
+ call void @NRT_decref(i8* %ptr)
397
+ ret void
398
+ bb_C:
399
+ call void @NRT_decref(i8* %ptr)
400
+ br label %bb_B ; illegal jump to other decref
401
+ }
402
+ """
403
+
404
+ def test_fanout_2(self):
405
+ mod, stats = self.check(self.fanout_2)
406
+ self.assertEqual(stats.fanout, 0)
407
+
408
+ fanout_3 = r"""
409
+ define void @main(i8* %ptr, i1 %cond) {
410
+ bb_A:
411
+ call void @NRT_incref(i8* %ptr)
412
+ call void @NRT_incref(i8* %ptr)
413
+ br i1 %cond, label %bb_B, label %bb_C
414
+ bb_B:
415
+ call void @NRT_decref(i8* %ptr)
416
+ call void @NRT_decref(i8* %ptr)
417
+ call void @NRT_decref(i8* %ptr)
418
+ ret void
419
+ bb_C:
420
+ call void @NRT_decref(i8* %ptr)
421
+ call void @NRT_decref(i8* %ptr)
422
+ ret void
423
+ }
424
+ """
425
+
426
+ def test_fanout_3(self):
427
+ mod, stats = self.check(self.fanout_3)
428
+ self.assertEqual(stats.fanout, 6)
429
+
430
+ def test_fanout_3_limited(self):
431
+ # With subgraph limit at 1, it is essentially turning off the fanout
432
+ # pruner.
433
+ mod, stats = self.check(self.fanout_3, subgraph_limit=1)
434
+ self.assertEqual(stats.fanout, 0)
435
+
436
+
437
+ class TestFanoutRaise(BaseTestByIR):
438
+ refprune_bitmask = llvm.RefPruneSubpasses.FANOUT_RAISE
439
+
440
+ fanout_raise_1 = r"""
441
+ define i32 @main(i8* %ptr, i1 %cond, i8** %excinfo) {
442
+ bb_A:
443
+ call void @NRT_incref(i8* %ptr)
444
+ br i1 %cond, label %bb_B, label %bb_C
445
+ bb_B:
446
+ call void @NRT_decref(i8* %ptr)
447
+ ret i32 0
448
+ bb_C:
449
+ store i8* null, i8** %excinfo, !numba_exception_output !0
450
+ ret i32 1
451
+ }
452
+ !0 = !{i1 true}
453
+ """
454
+
455
+ def test_fanout_raise_1(self):
456
+ mod, stats = self.check(self.fanout_raise_1)
457
+ self.assertEqual(stats.fanout_raise, 2)
458
+
459
+ fanout_raise_2 = r"""
460
+ define i32 @main(i8* %ptr, i1 %cond, i8** %excinfo) {
461
+ bb_A:
462
+ call void @NRT_incref(i8* %ptr)
463
+ br i1 %cond, label %bb_B, label %bb_C
464
+ bb_B:
465
+ call void @NRT_decref(i8* %ptr)
466
+ ret i32 0
467
+ bb_C:
468
+ store i8* null, i8** %excinfo, !numba_exception_typo !0 ; bad metadata
469
+ ret i32 1
470
+ }
471
+
472
+ !0 = !{i1 true}
473
+ """
474
+
475
+ def test_fanout_raise_2(self):
476
+ # This is ensuring that fanout_raise is not pruning when the metadata
477
+ # is incorrectly named.
478
+ mod, stats = self.check(self.fanout_raise_2)
479
+ self.assertEqual(stats.fanout_raise, 0)
480
+
481
+ fanout_raise_3 = r"""
482
+ define i32 @main(i8* %ptr, i1 %cond, i8** %excinfo) {
483
+ bb_A:
484
+ call void @NRT_incref(i8* %ptr)
485
+ br i1 %cond, label %bb_B, label %bb_C
486
+ bb_B:
487
+ call void @NRT_decref(i8* %ptr)
488
+ ret i32 0
489
+ bb_C:
490
+ store i8* null, i8** %excinfo, !numba_exception_output !0
491
+ ret i32 1
492
+ }
493
+
494
+ !0 = !{i32 1} ; ok; use i32
495
+ """
496
+
497
+ def test_fanout_raise_3(self):
498
+ mod, stats = self.check(self.fanout_raise_3)
499
+ self.assertEqual(stats.fanout_raise, 2)
500
+
501
+ fanout_raise_4 = r"""
502
+ define i32 @main(i8* %ptr, i1 %cond, i8** %excinfo) {
503
+ bb_A:
504
+ call void @NRT_incref(i8* %ptr)
505
+ br i1 %cond, label %bb_B, label %bb_C
506
+ bb_B:
507
+ ret i32 1 ; BAD; all tails are raising without decref
508
+ bb_C:
509
+ ret i32 1 ; BAD; all tails are raising without decref
510
+ }
511
+
512
+ !0 = !{i1 1}
513
+ """
514
+
515
+ def test_fanout_raise_4(self):
516
+ mod, stats = self.check(self.fanout_raise_4)
517
+ self.assertEqual(stats.fanout_raise, 0)
518
+
519
+ fanout_raise_5 = r"""
520
+ define i32 @main(i8* %ptr, i1 %cond, i8** %excinfo) {
521
+ bb_A:
522
+ call void @NRT_incref(i8* %ptr)
523
+ br i1 %cond, label %bb_B, label %bb_C
524
+ bb_B:
525
+ call void @NRT_decref(i8* %ptr)
526
+ br label %common.ret
527
+ bb_C:
528
+ store i8* null, i8** %excinfo, !numba_exception_output !0
529
+ br label %common.ret
530
+ common.ret:
531
+ %common.ret.op = phi i32 [ 0, %bb_B ], [ 1, %bb_C ]
532
+ ret i32 %common.ret.op
533
+ }
534
+ !0 = !{i1 1}
535
+ """
536
+
537
+ def test_fanout_raise_5(self):
538
+ mod, stats = self.check(self.fanout_raise_5)
539
+ self.assertEqual(stats.fanout_raise, 2)
540
+
541
+ # test case 6 is from https://github.com/numba/llvmlite/issues/1023
542
+ fanout_raise_6 = r"""
543
+ define i32 @main(i8* %ptr, i1 %cond1, i1 %cond2, i1 %cond3, i8** %excinfo) {
544
+ bb_A:
545
+ call void @NRT_incref(i8* %ptr)
546
+ call void @NRT_incref(i8* %ptr)
547
+ br i1 %cond1, label %bb_B, label %bb_C
548
+ bb_B:
549
+ call void @NRT_decref(i8* %ptr)
550
+ br i1 %cond2, label %bb_D, label %bb_E
551
+ bb_C:
552
+ store i8* null, i8** %excinfo, !numba_exception_output !0
553
+ ret i32 1
554
+ bb_D:
555
+ call void @NRT_decref(i8* %ptr)
556
+ ret i32 0
557
+ bb_E:
558
+ call void @NRT_incref(i8* %ptr)
559
+ br i1 %cond3, label %bb_F, label %bb_C
560
+ bb_F:
561
+ call void @NRT_decref(i8* %ptr)
562
+ call void @NRT_decref(i8* %ptr)
563
+ ret i32 0
564
+ }
565
+ !0 = !{i1 1}
566
+ """
567
+
568
+ def test_fanout_raise_6(self):
569
+ mod, stats = self.check(self.fanout_raise_6)
570
+ self.assertEqual(stats.fanout_raise, 7)
571
+
572
+
573
+ if __name__ == '__main__':
574
+ unittest.main()
@@ -0,0 +1,60 @@
1
+ import math
2
+ import sys
3
+ import unittest
4
+
5
+ from llvmlite.ir import (
6
+ Constant, FloatType, DoubleType, LiteralStructType, IntType,
7
+ ArrayType, HalfType)
8
+ from llvmlite.tests import TestCase
9
+
10
+
11
+ int8 = IntType(8)
12
+ int16 = IntType(16)
13
+
14
+
15
+ PY36_OR_LATER = sys.version_info[:2] >= (3, 6)
16
+
17
+
18
+ class TestValueRepr(TestCase):
19
+
20
+ def test_double_repr(self):
21
+ def check_repr(val, expected):
22
+ c = Constant(DoubleType(), val)
23
+ self.assertEqual(str(c), expected)
24
+ check_repr(math.pi, "double 0x400921fb54442d18")
25
+ check_repr(float('inf'), "double 0x7ff0000000000000")
26
+ check_repr(float('-inf'), "double 0xfff0000000000000")
27
+
28
+ def test_float_repr(self):
29
+ def check_repr(val, expected):
30
+ c = Constant(FloatType(), val)
31
+ self.assertEqual(str(c), expected)
32
+ check_repr(math.pi, "float 0x400921fb60000000")
33
+ check_repr(float('inf'), "float 0x7ff0000000000000")
34
+ check_repr(float('-inf'), "float 0xfff0000000000000")
35
+
36
+ @unittest.skipUnless(PY36_OR_LATER, 'py36+ only')
37
+ def test_half_repr(self):
38
+ def check_repr(val, expected):
39
+ c = Constant(HalfType(), val)
40
+ self.assertEqual(str(c), expected)
41
+ check_repr(math.pi, "half 0x4009200000000000")
42
+ check_repr(float('inf'), "half 0x7ff0000000000000")
43
+ check_repr(float('-inf'), "half 0xfff0000000000000")
44
+
45
+ def test_struct_repr(self):
46
+ tp = LiteralStructType([int8, int16])
47
+ c = Constant(tp, (Constant(int8, 100), Constant(int16, 1000)))
48
+ self.assertEqual(str(c), "{i8, i16} {i8 100, i16 1000}")
49
+
50
+ def test_array_repr(self):
51
+ tp = ArrayType(int8, 3)
52
+ values = [Constant(int8, x) for x in (5, 10, -15)]
53
+ c = Constant(tp, values)
54
+ self.assertEqual(str(c), "[3 x i8] [i8 5, i8 10, i8 -15]")
55
+ c = Constant(tp, bytearray(b"\x01\x02\x03"))
56
+ self.assertEqual(str(c), '[3 x i8] c"\\01\\02\\03"')
57
+
58
+
59
+ if __name__ == "__main__":
60
+ unittest.main()
llvmlite/utils.py ADDED
@@ -0,0 +1,29 @@
1
+ import os
2
+ import sys
3
+
4
+
5
+ # This module must be importable without loading the binding, to avoid
6
+ # bootstrapping issues in setup.py.
7
+
8
+ def get_library_name():
9
+ """
10
+ Return the name of the llvmlite shared library file.
11
+ """
12
+ if os.name == 'posix':
13
+ if sys.platform == 'darwin':
14
+ return 'libllvmlite.dylib'
15
+ else:
16
+ return 'libllvmlite.so'
17
+ else:
18
+ assert os.name == 'nt'
19
+ return 'llvmlite.dll'
20
+
21
+
22
+ def get_library_files():
23
+ """
24
+ Return the names of shared library files needed for this platform.
25
+ """
26
+ files = [get_library_name()]
27
+ if os.name == 'nt':
28
+ files.extend(['msvcr120.dll', 'msvcp120.dll'])
29
+ return files