blob: 18dbf6df563f71967973ce2c8beb021b180deb37 [file] [log] [blame]
Peter Collingbournee6909c82015-02-20 20:30:47 +00001=======
2Bitsets
3=======
4
5This is a mechanism that allows IR modules to co-operatively build pointer
6sets corresponding to addresses within a given set of globals. One example
7of a use case for this is to allow a C++ program to efficiently verify (at
8each call site) that a vtable pointer is in the set of valid vtable pointers
9for the type of the class or its derived classes.
10
11To use the mechanism, a client creates a global metadata node named
12``llvm.bitsets``. Each element is a metadata node with three elements:
Peter Collingbourne8d24ae92015-09-08 22:49:35 +000013
141. a metadata object representing an identifier for the bitset
152. either a global variable or a function
163. a byte offset into the global (generally zero for functions)
17
18Each bitset must exclusively contain either global variables or functions.
19
20.. admonition:: Limitation
21
22 The current implementation only supports functions as members of bitsets on
23 the x86-32 and x86-64 architectures.
Peter Collingbournee6909c82015-02-20 20:30:47 +000024
25This will cause a link-time optimization pass to generate bitsets from the
Peter Collingbourne8d24ae92015-09-08 22:49:35 +000026memory addresses referenced from the elements of the bitset metadata. The
27pass will lay out referenced global variables consecutively, so their
28definitions must be available at LTO time.
29
30A bit set containing functions is transformed into a jump table, which
31is a block of code consisting of one branch instruction for each of the
32functions in the bit set that branches to the target function, and redirect
33any taken function addresses to the corresponding jump table entry. In the
34object file's symbol table, the jump table entries take the identities of
35the original functions, so that addresses taken outside the module will pass
36any verification done inside the module.
37
38Jump tables may call external functions, so their definitions need not
39be available at LTO time. Note that if an externally defined function is a
40member of a bitset, there is no guarantee that its identity within the module
41will be the same as its identity outside of the module, as the former will
42be the jump table entry if a jump table is necessary.
43
44The `GlobalLayoutBuilder`_ class is responsible for laying out the globals
45efficiently to minimize the sizes of the underlying bitsets. An intrinsic,
46:ref:`llvm.bitset.test <bitset.test>`, generates code to test whether a
47given pointer is a member of a bitset.
Peter Collingbournee6909c82015-02-20 20:30:47 +000048
49:Example:
50
51::
52
53 target datalayout = "e-p:32:32"
54
55 @a = internal global i32 0
56 @b = internal global i32 0
57 @c = internal global i32 0
58 @d = internal global [2 x i32] [i32 0, i32 0]
59
Peter Collingbourne8d24ae92015-09-08 22:49:35 +000060 define void @e() {
61 ret void
62 }
63
64 define void @f() {
65 ret void
66 }
67
68 declare void @g()
69
70 !llvm.bitsets = !{!0, !1, !2, !3, !4, !5, !6}
Peter Collingbournee6909c82015-02-20 20:30:47 +000071
72 !0 = !{!"bitset1", i32* @a, i32 0}
73 !1 = !{!"bitset1", i32* @b, i32 0}
74 !2 = !{!"bitset2", i32* @b, i32 0}
75 !3 = !{!"bitset2", i32* @c, i32 0}
76 !4 = !{!"bitset2", i32* @d, i32 4}
Peter Collingbourne8d24ae92015-09-08 22:49:35 +000077 !5 = !{!"bitset3", void ()* @e, i32 0}
78 !6 = !{!"bitset3", void ()* @g, i32 0}
Peter Collingbournee6909c82015-02-20 20:30:47 +000079
80 declare i1 @llvm.bitset.test(i8* %ptr, metadata %bitset) nounwind readnone
81
82 define i1 @foo(i32* %p) {
83 %pi8 = bitcast i32* %p to i8*
84 %x = call i1 @llvm.bitset.test(i8* %pi8, metadata !"bitset1")
85 ret i1 %x
86 }
87
88 define i1 @bar(i32* %p) {
89 %pi8 = bitcast i32* %p to i8*
90 %x = call i1 @llvm.bitset.test(i8* %pi8, metadata !"bitset2")
91 ret i1 %x
92 }
93
Peter Collingbourne8d24ae92015-09-08 22:49:35 +000094 define i1 @baz(void ()* %p) {
95 %pi8 = bitcast void ()* %p to i8*
96 %x = call i1 @llvm.bitset.test(i8* %pi8, metadata !"bitset3")
97 ret i1 %x
98 }
99
Peter Collingbournee6909c82015-02-20 20:30:47 +0000100 define void @main() {
101 %a1 = call i1 @foo(i32* @a) ; returns 1
102 %b1 = call i1 @foo(i32* @b) ; returns 1
103 %c1 = call i1 @foo(i32* @c) ; returns 0
104 %a2 = call i1 @bar(i32* @a) ; returns 0
105 %b2 = call i1 @bar(i32* @b) ; returns 1
106 %c2 = call i1 @bar(i32* @c) ; returns 1
107 %d02 = call i1 @bar(i32* getelementptr ([2 x i32]* @d, i32 0, i32 0)) ; returns 0
108 %d12 = call i1 @bar(i32* getelementptr ([2 x i32]* @d, i32 0, i32 1)) ; returns 1
Peter Collingbourne8d24ae92015-09-08 22:49:35 +0000109 %e = call i1 @baz(void ()* @e) ; returns 1
110 %f = call i1 @baz(void ()* @f) ; returns 0
111 %g = call i1 @baz(void ()* @g) ; returns 1
Peter Collingbournee6909c82015-02-20 20:30:47 +0000112 ret void
113 }
Peter Collingbourne1baeaa32015-02-24 23:17:02 +0000114
115.. _GlobalLayoutBuilder: http://llvm.org/klaus/llvm/blob/master/include/llvm/Transforms/IPO/LowerBitSets.h