22import cllvm
33#endif
44
5- /// Enumerates the supported models of reference of thread-local variables.
5+ /// A `Global` represents a region of memory allocated at compile time instead
6+ /// of at runtime. A global variable must either have an initializer, or make
7+ /// reference to an external definition that has an initializer.
8+ public final class Global : IRGlobal {
9+ internal let llvm : LLVMValueRef
10+
11+ internal init ( llvm: LLVMValueRef ) {
12+ self . llvm = llvm
13+ }
14+
15+ /// Returns whether this global variable has no initializer because it makes
16+ /// reference to an initialized value in another translation unit.
17+ public var isExternallyInitialized : Bool {
18+ get { return LLVMIsExternallyInitialized ( llvm) != 0 }
19+ set { LLVMSetExternallyInitialized ( llvm, newValue. llvm) }
20+ }
21+
22+ /// Retrieves the initializer for this global variable, if it exists.
23+ public var initializer : IRValue ? {
24+ get { return LLVMGetInitializer ( asLLVM ( ) ) }
25+ set { LLVMSetInitializer ( asLLVM ( ) , newValue!. asLLVM ( ) ) }
26+ }
27+
28+ /// Returns whether this global variable is a constant, whether or not the
29+ /// final definition of the global is not.
30+ public var isGlobalConstant : Bool {
31+ get { return LLVMIsGlobalConstant ( asLLVM ( ) ) != 0 }
32+ set { LLVMSetGlobalConstant ( asLLVM ( ) , newValue. llvm) }
33+ }
34+
35+ /// Returns whether this global variable is thread-local. That is, returns
36+ /// if this variable is not shared by multiple threads.
37+ public var isThreadLocal : Bool {
38+ get { return LLVMIsThreadLocal ( asLLVM ( ) ) != 0 }
39+ set { LLVMSetThreadLocal ( asLLVM ( ) , newValue. llvm) }
40+ }
41+
42+ /// Accesses the model of reference for this global variable if it is
43+ /// thread-local.
44+ public var threadLocalModel : ThreadLocalModel {
45+ get { return ThreadLocalModel ( llvm: LLVMGetThreadLocalMode ( asLLVM ( ) ) ) }
46+ set { LLVMSetThreadLocalMode ( asLLVM ( ) , newValue. llvm) }
47+ }
48+
49+ /// Retrieves the previous global in the module, if there is one.
50+ public func previous( ) -> Global ? {
51+ guard let previous = LLVMGetPreviousGlobal ( llvm) else { return nil }
52+ return Global ( llvm: previous)
53+ }
54+
55+ /// Retrieves the next global in the module, if there is one.
56+ public func next( ) -> Global ? {
57+ guard let next = LLVMGetNextGlobal ( llvm) else { return nil }
58+ return Global ( llvm: next)
59+ }
60+
61+ /// Deletes the global variable from its containing module.
62+ /// - note: This does not remove references to this global from the
63+ /// module. Ensure you have removed all instructions that reference
64+ /// this global before deleting it.
65+ public func delete( ) {
66+ LLVMDeleteGlobal ( llvm)
67+ }
68+
69+ /// Retrieves the underlying LLVM value object.
70+ public func asLLVM( ) -> LLVMValueRef {
71+ return llvm
72+ }
73+ }
74+
75+ /// Enumerates the supported models of reference of thread-local variables.
676///
777/// These models are listed from the most general, but least optimized, to the
878/// fastest, but most restrictive in general, as architectural differences
@@ -27,9 +97,9 @@ import cllvm
2797public enum ThreadLocalModel {
2898 /// The variable is not thread local and hence has no associated model.
2999 case notThreadLocal
30- /// Allows reference of all thread-local variables, from either a shared
31- /// object or a dynamic executable. This model also supports the deferred
32- /// allocation of a block of thread-local storage when the block is first
100+ /// Allows reference of all thread-local variables, from either a shared
101+ /// object or a dynamic executable. This model also supports the deferred
102+ /// allocation of a block of thread-local storage when the block is first
33103 /// referenced from a specific thread. Note that the linker is free to
34104 /// optimize accesses using this model to one of the more specific models
35105 /// below which may ultimately defeat lazy allocation of the TLS storagee
@@ -49,7 +119,7 @@ public enum ThreadLocalModel {
49119 /// object being built. In this case, the compiler instructs the linker
50120 /// to statically bind the dynamic offset of the variable and use this model.
51121 ///
52- /// This model provides a performance benefit over the General Dynamic model.
122+ /// This model provides a performance benefit over the General Dynamic model.
53123 /// Only one call to `__tls_get_addr` is required per function, to determine
54124 /// the starting address of the variable within the TLS block for its
55125 /// parent module. Additional accesses can add an offset to this address
@@ -63,29 +133,29 @@ public enum ThreadLocalModel {
63133 /// The linker cannot, in general, optimize from the general dynamic model
64134 /// to the local dynamic model.
65135 case localDynamic
66- /// This model can only reference thread-local variables which are available
67- /// as part of the initial static thread-local template. This template is
68- /// composed of all thread-local storage blocks that are available at process
69- /// startup, plus a small backup reservation.
136+ /// This model can only reference thread-local variables which are available
137+ /// as part of the initial static thread-local template. This template is
138+ /// composed of all thread-local storage blocks that are available at process
139+ /// startup, plus a small backup reservation.
70140 ///
71141 /// In this model, the thread pointer-relative offset for a given variable `x`
72142 /// is stored in the GOT entry for x.
73143 ///
74- /// This model can reference a limited number of thread-local variables from
144+ /// This model can reference a limited number of thread-local variables from
75145 /// shared libraries loaded after initial process startup, such as by means of
76- /// lazy loading, filters, or `dlopen()`. This access is satisfied from a
77- /// fixed backup reservation. This reservation can only provide storage for
78- /// uninitialized thread-local data items. For maximum flexibility, shared
146+ /// lazy loading, filters, or `dlopen()`. This access is satisfied from a
147+ /// fixed backup reservation. This reservation can only provide storage for
148+ /// uninitialized thread-local data items. For maximum flexibility, shared
79149 /// objects should reference thread-local variables using a dynamic model of
80150 /// thread-local storage.
81151 case initialExec
82152 /// This model is an optimization of the `localDynamic` model.
83153 ///
84154 /// This model can only reference thread-local variables which are part of the
85155 /// thread-local storage block of the dynamic executable. The linker
86- /// calculates the thread pointer-relative offsets statically, without the
87- /// need for dynamic relocations, or the extra reference to the GOT. This
88- /// model can not be used to reference variables outside of the dynamic
156+ /// calculates the thread pointer-relative offsets statically, without the
157+ /// need for dynamic relocations, or the extra reference to the GOT. This
158+ /// model can not be used to reference variables outside of the dynamic
89159 /// executable.
90160 case localExec
91161
@@ -113,73 +183,3 @@ public enum ThreadLocalModel {
113183 return ThreadLocalModel . modeMapping [ self ] !
114184 }
115185}
116-
117- /// A `Global` represents a region of memory allocated at compile time instead
118- /// of at runtime. A global variable must either have an initializer, or make
119- /// reference to an external definition that has an initializer.
120- public final class Global : IRGlobal {
121- internal let llvm : LLVMValueRef
122-
123- internal init ( llvm: LLVMValueRef ) {
124- self . llvm = llvm
125- }
126-
127- /// Returns whether this global variable has no initializer because it makes
128- /// reference to an initialized value in another translation unit.
129- public var isExternallyInitialized : Bool {
130- get { return LLVMIsExternallyInitialized ( llvm) != 0 }
131- set { LLVMSetExternallyInitialized ( llvm, newValue. llvm) }
132- }
133-
134- /// Retrieves the initializer for this global variable, if it exists.
135- public var initializer : IRValue ? {
136- get { return LLVMGetInitializer ( asLLVM ( ) ) }
137- set { LLVMSetInitializer ( asLLVM ( ) , newValue!. asLLVM ( ) ) }
138- }
139-
140- /// Returns whether this global variable is a constant, whether or not the
141- /// final definition of the global is not.
142- public var isGlobalConstant : Bool {
143- get { return LLVMIsGlobalConstant ( asLLVM ( ) ) != 0 }
144- set { LLVMSetGlobalConstant ( asLLVM ( ) , newValue. llvm) }
145- }
146-
147- /// Returns whether this global variable is thread-local. That is, returns
148- /// if this variable is not shared by multiple threads.
149- public var isThreadLocal : Bool {
150- get { return LLVMIsThreadLocal ( asLLVM ( ) ) != 0 }
151- set { LLVMSetThreadLocal ( asLLVM ( ) , newValue. llvm) }
152- }
153-
154- /// Accesses the model of reference for this global variable if it is
155- /// thread-local.
156- public var threadLocalModel : ThreadLocalModel {
157- get { return ThreadLocalModel ( llvm: LLVMGetThreadLocalMode ( asLLVM ( ) ) ) }
158- set { LLVMSetThreadLocalMode ( asLLVM ( ) , newValue. llvm) }
159- }
160-
161- /// Retrieves the previous global in the module, if there is one.
162- public func previous( ) -> Global ? {
163- guard let previous = LLVMGetPreviousGlobal ( llvm) else { return nil }
164- return Global ( llvm: previous)
165- }
166-
167- /// Retrieves the next global in the module, if there is one.
168- public func next( ) -> Global ? {
169- guard let next = LLVMGetNextGlobal ( llvm) else { return nil }
170- return Global ( llvm: next)
171- }
172-
173- /// Deletes the global variable from its containing module.
174- /// - note: This does not remove references to this global from the
175- /// module. Ensure you have removed all instructions that reference
176- /// this global before deleting it.
177- public func delete( ) {
178- LLVMDeleteGlobal ( llvm)
179- }
180-
181- /// Retrieves the underlying LLVM value object.
182- public func asLLVM( ) -> LLVMValueRef {
183- return llvm
184- }
185- }
0 commit comments