llvmlite 0.44.0rc1__cp311-cp311-macosx_11_0_arm64.whl → 0.45.0__cp311-cp311-macosx_11_0_arm64.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of llvmlite might be problematic. Click here for more details.
- llvmlite/__init__.py +6 -5
- llvmlite/_version.py +2 -2
- llvmlite/binding/__init__.py +1 -2
- llvmlite/binding/config.py +143 -0
- llvmlite/binding/context.py +2 -10
- llvmlite/binding/ffi.py +1 -1
- llvmlite/binding/initfini.py +14 -2
- llvmlite/binding/libllvmlite.dylib +0 -0
- llvmlite/binding/newpassmanagers.py +759 -67
- llvmlite/binding/targets.py +14 -72
- llvmlite/binding/typeref.py +1 -19
- llvmlite/ir/builder.py +1 -1
- llvmlite/ir/module.py +11 -1
- llvmlite/ir/types.py +15 -19
- llvmlite/tests/refprune_proto.py +1 -0
- llvmlite/tests/test_binding.py +394 -452
- llvmlite/tests/test_ir.py +176 -67
- llvmlite/tests/test_refprune.py +10 -166
- {llvmlite-0.44.0rc1.dist-info → llvmlite-0.45.0.dist-info}/METADATA +13 -8
- llvmlite-0.45.0.dist-info/RECORD +44 -0
- {llvmlite-0.44.0rc1.dist-info → llvmlite-0.45.0.dist-info}/WHEEL +1 -1
- llvmlite/binding/passmanagers.py +0 -946
- llvmlite/binding/transforms.py +0 -151
- llvmlite-0.44.0rc1.dist-info/LICENSE.thirdparty +0 -225
- llvmlite-0.44.0rc1.dist-info/RECORD +0 -46
- {llvmlite-0.44.0rc1.dist-info → llvmlite-0.45.0.dist-info/licenses}/LICENSE +0 -0
- {llvmlite-0.44.0rc1.dist-info → llvmlite-0.45.0.dist-info}/top_level.txt +0 -0
llvmlite/tests/test_binding.py
CHANGED
|
@@ -18,14 +18,29 @@ from llvmlite import binding as llvm
|
|
|
18
18
|
from llvmlite.binding import ffi
|
|
19
19
|
from llvmlite.tests import TestCase
|
|
20
20
|
|
|
21
|
-
# FIXME: Remove me once typed pointers are no longer supported.
|
|
22
|
-
from llvmlite import opaque_pointers_enabled
|
|
23
|
-
|
|
24
21
|
# arvm7l needs extra ABI symbols to link successfully
|
|
25
22
|
if platform.machine() == 'armv7l':
|
|
26
23
|
llvm.load_library_permanently('libgcc_s.so.1')
|
|
27
24
|
|
|
28
25
|
|
|
26
|
+
is_conda_package = unittest.skipUnless(llvm.package_format == "conda",
|
|
27
|
+
("conda package test only, have "
|
|
28
|
+
f"{llvm.package_format}"))
|
|
29
|
+
is_wheel_package = unittest.skipUnless(llvm.package_format == "wheel",
|
|
30
|
+
("wheel package test only, have "
|
|
31
|
+
f"{llvm.package_format}"))
|
|
32
|
+
|
|
33
|
+
_HAVE_LIEF = False
|
|
34
|
+
try:
|
|
35
|
+
import lief # noqa: F401
|
|
36
|
+
_HAVE_LIEF = True
|
|
37
|
+
except ImportError:
|
|
38
|
+
pass
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
needs_lief = unittest.skipUnless(_HAVE_LIEF, "test needs py-lief package")
|
|
42
|
+
|
|
43
|
+
|
|
29
44
|
def no_de_locale():
|
|
30
45
|
cur = locale.setlocale(locale.LC_ALL)
|
|
31
46
|
try:
|
|
@@ -415,11 +430,11 @@ riscv_asm_ilp32 = [
|
|
|
415
430
|
'addi\tsp, sp, -16',
|
|
416
431
|
'sw\ta1, 8(sp)',
|
|
417
432
|
'sw\ta2, 12(sp)',
|
|
418
|
-
'fld\
|
|
419
|
-
'fmv.w.x\
|
|
420
|
-
'fcvt.d.s\
|
|
421
|
-
'fadd.d\
|
|
422
|
-
'fsd\
|
|
433
|
+
'fld\tfa5, 8(sp)',
|
|
434
|
+
'fmv.w.x\tfa4, a0',
|
|
435
|
+
'fcvt.d.s\tfa4, fa4',
|
|
436
|
+
'fadd.d\tfa5, fa4, fa5',
|
|
437
|
+
'fsd\tfa5, 8(sp)',
|
|
423
438
|
'lw\ta0, 8(sp)',
|
|
424
439
|
'lw\ta1, 12(sp)',
|
|
425
440
|
'addi\tsp, sp, 16',
|
|
@@ -431,10 +446,10 @@ riscv_asm_ilp32f = [
|
|
|
431
446
|
'addi\tsp, sp, -16',
|
|
432
447
|
'sw\ta0, 8(sp)',
|
|
433
448
|
'sw\ta1, 12(sp)',
|
|
434
|
-
'fld\
|
|
435
|
-
'fcvt.d.s\
|
|
436
|
-
'fadd.d\
|
|
437
|
-
'fsd\
|
|
449
|
+
'fld\tfa5, 8(sp)',
|
|
450
|
+
'fcvt.d.s\tfa4, fa0',
|
|
451
|
+
'fadd.d\tfa5, fa4, fa5',
|
|
452
|
+
'fsd\tfa5, 8(sp)',
|
|
438
453
|
'lw\ta0, 8(sp)',
|
|
439
454
|
'lw\ta1, 12(sp)',
|
|
440
455
|
'addi\tsp, sp, 16',
|
|
@@ -443,8 +458,8 @@ riscv_asm_ilp32f = [
|
|
|
443
458
|
|
|
444
459
|
|
|
445
460
|
riscv_asm_ilp32d = [
|
|
446
|
-
'fcvt.d.s\
|
|
447
|
-
'fadd.d\tfa0,
|
|
461
|
+
'fcvt.d.s\tfa5, fa0',
|
|
462
|
+
'fadd.d\tfa0, fa5, fa1',
|
|
448
463
|
'ret'
|
|
449
464
|
]
|
|
450
465
|
|
|
@@ -654,7 +669,6 @@ attributes #1 = { argmemonly nofree nounwind willreturn }
|
|
|
654
669
|
class BaseTest(TestCase):
|
|
655
670
|
|
|
656
671
|
def setUp(self):
|
|
657
|
-
llvm.initialize()
|
|
658
672
|
llvm.initialize_native_target()
|
|
659
673
|
llvm.initialize_native_asmprinter()
|
|
660
674
|
gc.collect()
|
|
@@ -718,13 +732,21 @@ class TestDependencies(BaseTest):
|
|
|
718
732
|
self.fail("failed parsing dependencies? got %r" % (deps,))
|
|
719
733
|
# Ensure all dependencies are expected
|
|
720
734
|
allowed = set(['librt', 'libdl', 'libpthread', 'libz', 'libm',
|
|
721
|
-
'libgcc_s', 'libc', 'ld-linux', 'ld64'
|
|
735
|
+
'libgcc_s', 'libc', 'ld-linux', 'ld64', 'libzstd',
|
|
736
|
+
'libstdc++'])
|
|
722
737
|
if platform.python_implementation() == 'PyPy':
|
|
723
738
|
allowed.add('libtinfo')
|
|
724
739
|
|
|
740
|
+
fails = []
|
|
725
741
|
for dep in deps:
|
|
726
742
|
if not dep.startswith('ld-linux-') and dep not in allowed:
|
|
727
|
-
|
|
743
|
+
fails.append(dep)
|
|
744
|
+
if len(fails) == 1:
|
|
745
|
+
self.fail("unexpected dependency %r in %r" % (fails[0], deps))
|
|
746
|
+
elif len(fails) > 1:
|
|
747
|
+
self.fail("unexpected dependencies %r in %r" % (fails, deps))
|
|
748
|
+
else:
|
|
749
|
+
pass # test passes
|
|
728
750
|
|
|
729
751
|
|
|
730
752
|
class TestRISCVABI(BaseTest):
|
|
@@ -892,7 +914,6 @@ class TestMisc(BaseTest):
|
|
|
892
914
|
code = """if 1:
|
|
893
915
|
from llvmlite import binding as llvm
|
|
894
916
|
|
|
895
|
-
llvm.initialize()
|
|
896
917
|
llvm.initialize_native_target()
|
|
897
918
|
llvm.initialize_native_asmprinter()
|
|
898
919
|
llvm.initialize_all_targets()
|
|
@@ -901,6 +922,11 @@ class TestMisc(BaseTest):
|
|
|
901
922
|
"""
|
|
902
923
|
subprocess.check_call([sys.executable, "-c", code])
|
|
903
924
|
|
|
925
|
+
def test_deprecated_init(self):
|
|
926
|
+
regex = r"llvmlite.binding.initialize\(\) is deprecated"
|
|
927
|
+
with self.assertRaisesRegex(RuntimeError, expected_regex=regex):
|
|
928
|
+
llvm.initialize()
|
|
929
|
+
|
|
904
930
|
def test_set_option(self):
|
|
905
931
|
# We cannot set an option multiple times (LLVM would exit() the
|
|
906
932
|
# process), so run the code in a subprocess.
|
|
@@ -914,9 +940,9 @@ class TestMisc(BaseTest):
|
|
|
914
940
|
def test_version(self):
|
|
915
941
|
major, minor, patch = llvm.llvm_version_info
|
|
916
942
|
# one of these can be valid
|
|
917
|
-
valid = (
|
|
943
|
+
valid = (20,)
|
|
918
944
|
self.assertIn(major, valid)
|
|
919
|
-
self.assertIn(patch, range(
|
|
945
|
+
self.assertIn(patch, range(9))
|
|
920
946
|
|
|
921
947
|
def test_check_jit_execution(self):
|
|
922
948
|
llvm.check_jit_execution()
|
|
@@ -1361,7 +1387,10 @@ class TestMCJit(BaseTest, JITWithTMTestMixin):
|
|
|
1361
1387
|
# #1000. Since OrcJIT is experimental, and we don't test regularly during
|
|
1362
1388
|
# llvmlite development on non-x86 platforms, it seems safest to skip these
|
|
1363
1389
|
# tests on non-x86 platforms.
|
|
1364
|
-
|
|
1390
|
+
# After LLVM20 upgrades skip on X86 too as ORCJit complains about missing
|
|
1391
|
+
# JITDyLib symbol.
|
|
1392
|
+
# TODO: Investigate this further.
|
|
1393
|
+
@unittest.skip("OrcJIT support is experimental")
|
|
1365
1394
|
class TestOrcLLJIT(BaseTest):
|
|
1366
1395
|
|
|
1367
1396
|
def jit(self, asm=asm_sum, func_name="sum", target_machine=None,
|
|
@@ -1647,12 +1676,7 @@ class TestValueRef(BaseTest):
|
|
|
1647
1676
|
mod = self.module()
|
|
1648
1677
|
st = mod.get_global_variable("glob_struct")
|
|
1649
1678
|
self.assertTrue(st.type.is_pointer)
|
|
1650
|
-
|
|
1651
|
-
if opaque_pointers_enabled:
|
|
1652
|
-
self.assertIsNotNone(re.match(r'ptr', str(st.type)))
|
|
1653
|
-
else:
|
|
1654
|
-
self.assertIsNotNone(re.match(r'%struct\.glob_type(\.[\d]+)?\*',
|
|
1655
|
-
str(st.type)))
|
|
1679
|
+
self.assertIsNotNone(re.match(r'ptr', str(st.type)))
|
|
1656
1680
|
self.assertIsNotNone(re.match(
|
|
1657
1681
|
r"%struct\.glob_type(\.[\d]+)? = type { i64, \[2 x i64\] }",
|
|
1658
1682
|
str(st.global_value_type)))
|
|
@@ -1741,7 +1765,7 @@ class TestValueRef(BaseTest):
|
|
|
1741
1765
|
|
|
1742
1766
|
def test_function_attributes(self):
|
|
1743
1767
|
ver = llvm.llvm_version_info[0]
|
|
1744
|
-
readonly_attrs = [b'memory(read)' if ver
|
|
1768
|
+
readonly_attrs = [b'memory(read)' if ver > 15 else b'readonly']
|
|
1745
1769
|
mod = self.module(asm_attributes)
|
|
1746
1770
|
for func in mod.functions:
|
|
1747
1771
|
attrs = list(func.attributes)
|
|
@@ -1841,11 +1865,7 @@ class TestValueRef(BaseTest):
|
|
|
1841
1865
|
inst = list(list(func.blocks)[0].instructions)[0]
|
|
1842
1866
|
arg = list(inst.operands)[0]
|
|
1843
1867
|
self.assertTrue(arg.is_constant)
|
|
1844
|
-
|
|
1845
|
-
if opaque_pointers_enabled:
|
|
1846
|
-
self.assertEqual(arg.get_constant_value(), 'ptr null')
|
|
1847
|
-
else:
|
|
1848
|
-
self.assertEqual(arg.get_constant_value(), 'i64* null')
|
|
1868
|
+
self.assertEqual(arg.get_constant_value(), 'ptr null')
|
|
1849
1869
|
|
|
1850
1870
|
def test_incoming_phi_blocks(self):
|
|
1851
1871
|
mod = self.module(asm_phi_blocks)
|
|
@@ -1950,12 +1970,7 @@ class TestTypeRef(BaseTest):
|
|
|
1950
1970
|
self.assertTrue(func.type.is_pointer)
|
|
1951
1971
|
with self.assertRaises(ValueError) as raises:
|
|
1952
1972
|
func.type.is_function_vararg
|
|
1953
|
-
|
|
1954
|
-
if opaque_pointers_enabled:
|
|
1955
|
-
self.assertIn("Type ptr is not a function", str(raises.exception))
|
|
1956
|
-
else:
|
|
1957
|
-
self.assertIn("Type i32 (i32, i32)* is not a function",
|
|
1958
|
-
str(raises.exception))
|
|
1973
|
+
self.assertIn("Type ptr is not a function", str(raises.exception))
|
|
1959
1974
|
|
|
1960
1975
|
def test_function_typeref_as_ir(self):
|
|
1961
1976
|
mod = self.module()
|
|
@@ -2244,11 +2259,6 @@ class TestTargetData(BaseTest):
|
|
|
2244
2259
|
|
|
2245
2260
|
class TestTargetMachine(BaseTest):
|
|
2246
2261
|
|
|
2247
|
-
def test_add_analysis_passes(self):
|
|
2248
|
-
tm = self.target_machine(jit=False)
|
|
2249
|
-
pm = llvm.create_module_pass_manager()
|
|
2250
|
-
tm.add_analysis_passes(pm)
|
|
2251
|
-
|
|
2252
2262
|
def test_target_data_from_tm(self):
|
|
2253
2263
|
tm = self.target_machine(jit=False)
|
|
2254
2264
|
td = tm.target_data
|
|
@@ -2259,370 +2269,6 @@ class TestTargetMachine(BaseTest):
|
|
|
2259
2269
|
self.assertEqual(td.get_abi_size(gv_i32.type), pointer_size)
|
|
2260
2270
|
|
|
2261
2271
|
|
|
2262
|
-
class TestPassManagerBuilder(BaseTest):
|
|
2263
|
-
|
|
2264
|
-
def pmb(self):
|
|
2265
|
-
return llvm.PassManagerBuilder()
|
|
2266
|
-
|
|
2267
|
-
def test_old_api(self):
|
|
2268
|
-
# Test the create_pass_manager_builder() factory function
|
|
2269
|
-
pmb = llvm.create_pass_manager_builder()
|
|
2270
|
-
pmb.inlining_threshold = 2
|
|
2271
|
-
pmb.opt_level = 3
|
|
2272
|
-
|
|
2273
|
-
def test_close(self):
|
|
2274
|
-
pmb = self.pmb()
|
|
2275
|
-
pmb.close()
|
|
2276
|
-
pmb.close()
|
|
2277
|
-
|
|
2278
|
-
def test_opt_level(self):
|
|
2279
|
-
pmb = self.pmb()
|
|
2280
|
-
self.assertIsInstance(pmb.opt_level, int)
|
|
2281
|
-
for i in range(4):
|
|
2282
|
-
pmb.opt_level = i
|
|
2283
|
-
self.assertEqual(pmb.opt_level, i)
|
|
2284
|
-
|
|
2285
|
-
def test_size_level(self):
|
|
2286
|
-
pmb = self.pmb()
|
|
2287
|
-
self.assertIsInstance(pmb.size_level, int)
|
|
2288
|
-
for i in range(4):
|
|
2289
|
-
pmb.size_level = i
|
|
2290
|
-
self.assertEqual(pmb.size_level, i)
|
|
2291
|
-
|
|
2292
|
-
def test_inlining_threshold(self):
|
|
2293
|
-
pmb = self.pmb()
|
|
2294
|
-
with self.assertRaises(NotImplementedError):
|
|
2295
|
-
pmb.inlining_threshold
|
|
2296
|
-
for i in (25, 80, 350):
|
|
2297
|
-
pmb.inlining_threshold = i
|
|
2298
|
-
|
|
2299
|
-
def test_disable_unroll_loops(self):
|
|
2300
|
-
pmb = self.pmb()
|
|
2301
|
-
self.assertIsInstance(pmb.disable_unroll_loops, bool)
|
|
2302
|
-
for b in (True, False):
|
|
2303
|
-
pmb.disable_unroll_loops = b
|
|
2304
|
-
self.assertEqual(pmb.disable_unroll_loops, b)
|
|
2305
|
-
|
|
2306
|
-
def test_loop_vectorize(self):
|
|
2307
|
-
pmb = self.pmb()
|
|
2308
|
-
self.assertIsInstance(pmb.loop_vectorize, bool)
|
|
2309
|
-
for b in (True, False):
|
|
2310
|
-
pmb.loop_vectorize = b
|
|
2311
|
-
self.assertEqual(pmb.loop_vectorize, b)
|
|
2312
|
-
|
|
2313
|
-
def test_slp_vectorize(self):
|
|
2314
|
-
pmb = self.pmb()
|
|
2315
|
-
self.assertIsInstance(pmb.slp_vectorize, bool)
|
|
2316
|
-
for b in (True, False):
|
|
2317
|
-
pmb.slp_vectorize = b
|
|
2318
|
-
self.assertEqual(pmb.slp_vectorize, b)
|
|
2319
|
-
|
|
2320
|
-
def test_populate_module_pass_manager(self):
|
|
2321
|
-
pmb = self.pmb()
|
|
2322
|
-
pm = llvm.create_module_pass_manager()
|
|
2323
|
-
pmb.populate(pm)
|
|
2324
|
-
pmb.close()
|
|
2325
|
-
pm.close()
|
|
2326
|
-
|
|
2327
|
-
def test_populate_function_pass_manager(self):
|
|
2328
|
-
mod = self.module()
|
|
2329
|
-
pmb = self.pmb()
|
|
2330
|
-
pm = llvm.create_function_pass_manager(mod)
|
|
2331
|
-
pmb.populate(pm)
|
|
2332
|
-
pmb.close()
|
|
2333
|
-
pm.close()
|
|
2334
|
-
|
|
2335
|
-
|
|
2336
|
-
class PassManagerTestMixin(object):
|
|
2337
|
-
|
|
2338
|
-
def pmb(self):
|
|
2339
|
-
pmb = llvm.create_pass_manager_builder()
|
|
2340
|
-
pmb.opt_level = 2
|
|
2341
|
-
pmb.inlining_threshold = 300
|
|
2342
|
-
return pmb
|
|
2343
|
-
|
|
2344
|
-
def test_close(self):
|
|
2345
|
-
pm = self.pm()
|
|
2346
|
-
pm.close()
|
|
2347
|
-
pm.close()
|
|
2348
|
-
|
|
2349
|
-
|
|
2350
|
-
class TestModulePassManager(BaseTest, PassManagerTestMixin):
|
|
2351
|
-
|
|
2352
|
-
def pm(self):
|
|
2353
|
-
return llvm.create_module_pass_manager()
|
|
2354
|
-
|
|
2355
|
-
def test_run(self):
|
|
2356
|
-
pm = self.pm()
|
|
2357
|
-
self.pmb().populate(pm)
|
|
2358
|
-
mod = self.module()
|
|
2359
|
-
orig_asm = str(mod)
|
|
2360
|
-
pm.run(mod)
|
|
2361
|
-
opt_asm = str(mod)
|
|
2362
|
-
# Quick check that optimizations were run, should get:
|
|
2363
|
-
# define i32 @sum(i32 %.1, i32 %.2) local_unnamed_addr #0 {
|
|
2364
|
-
# %.X = add i32 %.2, %.1
|
|
2365
|
-
# ret i32 %.X
|
|
2366
|
-
# }
|
|
2367
|
-
# where X in %.X is 3 or 4
|
|
2368
|
-
opt_asm_split = opt_asm.splitlines()
|
|
2369
|
-
for idx, l in enumerate(opt_asm_split):
|
|
2370
|
-
if l.strip().startswith('ret i32'):
|
|
2371
|
-
toks = {'%.3', '%.4'}
|
|
2372
|
-
for t in toks:
|
|
2373
|
-
if t in l:
|
|
2374
|
-
break
|
|
2375
|
-
else:
|
|
2376
|
-
raise RuntimeError("expected tokens not found")
|
|
2377
|
-
othertoken = (toks ^ {t}).pop()
|
|
2378
|
-
|
|
2379
|
-
self.assertIn("%.3", orig_asm)
|
|
2380
|
-
self.assertNotIn(othertoken, opt_asm)
|
|
2381
|
-
break
|
|
2382
|
-
else:
|
|
2383
|
-
raise RuntimeError("expected IR not found")
|
|
2384
|
-
|
|
2385
|
-
def test_run_with_remarks_successful_inline(self):
|
|
2386
|
-
pm = self.pm()
|
|
2387
|
-
pm.add_function_inlining_pass(70)
|
|
2388
|
-
self.pmb().populate(pm)
|
|
2389
|
-
mod = self.module(asm_inlineasm2)
|
|
2390
|
-
(status, remarks) = pm.run_with_remarks(mod)
|
|
2391
|
-
self.assertTrue(status)
|
|
2392
|
-
# Inlining has happened? The remark will tell us.
|
|
2393
|
-
self.assertIn("Passed", remarks)
|
|
2394
|
-
self.assertIn("inlineme", remarks)
|
|
2395
|
-
|
|
2396
|
-
def test_run_with_remarks_failed_inline(self):
|
|
2397
|
-
pm = self.pm()
|
|
2398
|
-
pm.add_function_inlining_pass(0)
|
|
2399
|
-
self.pmb().populate(pm)
|
|
2400
|
-
mod = self.module(asm_inlineasm3)
|
|
2401
|
-
(status, remarks) = pm.run_with_remarks(mod)
|
|
2402
|
-
self.assertTrue(status)
|
|
2403
|
-
|
|
2404
|
-
# Inlining has not happened? The remark will tell us.
|
|
2405
|
-
self.assertIn("Missed", remarks)
|
|
2406
|
-
self.assertIn("inlineme", remarks)
|
|
2407
|
-
self.assertIn("noinline function attribute", remarks)
|
|
2408
|
-
|
|
2409
|
-
def test_run_with_remarks_inline_filter_out(self):
|
|
2410
|
-
pm = self.pm()
|
|
2411
|
-
pm.add_function_inlining_pass(70)
|
|
2412
|
-
self.pmb().populate(pm)
|
|
2413
|
-
mod = self.module(asm_inlineasm2)
|
|
2414
|
-
(status, remarks) = pm.run_with_remarks(mod, remarks_filter="nothing")
|
|
2415
|
-
self.assertTrue(status)
|
|
2416
|
-
self.assertEqual("", remarks)
|
|
2417
|
-
|
|
2418
|
-
def test_run_with_remarks_inline_filter_in(self):
|
|
2419
|
-
pm = self.pm()
|
|
2420
|
-
pm.add_function_inlining_pass(70)
|
|
2421
|
-
self.pmb().populate(pm)
|
|
2422
|
-
mod = self.module(asm_inlineasm2)
|
|
2423
|
-
(status, remarks) = pm.run_with_remarks(mod, remarks_filter="inlin.*")
|
|
2424
|
-
self.assertTrue(status)
|
|
2425
|
-
self.assertIn("Passed", remarks)
|
|
2426
|
-
self.assertIn("inlineme", remarks)
|
|
2427
|
-
|
|
2428
|
-
|
|
2429
|
-
class TestFunctionPassManager(BaseTest, PassManagerTestMixin):
|
|
2430
|
-
|
|
2431
|
-
def pm(self, mod=None):
|
|
2432
|
-
mod = mod or self.module()
|
|
2433
|
-
return llvm.create_function_pass_manager(mod)
|
|
2434
|
-
|
|
2435
|
-
def test_initfini(self):
|
|
2436
|
-
pm = self.pm()
|
|
2437
|
-
pm.initialize()
|
|
2438
|
-
pm.finalize()
|
|
2439
|
-
|
|
2440
|
-
def test_run(self):
|
|
2441
|
-
mod = self.module()
|
|
2442
|
-
fn = mod.get_function("sum")
|
|
2443
|
-
pm = self.pm(mod)
|
|
2444
|
-
self.pmb().populate(pm)
|
|
2445
|
-
mod.close()
|
|
2446
|
-
orig_asm = str(fn)
|
|
2447
|
-
pm.initialize()
|
|
2448
|
-
pm.run(fn)
|
|
2449
|
-
pm.finalize()
|
|
2450
|
-
opt_asm = str(fn)
|
|
2451
|
-
# Quick check that optimizations were run
|
|
2452
|
-
self.assertIn("%.4", orig_asm)
|
|
2453
|
-
self.assertNotIn("%.4", opt_asm)
|
|
2454
|
-
|
|
2455
|
-
def test_run_with_remarks(self):
|
|
2456
|
-
mod = self.module(licm_asm)
|
|
2457
|
-
fn = mod.get_function("licm")
|
|
2458
|
-
pm = self.pm(mod)
|
|
2459
|
-
pm.add_licm_pass()
|
|
2460
|
-
self.pmb().populate(pm)
|
|
2461
|
-
mod.close()
|
|
2462
|
-
|
|
2463
|
-
pm.initialize()
|
|
2464
|
-
(ok, remarks) = pm.run_with_remarks(fn)
|
|
2465
|
-
pm.finalize()
|
|
2466
|
-
self.assertTrue(ok)
|
|
2467
|
-
self.assertIn("Passed", remarks)
|
|
2468
|
-
self.assertIn("licm", remarks)
|
|
2469
|
-
|
|
2470
|
-
def test_run_with_remarks_filter_out(self):
|
|
2471
|
-
mod = self.module(licm_asm)
|
|
2472
|
-
fn = mod.get_function("licm")
|
|
2473
|
-
pm = self.pm(mod)
|
|
2474
|
-
pm.add_licm_pass()
|
|
2475
|
-
self.pmb().populate(pm)
|
|
2476
|
-
mod.close()
|
|
2477
|
-
|
|
2478
|
-
pm.initialize()
|
|
2479
|
-
(ok, remarks) = pm.run_with_remarks(fn, remarks_filter="nothing")
|
|
2480
|
-
pm.finalize()
|
|
2481
|
-
self.assertTrue(ok)
|
|
2482
|
-
self.assertEqual("", remarks)
|
|
2483
|
-
|
|
2484
|
-
def test_run_with_remarks_filter_in(self):
|
|
2485
|
-
mod = self.module(licm_asm)
|
|
2486
|
-
fn = mod.get_function("licm")
|
|
2487
|
-
pm = self.pm(mod)
|
|
2488
|
-
pm.add_licm_pass()
|
|
2489
|
-
self.pmb().populate(pm)
|
|
2490
|
-
mod.close()
|
|
2491
|
-
|
|
2492
|
-
pm.initialize()
|
|
2493
|
-
(ok, remarks) = pm.run_with_remarks(fn, remarks_filter="licm")
|
|
2494
|
-
pm.finalize()
|
|
2495
|
-
self.assertTrue(ok)
|
|
2496
|
-
self.assertIn("Passed", remarks)
|
|
2497
|
-
self.assertIn("licm", remarks)
|
|
2498
|
-
|
|
2499
|
-
|
|
2500
|
-
class TestPasses(BaseTest, PassManagerTestMixin):
|
|
2501
|
-
|
|
2502
|
-
def pm(self):
|
|
2503
|
-
return llvm.create_module_pass_manager()
|
|
2504
|
-
|
|
2505
|
-
def test_populate(self):
|
|
2506
|
-
llvm_ver = llvm.llvm_version_info[0]
|
|
2507
|
-
|
|
2508
|
-
pm = self.pm()
|
|
2509
|
-
pm.add_target_library_info("") # unspecified target triple
|
|
2510
|
-
pm.add_constant_merge_pass()
|
|
2511
|
-
pm.add_dead_arg_elimination_pass()
|
|
2512
|
-
pm.add_function_attrs_pass()
|
|
2513
|
-
pm.add_function_inlining_pass(225)
|
|
2514
|
-
pm.add_global_dce_pass()
|
|
2515
|
-
pm.add_global_optimizer_pass()
|
|
2516
|
-
pm.add_ipsccp_pass()
|
|
2517
|
-
pm.add_dead_code_elimination_pass()
|
|
2518
|
-
pm.add_cfg_simplification_pass()
|
|
2519
|
-
pm.add_gvn_pass()
|
|
2520
|
-
pm.add_instruction_combining_pass()
|
|
2521
|
-
pm.add_licm_pass()
|
|
2522
|
-
pm.add_sccp_pass()
|
|
2523
|
-
pm.add_sroa_pass()
|
|
2524
|
-
pm.add_type_based_alias_analysis_pass()
|
|
2525
|
-
pm.add_basic_alias_analysis_pass()
|
|
2526
|
-
pm.add_loop_rotate_pass()
|
|
2527
|
-
pm.add_region_info_pass()
|
|
2528
|
-
pm.add_scalar_evolution_aa_pass()
|
|
2529
|
-
pm.add_aggressive_dead_code_elimination_pass()
|
|
2530
|
-
pm.add_aa_eval_pass()
|
|
2531
|
-
pm.add_always_inliner_pass()
|
|
2532
|
-
pm.add_break_critical_edges_pass()
|
|
2533
|
-
pm.add_dead_store_elimination_pass()
|
|
2534
|
-
pm.add_reverse_post_order_function_attrs_pass()
|
|
2535
|
-
|
|
2536
|
-
if llvm_ver < 16:
|
|
2537
|
-
pm.add_aggressive_instruction_combining_pass()
|
|
2538
|
-
|
|
2539
|
-
pm.add_internalize_pass()
|
|
2540
|
-
pm.add_jump_threading_pass(7)
|
|
2541
|
-
pm.add_lcssa_pass()
|
|
2542
|
-
pm.add_loop_deletion_pass()
|
|
2543
|
-
pm.add_loop_extractor_pass()
|
|
2544
|
-
pm.add_single_loop_extractor_pass()
|
|
2545
|
-
pm.add_loop_strength_reduce_pass()
|
|
2546
|
-
pm.add_loop_simplification_pass()
|
|
2547
|
-
pm.add_loop_unroll_pass()
|
|
2548
|
-
pm.add_loop_unroll_and_jam_pass()
|
|
2549
|
-
pm.add_lower_atomic_pass()
|
|
2550
|
-
pm.add_lower_invoke_pass()
|
|
2551
|
-
pm.add_lower_switch_pass()
|
|
2552
|
-
pm.add_memcpy_optimization_pass()
|
|
2553
|
-
pm.add_merge_functions_pass()
|
|
2554
|
-
pm.add_merge_returns_pass()
|
|
2555
|
-
pm.add_partial_inlining_pass()
|
|
2556
|
-
|
|
2557
|
-
if llvm_ver < 16:
|
|
2558
|
-
pm.add_prune_exception_handling_pass()
|
|
2559
|
-
|
|
2560
|
-
pm.add_reassociate_expressions_pass()
|
|
2561
|
-
pm.add_demote_register_to_memory_pass()
|
|
2562
|
-
pm.add_sink_pass()
|
|
2563
|
-
pm.add_strip_symbols_pass()
|
|
2564
|
-
pm.add_strip_dead_debug_info_pass()
|
|
2565
|
-
pm.add_strip_dead_prototypes_pass()
|
|
2566
|
-
pm.add_strip_debug_declare_pass()
|
|
2567
|
-
pm.add_strip_nondebug_symbols_pass()
|
|
2568
|
-
pm.add_tail_call_elimination_pass()
|
|
2569
|
-
pm.add_basic_aa_pass()
|
|
2570
|
-
pm.add_dependence_analysis_pass()
|
|
2571
|
-
pm.add_dot_call_graph_pass()
|
|
2572
|
-
pm.add_dot_cfg_printer_pass()
|
|
2573
|
-
pm.add_dot_dom_printer_pass()
|
|
2574
|
-
pm.add_dot_postdom_printer_pass()
|
|
2575
|
-
pm.add_globals_mod_ref_aa_pass()
|
|
2576
|
-
pm.add_iv_users_pass()
|
|
2577
|
-
pm.add_lazy_value_info_pass()
|
|
2578
|
-
pm.add_lint_pass()
|
|
2579
|
-
pm.add_module_debug_info_pass()
|
|
2580
|
-
pm.add_refprune_pass()
|
|
2581
|
-
pm.add_instruction_namer_pass()
|
|
2582
|
-
|
|
2583
|
-
@unittest.skipUnless(platform.machine().startswith("x86"), "x86 only")
|
|
2584
|
-
def test_target_library_info_behavior(self):
|
|
2585
|
-
"""Test a specific situation that demonstrate TLI is affecting
|
|
2586
|
-
optimization. See https://github.com/numba/numba/issues/8898.
|
|
2587
|
-
"""
|
|
2588
|
-
def run(use_tli):
|
|
2589
|
-
mod = llvm.parse_assembly(asm_tli_exp2)
|
|
2590
|
-
target = llvm.Target.from_triple(mod.triple)
|
|
2591
|
-
tm = target.create_target_machine()
|
|
2592
|
-
pm = llvm.ModulePassManager()
|
|
2593
|
-
tm.add_analysis_passes(pm)
|
|
2594
|
-
if use_tli:
|
|
2595
|
-
pm.add_target_library_info(mod.triple)
|
|
2596
|
-
pm.add_instruction_combining_pass()
|
|
2597
|
-
pm.run(mod)
|
|
2598
|
-
return mod
|
|
2599
|
-
|
|
2600
|
-
# Run with TLI should suppress transformation of exp2 -> ldexpf
|
|
2601
|
-
mod = run(use_tli=True)
|
|
2602
|
-
self.assertIn("call float @llvm.exp2.f32", str(mod))
|
|
2603
|
-
|
|
2604
|
-
# Run without TLI will enable the transformation
|
|
2605
|
-
mod = run(use_tli=False)
|
|
2606
|
-
self.assertNotIn("call float @llvm.exp2.f32", str(mod))
|
|
2607
|
-
self.assertIn("call float @ldexpf", str(mod))
|
|
2608
|
-
|
|
2609
|
-
def test_instruction_namer_pass(self):
|
|
2610
|
-
asm = asm_inlineasm3.format(triple=llvm.get_default_triple())
|
|
2611
|
-
mod = llvm.parse_assembly(asm)
|
|
2612
|
-
|
|
2613
|
-
# Run instnamer pass
|
|
2614
|
-
pm = llvm.ModulePassManager()
|
|
2615
|
-
pm.add_instruction_namer_pass()
|
|
2616
|
-
pm.run(mod)
|
|
2617
|
-
|
|
2618
|
-
# Test that unnamed instructions are now named
|
|
2619
|
-
func = mod.get_function('foo')
|
|
2620
|
-
first_block = next(func.blocks)
|
|
2621
|
-
instructions = list(first_block.instructions)
|
|
2622
|
-
self.assertEqual(instructions[0].name, 'i')
|
|
2623
|
-
self.assertEqual(instructions[1].name, 'i2')
|
|
2624
|
-
|
|
2625
|
-
|
|
2626
2272
|
class TestDylib(BaseTest):
|
|
2627
2273
|
|
|
2628
2274
|
def test_bad_library(self):
|
|
@@ -2711,6 +2357,8 @@ class TestTypeParsing(BaseTest):
|
|
|
2711
2357
|
|
|
2712
2358
|
|
|
2713
2359
|
class TestGlobalConstructors(TestMCJit):
|
|
2360
|
+
@unittest.skipIf(platform.system() == "Darwin",
|
|
2361
|
+
"__cxa_atexit is broken on OSX in MCJIT")
|
|
2714
2362
|
def test_global_ctors_dtors(self):
|
|
2715
2363
|
# test issue #303
|
|
2716
2364
|
# (https://github.com/numba/llvmlite/issues/303)
|
|
@@ -2822,19 +2470,19 @@ class TestObjectFile(BaseTest):
|
|
|
2822
2470
|
obj_bin = target_machine.emit_object(mod)
|
|
2823
2471
|
obj = llvm.ObjectFileRef.from_data(obj_bin)
|
|
2824
2472
|
# Check that we have a text section, and that she has a name and data
|
|
2825
|
-
|
|
2473
|
+
has_text_and_data = False
|
|
2826
2474
|
last_address = -1
|
|
2827
2475
|
for s in obj.sections():
|
|
2828
|
-
if
|
|
2829
|
-
|
|
2830
|
-
|
|
2831
|
-
|
|
2832
|
-
|
|
2833
|
-
|
|
2834
|
-
|
|
2476
|
+
if (
|
|
2477
|
+
s.is_text()
|
|
2478
|
+
and len(s.data()) > 0
|
|
2479
|
+
and s.address() is not None
|
|
2480
|
+
and last_address < s.address()
|
|
2481
|
+
):
|
|
2482
|
+
has_text_and_data = True
|
|
2835
2483
|
last_address = s.address()
|
|
2836
2484
|
break
|
|
2837
|
-
self.assertTrue(
|
|
2485
|
+
self.assertTrue(has_text_and_data)
|
|
2838
2486
|
|
|
2839
2487
|
def test_add_object_file(self):
|
|
2840
2488
|
target_machine = self.target_machine(jit=False)
|
|
@@ -2889,31 +2537,6 @@ class TestObjectFile(BaseTest):
|
|
|
2889
2537
|
self.assertEqual(s.data().hex(), issue_632_text)
|
|
2890
2538
|
|
|
2891
2539
|
|
|
2892
|
-
class TestTimePasses(BaseTest):
|
|
2893
|
-
def test_reporting(self):
|
|
2894
|
-
mp = llvm.create_module_pass_manager()
|
|
2895
|
-
|
|
2896
|
-
pmb = llvm.create_pass_manager_builder()
|
|
2897
|
-
pmb.opt_level = 3
|
|
2898
|
-
pmb.populate(mp)
|
|
2899
|
-
|
|
2900
|
-
try:
|
|
2901
|
-
llvm.set_time_passes(True)
|
|
2902
|
-
mp.run(self.module())
|
|
2903
|
-
mp.run(self.module())
|
|
2904
|
-
mp.run(self.module())
|
|
2905
|
-
finally:
|
|
2906
|
-
report = llvm.report_and_reset_timings()
|
|
2907
|
-
llvm.set_time_passes(False)
|
|
2908
|
-
|
|
2909
|
-
self.assertIsInstance(report, str)
|
|
2910
|
-
self.assertEqual(report.count("Pass execution timing report"), 1)
|
|
2911
|
-
|
|
2912
|
-
def test_empty_report(self):
|
|
2913
|
-
# Returns empty str if no data is collected
|
|
2914
|
-
self.assertFalse(llvm.report_and_reset_timings())
|
|
2915
|
-
|
|
2916
|
-
|
|
2917
2540
|
class TestLLVMLockCallbacks(BaseTest):
|
|
2918
2541
|
def test_lock_callbacks(self):
|
|
2919
2542
|
events = []
|
|
@@ -2930,7 +2553,7 @@ class TestLLVMLockCallbacks(BaseTest):
|
|
|
2930
2553
|
# Check: events are initially empty
|
|
2931
2554
|
self.assertFalse(events)
|
|
2932
2555
|
# Call LLVM functions
|
|
2933
|
-
llvm.
|
|
2556
|
+
llvm.create_new_module_pass_manager()
|
|
2934
2557
|
# Check: there must be at least one acq and one rel
|
|
2935
2558
|
self.assertIn("acq", events)
|
|
2936
2559
|
self.assertIn("rel", events)
|
|
@@ -2966,13 +2589,11 @@ class TestPipelineTuningOptions(BaseTest):
|
|
|
2966
2589
|
pto.size_level = i
|
|
2967
2590
|
self.assertEqual(pto.size_level, i)
|
|
2968
2591
|
|
|
2969
|
-
|
|
2970
|
-
|
|
2971
|
-
|
|
2972
|
-
|
|
2973
|
-
|
|
2974
|
-
# for i in (25, 80, 350):
|
|
2975
|
-
# pto.inlining_threshold = i
|
|
2592
|
+
def test_inlining_threshold(self):
|
|
2593
|
+
pto = self.pto()
|
|
2594
|
+
self.assertIsInstance(pto.inlining_threshold, int)
|
|
2595
|
+
for i in (25, 80, 350):
|
|
2596
|
+
pto.inlining_threshold = i
|
|
2976
2597
|
|
|
2977
2598
|
def test_loop_interleaving(self):
|
|
2978
2599
|
pto = self.pto()
|
|
@@ -3058,6 +2679,56 @@ class TestPassBuilder(BaseTest, NewPassManagerMixin):
|
|
|
3058
2679
|
fpm.run(self.module().get_function("sum"), pb)
|
|
3059
2680
|
pb.close()
|
|
3060
2681
|
|
|
2682
|
+
def test_time_passes(self):
|
|
2683
|
+
"""Test pass timing reports for O3 and O0 optimization levels"""
|
|
2684
|
+
def run_with_timing(speed_level):
|
|
2685
|
+
mod = self.module()
|
|
2686
|
+
pb = self.pb(speed_level=speed_level, size_level=0)
|
|
2687
|
+
pb.start_pass_timing()
|
|
2688
|
+
mpm = pb.getModulePassManager()
|
|
2689
|
+
mpm.run(mod, pb)
|
|
2690
|
+
report = pb.finish_pass_timing()
|
|
2691
|
+
pb.close()
|
|
2692
|
+
return report
|
|
2693
|
+
|
|
2694
|
+
report_O3 = run_with_timing(3)
|
|
2695
|
+
report_O0 = run_with_timing(0)
|
|
2696
|
+
|
|
2697
|
+
self.assertIsInstance(report_O3, str)
|
|
2698
|
+
self.assertIsInstance(report_O0, str)
|
|
2699
|
+
self.assertEqual(report_O3.count("Pass execution timing report"), 1)
|
|
2700
|
+
self.assertEqual(report_O0.count("Pass execution timing report"), 1)
|
|
2701
|
+
|
|
2702
|
+
def test_empty_report(self):
|
|
2703
|
+
mod = self.module()
|
|
2704
|
+
pb = self.pb()
|
|
2705
|
+
mpm = pb.getModulePassManager()
|
|
2706
|
+
mpm.run(mod, pb)
|
|
2707
|
+
pb.start_pass_timing()
|
|
2708
|
+
report = pb.finish_pass_timing()
|
|
2709
|
+
pb.close()
|
|
2710
|
+
self.assertFalse(report)
|
|
2711
|
+
|
|
2712
|
+
def test_multiple_timers_error(self):
|
|
2713
|
+
mod = self.module()
|
|
2714
|
+
pb = self.pb()
|
|
2715
|
+
pb.start_pass_timing()
|
|
2716
|
+
mpm = pb.getModulePassManager()
|
|
2717
|
+
mpm.run(mod, pb)
|
|
2718
|
+
pb.finish_pass_timing()
|
|
2719
|
+
with self.assertRaisesRegex(RuntimeError, "only be done once"):
|
|
2720
|
+
pb.start_pass_timing()
|
|
2721
|
+
pb.close()
|
|
2722
|
+
|
|
2723
|
+
def test_empty_report_error(self):
|
|
2724
|
+
mod = self.module()
|
|
2725
|
+
pb = self.pb()
|
|
2726
|
+
mpm = pb.getModulePassManager()
|
|
2727
|
+
mpm.run(mod, pb)
|
|
2728
|
+
with self.assertRaisesRegex(RuntimeError, "not enabled"):
|
|
2729
|
+
pb.finish_pass_timing()
|
|
2730
|
+
pb.close()
|
|
2731
|
+
|
|
3061
2732
|
|
|
3062
2733
|
class TestNewModulePassManager(BaseTest, NewPassManagerMixin):
|
|
3063
2734
|
def pm(self):
|
|
@@ -3118,13 +2789,66 @@ class TestNewModulePassManager(BaseTest, NewPassManagerMixin):
|
|
|
3118
2789
|
|
|
3119
2790
|
def test_add_passes(self):
|
|
3120
2791
|
mpm = self.pm()
|
|
2792
|
+
mpm.add_argument_promotion_pass()
|
|
2793
|
+
mpm.add_post_order_function_attributes_pass()
|
|
3121
2794
|
mpm.add_verifier()
|
|
2795
|
+
mpm.add_constant_merge_pass()
|
|
2796
|
+
mpm.add_dead_arg_elimination_pass()
|
|
2797
|
+
mpm.add_dot_call_graph_printer_pass()
|
|
2798
|
+
mpm.add_always_inliner_pass()
|
|
2799
|
+
mpm.add_rpo_function_attrs_pass()
|
|
2800
|
+
mpm.add_global_dead_code_eliminate_pass()
|
|
2801
|
+
mpm.add_global_opt_pass()
|
|
2802
|
+
mpm.add_ipsccp_pass()
|
|
2803
|
+
mpm.add_internalize_pass()
|
|
2804
|
+
mpm.add_loop_extract_pass()
|
|
2805
|
+
mpm.add_merge_functions_pass()
|
|
2806
|
+
mpm.add_partial_inliner_pass()
|
|
2807
|
+
mpm.add_strip_symbols_pass()
|
|
2808
|
+
mpm.add_strip_dead_debug_info_pass()
|
|
2809
|
+
mpm.add_strip_dead_prototype_pass()
|
|
2810
|
+
mpm.add_strip_debug_declare_pass()
|
|
2811
|
+
mpm.add_strip_non_debug_symbols_pass()
|
|
3122
2812
|
mpm.add_aa_eval_pass()
|
|
3123
2813
|
mpm.add_simplify_cfg_pass()
|
|
3124
2814
|
mpm.add_loop_unroll_pass()
|
|
3125
|
-
mpm.add_loop_rotate_pass()
|
|
3126
2815
|
mpm.add_instruction_combine_pass()
|
|
3127
2816
|
mpm.add_jump_threading_pass()
|
|
2817
|
+
mpm.add_cfg_printer_pass()
|
|
2818
|
+
mpm.add_cfg_only_printer_pass()
|
|
2819
|
+
mpm.add_dom_printer_pass()
|
|
2820
|
+
mpm.add_dom_only_printer_pass()
|
|
2821
|
+
mpm.add_post_dom_printer_pass()
|
|
2822
|
+
mpm.add_post_dom_only_printer_pass()
|
|
2823
|
+
mpm.add_dom_viewer_pass()
|
|
2824
|
+
mpm.add_dom_only_printer_pass()
|
|
2825
|
+
mpm.add_post_dom_viewer_pass()
|
|
2826
|
+
mpm.add_post_dom_only_viewer_pass()
|
|
2827
|
+
mpm.add_lint_pass()
|
|
2828
|
+
mpm.add_aggressive_dce_pass()
|
|
2829
|
+
mpm.add_break_critical_edges_pass()
|
|
2830
|
+
mpm.add_dead_store_elimination_pass()
|
|
2831
|
+
mpm.add_dead_code_elimination_pass()
|
|
2832
|
+
mpm.add_aggressive_instcombine_pass()
|
|
2833
|
+
mpm.add_lcssa_pass()
|
|
2834
|
+
mpm.add_new_gvn_pass()
|
|
2835
|
+
mpm.add_loop_simplify_pass()
|
|
2836
|
+
mpm.add_loop_unroll_and_jam_pass()
|
|
2837
|
+
mpm.add_sccp_pass()
|
|
2838
|
+
mpm.add_lower_atomic_pass()
|
|
2839
|
+
mpm.add_lower_invoke_pass()
|
|
2840
|
+
mpm.add_lower_switch_pass()
|
|
2841
|
+
mpm.add_mem_copy_opt_pass()
|
|
2842
|
+
mpm.add_unify_function_exit_nodes_pass()
|
|
2843
|
+
mpm.add_reassociate_pass()
|
|
2844
|
+
mpm.add_register_to_memory_pass()
|
|
2845
|
+
mpm.add_sroa_pass()
|
|
2846
|
+
mpm.add_sinking_pass()
|
|
2847
|
+
mpm.add_tail_call_elimination_pass()
|
|
2848
|
+
mpm.add_instruction_namer_pass()
|
|
2849
|
+
mpm.add_loop_deletion_pass()
|
|
2850
|
+
mpm.add_loop_strength_reduce_pass()
|
|
2851
|
+
mpm.add_loop_rotate_pass()
|
|
3128
2852
|
mpm.add_refprune_pass()
|
|
3129
2853
|
|
|
3130
2854
|
|
|
@@ -3198,11 +2922,229 @@ class TestNewFunctionPassManager(BaseTest, NewPassManagerMixin):
|
|
|
3198
2922
|
fpm.add_aa_eval_pass()
|
|
3199
2923
|
fpm.add_simplify_cfg_pass()
|
|
3200
2924
|
fpm.add_loop_unroll_pass()
|
|
3201
|
-
fpm.add_loop_rotate_pass()
|
|
3202
2925
|
fpm.add_instruction_combine_pass()
|
|
3203
2926
|
fpm.add_jump_threading_pass()
|
|
2927
|
+
fpm.add_cfg_printer_pass()
|
|
2928
|
+
fpm.add_cfg_only_printer_pass()
|
|
2929
|
+
fpm.add_dom_printer_pass()
|
|
2930
|
+
fpm.add_dom_only_printer_pass()
|
|
2931
|
+
fpm.add_post_dom_printer_pass()
|
|
2932
|
+
fpm.add_post_dom_only_printer_pass()
|
|
2933
|
+
fpm.add_dom_viewer_pass()
|
|
2934
|
+
fpm.add_dom_only_printer_pass()
|
|
2935
|
+
fpm.add_post_dom_viewer_pass()
|
|
2936
|
+
fpm.add_post_dom_only_viewer_pass()
|
|
2937
|
+
fpm.add_lint_pass()
|
|
2938
|
+
fpm.add_aggressive_dce_pass()
|
|
2939
|
+
fpm.add_break_critical_edges_pass()
|
|
2940
|
+
fpm.add_dead_store_elimination_pass()
|
|
2941
|
+
fpm.add_dead_code_elimination_pass()
|
|
2942
|
+
fpm.add_aggressive_instcombine_pass()
|
|
2943
|
+
fpm.add_lcssa_pass()
|
|
2944
|
+
fpm.add_new_gvn_pass()
|
|
2945
|
+
fpm.add_loop_simplify_pass()
|
|
2946
|
+
fpm.add_loop_unroll_and_jam_pass()
|
|
2947
|
+
fpm.add_sccp_pass()
|
|
2948
|
+
fpm.add_lower_atomic_pass()
|
|
2949
|
+
fpm.add_lower_invoke_pass()
|
|
2950
|
+
fpm.add_lower_switch_pass()
|
|
2951
|
+
fpm.add_mem_copy_opt_pass()
|
|
2952
|
+
fpm.add_unify_function_exit_nodes_pass()
|
|
2953
|
+
fpm.add_reassociate_pass()
|
|
2954
|
+
fpm.add_register_to_memory_pass()
|
|
2955
|
+
fpm.add_sroa_pass()
|
|
2956
|
+
fpm.add_sinking_pass()
|
|
2957
|
+
fpm.add_tail_call_elimination_pass()
|
|
2958
|
+
fpm.add_instruction_namer_pass()
|
|
2959
|
+
fpm.add_loop_deletion_pass()
|
|
2960
|
+
fpm.add_loop_strength_reduce_pass()
|
|
2961
|
+
fpm.add_loop_rotate_pass()
|
|
3204
2962
|
fpm.add_refprune_pass()
|
|
3205
2963
|
|
|
3206
2964
|
|
|
2965
|
+
@unittest.skipUnless(os.environ.get('LLVMLITE_DIST_TEST'),
|
|
2966
|
+
"Distribution-specific test")
|
|
2967
|
+
@needs_lief
|
|
2968
|
+
class TestBuild(TestCase):
|
|
2969
|
+
# These tests are for use by the Numba project maintainers to check that
|
|
2970
|
+
# package builds for which they are responsible are producing artifacts in
|
|
2971
|
+
# the expected way. If you are a package maintainer and these tests are
|
|
2972
|
+
# running, they shouldn't be by default. The only way they will run is if
|
|
2973
|
+
# the environment variable LLVMLITE_DIST_TEST is set. The things they are
|
|
2974
|
+
# checking are based on how the Numba project maintainers want to ship the
|
|
2975
|
+
# packages, this may be entirely different to how other maintainers wish to
|
|
2976
|
+
# ship. Basically, don't enable these tests unless you are sure they are
|
|
2977
|
+
# suitable for your use case.
|
|
2978
|
+
#
|
|
2979
|
+
# The llvmlite DSO is the foundation of Numba's JIT compiler stack and is
|
|
2980
|
+
# also used by other similar projects. It has to link against LLVM as that
|
|
2981
|
+
# is what provides the tooling to do e.g. IR generation and JIT compilation.
|
|
2982
|
+
# There are various options surrounding how to build LLVM and then how to
|
|
2983
|
+
# link it into llvmlite. There have been many occurences of surprising
|
|
2984
|
+
# linkages, symbol collisions and various other issues.
|
|
2985
|
+
#
|
|
2986
|
+
# The following tests are designed to try and test out some of the more
|
|
2987
|
+
# common combinations of package type and linkage.
|
|
2988
|
+
#
|
|
2989
|
+
# NOTE: For Numba project maintainers on packaging formats and expected
|
|
2990
|
+
# linkage. The following dictionaries capture the state of linkage as of
|
|
2991
|
+
# llvmlite release 0.44. This is not an indication that it is correct, just
|
|
2992
|
+
# that this is what is present in practice and clearly "works" to a large
|
|
2993
|
+
# degree by virtue of having fixed the few reported issues. If you need to
|
|
2994
|
+
# modify these dictionaries based on new information, that's fine, just make
|
|
2995
|
+
# sure that it is an understood action opposed to just capturing what
|
|
2996
|
+
# happened!
|
|
2997
|
+
|
|
2998
|
+
wheel_expected = {"linux": {"x86_64": set(["pthread",
|
|
2999
|
+
"z",
|
|
3000
|
+
"dl",
|
|
3001
|
+
"m",
|
|
3002
|
+
"gcc_s",
|
|
3003
|
+
"c",
|
|
3004
|
+
"rt",
|
|
3005
|
+
"stdc++",
|
|
3006
|
+
"ld-linux-x86-64",]),
|
|
3007
|
+
"aarch64": set(["pthread",
|
|
3008
|
+
"z",
|
|
3009
|
+
"dl",
|
|
3010
|
+
"m",
|
|
3011
|
+
"gcc_s",
|
|
3012
|
+
"c",
|
|
3013
|
+
"rt",
|
|
3014
|
+
"stdc++",]),
|
|
3015
|
+
}, # end linux
|
|
3016
|
+
# NOTE: on windows, this includes a "capture what is
|
|
3017
|
+
# present and known to work and make sure it doesn"t
|
|
3018
|
+
# change" approach.
|
|
3019
|
+
"windows": {"amd64": set(["advapi32",
|
|
3020
|
+
"kernel32",
|
|
3021
|
+
"ntdll",
|
|
3022
|
+
"msvcp140",
|
|
3023
|
+
"vcruntime140",
|
|
3024
|
+
"vcruntime140_1",
|
|
3025
|
+
"api-ms-win-crt-convert-l1-1-0",
|
|
3026
|
+
"api-ms-win-crt-environment-l1-1-0", # noqa: E501
|
|
3027
|
+
"api-ms-win-crt-heap-l1-1-0",
|
|
3028
|
+
"api-ms-win-crt-locale-l1-1-0",
|
|
3029
|
+
"api-ms-win-crt-math-l1-1-0",
|
|
3030
|
+
"api-ms-win-crt-runtime-l1-1-0",
|
|
3031
|
+
"api-ms-win-crt-stdio-l1-1-0",
|
|
3032
|
+
"api-ms-win-crt-string-l1-1-0",
|
|
3033
|
+
"api-ms-win-crt-time-l1-1-0",
|
|
3034
|
+
"api-ms-win-crt-utility-l1-1-0",
|
|
3035
|
+
"shell32", # this is delayed
|
|
3036
|
+
"ole32",]), # also delayed
|
|
3037
|
+
}, # end windows
|
|
3038
|
+
"darwin": {"x86_64": set(["llvmlite",
|
|
3039
|
+
"system",
|
|
3040
|
+
"z",
|
|
3041
|
+
"corefoundation",
|
|
3042
|
+
"c++",]),
|
|
3043
|
+
"arm64": set(["llvmlite",
|
|
3044
|
+
"system",
|
|
3045
|
+
"z",
|
|
3046
|
+
"c++",]),
|
|
3047
|
+
},# end darwin
|
|
3048
|
+
} # end wheel_expected
|
|
3049
|
+
|
|
3050
|
+
conda_expected = {"linux": {"x86_64": set(["pthread",
|
|
3051
|
+
"z",
|
|
3052
|
+
"zstd",
|
|
3053
|
+
"dl",
|
|
3054
|
+
"m",
|
|
3055
|
+
"gcc_s",
|
|
3056
|
+
"c",
|
|
3057
|
+
# "stdc++", conda has static c++
|
|
3058
|
+
"ld-linux-x86-64",]),
|
|
3059
|
+
"aarch64": set(["pthread",
|
|
3060
|
+
"z",
|
|
3061
|
+
"zstd",
|
|
3062
|
+
"dl",
|
|
3063
|
+
"m",
|
|
3064
|
+
"gcc_s",
|
|
3065
|
+
"c",
|
|
3066
|
+
# "stdc++", conda has static c++ # noqa: E501
|
|
3067
|
+
"ld-linux-aarch64",]),
|
|
3068
|
+
}, # end linux
|
|
3069
|
+
# NOTE: on windows, this includes a "capture what is
|
|
3070
|
+
# present and known to work and make sure it doesn"t
|
|
3071
|
+
# change" approach.
|
|
3072
|
+
"windows": {"amd64": set(["z",
|
|
3073
|
+
"zstd",
|
|
3074
|
+
"advapi32",
|
|
3075
|
+
"kernel32",
|
|
3076
|
+
"ntdll",
|
|
3077
|
+
"msvcp140",
|
|
3078
|
+
"vcruntime140",
|
|
3079
|
+
"vcruntime140_1",
|
|
3080
|
+
"api-ms-win-crt-convert-l1-1-0",
|
|
3081
|
+
"api-ms-win-crt-environment-l1-1-0", # noqa: E501
|
|
3082
|
+
"api-ms-win-crt-heap-l1-1-0",
|
|
3083
|
+
"api-ms-win-crt-locale-l1-1-0",
|
|
3084
|
+
"api-ms-win-crt-math-l1-1-0",
|
|
3085
|
+
"api-ms-win-crt-runtime-l1-1-0",
|
|
3086
|
+
"api-ms-win-crt-stdio-l1-1-0",
|
|
3087
|
+
"api-ms-win-crt-string-l1-1-0",
|
|
3088
|
+
"api-ms-win-crt-time-l1-1-0",
|
|
3089
|
+
"api-ms-win-crt-utility-l1-1-0",
|
|
3090
|
+
"shell32", # this is delayed
|
|
3091
|
+
"ole32",]), # also delayed
|
|
3092
|
+
}, # end windows
|
|
3093
|
+
"darwin": {"x86_64": set(["llvmlite",
|
|
3094
|
+
"system",
|
|
3095
|
+
"z",
|
|
3096
|
+
"zstd",
|
|
3097
|
+
"corefoundation",
|
|
3098
|
+
"c++",]),
|
|
3099
|
+
"arm64": set(["llvmlite",
|
|
3100
|
+
"system",
|
|
3101
|
+
"z",
|
|
3102
|
+
"zstd",
|
|
3103
|
+
"c++",]),
|
|
3104
|
+
},# end darwin
|
|
3105
|
+
} # end wheel_expected
|
|
3106
|
+
|
|
3107
|
+
def check_linkage(self, info, package_type):
|
|
3108
|
+
machine = platform.machine().lower()
|
|
3109
|
+
os_name = platform.system().lower()
|
|
3110
|
+
|
|
3111
|
+
if package_type == "wheel":
|
|
3112
|
+
expected = self.wheel_expected[os_name][machine]
|
|
3113
|
+
elif package_type == "conda":
|
|
3114
|
+
expected = self.conda_expected[os_name][machine]
|
|
3115
|
+
else:
|
|
3116
|
+
raise ValueError(f"Unexpected package type: {package_type}")
|
|
3117
|
+
|
|
3118
|
+
got = set(info["canonicalised_linked_libraries"])
|
|
3119
|
+
|
|
3120
|
+
try:
|
|
3121
|
+
self.assertEqual(expected, got)
|
|
3122
|
+
except AssertionError as e:
|
|
3123
|
+
msg = ("Unexpected linkage encountered for libllvmlite:\n"
|
|
3124
|
+
f"Expected: {sorted(expected)}\n"
|
|
3125
|
+
f" Got: {sorted(got)}\n\n"
|
|
3126
|
+
f"Difference: {set.symmetric_difference(expected, got)}\n"
|
|
3127
|
+
f"Only in Expected: {set.difference(expected, got)}\n"
|
|
3128
|
+
f"Only in Got: {set.difference(got, expected)}\n")
|
|
3129
|
+
raise AssertionError(msg) from e
|
|
3130
|
+
|
|
3131
|
+
@is_wheel_package
|
|
3132
|
+
def test_wheel_build(self):
|
|
3133
|
+
info = llvm.config.get_sysinfo()
|
|
3134
|
+
self.assertEqual(info['llvm_linkage_type'], "static")
|
|
3135
|
+
self.assertEqual(info['llvm_assertions_state'], "on")
|
|
3136
|
+
self.check_linkage(info, "wheel")
|
|
3137
|
+
|
|
3138
|
+
@is_conda_package
|
|
3139
|
+
def test_conda_build(self):
|
|
3140
|
+
info = llvm.config.get_sysinfo()
|
|
3141
|
+
self.assertEqual(info['llvm_linkage_type'], "static")
|
|
3142
|
+
self.assertEqual(info['llvm_assertions_state'], "on")
|
|
3143
|
+
|
|
3144
|
+
self.check_linkage(info, "conda")
|
|
3145
|
+
if platform.system().lower() == "linux":
|
|
3146
|
+
self.assertEqual(info['libstdcxx_linkage_type'], "static")
|
|
3147
|
+
|
|
3148
|
+
|
|
3207
3149
|
if __name__ == "__main__":
|
|
3208
3150
|
unittest.main()
|