@@ -3,6 +3,7 @@ use std::ops::Deref;
3
3
use std:: { iter, ptr} ;
4
4
5
5
pub ( crate ) mod autodiff;
6
+ pub ( crate ) mod gpu_offload;
6
7
7
8
use libc:: { c_char, c_uint, size_t} ;
8
9
use rustc_abi as abi;
@@ -117,6 +118,74 @@ impl<'a, 'll, CX: Borrow<SCx<'ll>>> GenericBuilder<'a, 'll, CX> {
117
118
}
118
119
bx
119
120
}
121
+
122
+ // The generic builder has less functionality and thus (unlike the other alloca) we can not
123
+ // easily jump to the beginning of the function to place our allocas there. We trust the user
124
+ // to manually do that. FIXME(offload): improve the genericCx and add more llvm wrappers to
125
+ // handle this.
126
+ pub ( crate ) fn direct_alloca ( & mut self , ty : & ' ll Type , align : Align , name : & str ) -> & ' ll Value {
127
+ let val = unsafe {
128
+ let alloca = llvm:: LLVMBuildAlloca ( self . llbuilder , ty, UNNAMED ) ;
129
+ llvm:: LLVMSetAlignment ( alloca, align. bytes ( ) as c_uint ) ;
130
+ // Cast to default addrspace if necessary
131
+ llvm:: LLVMBuildPointerCast ( self . llbuilder , alloca, self . cx . type_ptr ( ) , UNNAMED )
132
+ } ;
133
+ if name != "" {
134
+ let name = std:: ffi:: CString :: new ( name) . unwrap ( ) ;
135
+ llvm:: set_value_name ( val, & name. as_bytes ( ) ) ;
136
+ }
137
+ val
138
+ }
139
+
140
+ pub ( crate ) fn inbounds_gep (
141
+ & mut self ,
142
+ ty : & ' ll Type ,
143
+ ptr : & ' ll Value ,
144
+ indices : & [ & ' ll Value ] ,
145
+ ) -> & ' ll Value {
146
+ unsafe {
147
+ llvm:: LLVMBuildGEPWithNoWrapFlags (
148
+ self . llbuilder ,
149
+ ty,
150
+ ptr,
151
+ indices. as_ptr ( ) ,
152
+ indices. len ( ) as c_uint ,
153
+ UNNAMED ,
154
+ GEPNoWrapFlags :: InBounds ,
155
+ )
156
+ }
157
+ }
158
+
159
+ pub ( crate ) fn store ( & mut self , val : & ' ll Value , ptr : & ' ll Value , align : Align ) -> & ' ll Value {
160
+ debug ! ( "Store {:?} -> {:?}" , val, ptr) ;
161
+ assert_eq ! ( self . cx. type_kind( self . cx. val_ty( ptr) ) , TypeKind :: Pointer ) ;
162
+ unsafe {
163
+ let store = llvm:: LLVMBuildStore ( self . llbuilder , val, ptr) ;
164
+ llvm:: LLVMSetAlignment ( store, align. bytes ( ) as c_uint ) ;
165
+ store
166
+ }
167
+ }
168
+
169
+ pub ( crate ) fn load ( & mut self , ty : & ' ll Type , ptr : & ' ll Value , align : Align ) -> & ' ll Value {
170
+ unsafe {
171
+ let load = llvm:: LLVMBuildLoad2 ( self . llbuilder , ty, ptr, UNNAMED ) ;
172
+ llvm:: LLVMSetAlignment ( load, align. bytes ( ) as c_uint ) ;
173
+ load
174
+ }
175
+ }
176
+
177
+ fn memset ( & mut self , ptr : & ' ll Value , fill_byte : & ' ll Value , size : & ' ll Value , align : Align ) {
178
+ unsafe {
179
+ llvm:: LLVMRustBuildMemSet (
180
+ self . llbuilder ,
181
+ ptr,
182
+ align. bytes ( ) as c_uint ,
183
+ fill_byte,
184
+ size,
185
+ false ,
186
+ ) ;
187
+ }
188
+ }
120
189
}
121
190
122
191
/// Empty string, to be used where LLVM expects an instruction name, indicating
0 commit comments