llvmlite 0.43.0rc1__cp311-cp311-macosx_11_0_arm64.whl → 0.44.0rc2__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 +7 -0
- llvmlite/_version.py +2 -2
- llvmlite/binding/__init__.py +1 -0
- llvmlite/binding/context.py +12 -2
- llvmlite/binding/ffi.py +6 -1
- llvmlite/binding/libllvmlite.dylib +0 -0
- llvmlite/binding/newpassmanagers.py +357 -0
- llvmlite/binding/passmanagers.py +25 -18
- llvmlite/binding/targets.py +75 -5
- llvmlite/binding/typeref.py +88 -1
- llvmlite/binding/value.py +14 -0
- llvmlite/ir/builder.py +8 -7
- llvmlite/ir/context.py +2 -2
- llvmlite/ir/instructions.py +52 -25
- llvmlite/ir/types.py +137 -17
- llvmlite/ir/values.py +2 -2
- llvmlite/tests/test_binding.py +663 -40
- llvmlite/tests/test_ir.py +411 -146
- llvmlite/tests/test_refprune.py +179 -6
- {llvmlite-0.43.0rc1.dist-info → llvmlite-0.44.0rc2.dist-info}/METADATA +7 -6
- llvmlite-0.44.0rc2.dist-info/RECORD +46 -0
- {llvmlite-0.43.0rc1.dist-info → llvmlite-0.44.0rc2.dist-info}/WHEEL +1 -1
- llvmlite-0.43.0rc1.dist-info/RECORD +0 -45
- {llvmlite-0.43.0rc1.dist-info → llvmlite-0.44.0rc2.dist-info}/LICENSE +0 -0
- {llvmlite-0.43.0rc1.dist-info → llvmlite-0.44.0rc2.dist-info}/LICENSE.thirdparty +0 -0
- {llvmlite-0.43.0rc1.dist-info → llvmlite-0.44.0rc2.dist-info}/top_level.txt +0 -0
llvmlite/tests/test_binding.py
CHANGED
|
@@ -18,7 +18,8 @@ from llvmlite import binding as llvm
|
|
|
18
18
|
from llvmlite.binding import ffi
|
|
19
19
|
from llvmlite.tests import TestCase
|
|
20
20
|
|
|
21
|
-
|
|
21
|
+
# FIXME: Remove me once typed pointers are no longer supported.
|
|
22
|
+
from llvmlite import opaque_pointers_enabled
|
|
22
23
|
|
|
23
24
|
# arvm7l needs extra ABI symbols to link successfully
|
|
24
25
|
if platform.machine() == 'armv7l':
|
|
@@ -78,6 +79,16 @@ asm_sum3 = r"""
|
|
|
78
79
|
}}
|
|
79
80
|
"""
|
|
80
81
|
|
|
82
|
+
asm_sum4 = r"""
|
|
83
|
+
; ModuleID = '<string>'
|
|
84
|
+
target triple = "{triple}"
|
|
85
|
+
|
|
86
|
+
define i32 @sum(i32 %.1, i32 %.2) {{
|
|
87
|
+
%.3 = add i32 %.1, %.2
|
|
88
|
+
ret i32 0
|
|
89
|
+
}}
|
|
90
|
+
"""
|
|
91
|
+
|
|
81
92
|
asm_mul = r"""
|
|
82
93
|
; ModuleID = '<string>'
|
|
83
94
|
target triple = "{triple}"
|
|
@@ -444,6 +455,26 @@ declare void @a_readonly_func(i8 *) readonly
|
|
|
444
455
|
declare i8* @a_arg0_return_func(i8* returned, i32*)
|
|
445
456
|
"""
|
|
446
457
|
|
|
458
|
+
asm_alloca_optnone = r"""
|
|
459
|
+
define double @foo(i32 %i, double %j) optnone noinline {
|
|
460
|
+
%I = alloca i32 ; <i32*> [#uses=4]
|
|
461
|
+
%J = alloca double ; <double*> [#uses=2]
|
|
462
|
+
store i32 %i, i32* %I
|
|
463
|
+
store double %j, double* %J
|
|
464
|
+
%t1 = load i32, i32* %I ; <i32> [#uses=1]
|
|
465
|
+
%t2 = add i32 %t1, 1 ; <i32> [#uses=1]
|
|
466
|
+
store i32 %t2, i32* %I
|
|
467
|
+
%t3 = load i32, i32* %I ; <i32> [#uses=1]
|
|
468
|
+
%t4 = sitofp i32 %t3 to double ; <double> [#uses=1]
|
|
469
|
+
%t5 = load double, double* %J ; <double> [#uses=1]
|
|
470
|
+
%t6 = fmul double %t4, %t5 ; <double> [#uses=1]
|
|
471
|
+
ret double %t6
|
|
472
|
+
}
|
|
473
|
+
"""
|
|
474
|
+
|
|
475
|
+
asm_declaration = r"""
|
|
476
|
+
declare void @test_declare(i32* )
|
|
477
|
+
"""
|
|
447
478
|
|
|
448
479
|
# This produces the following output from objdump:
|
|
449
480
|
#
|
|
@@ -523,6 +554,102 @@ for.body:
|
|
|
523
554
|
}}
|
|
524
555
|
"""
|
|
525
556
|
|
|
557
|
+
asm_cpp_class = r"""
|
|
558
|
+
; Source C++
|
|
559
|
+
;-----------------------------------------
|
|
560
|
+
; class MyClass;
|
|
561
|
+
;
|
|
562
|
+
; class MyClassDefined{
|
|
563
|
+
; MyClass *member;
|
|
564
|
+
; MyClass *m2;
|
|
565
|
+
; MyClass *m3;
|
|
566
|
+
; };
|
|
567
|
+
;
|
|
568
|
+
; void foo(MyClass *c, MyClassDefined){ }
|
|
569
|
+
;-----------------------------------------
|
|
570
|
+
; LLVM-IR by: clang -arch arm64 -S -emit-llvm file.cpp
|
|
571
|
+
; ModuleID = 'file.cpp'
|
|
572
|
+
source_filename = "class.cpp"
|
|
573
|
+
target datalayout = "e-m:o-i64:64-i128:128-n32:64-S128"
|
|
574
|
+
target triple = "arm64-apple-macosx13.3.0"
|
|
575
|
+
|
|
576
|
+
%class.MyClass = type opaque
|
|
577
|
+
%class.MyClassDefined = type { %class.MyClass*, %class.MyClass*, %class.MyClass* }
|
|
578
|
+
|
|
579
|
+
; Function Attrs: noinline nounwind optnone ssp uwtable(sync)
|
|
580
|
+
define void @_Z3fooP7MyClass14MyClassDefined(%class.MyClass* noundef %0, %class.MyClassDefined* noundef %1) {
|
|
581
|
+
%3 = alloca %class.MyClass*, align 8
|
|
582
|
+
store %class.MyClass* %0, %class.MyClass** %3, align 8
|
|
583
|
+
ret void
|
|
584
|
+
}
|
|
585
|
+
|
|
586
|
+
!llvm.module.flags = !{!0, !1, !2, !3, !4, !5, !6, !7, !8}
|
|
587
|
+
!llvm.ident = !{!9}
|
|
588
|
+
|
|
589
|
+
!0 = !{i32 2, !"SDK Version", [2 x i32] [i32 13, i32 3]}
|
|
590
|
+
!1 = !{i32 1, !"wchar_size", i32 4}
|
|
591
|
+
!2 = !{i32 8, !"branch-target-enforcement", i32 0}
|
|
592
|
+
!3 = !{i32 8, !"sign-return-address", i32 0}
|
|
593
|
+
!4 = !{i32 8, !"sign-return-address-all", i32 0}
|
|
594
|
+
!5 = !{i32 8, !"sign-return-address-with-bkey", i32 0}
|
|
595
|
+
!6 = !{i32 7, !"PIC Level", i32 2}
|
|
596
|
+
!7 = !{i32 7, !"uwtable", i32 1}
|
|
597
|
+
!8 = !{i32 7, !"frame-pointer", i32 1}
|
|
598
|
+
!9 = !{!"Apple clang version 14.0.3 (clang-1403.0.22.14.1)"}
|
|
599
|
+
|
|
600
|
+
""" # noqa
|
|
601
|
+
|
|
602
|
+
asm_cpp_vector = r"""; Source C++
|
|
603
|
+
;-----------------------------------------
|
|
604
|
+
|
|
605
|
+
; struct Vector2D{
|
|
606
|
+
; float x, y;
|
|
607
|
+
; };
|
|
608
|
+
;
|
|
609
|
+
; void foo(Vector2D vec, Vector2D *out) {
|
|
610
|
+
; *out = vec;
|
|
611
|
+
; }
|
|
612
|
+
;-----------------------------------------
|
|
613
|
+
; LLVM-IR by: clang -arch x86_64 -S -emit-llvm file.cpp
|
|
614
|
+
; ModuleID = 'file.cpp'
|
|
615
|
+
source_filename = "class.cpp"
|
|
616
|
+
target datalayout = "e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
|
|
617
|
+
target triple = "x86_64-apple-macosx13.3.0"
|
|
618
|
+
|
|
619
|
+
%struct.Vector2D = type { float, float }
|
|
620
|
+
|
|
621
|
+
; Function Attrs: noinline nounwind optnone ssp uwtable
|
|
622
|
+
define void @_Z3foo8Vector2DPS_(<2 x float> %0, %struct.Vector2D* noundef %1) #0 {
|
|
623
|
+
%3 = alloca %struct.Vector2D, align 4
|
|
624
|
+
%4 = alloca %struct.Vector2D*, align 8
|
|
625
|
+
%5 = bitcast %struct.Vector2D* %3 to <2 x float>*
|
|
626
|
+
store <2 x float> %0, <2 x float>* %5, align 4
|
|
627
|
+
store %struct.Vector2D* %1, %struct.Vector2D** %4, align 8
|
|
628
|
+
%6 = load %struct.Vector2D*, %struct.Vector2D** %4, align 8
|
|
629
|
+
%7 = bitcast %struct.Vector2D* %6 to i8*
|
|
630
|
+
%8 = bitcast %struct.Vector2D* %3 to i8*
|
|
631
|
+
call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 4 %7, i8* align 4 %8, i64 8, i1 false)
|
|
632
|
+
ret void
|
|
633
|
+
}
|
|
634
|
+
|
|
635
|
+
; Function Attrs: argmemonly nofree nounwind willreturn
|
|
636
|
+
declare void @llvm.memcpy.p0i8.p0i8.i64(i8* noalias nocapture writeonly, i8* noalias nocapture readonly, i64, i1 immarg) #1
|
|
637
|
+
|
|
638
|
+
attributes #0 = { noinline nounwind optnone ssp uwtable "darwin-stkchk-strong-link" "frame-pointer"="all" "min-legal-vector-width"="64" "no-trapping-math"="true" "probe-stack"="___chkstk_darwin" "stack-protector-buffer-size"="8" "target-cpu"="penryn" "target-features"="+cx16,+cx8,+fxsr,+mmx,+sahf,+sse,+sse2,+sse3,+sse4.1,+ssse3,+x87" "tune-cpu"="generic" }
|
|
639
|
+
attributes #1 = { argmemonly nofree nounwind willreturn }
|
|
640
|
+
|
|
641
|
+
!llvm.module.flags = !{!0, !1, !2, !3, !4}
|
|
642
|
+
!llvm.ident = !{!5}
|
|
643
|
+
|
|
644
|
+
!0 = !{i32 2, !"SDK Version", [2 x i32] [i32 13, i32 3]}
|
|
645
|
+
!1 = !{i32 1, !"wchar_size", i32 4}
|
|
646
|
+
!2 = !{i32 7, !"PIC Level", i32 2}
|
|
647
|
+
!3 = !{i32 7, !"uwtable", i32 2}
|
|
648
|
+
!4 = !{i32 7, !"frame-pointer", i32 2}
|
|
649
|
+
!5 = !{!"Apple clang version 14.0.3 (clang-1403.0.22.14.1)"}
|
|
650
|
+
|
|
651
|
+
""" # noqa
|
|
652
|
+
|
|
526
653
|
|
|
527
654
|
class BaseTest(TestCase):
|
|
528
655
|
|
|
@@ -787,7 +914,7 @@ class TestMisc(BaseTest):
|
|
|
787
914
|
def test_version(self):
|
|
788
915
|
major, minor, patch = llvm.llvm_version_info
|
|
789
916
|
# one of these can be valid
|
|
790
|
-
valid = (
|
|
917
|
+
valid = (15, 16)
|
|
791
918
|
self.assertIn(major, valid)
|
|
792
919
|
self.assertIn(patch, range(8))
|
|
793
920
|
|
|
@@ -986,13 +1113,9 @@ class TestModuleRef(BaseTest):
|
|
|
986
1113
|
with self.assertRaises(RuntimeError) as cm:
|
|
987
1114
|
llvm.parse_bitcode(b"")
|
|
988
1115
|
self.assertIn("LLVM bitcode parsing error", str(cm.exception))
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
else:
|
|
993
|
-
self.assertIn(
|
|
994
|
-
"file too small to contain bitcode header", str(cm.exception),
|
|
995
|
-
)
|
|
1116
|
+
self.assertIn(
|
|
1117
|
+
"file too small to contain bitcode header", str(cm.exception),
|
|
1118
|
+
)
|
|
996
1119
|
|
|
997
1120
|
def test_bitcode_roundtrip(self):
|
|
998
1121
|
# create a new context to avoid struct renaming
|
|
@@ -1116,14 +1239,14 @@ class JITTestMixin(object):
|
|
|
1116
1239
|
for g in (gv_i32, gv_i8, gv_struct):
|
|
1117
1240
|
self.assertEqual(td.get_abi_size(g.type), pointer_size)
|
|
1118
1241
|
|
|
1119
|
-
self.assertEqual(td.
|
|
1120
|
-
self.assertEqual(td.
|
|
1242
|
+
self.assertEqual(td.get_abi_size(gv_i32.global_value_type), 4)
|
|
1243
|
+
self.assertEqual(td.get_abi_alignment(gv_i32.global_value_type), 4)
|
|
1121
1244
|
|
|
1122
|
-
self.assertEqual(td.
|
|
1123
|
-
self.assertIn(td.
|
|
1245
|
+
self.assertEqual(td.get_abi_size(gv_i8.global_value_type), 1)
|
|
1246
|
+
self.assertIn(td.get_abi_alignment(gv_i8.global_value_type), (1, 2, 4))
|
|
1124
1247
|
|
|
1125
|
-
self.assertEqual(td.
|
|
1126
|
-
self.assertIn(td.
|
|
1248
|
+
self.assertEqual(td.get_abi_size(gv_struct.global_value_type), 24)
|
|
1249
|
+
self.assertIn(td.get_abi_alignment(gv_struct.global_value_type), (4, 8))
|
|
1127
1250
|
|
|
1128
1251
|
def test_object_cache_notify(self):
|
|
1129
1252
|
notifies = []
|
|
@@ -1507,28 +1630,32 @@ class TestValueRef(BaseTest):
|
|
|
1507
1630
|
self.assertEqual(tp.name, "")
|
|
1508
1631
|
st = mod.get_global_variable("glob_struct")
|
|
1509
1632
|
self.assertIsNotNone(re.match(r"struct\.glob_type(\.[\d]+)?",
|
|
1510
|
-
st.
|
|
1633
|
+
st.global_value_type.name))
|
|
1511
1634
|
|
|
1512
1635
|
def test_type_printing_variable(self):
|
|
1513
1636
|
mod = self.module()
|
|
1514
1637
|
glob = mod.get_global_variable("glob")
|
|
1515
|
-
tp = glob.
|
|
1516
|
-
self.assertEqual(str(tp), 'i32
|
|
1638
|
+
tp = glob.global_value_type
|
|
1639
|
+
self.assertEqual(str(tp), 'i32')
|
|
1517
1640
|
|
|
1518
1641
|
def test_type_printing_function(self):
|
|
1519
1642
|
mod = self.module()
|
|
1520
1643
|
fn = mod.get_function("sum")
|
|
1521
|
-
self.assertEqual(str(fn.
|
|
1644
|
+
self.assertEqual(str(fn.global_value_type), "i32 (i32, i32)")
|
|
1522
1645
|
|
|
1523
1646
|
def test_type_printing_struct(self):
|
|
1524
1647
|
mod = self.module()
|
|
1525
1648
|
st = mod.get_global_variable("glob_struct")
|
|
1526
1649
|
self.assertTrue(st.type.is_pointer)
|
|
1527
|
-
|
|
1528
|
-
|
|
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)))
|
|
1529
1656
|
self.assertIsNotNone(re.match(
|
|
1530
1657
|
r"%struct\.glob_type(\.[\d]+)? = type { i64, \[2 x i64\] }",
|
|
1531
|
-
str(st.
|
|
1658
|
+
str(st.global_value_type)))
|
|
1532
1659
|
|
|
1533
1660
|
def test_close(self):
|
|
1534
1661
|
glob = self.glob()
|
|
@@ -1613,11 +1740,13 @@ class TestValueRef(BaseTest):
|
|
|
1613
1740
|
self.assertEqual(str(operands[1].type), 'i32')
|
|
1614
1741
|
|
|
1615
1742
|
def test_function_attributes(self):
|
|
1743
|
+
ver = llvm.llvm_version_info[0]
|
|
1744
|
+
readonly_attrs = [b'memory(read)' if ver == 16 else b'readonly']
|
|
1616
1745
|
mod = self.module(asm_attributes)
|
|
1617
1746
|
for func in mod.functions:
|
|
1618
1747
|
attrs = list(func.attributes)
|
|
1619
1748
|
if func.name == 'a_readonly_func':
|
|
1620
|
-
self.assertEqual(attrs,
|
|
1749
|
+
self.assertEqual(attrs, readonly_attrs)
|
|
1621
1750
|
elif func.name == 'a_arg0_return_func':
|
|
1622
1751
|
self.assertEqual(attrs, [])
|
|
1623
1752
|
args = list(func.arguments)
|
|
@@ -1712,7 +1841,11 @@ class TestValueRef(BaseTest):
|
|
|
1712
1841
|
inst = list(list(func.blocks)[0].instructions)[0]
|
|
1713
1842
|
arg = list(inst.operands)[0]
|
|
1714
1843
|
self.assertTrue(arg.is_constant)
|
|
1715
|
-
|
|
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')
|
|
1716
1849
|
|
|
1717
1850
|
def test_incoming_phi_blocks(self):
|
|
1718
1851
|
mod = self.module(asm_phi_blocks)
|
|
@@ -1741,7 +1874,7 @@ class TestTypeRef(BaseTest):
|
|
|
1741
1874
|
def test_str(self):
|
|
1742
1875
|
mod = self.module()
|
|
1743
1876
|
glob = mod.get_global_variable("glob")
|
|
1744
|
-
self.assertEqual(str(glob.
|
|
1877
|
+
self.assertEqual(str(glob.global_value_type), "i32")
|
|
1745
1878
|
glob_struct_type = mod.get_struct_type("struct.glob_type")
|
|
1746
1879
|
self.assertEqual(str(glob_struct_type),
|
|
1747
1880
|
"%struct.glob_type = type { i64, [2 x i64] }")
|
|
@@ -1761,7 +1894,7 @@ class TestTypeRef(BaseTest):
|
|
|
1761
1894
|
self.assertEqual(glob_struct.type.type_kind, llvm.TypeKind.pointer)
|
|
1762
1895
|
self.assertTrue(glob_struct.type.is_pointer)
|
|
1763
1896
|
|
|
1764
|
-
stype =
|
|
1897
|
+
stype = glob_struct.global_value_type
|
|
1765
1898
|
self.assertEqual(stype.type_kind, llvm.TypeKind.struct)
|
|
1766
1899
|
self.assertTrue(stype.is_struct)
|
|
1767
1900
|
|
|
@@ -1777,7 +1910,7 @@ class TestTypeRef(BaseTest):
|
|
|
1777
1910
|
|
|
1778
1911
|
funcptr = mod.get_function("sum").type
|
|
1779
1912
|
self.assertEqual(funcptr.type_kind, llvm.TypeKind.pointer)
|
|
1780
|
-
functype
|
|
1913
|
+
functype = mod.get_function("sum").global_value_type
|
|
1781
1914
|
self.assertEqual(functype.type_kind, llvm.TypeKind.function)
|
|
1782
1915
|
|
|
1783
1916
|
def test_element_count(self):
|
|
@@ -1805,20 +1938,186 @@ class TestTypeRef(BaseTest):
|
|
|
1805
1938
|
# Variadic function
|
|
1806
1939
|
mod = self.module(asm_vararg_declare)
|
|
1807
1940
|
func = mod.get_function('vararg')
|
|
1808
|
-
decltype = func.
|
|
1941
|
+
decltype = func.global_value_type
|
|
1809
1942
|
self.assertTrue(decltype.is_function_vararg)
|
|
1810
1943
|
|
|
1811
1944
|
mod = self.module(asm_sum_declare)
|
|
1812
1945
|
func = mod.get_function('sum')
|
|
1813
|
-
decltype = func.
|
|
1946
|
+
decltype = func.global_value_type
|
|
1814
1947
|
self.assertFalse(decltype.is_function_vararg)
|
|
1815
1948
|
|
|
1816
1949
|
# test that the function pointer type cannot use is_function_vararg
|
|
1817
1950
|
self.assertTrue(func.type.is_pointer)
|
|
1818
1951
|
with self.assertRaises(ValueError) as raises:
|
|
1819
1952
|
func.type.is_function_vararg
|
|
1820
|
-
|
|
1821
|
-
|
|
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))
|
|
1959
|
+
|
|
1960
|
+
def test_function_typeref_as_ir(self):
|
|
1961
|
+
mod = self.module()
|
|
1962
|
+
|
|
1963
|
+
[fn] = list(mod.functions)
|
|
1964
|
+
# .type gives a pointer type, a problem if it's opaque (llvm15+)
|
|
1965
|
+
self.assertEqual(fn.type.type_kind, llvm.TypeKind.pointer)
|
|
1966
|
+
self.assertFalse(fn.type.is_function)
|
|
1967
|
+
# Use .global_value_type instead
|
|
1968
|
+
fnty = fn.global_value_type
|
|
1969
|
+
self.assertEqual(fnty.type_kind, llvm.TypeKind.function)
|
|
1970
|
+
self.assertTrue(fnty.is_function)
|
|
1971
|
+
# Run .as_ir() to get llvmlite.ir.FunctionType
|
|
1972
|
+
tyir = fnty.as_ir(ir.global_context)
|
|
1973
|
+
self.assertIsInstance(tyir, ir.FunctionType)
|
|
1974
|
+
self.assertEqual(tyir.args, (ir.IntType(32), ir.IntType(32)))
|
|
1975
|
+
self.assertEqual(tyir.return_type ,ir.IntType(32))
|
|
1976
|
+
|
|
1977
|
+
def test_void_typeref_as_ir(self):
|
|
1978
|
+
# Void type can only be used as return-type of llvmlite.ir.FunctionType.
|
|
1979
|
+
fnty = ir.FunctionType(ir.VoidType(), ())
|
|
1980
|
+
irmod = ir.Module()
|
|
1981
|
+
fn = ir.Function(irmod, fnty, "foo")
|
|
1982
|
+
mod = self.module(str(irmod))
|
|
1983
|
+
fn = mod.get_function("foo")
|
|
1984
|
+
gvty = fn.global_value_type
|
|
1985
|
+
self.assertEqual(fnty.return_type,
|
|
1986
|
+
gvty.as_ir(ir.global_context).return_type)
|
|
1987
|
+
|
|
1988
|
+
def test_global_typeref_as_ir(self):
|
|
1989
|
+
from llvmlite.binding.typeref import _TypeKindToIRType
|
|
1990
|
+
ctx = ir.Context()
|
|
1991
|
+
|
|
1992
|
+
skipped = {
|
|
1993
|
+
"function", # tested in test_function_typeref_as_ir
|
|
1994
|
+
"void", # tested in test_void_typeref_as_ir
|
|
1995
|
+
}
|
|
1996
|
+
|
|
1997
|
+
makers = {}
|
|
1998
|
+
|
|
1999
|
+
def maker_half():
|
|
2000
|
+
yield ir.HalfType()
|
|
2001
|
+
|
|
2002
|
+
makers['half'] = maker_half
|
|
2003
|
+
|
|
2004
|
+
def maker_float():
|
|
2005
|
+
yield ir.FloatType()
|
|
2006
|
+
|
|
2007
|
+
makers['float'] = maker_float
|
|
2008
|
+
|
|
2009
|
+
def maker_double():
|
|
2010
|
+
yield ir.DoubleType()
|
|
2011
|
+
|
|
2012
|
+
makers['double'] = maker_double
|
|
2013
|
+
|
|
2014
|
+
def maker_integer():
|
|
2015
|
+
yield ir.IntType(32)
|
|
2016
|
+
|
|
2017
|
+
makers['integer'] = maker_integer
|
|
2018
|
+
|
|
2019
|
+
def maker_pointer():
|
|
2020
|
+
yield ir.PointerType(ir.IntType(8))
|
|
2021
|
+
# opaque struct ptr
|
|
2022
|
+
yield ctx.get_identified_type("myclass").as_pointer()
|
|
2023
|
+
# named struct with defined body
|
|
2024
|
+
myclass2 = ctx.get_identified_type("myclass2")
|
|
2025
|
+
myclass2.set_body(ir.IntType(8))
|
|
2026
|
+
yield myclass2.as_pointer()
|
|
2027
|
+
|
|
2028
|
+
makers['pointer'] = maker_pointer
|
|
2029
|
+
|
|
2030
|
+
def maker_array():
|
|
2031
|
+
yield ir.ArrayType(ir.IntType(8), 123)
|
|
2032
|
+
|
|
2033
|
+
makers['array'] = maker_array
|
|
2034
|
+
|
|
2035
|
+
def maker_vector():
|
|
2036
|
+
yield ir.VectorType(ir.FloatType(), 2)
|
|
2037
|
+
|
|
2038
|
+
makers['vector'] = maker_vector
|
|
2039
|
+
|
|
2040
|
+
def maker_struct():
|
|
2041
|
+
yield ir.LiteralStructType([ir.FloatType(), ir.IntType(64)])
|
|
2042
|
+
yield ir.LiteralStructType([ir.FloatType(), ir.IntType(64)],
|
|
2043
|
+
packed=True)
|
|
2044
|
+
|
|
2045
|
+
makers['struct'] = maker_struct
|
|
2046
|
+
|
|
2047
|
+
# Ensure that number of supported TypeKind matches number of makers
|
|
2048
|
+
self.assertEqual({x.name for x in _TypeKindToIRType.keys()},
|
|
2049
|
+
set(makers.keys()) | set(skipped))
|
|
2050
|
+
|
|
2051
|
+
# Test each type-kind
|
|
2052
|
+
for type_kind, irtype in _TypeKindToIRType.items():
|
|
2053
|
+
if type_kind.name in skipped:
|
|
2054
|
+
continue
|
|
2055
|
+
for ty in makers[type_kind.name]():
|
|
2056
|
+
with self.subTest(f"{type_kind!s} -> {ty}"):
|
|
2057
|
+
irmod = ir.Module(context=ctx)
|
|
2058
|
+
ir.GlobalVariable(irmod, ty, name='gv')
|
|
2059
|
+
asm = str(irmod)
|
|
2060
|
+
mod = llvm.parse_assembly(asm)
|
|
2061
|
+
gv = mod.get_global_variable("gv")
|
|
2062
|
+
gvty = gv.global_value_type
|
|
2063
|
+
got = gvty.as_ir(ir.Context()) # fresh context
|
|
2064
|
+
self.assertEqual(got, ty)
|
|
2065
|
+
self.assertIsInstance(got, irtype)
|
|
2066
|
+
|
|
2067
|
+
def _check_typeref_as_ir_for_wrappers(self, asm, target_symbol):
|
|
2068
|
+
# Get a clang++ defined function from a llvm ir
|
|
2069
|
+
mod = llvm.parse_assembly(asm)
|
|
2070
|
+
cppfn = mod.get_function(target_symbol)
|
|
2071
|
+
cppfntype = cppfn.global_value_type
|
|
2072
|
+
|
|
2073
|
+
# Get the function type into a new context
|
|
2074
|
+
my_context = ir.Context() # don't populate global context
|
|
2075
|
+
ty = cppfntype.as_ir(ir_ctx=my_context)
|
|
2076
|
+
|
|
2077
|
+
# Build a wrapper module for the cpp function
|
|
2078
|
+
wrapper_mod = ir.Module(context=my_context)
|
|
2079
|
+
# declare the original function
|
|
2080
|
+
declfn = ir.Function(wrapper_mod, ty, name=cppfn.name)
|
|
2081
|
+
# populate the wrapper function
|
|
2082
|
+
wrapfn = ir.Function(wrapper_mod, ty, name="wrapper")
|
|
2083
|
+
builder = ir.IRBuilder(wrapfn.append_basic_block())
|
|
2084
|
+
# just call the original function
|
|
2085
|
+
builder.call(declfn, wrapfn.args)
|
|
2086
|
+
builder.ret_void()
|
|
2087
|
+
# Create a new LLVM module with the wrapper
|
|
2088
|
+
new_mod = llvm.parse_assembly(str(wrapper_mod))
|
|
2089
|
+
self.assertTrue(new_mod.get_function(declfn.name).is_declaration,
|
|
2090
|
+
msg="declfn must not have a body")
|
|
2091
|
+
# Merge/link the original module into the new module
|
|
2092
|
+
new_mod.link_in(mod, preserve=True)
|
|
2093
|
+
self.assertEqual(len(list(new_mod.functions)),
|
|
2094
|
+
len(list(mod.functions)) + 1,
|
|
2095
|
+
msg="the only new function is the wrapper")
|
|
2096
|
+
self.assertFalse(new_mod.get_function(declfn.name).is_declaration,
|
|
2097
|
+
msg="declfn must have a body now")
|
|
2098
|
+
self.assertEqual(new_mod.get_function(declfn.name).global_value_type,
|
|
2099
|
+
new_mod.get_function(wrapfn.name).global_value_type,
|
|
2100
|
+
msg="declfn and wrapfn must have the same llvm Type")
|
|
2101
|
+
|
|
2102
|
+
def test_typeref_as_ir_for_wrappers_of_cpp_class(self):
|
|
2103
|
+
"""Exercise extracting C++ defined class types.
|
|
2104
|
+
Contains both opaque and non-opaque class definitions.
|
|
2105
|
+
"""
|
|
2106
|
+
self._check_typeref_as_ir_for_wrappers(
|
|
2107
|
+
asm_cpp_class,
|
|
2108
|
+
"_Z3fooP7MyClass14MyClassDefined",
|
|
2109
|
+
)
|
|
2110
|
+
|
|
2111
|
+
def test_typeref_as_ir_for_wrappers_of_cpp_vector_struct(self):
|
|
2112
|
+
"""Exercise extracting C++ struct types that are passed as vectors.
|
|
2113
|
+
|
|
2114
|
+
IA64 ABI on x86_64 will put struct with two floats as
|
|
2115
|
+
a vector of two floats.
|
|
2116
|
+
"""
|
|
2117
|
+
self._check_typeref_as_ir_for_wrappers(
|
|
2118
|
+
asm_cpp_vector,
|
|
2119
|
+
"_Z3foo8Vector2DPS_",
|
|
2120
|
+
)
|
|
1822
2121
|
|
|
1823
2122
|
|
|
1824
2123
|
class TestTarget(BaseTest):
|
|
@@ -1860,6 +2159,57 @@ class TestTarget(BaseTest):
|
|
|
1860
2159
|
self.assertIn(target.name, s)
|
|
1861
2160
|
self.assertIn(target.description, s)
|
|
1862
2161
|
|
|
2162
|
+
def test_get_parts_from_triple(self):
|
|
2163
|
+
# Tests adapted from llvm-14::llvm/unittests/ADT/TripleTest.cpp
|
|
2164
|
+
cases = [
|
|
2165
|
+
("x86_64-scei-ps4",
|
|
2166
|
+
llvm.targets.Triple(Arch="x86_64", SubArch='',
|
|
2167
|
+
Vendor="scei", OS="ps4",
|
|
2168
|
+
Env="unknown", ObjectFormat="ELF")),
|
|
2169
|
+
("x86_64-sie-ps4",
|
|
2170
|
+
llvm.targets.Triple(Arch="x86_64", SubArch='',
|
|
2171
|
+
Vendor="scei", OS="ps4",
|
|
2172
|
+
Env="unknown", ObjectFormat="ELF")),
|
|
2173
|
+
("powerpc-dunno-notsure",
|
|
2174
|
+
llvm.targets.Triple(Arch="powerpc", SubArch='',
|
|
2175
|
+
Vendor="unknown", OS="unknown",
|
|
2176
|
+
Env="unknown", ObjectFormat="ELF")),
|
|
2177
|
+
("powerpcspe-unknown-freebsd",
|
|
2178
|
+
llvm.targets.Triple(Arch="powerpc", SubArch='spe',
|
|
2179
|
+
Vendor="unknown", OS="freebsd",
|
|
2180
|
+
Env="unknown", ObjectFormat="ELF")),
|
|
2181
|
+
("armv6hl-none-linux-gnueabi",
|
|
2182
|
+
llvm.targets.Triple(Arch="arm", SubArch='v6hl',
|
|
2183
|
+
Vendor="unknown", OS="linux",
|
|
2184
|
+
Env="gnueabi", ObjectFormat="ELF")),
|
|
2185
|
+
("i686-unknown-linux-gnu",
|
|
2186
|
+
llvm.targets.Triple(Arch="i386", SubArch='',
|
|
2187
|
+
Vendor="unknown", OS="linux",
|
|
2188
|
+
Env="gnu", ObjectFormat="ELF")),
|
|
2189
|
+
("i686-apple-macosx",
|
|
2190
|
+
llvm.targets.Triple(Arch="i386", SubArch='',
|
|
2191
|
+
Vendor="apple", OS="macosx",
|
|
2192
|
+
Env="unknown", ObjectFormat="MachO")),
|
|
2193
|
+
("i686-dunno-win32",
|
|
2194
|
+
llvm.targets.Triple(Arch="i386", SubArch='',
|
|
2195
|
+
Vendor="unknown", OS="windows",
|
|
2196
|
+
Env="msvc", ObjectFormat="COFF")),
|
|
2197
|
+
("s390x-ibm-zos",
|
|
2198
|
+
llvm.targets.Triple(Arch="s390x", SubArch='',
|
|
2199
|
+
Vendor="ibm", OS="zos",
|
|
2200
|
+
Env="unknown", ObjectFormat="GOFF")),
|
|
2201
|
+
("wasm64-wasi",
|
|
2202
|
+
llvm.targets.Triple(Arch="wasm64", SubArch='',
|
|
2203
|
+
Vendor="unknown", OS="wasi",
|
|
2204
|
+
Env="unknown", ObjectFormat="Wasm")),
|
|
2205
|
+
]
|
|
2206
|
+
|
|
2207
|
+
for case in cases:
|
|
2208
|
+
triple_str, triple_obj = case
|
|
2209
|
+
res = llvm.get_triple_parts(triple_str)
|
|
2210
|
+
|
|
2211
|
+
self.assertEqual(res, triple_obj)
|
|
2212
|
+
|
|
1863
2213
|
|
|
1864
2214
|
class TestTargetData(BaseTest):
|
|
1865
2215
|
|
|
@@ -1875,10 +2225,10 @@ class TestTargetData(BaseTest):
|
|
|
1875
2225
|
td = self.target_data()
|
|
1876
2226
|
|
|
1877
2227
|
glob = self.glob()
|
|
1878
|
-
self.assertEqual(td.
|
|
2228
|
+
self.assertEqual(td.get_abi_size(glob.global_value_type), 4)
|
|
1879
2229
|
|
|
1880
2230
|
glob = self.glob("glob_struct")
|
|
1881
|
-
self.assertEqual(td.
|
|
2231
|
+
self.assertEqual(td.get_abi_size(glob.global_value_type), 24)
|
|
1882
2232
|
|
|
1883
2233
|
def test_get_struct_element_offset(self):
|
|
1884
2234
|
td = self.target_data()
|
|
@@ -1887,7 +2237,7 @@ class TestTargetData(BaseTest):
|
|
|
1887
2237
|
with self.assertRaises(ValueError):
|
|
1888
2238
|
td.get_element_offset(glob.type, 0)
|
|
1889
2239
|
|
|
1890
|
-
struct_type = glob.
|
|
2240
|
+
struct_type = glob.global_value_type
|
|
1891
2241
|
self.assertEqual(td.get_element_offset(struct_type, 0), 0)
|
|
1892
2242
|
self.assertEqual(td.get_element_offset(struct_type, 1), 8)
|
|
1893
2243
|
|
|
@@ -2153,6 +2503,8 @@ class TestPasses(BaseTest, PassManagerTestMixin):
|
|
|
2153
2503
|
return llvm.create_module_pass_manager()
|
|
2154
2504
|
|
|
2155
2505
|
def test_populate(self):
|
|
2506
|
+
llvm_ver = llvm.llvm_version_info[0]
|
|
2507
|
+
|
|
2156
2508
|
pm = self.pm()
|
|
2157
2509
|
pm.add_target_library_info("") # unspecified target triple
|
|
2158
2510
|
pm.add_constant_merge_pass()
|
|
@@ -2177,12 +2529,13 @@ class TestPasses(BaseTest, PassManagerTestMixin):
|
|
|
2177
2529
|
pm.add_aggressive_dead_code_elimination_pass()
|
|
2178
2530
|
pm.add_aa_eval_pass()
|
|
2179
2531
|
pm.add_always_inliner_pass()
|
|
2180
|
-
if llvm_version_major < 15:
|
|
2181
|
-
pm.add_arg_promotion_pass(42)
|
|
2182
2532
|
pm.add_break_critical_edges_pass()
|
|
2183
2533
|
pm.add_dead_store_elimination_pass()
|
|
2184
2534
|
pm.add_reverse_post_order_function_attrs_pass()
|
|
2185
|
-
|
|
2535
|
+
|
|
2536
|
+
if llvm_ver < 16:
|
|
2537
|
+
pm.add_aggressive_instruction_combining_pass()
|
|
2538
|
+
|
|
2186
2539
|
pm.add_internalize_pass()
|
|
2187
2540
|
pm.add_jump_threading_pass(7)
|
|
2188
2541
|
pm.add_lcssa_pass()
|
|
@@ -2193,8 +2546,6 @@ class TestPasses(BaseTest, PassManagerTestMixin):
|
|
|
2193
2546
|
pm.add_loop_simplification_pass()
|
|
2194
2547
|
pm.add_loop_unroll_pass()
|
|
2195
2548
|
pm.add_loop_unroll_and_jam_pass()
|
|
2196
|
-
if llvm_version_major < 15:
|
|
2197
|
-
pm.add_loop_unswitch_pass()
|
|
2198
2549
|
pm.add_lower_atomic_pass()
|
|
2199
2550
|
pm.add_lower_invoke_pass()
|
|
2200
2551
|
pm.add_lower_switch_pass()
|
|
@@ -2202,7 +2553,10 @@ class TestPasses(BaseTest, PassManagerTestMixin):
|
|
|
2202
2553
|
pm.add_merge_functions_pass()
|
|
2203
2554
|
pm.add_merge_returns_pass()
|
|
2204
2555
|
pm.add_partial_inlining_pass()
|
|
2205
|
-
|
|
2556
|
+
|
|
2557
|
+
if llvm_ver < 16:
|
|
2558
|
+
pm.add_prune_exception_handling_pass()
|
|
2559
|
+
|
|
2206
2560
|
pm.add_reassociate_expressions_pass()
|
|
2207
2561
|
pm.add_demote_register_to_memory_pass()
|
|
2208
2562
|
pm.add_sink_pass()
|
|
@@ -2347,6 +2701,14 @@ class TestTypeParsing(BaseTest):
|
|
|
2347
2701
|
# Also test constant text repr
|
|
2348
2702
|
gv.initializer = ir.Constant(typ, [1])
|
|
2349
2703
|
|
|
2704
|
+
# Packed layout created from Constant.literal_struct
|
|
2705
|
+
with self.check_parsing() as mod:
|
|
2706
|
+
const = ir.Constant.literal_struct([ir.IntType(32)(1),
|
|
2707
|
+
ir.IntType(32)(2)],
|
|
2708
|
+
packed=True)
|
|
2709
|
+
gv = ir.GlobalVariable(mod, const.type, "foo")
|
|
2710
|
+
gv.initializer = const
|
|
2711
|
+
|
|
2350
2712
|
|
|
2351
2713
|
class TestGlobalConstructors(TestMCJit):
|
|
2352
2714
|
def test_global_ctors_dtors(self):
|
|
@@ -2581,5 +2943,266 @@ class TestLLVMLockCallbacks(BaseTest):
|
|
|
2581
2943
|
llvm.ffi.unregister_lock_callback(acq, rel)
|
|
2582
2944
|
|
|
2583
2945
|
|
|
2946
|
+
class TestPipelineTuningOptions(BaseTest):
|
|
2947
|
+
|
|
2948
|
+
def pto(self):
|
|
2949
|
+
return llvm.create_pipeline_tuning_options()
|
|
2950
|
+
|
|
2951
|
+
def test_close(self):
|
|
2952
|
+
pto = self.pto()
|
|
2953
|
+
pto.close()
|
|
2954
|
+
|
|
2955
|
+
def test_speed_level(self):
|
|
2956
|
+
pto = self.pto()
|
|
2957
|
+
self.assertIsInstance(pto.speed_level, int)
|
|
2958
|
+
for i in range(4):
|
|
2959
|
+
pto.speed_level = i
|
|
2960
|
+
self.assertEqual(pto.speed_level, i)
|
|
2961
|
+
|
|
2962
|
+
def test_size_level(self):
|
|
2963
|
+
pto = self.pto()
|
|
2964
|
+
self.assertIsInstance(pto.size_level, int)
|
|
2965
|
+
for i in range(3):
|
|
2966
|
+
pto.size_level = i
|
|
2967
|
+
self.assertEqual(pto.size_level, i)
|
|
2968
|
+
|
|
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
|
|
2976
|
+
|
|
2977
|
+
def test_loop_interleaving(self):
|
|
2978
|
+
pto = self.pto()
|
|
2979
|
+
self.assertIsInstance(pto.loop_interleaving, bool)
|
|
2980
|
+
for b in (True, False):
|
|
2981
|
+
pto.loop_interleaving = b
|
|
2982
|
+
self.assertEqual(pto.loop_interleaving, b)
|
|
2983
|
+
|
|
2984
|
+
def test_loop_vectorization(self):
|
|
2985
|
+
pto = self.pto()
|
|
2986
|
+
self.assertIsInstance(pto.loop_vectorization, bool)
|
|
2987
|
+
for b in (True, False):
|
|
2988
|
+
pto.loop_vectorization = b
|
|
2989
|
+
self.assertEqual(pto.loop_vectorization, b)
|
|
2990
|
+
|
|
2991
|
+
def test_slp_vectorization(self):
|
|
2992
|
+
pto = self.pto()
|
|
2993
|
+
self.assertIsInstance(pto.slp_vectorization, bool)
|
|
2994
|
+
for b in (True, False):
|
|
2995
|
+
pto.slp_vectorization = b
|
|
2996
|
+
self.assertEqual(pto.slp_vectorization, b)
|
|
2997
|
+
|
|
2998
|
+
def test_loop_unrolling(self):
|
|
2999
|
+
pto = self.pto()
|
|
3000
|
+
self.assertIsInstance(pto.loop_unrolling, bool)
|
|
3001
|
+
for b in (True, False):
|
|
3002
|
+
pto.loop_unrolling = b
|
|
3003
|
+
self.assertEqual(pto.loop_unrolling, b)
|
|
3004
|
+
|
|
3005
|
+
def test_speed_level_constraints(self):
|
|
3006
|
+
pto = self.pto()
|
|
3007
|
+
with self.assertRaises(ValueError):
|
|
3008
|
+
pto.speed_level = 4
|
|
3009
|
+
with self.assertRaises(ValueError):
|
|
3010
|
+
pto.speed_level = -1
|
|
3011
|
+
|
|
3012
|
+
def test_size_level_constraints(self):
|
|
3013
|
+
pto = self.pto()
|
|
3014
|
+
with self.assertRaises(ValueError):
|
|
3015
|
+
pto.size_level = 3
|
|
3016
|
+
with self.assertRaises(ValueError):
|
|
3017
|
+
pto.speed_level = -1
|
|
3018
|
+
with self.assertRaises(ValueError):
|
|
3019
|
+
pto.speed_level = 3
|
|
3020
|
+
pto.size_level = 2
|
|
3021
|
+
|
|
3022
|
+
|
|
3023
|
+
class NewPassManagerMixin(object):
|
|
3024
|
+
|
|
3025
|
+
def pb(self, speed_level=0, size_level=0):
|
|
3026
|
+
tm = self.target_machine(jit=False)
|
|
3027
|
+
pto = llvm.create_pipeline_tuning_options(speed_level, size_level)
|
|
3028
|
+
pb = llvm.create_pass_builder(tm, pto)
|
|
3029
|
+
return pb
|
|
3030
|
+
|
|
3031
|
+
|
|
3032
|
+
class TestPassBuilder(BaseTest, NewPassManagerMixin):
|
|
3033
|
+
|
|
3034
|
+
def test_close(self):
|
|
3035
|
+
pb = self.pb()
|
|
3036
|
+
pb.close()
|
|
3037
|
+
|
|
3038
|
+
def test_pto(self):
|
|
3039
|
+
tm = self.target_machine(jit=False)
|
|
3040
|
+
pto = llvm.create_pipeline_tuning_options(3, 0)
|
|
3041
|
+
pto.inlining_threshold = 2
|
|
3042
|
+
pto.loop_interleaving = True
|
|
3043
|
+
pto.loop_vectorization = True
|
|
3044
|
+
pto.slp_vectorization = True
|
|
3045
|
+
pto.loop_unrolling = False
|
|
3046
|
+
pb = llvm.create_pass_builder(tm, pto)
|
|
3047
|
+
pb.close()
|
|
3048
|
+
|
|
3049
|
+
def test_get_module_pass_manager(self):
|
|
3050
|
+
pb = self.pb()
|
|
3051
|
+
mpm = pb.getModulePassManager()
|
|
3052
|
+
mpm.run(self.module(), pb)
|
|
3053
|
+
pb.close()
|
|
3054
|
+
|
|
3055
|
+
def test_get_function_pass_manager(self):
|
|
3056
|
+
pb = self.pb()
|
|
3057
|
+
fpm = pb.getFunctionPassManager()
|
|
3058
|
+
fpm.run(self.module().get_function("sum"), pb)
|
|
3059
|
+
pb.close()
|
|
3060
|
+
|
|
3061
|
+
|
|
3062
|
+
class TestNewModulePassManager(BaseTest, NewPassManagerMixin):
|
|
3063
|
+
def pm(self):
|
|
3064
|
+
return llvm.create_new_module_pass_manager()
|
|
3065
|
+
|
|
3066
|
+
def run_o_n(self, level):
|
|
3067
|
+
mod = self.module()
|
|
3068
|
+
orig_asm = str(mod)
|
|
3069
|
+
pb = self.pb(speed_level=level, size_level=0)
|
|
3070
|
+
mpm = pb.getModulePassManager()
|
|
3071
|
+
mpm.run(mod, pb)
|
|
3072
|
+
optimized_asm = str(mod)
|
|
3073
|
+
return orig_asm, optimized_asm
|
|
3074
|
+
|
|
3075
|
+
def test_close(self):
|
|
3076
|
+
mpm = self.pm()
|
|
3077
|
+
mpm.close()
|
|
3078
|
+
|
|
3079
|
+
def test_run_o3(self):
|
|
3080
|
+
orig_asm, optimized_asm = self.run_o_n(3)
|
|
3081
|
+
self.assertIn("%.4", orig_asm)
|
|
3082
|
+
self.assertNotIn("%.4", optimized_asm)
|
|
3083
|
+
|
|
3084
|
+
def test_run_o0(self):
|
|
3085
|
+
orig_asm, optimized_asm = self.run_o_n(0)
|
|
3086
|
+
self.assertIn("%.4", orig_asm)
|
|
3087
|
+
self.assertIn("%.4", optimized_asm)
|
|
3088
|
+
|
|
3089
|
+
def test_instcombine(self):
|
|
3090
|
+
pb = self.pb()
|
|
3091
|
+
mpm = self.pm()
|
|
3092
|
+
mpm.add_instruction_combine_pass()
|
|
3093
|
+
mod = self.module(asm_sum4)
|
|
3094
|
+
orig_asm = str(mod)
|
|
3095
|
+
mpm.run(mod, pb)
|
|
3096
|
+
optimized_asm = str(mod)
|
|
3097
|
+
self.assertIn("%.3", orig_asm)
|
|
3098
|
+
self.assertNotIn("%.3", optimized_asm)
|
|
3099
|
+
|
|
3100
|
+
def test_optnone(self):
|
|
3101
|
+
pb = self.pb(speed_level=3, size_level=0)
|
|
3102
|
+
orig_asm = str(asm_alloca_optnone.replace("optnone ", ""))
|
|
3103
|
+
mod = llvm.parse_assembly(orig_asm)
|
|
3104
|
+
mpm = pb.getModulePassManager()
|
|
3105
|
+
mpm.run(mod, pb)
|
|
3106
|
+
optimized_asm = str(mod)
|
|
3107
|
+
self.assertIn("alloca", orig_asm)
|
|
3108
|
+
self.assertNotIn("alloca", optimized_asm)
|
|
3109
|
+
|
|
3110
|
+
# Module shouldn't be optimized if the function has `optnone` attached
|
|
3111
|
+
orig_asm_optnone = str(asm_alloca_optnone)
|
|
3112
|
+
mpm = pb.getModulePassManager()
|
|
3113
|
+
mod = llvm.parse_assembly(orig_asm_optnone)
|
|
3114
|
+
mpm.run(mod, pb)
|
|
3115
|
+
optimized_asm_optnone = str(mod)
|
|
3116
|
+
self.assertIn("alloca", orig_asm_optnone)
|
|
3117
|
+
self.assertIn("alloca", optimized_asm_optnone)
|
|
3118
|
+
|
|
3119
|
+
def test_add_passes(self):
|
|
3120
|
+
mpm = self.pm()
|
|
3121
|
+
mpm.add_verifier()
|
|
3122
|
+
mpm.add_aa_eval_pass()
|
|
3123
|
+
mpm.add_simplify_cfg_pass()
|
|
3124
|
+
mpm.add_loop_unroll_pass()
|
|
3125
|
+
mpm.add_loop_rotate_pass()
|
|
3126
|
+
mpm.add_instruction_combine_pass()
|
|
3127
|
+
mpm.add_jump_threading_pass()
|
|
3128
|
+
mpm.add_refprune_pass()
|
|
3129
|
+
|
|
3130
|
+
|
|
3131
|
+
class TestNewFunctionPassManager(BaseTest, NewPassManagerMixin):
|
|
3132
|
+
def pm(self):
|
|
3133
|
+
return llvm.create_new_function_pass_manager()
|
|
3134
|
+
|
|
3135
|
+
def test_close(self):
|
|
3136
|
+
fpm = self.pm()
|
|
3137
|
+
fpm.close()
|
|
3138
|
+
|
|
3139
|
+
def run_o_n(self, level):
|
|
3140
|
+
mod = self.module()
|
|
3141
|
+
fun = mod.get_function("sum")
|
|
3142
|
+
orig_asm = str(fun)
|
|
3143
|
+
pb = self.pb(speed_level=level, size_level=0)
|
|
3144
|
+
fpm = pb.getFunctionPassManager()
|
|
3145
|
+
fpm.run(fun, pb)
|
|
3146
|
+
optimized_asm = str(fun)
|
|
3147
|
+
return orig_asm, optimized_asm
|
|
3148
|
+
|
|
3149
|
+
def test_run_o3(self):
|
|
3150
|
+
orig_asm, optimized_asm = self.run_o_n(3)
|
|
3151
|
+
self.assertIn("%.4", orig_asm)
|
|
3152
|
+
self.assertNotIn("%.4", optimized_asm)
|
|
3153
|
+
|
|
3154
|
+
def test_run_o0(self):
|
|
3155
|
+
orig_asm, optimized_asm = self.run_o_n(0)
|
|
3156
|
+
self.assertIn("%.4", orig_asm)
|
|
3157
|
+
self.assertIn("%.4", optimized_asm)
|
|
3158
|
+
|
|
3159
|
+
def test_optnone(self):
|
|
3160
|
+
pb = self.pb(speed_level=3, size_level=0)
|
|
3161
|
+
orig_asm = str(asm_alloca_optnone.replace("optnone ", ""))
|
|
3162
|
+
fun = llvm.parse_assembly(orig_asm).get_function("foo")
|
|
3163
|
+
fpm = pb.getFunctionPassManager()
|
|
3164
|
+
fpm.run(fun, pb)
|
|
3165
|
+
optimized_asm = str(fun)
|
|
3166
|
+
self.assertIn("alloca", orig_asm)
|
|
3167
|
+
self.assertNotIn("alloca", optimized_asm)
|
|
3168
|
+
|
|
3169
|
+
# Function shouldn't be optimized if the function has `optnone` attached
|
|
3170
|
+
orig_asm_optnone = str(asm_alloca_optnone)
|
|
3171
|
+
fun = llvm.parse_assembly(orig_asm_optnone).get_function("foo")
|
|
3172
|
+
fpm = pb.getFunctionPassManager()
|
|
3173
|
+
fpm.run(fun, pb)
|
|
3174
|
+
optimized_asm_optnone = str(fun)
|
|
3175
|
+
self.assertIn("alloca", orig_asm_optnone)
|
|
3176
|
+
self.assertIn("alloca", optimized_asm_optnone)
|
|
3177
|
+
|
|
3178
|
+
def test_instcombine(self):
|
|
3179
|
+
pb = self.pb()
|
|
3180
|
+
fpm = self.pm()
|
|
3181
|
+
fun = self.module(asm_sum4).get_function("sum")
|
|
3182
|
+
fpm.add_instruction_combine_pass()
|
|
3183
|
+
orig_asm = str(fun)
|
|
3184
|
+
fpm.run(fun, pb)
|
|
3185
|
+
optimized_asm = str(fun)
|
|
3186
|
+
self.assertIn("%.3", orig_asm)
|
|
3187
|
+
self.assertNotIn("%.3", optimized_asm)
|
|
3188
|
+
|
|
3189
|
+
# This should not crash
|
|
3190
|
+
def test_declarations(self):
|
|
3191
|
+
pb = self.pb(3)
|
|
3192
|
+
fpm = pb.getFunctionPassManager()
|
|
3193
|
+
for fun in llvm.parse_assembly(asm_declaration).functions:
|
|
3194
|
+
fpm.run(fun, pb)
|
|
3195
|
+
|
|
3196
|
+
def test_add_passes(self):
|
|
3197
|
+
fpm = self.pm()
|
|
3198
|
+
fpm.add_aa_eval_pass()
|
|
3199
|
+
fpm.add_simplify_cfg_pass()
|
|
3200
|
+
fpm.add_loop_unroll_pass()
|
|
3201
|
+
fpm.add_loop_rotate_pass()
|
|
3202
|
+
fpm.add_instruction_combine_pass()
|
|
3203
|
+
fpm.add_jump_threading_pass()
|
|
3204
|
+
fpm.add_refprune_pass()
|
|
3205
|
+
|
|
3206
|
+
|
|
2584
3207
|
if __name__ == "__main__":
|
|
2585
3208
|
unittest.main()
|