diff --git a/compiler/rustc_codegen_gcc/src/lib.rs b/compiler/rustc_codegen_gcc/src/lib.rs index 7329080ce1f71..34aead1a6300a 100644 --- a/compiler/rustc_codegen_gcc/src/lib.rs +++ b/compiler/rustc_codegen_gcc/src/lib.rs @@ -442,7 +442,6 @@ impl WriteBackendMethods for GccCodegenBackend { } fn autodiff( _cgcx: &CodegenContext, - _tcx: TyCtxt<'_>, _module: &ModuleCodegen, _diff_fncs: Vec, _config: &ModuleConfig, diff --git a/compiler/rustc_codegen_llvm/src/builder.rs b/compiler/rustc_codegen_llvm/src/builder.rs index 5a34b52e6ef30..d2de62b17f04d 100644 --- a/compiler/rustc_codegen_llvm/src/builder.rs +++ b/compiler/rustc_codegen_llvm/src/builder.rs @@ -1,4 +1,4 @@ -use std::borrow::Cow; +use std::borrow::{Borrow, Cow}; use std::ops::Deref; use std::{iter, ptr}; @@ -31,20 +31,22 @@ use tracing::{debug, instrument}; use crate::abi::FnAbiLlvmExt; use crate::attributes; use crate::common::Funclet; -use crate::context::CodegenCx; +use crate::context::{CodegenCx, SimpleCx}; use crate::llvm::{self, AtomicOrdering, AtomicRmwBinOp, BasicBlock, False, True}; use crate::type_::Type; use crate::type_of::LayoutLlvmExt; use crate::value::Value; -// All Builders must have an llfn associated with them #[must_use] -pub(crate) struct Builder<'a, 'll, 'tcx> { +pub(crate) struct GenericBuilder<'a, 'll, CX: Borrow>> { pub llbuilder: &'ll mut llvm::Builder<'ll>, - pub cx: &'a CodegenCx<'ll, 'tcx>, + pub cx: &'a CX, } -impl Drop for Builder<'_, '_, '_> { +pub(crate) type SBuilder<'a, 'll> = GenericBuilder<'a, 'll, SimpleCx<'ll>>; +pub(crate) type Builder<'a, 'll, 'tcx> = GenericBuilder<'a, 'll, CodegenCx<'ll, 'tcx>>; + +impl<'a, 'll, CX: Borrow>> Drop for GenericBuilder<'a, 'll, CX> { fn drop(&mut self) { unsafe { llvm::LLVMDisposeBuilder(&mut *(self.llbuilder as *mut _)); @@ -52,6 +54,112 @@ impl Drop for Builder<'_, '_, '_> { } } +impl<'a, 'll> SBuilder<'a, 'll> { + fn call( + &mut self, + llty: &'ll Type, + llfn: &'ll Value, + args: &[&'ll Value], + funclet: Option<&Funclet<'ll>>, + ) -> &'ll Value { + debug!("call {:?} with args ({:?})", llfn, args); + + let args = self.check_call("call", llty, llfn, args); + let funclet_bundle = funclet.map(|funclet| funclet.bundle()); + let mut bundles: SmallVec<[_; 2]> = SmallVec::new(); + if let Some(funclet_bundle) = funclet_bundle { + bundles.push(funclet_bundle); + } + + let call = unsafe { + llvm::LLVMBuildCallWithOperandBundles( + self.llbuilder, + llty, + llfn, + args.as_ptr() as *const &llvm::Value, + args.len() as c_uint, + bundles.as_ptr(), + bundles.len() as c_uint, + c"".as_ptr(), + ) + }; + call + } + + fn with_scx(scx: &'a SimpleCx<'ll>) -> Self { + // Create a fresh builder from the simple context. + let llbuilder = unsafe { llvm::LLVMCreateBuilderInContext(scx.llcx) }; + SBuilder { llbuilder, cx: scx } + } +} +impl<'a, 'll, CX: Borrow>> GenericBuilder<'a, 'll, CX> { + pub(crate) fn bitcast(&mut self, val: &'ll Value, dest_ty: &'ll Type) -> &'ll Value { + unsafe { llvm::LLVMBuildBitCast(self.llbuilder, val, dest_ty, UNNAMED) } + } + + fn ret_void(&mut self) { + unsafe { + llvm::LLVMBuildRetVoid(self.llbuilder); + } + } + + fn ret(&mut self, v: &'ll Value) { + unsafe { + llvm::LLVMBuildRet(self.llbuilder, v); + } + } +} +impl<'a, 'll> SBuilder<'a, 'll> { + fn build(cx: &'a SimpleCx<'ll>, llbb: &'ll BasicBlock) -> SBuilder<'a, 'll> { + let bx = SBuilder::with_scx(cx); + unsafe { + llvm::LLVMPositionBuilderAtEnd(bx.llbuilder, llbb); + } + bx + } + + fn check_call<'b>( + &mut self, + typ: &str, + fn_ty: &'ll Type, + llfn: &'ll Value, + args: &'b [&'ll Value], + ) -> Cow<'b, [&'ll Value]> { + assert!( + self.cx.type_kind(fn_ty) == TypeKind::Function, + "builder::{typ} not passed a function, but {fn_ty:?}" + ); + + let param_tys = self.cx.func_params_types(fn_ty); + + let all_args_match = iter::zip(¶m_tys, args.iter().map(|&v| self.cx.val_ty(v))) + .all(|(expected_ty, actual_ty)| *expected_ty == actual_ty); + + if all_args_match { + return Cow::Borrowed(args); + } + + let casted_args: Vec<_> = iter::zip(param_tys, args) + .enumerate() + .map(|(i, (expected_ty, &actual_val))| { + let actual_ty = self.cx.val_ty(actual_val); + if expected_ty != actual_ty { + debug!( + "type mismatch in function call of {:?}. \ + Expected {:?} for param {}, got {:?}; injecting bitcast", + llfn, expected_ty, i, actual_ty + ); + self.bitcast(actual_val, expected_ty) + } else { + actual_val + } + }) + .collect(); + + Cow::Owned(casted_args) + } +} + /// Empty string, to be used where LLVM expects an instruction name, indicating /// that the instruction is to be left unnamed (i.e. numbered, in textual IR). // FIXME(eddyb) pass `&CStr` directly to FFI once it's a thin pointer. @@ -1222,6 +1330,14 @@ impl<'ll> StaticBuilderMethods for Builder<'_, 'll, '_> { } impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> { + fn build(cx: &'a CodegenCx<'ll, 'tcx>, llbb: &'ll BasicBlock) -> Builder<'a, 'll, 'tcx> { + let bx = Builder::with_cx(cx); + unsafe { + llvm::LLVMPositionBuilderAtEnd(bx.llbuilder, llbb); + } + bx + } + fn with_cx(cx: &'a CodegenCx<'ll, 'tcx>) -> Self { // Create a fresh builder from the crate context. let llbuilder = unsafe { llvm::LLVMCreateBuilderInContext(cx.llcx) }; @@ -1231,13 +1347,16 @@ impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> { pub(crate) fn llfn(&self) -> &'ll Value { unsafe { llvm::LLVMGetBasicBlockParent(self.llbb()) } } +} +impl<'a, 'll, CX: Borrow>> GenericBuilder<'a, 'll, CX> { fn position_at_start(&mut self, llbb: &'ll BasicBlock) { unsafe { llvm::LLVMRustPositionBuilderAtStart(self.llbuilder, llbb); } } - +} +impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> { fn align_metadata(&mut self, load: &'ll Value, align: Align) { unsafe { let md = [llvm::LLVMValueAsMetadata(self.cx.const_u64(align.bytes()))]; @@ -1259,7 +1378,8 @@ impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> { self.set_metadata(inst, llvm::MD_unpredictable, md); } } - +} +impl<'a, 'll, CX: Borrow>> GenericBuilder<'a, 'll, CX> { pub(crate) fn minnum(&mut self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value { unsafe { llvm::LLVMRustBuildMinNum(self.llbuilder, lhs, rhs) } } @@ -1360,7 +1480,9 @@ impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> { let ret = unsafe { llvm::LLVMBuildCatchRet(self.llbuilder, funclet.cleanuppad(), unwind) }; ret.expect("LLVM does not have support for catchret") } +} +impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> { fn check_call<'b>( &mut self, typ: &str, @@ -1401,11 +1523,13 @@ impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> { Cow::Owned(casted_args) } - +} +impl<'a, 'll, CX: Borrow>> GenericBuilder<'a, 'll, CX> { pub(crate) fn va_arg(&mut self, list: &'ll Value, ty: &'ll Type) -> &'ll Value { unsafe { llvm::LLVMBuildVAArg(self.llbuilder, list, ty, UNNAMED) } } - +} +impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> { pub(crate) fn call_intrinsic(&mut self, intrinsic: &str, args: &[&'ll Value]) -> &'ll Value { let (ty, f) = self.cx.get_intrinsic(intrinsic); self.call(ty, None, None, f, args, None, None) @@ -1423,7 +1547,8 @@ impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> { self.call_intrinsic(intrinsic, &[self.cx.const_u64(size), ptr]); } - +} +impl<'a, 'll, CX: Borrow>> GenericBuilder<'a, 'll, CX> { pub(crate) fn phi( &mut self, ty: &'ll Type, @@ -1443,7 +1568,8 @@ impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> { llvm::LLVMAddIncoming(phi, &val, &bb, 1 as c_uint); } } - +} +impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> { fn fptoint_sat(&mut self, signed: bool, val: &'ll Value, dest_ty: &'ll Type) -> &'ll Value { let src_ty = self.cx.val_ty(val); let (float_ty, int_ty, vector_length) = if self.cx.type_kind(src_ty) == TypeKind::Vector { diff --git a/compiler/rustc_codegen_llvm/src/builder/autodiff.rs b/compiler/rustc_codegen_llvm/src/builder/autodiff.rs index 38f7eaa090f91..6b17b5f6989be 100644 --- a/compiler/rustc_codegen_llvm/src/builder/autodiff.rs +++ b/compiler/rustc_codegen_llvm/src/builder/autodiff.rs @@ -3,20 +3,19 @@ use std::ptr; use rustc_ast::expand::autodiff_attrs::{AutoDiffAttrs, AutoDiffItem, DiffActivity, DiffMode}; use rustc_codegen_ssa::ModuleCodegen; use rustc_codegen_ssa::back::write::ModuleConfig; -use rustc_codegen_ssa::traits::{BaseTypeCodegenMethods, BuilderMethods}; use rustc_errors::FatalError; -use rustc_middle::ty::TyCtxt; use rustc_session::config::Lto; use tracing::{debug, trace}; use crate::back::write::{llvm_err, llvm_optimize}; -use crate::builder::Builder; -use crate::declare::declare_raw_fn; +use crate::builder::SBuilder; +use crate::context::SimpleCx; +use crate::declare::declare_simple_fn; use crate::errors::LlvmError; use crate::llvm::AttributePlace::Function; use crate::llvm::{Metadata, True}; use crate::value::Value; -use crate::{CodegenContext, LlvmCodegenBackend, ModuleLlvm, attributes, context, llvm}; +use crate::{CodegenContext, LlvmCodegenBackend, ModuleLlvm, attributes, llvm}; fn get_params(fnc: &Value) -> Vec<&Value> { unsafe { @@ -38,8 +37,8 @@ fn get_params(fnc: &Value) -> Vec<&Value> { /// [^1]: // FIXME(ZuseZ4): `outer_fn` should include upstream safety checks to // cover some assumptions of enzyme/autodiff, which could lead to UB otherwise. -fn generate_enzyme_call<'ll, 'tcx>( - cx: &context::CodegenCx<'ll, 'tcx>, +fn generate_enzyme_call<'ll>( + cx: &SimpleCx<'ll>, fn_to_diff: &'ll Value, outer_fn: &'ll Value, attrs: AutoDiffAttrs, @@ -112,7 +111,7 @@ fn generate_enzyme_call<'ll, 'tcx>( //FIXME(ZuseZ4): the CC/Addr/Vis values are best effort guesses, we should look at tests and // think a bit more about what should go here. let cc = llvm::LLVMGetFunctionCallConv(outer_fn); - let ad_fn = declare_raw_fn( + let ad_fn = declare_simple_fn( cx, &ad_name, llvm::CallConv::try_from(cc).expect("invalid callconv"), @@ -132,7 +131,7 @@ fn generate_enzyme_call<'ll, 'tcx>( llvm::LLVMRustEraseInstFromParent(br); let last_inst = llvm::LLVMRustGetLastInstruction(entry).unwrap(); - let mut builder = Builder::build(cx, entry); + let mut builder = SBuilder::build(cx, entry); let num_args = llvm::LLVMCountParams(&fn_to_diff); let mut args = Vec::with_capacity(num_args as usize + 1); @@ -236,7 +235,7 @@ fn generate_enzyme_call<'ll, 'tcx>( } } - let call = builder.call(enzyme_ty, None, None, ad_fn, &args, None, None); + let call = builder.call(enzyme_ty, ad_fn, &args, None); // This part is a bit iffy. LLVM requires that a call to an inlineable function has some // metadata attachted to it, but we just created this code oota. Given that the @@ -274,10 +273,9 @@ fn generate_enzyme_call<'ll, 'tcx>( } } -pub(crate) fn differentiate<'ll, 'tcx>( +pub(crate) fn differentiate<'ll>( module: &'ll ModuleCodegen, cgcx: &CodegenContext, - tcx: TyCtxt<'tcx>, diff_items: Vec, config: &ModuleConfig, ) -> Result<(), FatalError> { @@ -286,8 +284,7 @@ pub(crate) fn differentiate<'ll, 'tcx>( } let diag_handler = cgcx.create_dcx(); - let (_, cgus) = tcx.collect_and_partition_mono_items(()); - let cx = context::CodegenCx::new(tcx, &cgus.first().unwrap(), &module.module_llvm); + let cx = SimpleCx { llmod: module.module_llvm.llmod(), llcx: module.module_llvm.llcx }; // Before dumping the module, we want all the TypeTrees to become part of the module. for item in diff_items.iter() { diff --git a/compiler/rustc_codegen_llvm/src/context.rs b/compiler/rustc_codegen_llvm/src/context.rs index d8fbe51b975a0..f0da415b8193a 100644 --- a/compiler/rustc_codegen_llvm/src/context.rs +++ b/compiler/rustc_codegen_llvm/src/context.rs @@ -1,11 +1,13 @@ use std::borrow::Borrow; use std::cell::{Cell, RefCell}; use std::ffi::{CStr, c_char, c_uint}; +use std::ops::Deref; use std::str; use rustc_abi::{HasDataLayout, TargetDataLayout, VariantIdx}; use rustc_codegen_ssa::back::versioned_llvm_target; use rustc_codegen_ssa::base::{wants_msvc_seh, wants_wasm_eh}; +use rustc_codegen_ssa::common::TypeKind; use rustc_codegen_ssa::errors as ssa_errors; use rustc_codegen_ssa::traits::*; use rustc_data_structures::base_n::{ALPHANUMERIC_ONLY, ToBaseN}; @@ -30,23 +32,46 @@ use smallvec::SmallVec; use crate::back::write::to_llvm_code_model; use crate::callee::get_fn; -use crate::common::AsCCharPtr; +use crate::common::{self, AsCCharPtr}; use crate::debuginfo::metadata::apply_vcall_visibility_metadata; use crate::llvm::{Metadata, MetadataType}; use crate::type_::Type; use crate::value::Value; use crate::{attributes, coverageinfo, debuginfo, llvm, llvm_util}; +/// `TyCtxt` (and related cache datastructures) can't be move between threads. +/// However, there are various cx related functions which we want to be available to the builder and +/// other compiler pieces. Here we define a small subset which has enough information and can be +/// moved around more freely. +pub(crate) struct SimpleCx<'ll> { + pub llmod: &'ll llvm::Module, + pub llcx: &'ll llvm::Context, +} + +impl<'ll> Borrow> for CodegenCx<'ll, '_> { + fn borrow(&self) -> &SimpleCx<'ll> { + &self.scx + } +} + +impl<'ll, 'tcx> Deref for CodegenCx<'ll, 'tcx> { + type Target = SimpleCx<'ll>; + + #[inline] + fn deref(&self) -> &Self::Target { + &self.scx + } +} + /// There is one `CodegenCx` per codegen unit. Each one has its own LLVM /// `llvm::Context` so that several codegen units may be processed in parallel. /// All other LLVM data structures in the `CodegenCx` are tied to that `llvm::Context`. pub(crate) struct CodegenCx<'ll, 'tcx> { pub tcx: TyCtxt<'tcx>, + pub scx: SimpleCx<'ll>, pub use_dll_storage_attrs: bool, pub tls_model: llvm::ThreadLocalMode, - pub llmod: &'ll llvm::Module, - pub llcx: &'ll llvm::Context, pub codegen_unit: &'tcx CodegenUnit<'tcx>, /// Cache instances of monomorphic and polymorphic items @@ -553,10 +578,9 @@ impl<'ll, 'tcx> CodegenCx<'ll, 'tcx> { CodegenCx { tcx, + scx: SimpleCx { llcx, llmod }, use_dll_storage_attrs, tls_model, - llmod, - llcx, codegen_unit, instances: Default::default(), vtables: Default::default(), @@ -600,6 +624,11 @@ impl<'ll, 'tcx> CodegenCx<'ll, 'tcx> { llvm::set_section(g, c"llvm.metadata"); } } +} +impl<'ll> SimpleCx<'ll> { + pub(crate) fn val_ty(&self, v: &'ll Value) -> &'ll Type { + common::val_ty(v) + } pub(crate) fn get_metadata_value(&self, metadata: &'ll Metadata) -> &'ll Value { unsafe { llvm::LLVMMetadataAsValue(self.llcx, metadata) } @@ -625,6 +654,10 @@ impl<'ll, 'tcx> CodegenCx<'ll, 'tcx> { llvm::LLVMMDStringInContext2(self.llcx, name.as_ptr() as *const c_char, name.len()) }) } + + pub(crate) fn type_kind(&self, ty: &'ll Type) -> TypeKind { + unsafe { llvm::LLVMRustGetTypeKind(ty).to_generic() } + } } impl<'ll, 'tcx> MiscCodegenMethods<'tcx> for CodegenCx<'ll, 'tcx> { @@ -1176,6 +1209,20 @@ impl CodegenCx<'_, '_> { } } +// This is a duplication of the set_metadata function above. However, so far it's the only one +// shared between both contexts, so it doesn't seem worth it to make the Cx generic like we did it +// for the Builder. +impl SimpleCx<'_> { + #[allow(unused)] + /// A wrapper for [`llvm::LLVMSetMetadata`], but it takes `Metadata` as a parameter instead of `Value`. + pub(crate) fn set_metadata<'a>(&self, val: &'a Value, kind_id: MetadataType, md: &'a Metadata) { + unsafe { + let node = llvm::LLVMMetadataAsValue(&self.llcx, md); + llvm::LLVMSetMetadata(val, kind_id as c_uint, node); + } + } +} + impl HasDataLayout for CodegenCx<'_, '_> { #[inline] fn data_layout(&self) -> &TargetDataLayout { diff --git a/compiler/rustc_codegen_llvm/src/declare.rs b/compiler/rustc_codegen_llvm/src/declare.rs index 3ec386f6b076c..80c8ff8e0d756 100644 --- a/compiler/rustc_codegen_llvm/src/declare.rs +++ b/compiler/rustc_codegen_llvm/src/declare.rs @@ -21,26 +21,26 @@ use tracing::debug; use crate::abi::{FnAbi, FnAbiLlvmExt}; use crate::common::AsCCharPtr; -use crate::context::CodegenCx; +use crate::context::{CodegenCx, SimpleCx}; use crate::llvm::AttributePlace::Function; use crate::llvm::Visibility; use crate::type_::Type; use crate::value::Value; use crate::{attributes, llvm}; -/// Declare a function. +/// Declare a function with a SimpleCx. /// /// If there’s a value with the same name already declared, the function will /// update the declaration and return existing Value instead. -pub(crate) fn declare_raw_fn<'ll>( - cx: &CodegenCx<'ll, '_>, +pub(crate) fn declare_simple_fn<'ll>( + cx: &SimpleCx<'ll>, name: &str, callconv: llvm::CallConv, unnamed: llvm::UnnamedAddr, visibility: llvm::Visibility, ty: &'ll Type, ) -> &'ll Value { - debug!("declare_raw_fn(name={:?}, ty={:?})", name, ty); + debug!("declare_simple_fn(name={:?}, ty={:?})", name, ty); let llfn = unsafe { llvm::LLVMRustGetOrInsertFunction(cx.llmod, name.as_c_char_ptr(), name.len(), ty) }; @@ -49,6 +49,24 @@ pub(crate) fn declare_raw_fn<'ll>( llvm::SetUnnamedAddress(llfn, unnamed); llvm::set_visibility(llfn, visibility); + llfn +} + +/// Declare a function. +/// +/// If there’s a value with the same name already declared, the function will +/// update the declaration and return existing Value instead. +pub(crate) fn declare_raw_fn<'ll, 'tcx>( + cx: &CodegenCx<'ll, 'tcx>, + name: &str, + callconv: llvm::CallConv, + unnamed: llvm::UnnamedAddr, + visibility: llvm::Visibility, + ty: &'ll Type, +) -> &'ll Value { + debug!("declare_raw_fn(name={:?}, ty={:?})", name, ty); + let llfn = declare_simple_fn(cx, name, callconv, unnamed, visibility, ty); + let mut attrs = SmallVec::<[_; 4]>::new(); if cx.tcx.sess.opts.cg.no_redzone.unwrap_or(cx.tcx.sess.target.disable_redzone) { diff --git a/compiler/rustc_codegen_llvm/src/intrinsic.rs b/compiler/rustc_codegen_llvm/src/intrinsic.rs index cabcfc9b42b4e..91b44b084b095 100644 --- a/compiler/rustc_codegen_llvm/src/intrinsic.rs +++ b/compiler/rustc_codegen_llvm/src/intrinsic.rs @@ -1081,11 +1081,11 @@ fn codegen_emcc_try<'ll>( // Helper function to give a Block to a closure to codegen a shim function. // This is currently primarily used for the `try` intrinsic functions above. -fn gen_fn<'ll, 'tcx>( - cx: &CodegenCx<'ll, 'tcx>, +fn gen_fn<'a, 'll, 'tcx>( + cx: &'a CodegenCx<'ll, 'tcx>, name: &str, rust_fn_sig: ty::PolyFnSig<'tcx>, - codegen: &mut dyn FnMut(Builder<'_, 'll, 'tcx>), + codegen: &mut dyn FnMut(Builder<'a, 'll, 'tcx>), ) -> (&'ll Type, &'ll Value) { let fn_abi = cx.fn_abi_of_fn_ptr(rust_fn_sig, ty::List::empty()); let llty = fn_abi.llvm_type(cx); @@ -1104,9 +1104,9 @@ fn gen_fn<'ll, 'tcx>( // catch exceptions. // // This function is only generated once and is then cached. -fn get_rust_try_fn<'ll, 'tcx>( - cx: &CodegenCx<'ll, 'tcx>, - codegen: &mut dyn FnMut(Builder<'_, 'll, 'tcx>), +fn get_rust_try_fn<'a, 'll, 'tcx>( + cx: &'a CodegenCx<'ll, 'tcx>, + codegen: &mut dyn FnMut(Builder<'a, 'll, 'tcx>), ) -> (&'ll Type, &'ll Value) { if let Some(llfn) = cx.rust_try_fn.get() { return llfn; diff --git a/compiler/rustc_codegen_llvm/src/lib.rs b/compiler/rustc_codegen_llvm/src/lib.rs index 06afe8bb3ad54..4a84fd29e4475 100644 --- a/compiler/rustc_codegen_llvm/src/lib.rs +++ b/compiler/rustc_codegen_llvm/src/lib.rs @@ -237,7 +237,6 @@ impl WriteBackendMethods for LlvmCodegenBackend { /// Generate autodiff rules fn autodiff( cgcx: &CodegenContext, - tcx: TyCtxt<'_>, module: &ModuleCodegen, diff_fncs: Vec, config: &ModuleConfig, @@ -246,7 +245,7 @@ impl WriteBackendMethods for LlvmCodegenBackend { let dcx = cgcx.create_dcx(); return Err(dcx.handle().emit_almost_fatal(AutoDiffWithoutLTO)); } - builder::autodiff::differentiate(module, cgcx, tcx, diff_fncs, config) + builder::autodiff::differentiate(module, cgcx, diff_fncs, config) } } diff --git a/compiler/rustc_codegen_llvm/src/type_.rs b/compiler/rustc_codegen_llvm/src/type_.rs index 6aec078e0de34..c56ad886120f0 100644 --- a/compiler/rustc_codegen_llvm/src/type_.rs +++ b/compiler/rustc_codegen_llvm/src/type_.rs @@ -11,7 +11,7 @@ use rustc_middle::ty::{self, Ty}; use rustc_target::callconv::{CastTarget, FnAbi, Reg}; use crate::abi::{FnAbiLlvmExt, LlvmType}; -use crate::context::CodegenCx; +use crate::context::{CodegenCx, SimpleCx}; pub(crate) use crate::llvm::Type; use crate::llvm::{Bool, False, Metadata, True}; use crate::type_of::LayoutLlvmExt; @@ -35,7 +35,8 @@ impl fmt::Debug for Type { } } -impl<'ll> CodegenCx<'ll, '_> { +impl<'ll> CodegenCx<'ll, '_> {} +impl<'ll> SimpleCx<'ll> { pub(crate) fn type_named_struct(&self, name: &str) -> &'ll Type { let name = SmallCStr::new(name); unsafe { llvm::LLVMStructCreateNamed(self.llcx, name.as_ptr()) } @@ -44,11 +45,9 @@ impl<'ll> CodegenCx<'ll, '_> { pub(crate) fn set_struct_body(&self, ty: &'ll Type, els: &[&'ll Type], packed: bool) { unsafe { llvm::LLVMStructSetBody(ty, els.as_ptr(), els.len() as c_uint, packed as Bool) } } - pub(crate) fn type_void(&self) -> &'ll Type { unsafe { llvm::LLVMVoidTypeInContext(self.llcx) } } - pub(crate) fn type_token(&self) -> &'ll Type { unsafe { llvm::LLVMTokenTypeInContext(self.llcx) } } @@ -75,7 +74,8 @@ impl<'ll> CodegenCx<'ll, '_> { args } } - +} +impl<'ll, 'tcx> CodegenCx<'ll, 'tcx> { pub(crate) fn type_bool(&self) -> &'ll Type { self.type_i8() } @@ -120,7 +120,8 @@ impl<'ll> CodegenCx<'ll, '_> { assert_eq!(size % unit_size, 0); self.type_array(self.type_from_integer(unit), size / unit_size) } - +} +impl<'ll> SimpleCx<'ll> { pub(crate) fn type_variadic_func(&self, args: &[&'ll Type], ret: &'ll Type) -> &'ll Type { unsafe { llvm::LLVMFunctionType(ret, args.as_ptr(), args.len() as c_uint, True) } } diff --git a/compiler/rustc_codegen_ssa/src/back/lto.rs b/compiler/rustc_codegen_ssa/src/back/lto.rs index efccf7687a1e4..9fd984b6419ee 100644 --- a/compiler/rustc_codegen_ssa/src/back/lto.rs +++ b/compiler/rustc_codegen_ssa/src/back/lto.rs @@ -4,7 +4,6 @@ use std::sync::Arc; use rustc_ast::expand::autodiff_attrs::AutoDiffItem; use rustc_data_structures::memmap::Mmap; use rustc_errors::FatalError; -use rustc_middle::ty::TyCtxt; use super::write::CodegenContext; use crate::ModuleCodegen; @@ -89,13 +88,12 @@ impl LtoModuleCodegen { pub unsafe fn autodiff( self, cgcx: &CodegenContext, - tcx: TyCtxt<'_>, diff_fncs: Vec, config: &ModuleConfig, ) -> Result, FatalError> { match &self { LtoModuleCodegen::Fat(module) => { - B::autodiff(cgcx, tcx, &module, diff_fncs, config)?; + B::autodiff(cgcx, &module, diff_fncs, config)?; } _ => panic!("autodiff called with non-fat LTO module"), } diff --git a/compiler/rustc_codegen_ssa/src/traits/write.rs b/compiler/rustc_codegen_ssa/src/traits/write.rs index 51e2255efe142..97fe614aa10cd 100644 --- a/compiler/rustc_codegen_ssa/src/traits/write.rs +++ b/compiler/rustc_codegen_ssa/src/traits/write.rs @@ -1,7 +1,6 @@ use rustc_ast::expand::autodiff_attrs::AutoDiffItem; use rustc_errors::{DiagCtxtHandle, FatalError}; use rustc_middle::dep_graph::WorkProduct; -use rustc_middle::ty::TyCtxt; use crate::back::lto::{LtoModuleCodegen, SerializedModule, ThinModule}; use crate::back::write::{CodegenContext, FatLtoInput, ModuleConfig}; @@ -65,7 +64,6 @@ pub trait WriteBackendMethods: 'static + Sized + Clone { fn serialize_module(module: ModuleCodegen) -> (String, Self::ModuleBuffer); fn autodiff( cgcx: &CodegenContext, - tcx: TyCtxt<'_>, module: &ModuleCodegen, diff_fncs: Vec, config: &ModuleConfig,