@@ -3,6 +3,7 @@ use std::ops::Deref;
33use std:: { iter, ptr} ;
44
55pub ( crate ) mod autodiff;
6+ pub ( crate ) mod gpu_offload;
67
78use libc:: { c_char, c_uint, size_t} ;
89use rustc_abi as abi;
@@ -117,6 +118,74 @@ impl<'a, 'll, CX: Borrow<SCx<'ll>>> GenericBuilder<'a, 'll, CX> {
117118 }
118119 bx
119120 }
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+ }
120189}
121190
122191/// Empty string, to be used where LLVM expects an instruction name, indicating
0 commit comments