@@ -19,7 +19,7 @@ use rustc_hir::def_id::LOCAL_CRATE;
1919use rustc_hir:: find_attr;
2020use rustc_middle:: mir:: BinOp ;
2121use rustc_middle:: ty:: layout:: { FnAbiOf , HasTyCtxt , HasTypingEnv , LayoutOf } ;
22- use rustc_middle:: ty:: offload_meta:: OffloadMetadata ;
22+ use rustc_middle:: ty:: offload_meta:: { MappingFlags , OffloadMetadata } ;
2323use rustc_middle:: ty:: { self , GenericArgsRef , Instance , SimdAlign , Ty , TyCtxt , TypingEnv } ;
2424use rustc_middle:: { bug, span_bug} ;
2525use rustc_session:: config:: CrateType ;
@@ -188,6 +188,17 @@ impl<'ll, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> {
188188 codegen_offload_preload ( self , tcx, instance, args) ;
189189 }
190190
191+ fn codegen_offload_preload_mut_drop (
192+ & mut self ,
193+ preload_ty : Ty < ' tcx > ,
194+ place : PlaceRef < ' tcx , & ' ll llvm:: Value > ,
195+ ) {
196+ let tcx = self . tcx ;
197+ dbg ! ( "Dropping PreloadMut; emit offload end mapper" ) ;
198+
199+ codegen_offload_preload_mut_drop ( self , tcx, preload_ty, place) ;
200+ }
201+
191202 fn codegen_intrinsic_call (
192203 & mut self ,
193204 instance : ty:: Instance < ' tcx > ,
@@ -1911,6 +1922,83 @@ fn codegen_autodiff<'ll, 'tcx>(
19111922 ) ;
19121923}
19131924
1925+ fn codegen_offload_preload_mut_drop < ' ll , ' tcx > (
1926+ bx : & mut Builder < ' _ , ' ll , ' tcx > ,
1927+ tcx : TyCtxt < ' tcx > ,
1928+ preload_ty : Ty < ' tcx > ,
1929+ place : PlaceRef < ' tcx , & ' ll llvm:: Value > ,
1930+ ) {
1931+ let cx = bx. cx ;
1932+ dbg ! ( "Starting the PreloadMut drop handling!" ) ;
1933+ // PreloadMut<'a, T> -> extract T.
1934+ let ty:: Adt ( _adt_def, generic_args) = preload_ty. kind ( ) else {
1935+ bug ! ( "expected PreloadMut ADT, got {preload_ty:?}" ) ;
1936+ } ;
1937+
1938+ // This should be the `T` parameter of PreloadMut<'a, T>.
1939+ // If this indexes the lifetime in your tree, use the correct type arg index
1940+ // or `generic_args.types().next().unwrap()`.
1941+ let pointee_ty: Ty < ' tcx > =
1942+ generic_args. types ( ) . next ( ) . unwrap_or_else ( || bug ! ( "PreloadMut without type parameter" ) ) ;
1943+
1944+ // Load field 0: `cpu_ptr: *mut T`.
1945+ let cpu_ptr_place = place. project_field ( bx, 0 ) ;
1946+ dbg ! ( & cpu_ptr_place) ;
1947+ let cpu_ptr_operand = bx. load_operand ( cpu_ptr_place) ;
1948+ dbg ! ( & cpu_ptr_operand) ;
1949+
1950+ let args: Vec < & ' ll Value > = match cpu_ptr_operand. val {
1951+ OperandValue :: Immediate ( ptr) => vec ! [ ptr] ,
1952+ OperandValue :: Pair ( _data, _meta) => {
1953+ bug ! ( "unsized PreloadMut drop not handled yet" )
1954+ }
1955+ _ => bug ! ( "unexpected PreloadMut cpu_ptr operand" ) ,
1956+ } ;
1957+
1958+ let mut meta = OffloadMetadata :: from_ty ( tcx, pointee_ty) ;
1959+ // We end a mut Mapper. Unless the user never mutated a mut variable passed in a mutable way, we
1960+ // must return it from the device to update the host version. If they never mutated it, they
1961+ // surely got a clippy or rustc warning, so it's up to them for wasting time.
1962+ meta. mode |= MappingFlags :: FROM ;
1963+ dbg ! ( & meta) ;
1964+ let metadata: & [ OffloadMetadata ; 1 ] = & [ meta] ;
1965+
1966+ let types: & Type = cx. layout_of ( pointee_ty) . llvm_type ( cx) ;
1967+
1968+ let offload_globals_ref = cx. offload_globals . borrow ( ) ;
1969+ let offload_globals = match offload_globals_ref. as_ref ( ) {
1970+ Some ( globals) => globals,
1971+ None => {
1972+ dbg ! ( "Have to initialize offload? This is a bug!" ) ;
1973+ return ;
1974+ }
1975+ } ;
1976+
1977+ let target_symbol = cx. generate_local_symbol_name ( "" ) ;
1978+ dbg ! ( "done for now" ) ;
1979+ let offload_data = gen_define_handling ( & cx, metadata, target_symbol, offload_globals) ;
1980+ let has_dynamic = metadata. iter ( ) . any ( |m| !matches ! ( m. payload_size, OffloadSize :: Static ( _) ) ) ;
1981+ let ( ty, ty2, a1, a2, a4) = crate :: builder:: gpu_helper:: preper_datatransfers (
1982+ bx,
1983+ & args,
1984+ & [ types] ,
1985+ offload_data. offload_sizes ,
1986+ metadata,
1987+ has_dynamic,
1988+ ) ;
1989+ let geps = crate :: builder:: gpu_helper:: get_geps ( bx, ty, ty2, a1, a2, a4, has_dynamic) ;
1990+
1991+ crate :: builder:: gpu_helper:: generate_mapper_call (
1992+ bx,
1993+ geps,
1994+ offload_data. memtransfer_end ,
1995+ offload_globals. end_mapper ,
1996+ offload_globals. mapper_fn_ty ,
1997+ 1 ,
1998+ offload_globals. ident_t_global ,
1999+ ) ;
2000+ }
2001+
19142002// For each PreLoad *call*, we now use some of our previous declared globals to move data to the gpu.
19152003// For now, we only handle the data transfer part of it. Consecutive calls become a no-op on the
19162004// LLVM side.
0 commit comments