llvmlite 0.44.0rc2__cp311-cp311-win_amd64.whl → 0.45.0rc2__cp311-cp311-win_amd64.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of llvmlite might be problematic. Click here for more details.

@@ -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\tft0, 8(sp)',
419
- 'fmv.w.x\tft1, a0',
420
- 'fcvt.d.s\tft1, ft1',
421
- 'fadd.d\tft0, ft1, ft0',
422
- 'fsd\tft0, 8(sp)',
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\tft0, 8(sp)',
435
- 'fcvt.d.s\tft1, fa0',
436
- 'fadd.d\tft0, ft1, ft0',
437
- 'fsd\tft0, 8(sp)',
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\tft0, fa0',
447
- 'fadd.d\tfa0, ft0, fa1',
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
- self.fail("unexpected dependency %r in %r" % (dep, deps))
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 = (15, 16)
943
+ valid = (20,)
918
944
  self.assertIn(major, valid)
919
- self.assertIn(patch, range(8))
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
- @unittest.skipUnless(platform.machine().startswith("x86"), "x86 only")
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
- # FIXME: Remove `else' once TP are no longer supported.
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 == 16 else b'readonly']
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
- # FIXME: Remove `else' once TP are no longer supported.
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
- # FIXME: Remove `else' once TP are no longer supported.
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
- has_text = False
2473
+ has_text_and_data = False
2826
2474
  last_address = -1
2827
2475
  for s in obj.sections():
2828
- if s.is_text():
2829
- has_text = True
2830
- self.assertIsNotNone(s.name())
2831
- self.assertTrue(s.size() > 0)
2832
- self.assertTrue(len(s.data()) > 0)
2833
- self.assertIsNotNone(s.address())
2834
- self.assertTrue(last_address < s.address())
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(has_text)
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.create_module_pass_manager()
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
- # // FIXME: Available from llvm16
2970
- # def test_inlining_threshold(self):
2971
- # pto = self.pto()
2972
- # with self.assertRaises(NotImplementedError):
2973
- # pto.inlining_threshold
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()