Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 386c233

Browse files
ZuseZ4oli-obk
andcommittedJan 24, 2025·
Make CodegenCx and Builder generic
Co-authored-by: Oli Scherer <[email protected]>
1 parent a48e7b0 commit 386c233

File tree

10 files changed

+239
-56
lines changed

10 files changed

+239
-56
lines changed
 

‎compiler/rustc_codegen_gcc/src/lib.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -442,7 +442,6 @@ impl WriteBackendMethods for GccCodegenBackend {
442442
}
443443
fn autodiff(
444444
_cgcx: &CodegenContext<Self>,
445-
_tcx: TyCtxt<'_>,
446445
_module: &ModuleCodegen<Self::Module>,
447446
_diff_fncs: Vec<AutoDiffItem>,
448447
_config: &ModuleConfig,

‎compiler/rustc_codegen_llvm/src/builder.rs

Lines changed: 138 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use std::borrow::Cow;
1+
use std::borrow::{Borrow, Cow};
22
use std::ops::Deref;
33
use std::{iter, ptr};
44

@@ -31,27 +31,135 @@ use tracing::{debug, instrument};
3131
use crate::abi::FnAbiLlvmExt;
3232
use crate::attributes;
3333
use crate::common::Funclet;
34-
use crate::context::CodegenCx;
34+
use crate::context::{CodegenCx, SimpleCx};
3535
use crate::llvm::{self, AtomicOrdering, AtomicRmwBinOp, BasicBlock, False, True};
3636
use crate::type_::Type;
3737
use crate::type_of::LayoutLlvmExt;
3838
use crate::value::Value;
3939

40-
// All Builders must have an llfn associated with them
4140
#[must_use]
42-
pub(crate) struct Builder<'a, 'll, 'tcx> {
41+
pub(crate) struct GenericBuilder<'a, 'll, CX: Borrow<SimpleCx<'ll>>> {
4342
pub llbuilder: &'ll mut llvm::Builder<'ll>,
44-
pub cx: &'a CodegenCx<'ll, 'tcx>,
43+
pub cx: &'a CX,
4544
}
4645

47-
impl Drop for Builder<'_, '_, '_> {
46+
pub(crate) type SBuilder<'a, 'll> = GenericBuilder<'a, 'll, SimpleCx<'ll>>;
47+
pub(crate) type Builder<'a, 'll, 'tcx> = GenericBuilder<'a, 'll, CodegenCx<'ll, 'tcx>>;
48+
49+
impl<'a, 'll, CX: Borrow<SimpleCx<'ll>>> Drop for GenericBuilder<'a, 'll, CX> {
4850
fn drop(&mut self) {
4951
unsafe {
5052
llvm::LLVMDisposeBuilder(&mut *(self.llbuilder as *mut _));
5153
}
5254
}
5355
}
5456

57+
impl<'a, 'll> SBuilder<'a, 'll> {
58+
fn call(
59+
&mut self,
60+
llty: &'ll Type,
61+
llfn: &'ll Value,
62+
args: &[&'ll Value],
63+
funclet: Option<&Funclet<'ll>>,
64+
) -> &'ll Value {
65+
debug!("call {:?} with args ({:?})", llfn, args);
66+
67+
let args = self.check_call("call", llty, llfn, args);
68+
let funclet_bundle = funclet.map(|funclet| funclet.bundle());
69+
let mut bundles: SmallVec<[_; 2]> = SmallVec::new();
70+
if let Some(funclet_bundle) = funclet_bundle {
71+
bundles.push(funclet_bundle);
72+
}
73+
74+
let call = unsafe {
75+
llvm::LLVMBuildCallWithOperandBundles(
76+
self.llbuilder,
77+
llty,
78+
llfn,
79+
args.as_ptr() as *const &llvm::Value,
80+
args.len() as c_uint,
81+
bundles.as_ptr(),
82+
bundles.len() as c_uint,
83+
c"".as_ptr(),
84+
)
85+
};
86+
call
87+
}
88+
89+
fn with_scx(scx: &'a SimpleCx<'ll>) -> Self {
90+
// Create a fresh builder from the simple context.
91+
let llbuilder = unsafe { llvm::LLVMCreateBuilderInContext(scx.llcx) };
92+
SBuilder { llbuilder, cx: scx }
93+
}
94+
}
95+
impl<'a, 'll, CX: Borrow<SimpleCx<'ll>>> GenericBuilder<'a, 'll, CX> {
96+
pub(crate) fn bitcast(&mut self, val: &'ll Value, dest_ty: &'ll Type) -> &'ll Value {
97+
unsafe { llvm::LLVMBuildBitCast(self.llbuilder, val, dest_ty, UNNAMED) }
98+
}
99+
100+
fn ret_void(&mut self) {
101+
unsafe {
102+
llvm::LLVMBuildRetVoid(self.llbuilder);
103+
}
104+
}
105+
106+
fn ret(&mut self, v: &'ll Value) {
107+
unsafe {
108+
llvm::LLVMBuildRet(self.llbuilder, v);
109+
}
110+
}
111+
}
112+
impl<'a, 'll> SBuilder<'a, 'll> {
113+
fn build(cx: &'a SimpleCx<'ll>, llbb: &'ll BasicBlock) -> SBuilder<'a, 'll> {
114+
let bx = SBuilder::with_scx(cx);
115+
unsafe {
116+
llvm::LLVMPositionBuilderAtEnd(bx.llbuilder, llbb);
117+
}
118+
bx
119+
}
120+
121+
fn check_call<'b>(
122+
&mut self,
123+
typ: &str,
124+
fn_ty: &'ll Type,
125+
llfn: &'ll Value,
126+
args: &'b [&'ll Value],
127+
) -> Cow<'b, [&'ll Value]> {
128+
assert!(
129+
self.cx.type_kind(fn_ty) == TypeKind::Function,
130+
"builder::{typ} not passed a function, but {fn_ty:?}"
131+
);
132+
133+
let param_tys = self.cx.func_params_types(fn_ty);
134+
135+
let all_args_match = iter::zip(&param_tys, args.iter().map(|&v| self.cx.val_ty(v)))
136+
.all(|(expected_ty, actual_ty)| *expected_ty == actual_ty);
137+
138+
if all_args_match {
139+
return Cow::Borrowed(args);
140+
}
141+
142+
let casted_args: Vec<_> = iter::zip(param_tys, args)
143+
.enumerate()
144+
.map(|(i, (expected_ty, &actual_val))| {
145+
let actual_ty = self.cx.val_ty(actual_val);
146+
if expected_ty != actual_ty {
147+
debug!(
148+
"type mismatch in function call of {:?}. \
149+
Expected {:?} for param {}, got {:?}; injecting bitcast",
150+
llfn, expected_ty, i, actual_ty
151+
);
152+
self.bitcast(actual_val, expected_ty)
153+
} else {
154+
actual_val
155+
}
156+
})
157+
.collect();
158+
159+
Cow::Owned(casted_args)
160+
}
161+
}
162+
55163
/// Empty string, to be used where LLVM expects an instruction name, indicating
56164
/// that the instruction is to be left unnamed (i.e. numbered, in textual IR).
57165
// FIXME(eddyb) pass `&CStr` directly to FFI once it's a thin pointer.
@@ -1222,6 +1330,14 @@ impl<'ll> StaticBuilderMethods for Builder<'_, 'll, '_> {
12221330
}
12231331

12241332
impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> {
1333+
fn build(cx: &'a CodegenCx<'ll, 'tcx>, llbb: &'ll BasicBlock) -> Builder<'a, 'll, 'tcx> {
1334+
let bx = Builder::with_cx(cx);
1335+
unsafe {
1336+
llvm::LLVMPositionBuilderAtEnd(bx.llbuilder, llbb);
1337+
}
1338+
bx
1339+
}
1340+
12251341
fn with_cx(cx: &'a CodegenCx<'ll, 'tcx>) -> Self {
12261342
// Create a fresh builder from the crate context.
12271343
let llbuilder = unsafe { llvm::LLVMCreateBuilderInContext(cx.llcx) };
@@ -1231,13 +1347,16 @@ impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> {
12311347
pub(crate) fn llfn(&self) -> &'ll Value {
12321348
unsafe { llvm::LLVMGetBasicBlockParent(self.llbb()) }
12331349
}
1350+
}
12341351

1352+
impl<'a, 'll, CX: Borrow<SimpleCx<'ll>>> GenericBuilder<'a, 'll, CX> {
12351353
fn position_at_start(&mut self, llbb: &'ll BasicBlock) {
12361354
unsafe {
12371355
llvm::LLVMRustPositionBuilderAtStart(self.llbuilder, llbb);
12381356
}
12391357
}
1240-
1358+
}
1359+
impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> {
12411360
fn align_metadata(&mut self, load: &'ll Value, align: Align) {
12421361
unsafe {
12431362
let md = [llvm::LLVMValueAsMetadata(self.cx.const_u64(align.bytes()))];
@@ -1259,7 +1378,8 @@ impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> {
12591378
self.set_metadata(inst, llvm::MD_unpredictable, md);
12601379
}
12611380
}
1262-
1381+
}
1382+
impl<'a, 'll, CX: Borrow<SimpleCx<'ll>>> GenericBuilder<'a, 'll, CX> {
12631383
pub(crate) fn minnum(&mut self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value {
12641384
unsafe { llvm::LLVMRustBuildMinNum(self.llbuilder, lhs, rhs) }
12651385
}
@@ -1360,7 +1480,9 @@ impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> {
13601480
let ret = unsafe { llvm::LLVMBuildCatchRet(self.llbuilder, funclet.cleanuppad(), unwind) };
13611481
ret.expect("LLVM does not have support for catchret")
13621482
}
1483+
}
13631484

1485+
impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> {
13641486
fn check_call<'b>(
13651487
&mut self,
13661488
typ: &str,
@@ -1401,11 +1523,13 @@ impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> {
14011523

14021524
Cow::Owned(casted_args)
14031525
}
1404-
1526+
}
1527+
impl<'a, 'll, CX: Borrow<SimpleCx<'ll>>> GenericBuilder<'a, 'll, CX> {
14051528
pub(crate) fn va_arg(&mut self, list: &'ll Value, ty: &'ll Type) -> &'ll Value {
14061529
unsafe { llvm::LLVMBuildVAArg(self.llbuilder, list, ty, UNNAMED) }
14071530
}
1408-
1531+
}
1532+
impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> {
14091533
pub(crate) fn call_intrinsic(&mut self, intrinsic: &str, args: &[&'ll Value]) -> &'ll Value {
14101534
let (ty, f) = self.cx.get_intrinsic(intrinsic);
14111535
self.call(ty, None, None, f, args, None, None)
@@ -1423,7 +1547,8 @@ impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> {
14231547

14241548
self.call_intrinsic(intrinsic, &[self.cx.const_u64(size), ptr]);
14251549
}
1426-
1550+
}
1551+
impl<'a, 'll, CX: Borrow<SimpleCx<'ll>>> GenericBuilder<'a, 'll, CX> {
14271552
pub(crate) fn phi(
14281553
&mut self,
14291554
ty: &'ll Type,
@@ -1443,7 +1568,8 @@ impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> {
14431568
llvm::LLVMAddIncoming(phi, &val, &bb, 1 as c_uint);
14441569
}
14451570
}
1446-
1571+
}
1572+
impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> {
14471573
fn fptoint_sat(&mut self, signed: bool, val: &'ll Value, dest_ty: &'ll Type) -> &'ll Value {
14481574
let src_ty = self.cx.val_ty(val);
14491575
let (float_ty, int_ty, vector_length) = if self.cx.type_kind(src_ty) == TypeKind::Vector {

‎compiler/rustc_codegen_llvm/src/builder/autodiff.rs

Lines changed: 11 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -3,20 +3,19 @@ use std::ptr;
33
use rustc_ast::expand::autodiff_attrs::{AutoDiffAttrs, AutoDiffItem, DiffActivity, DiffMode};
44
use rustc_codegen_ssa::ModuleCodegen;
55
use rustc_codegen_ssa::back::write::ModuleConfig;
6-
use rustc_codegen_ssa::traits::{BaseTypeCodegenMethods, BuilderMethods};
76
use rustc_errors::FatalError;
8-
use rustc_middle::ty::TyCtxt;
97
use rustc_session::config::Lto;
108
use tracing::{debug, trace};
119

1210
use crate::back::write::{llvm_err, llvm_optimize};
13-
use crate::builder::Builder;
14-
use crate::declare::declare_raw_fn;
11+
use crate::builder::SBuilder;
12+
use crate::context::SimpleCx;
13+
use crate::declare::declare_simple_fn;
1514
use crate::errors::LlvmError;
1615
use crate::llvm::AttributePlace::Function;
1716
use crate::llvm::{Metadata, True};
1817
use crate::value::Value;
19-
use crate::{CodegenContext, LlvmCodegenBackend, ModuleLlvm, attributes, context, llvm};
18+
use crate::{CodegenContext, LlvmCodegenBackend, ModuleLlvm, attributes, llvm};
2019

2120
fn get_params(fnc: &Value) -> Vec<&Value> {
2221
unsafe {
@@ -38,8 +37,8 @@ fn get_params(fnc: &Value) -> Vec<&Value> {
3837
/// [^1]: <https://enzyme.mit.edu/getting_started/CallingConvention/>
3938
// FIXME(ZuseZ4): `outer_fn` should include upstream safety checks to
4039
// cover some assumptions of enzyme/autodiff, which could lead to UB otherwise.
41-
fn generate_enzyme_call<'ll, 'tcx>(
42-
cx: &context::CodegenCx<'ll, 'tcx>,
40+
fn generate_enzyme_call<'ll>(
41+
cx: &SimpleCx<'ll>,
4342
fn_to_diff: &'ll Value,
4443
outer_fn: &'ll Value,
4544
attrs: AutoDiffAttrs,
@@ -112,7 +111,7 @@ fn generate_enzyme_call<'ll, 'tcx>(
112111
//FIXME(ZuseZ4): the CC/Addr/Vis values are best effort guesses, we should look at tests and
113112
// think a bit more about what should go here.
114113
let cc = llvm::LLVMGetFunctionCallConv(outer_fn);
115-
let ad_fn = declare_raw_fn(
114+
let ad_fn = declare_simple_fn(
116115
cx,
117116
&ad_name,
118117
llvm::CallConv::try_from(cc).expect("invalid callconv"),
@@ -132,7 +131,7 @@ fn generate_enzyme_call<'ll, 'tcx>(
132131
llvm::LLVMRustEraseInstFromParent(br);
133132

134133
let last_inst = llvm::LLVMRustGetLastInstruction(entry).unwrap();
135-
let mut builder = Builder::build(cx, entry);
134+
let mut builder = SBuilder::build(cx, entry);
136135

137136
let num_args = llvm::LLVMCountParams(&fn_to_diff);
138137
let mut args = Vec::with_capacity(num_args as usize + 1);
@@ -236,7 +235,7 @@ fn generate_enzyme_call<'ll, 'tcx>(
236235
}
237236
}
238237

239-
let call = builder.call(enzyme_ty, None, None, ad_fn, &args, None, None);
238+
let call = builder.call(enzyme_ty, ad_fn, &args, None);
240239

241240
// This part is a bit iffy. LLVM requires that a call to an inlineable function has some
242241
// metadata attachted to it, but we just created this code oota. Given that the
@@ -274,10 +273,9 @@ fn generate_enzyme_call<'ll, 'tcx>(
274273
}
275274
}
276275

277-
pub(crate) fn differentiate<'ll, 'tcx>(
276+
pub(crate) fn differentiate<'ll>(
278277
module: &'ll ModuleCodegen<ModuleLlvm>,
279278
cgcx: &CodegenContext<LlvmCodegenBackend>,
280-
tcx: TyCtxt<'tcx>,
281279
diff_items: Vec<AutoDiffItem>,
282280
config: &ModuleConfig,
283281
) -> Result<(), FatalError> {
@@ -286,8 +284,7 @@ pub(crate) fn differentiate<'ll, 'tcx>(
286284
}
287285

288286
let diag_handler = cgcx.create_dcx();
289-
let (_, cgus) = tcx.collect_and_partition_mono_items(());
290-
let cx = context::CodegenCx::new(tcx, &cgus.first().unwrap(), &module.module_llvm);
287+
let cx = SimpleCx { llmod: module.module_llvm.llmod(), llcx: module.module_llvm.llcx };
291288

292289
// Before dumping the module, we want all the TypeTrees to become part of the module.
293290
for item in diff_items.iter() {

‎compiler/rustc_codegen_llvm/src/context.rs

Lines changed: 52 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11
use std::borrow::Borrow;
22
use std::cell::{Cell, RefCell};
33
use std::ffi::{CStr, c_char, c_uint};
4+
use std::ops::Deref;
45
use std::str;
56

67
use rustc_abi::{HasDataLayout, TargetDataLayout, VariantIdx};
78
use rustc_codegen_ssa::back::versioned_llvm_target;
89
use rustc_codegen_ssa::base::{wants_msvc_seh, wants_wasm_eh};
10+
use rustc_codegen_ssa::common::TypeKind;
911
use rustc_codegen_ssa::errors as ssa_errors;
1012
use rustc_codegen_ssa::traits::*;
1113
use rustc_data_structures::base_n::{ALPHANUMERIC_ONLY, ToBaseN};
@@ -30,23 +32,46 @@ use smallvec::SmallVec;
3032

3133
use crate::back::write::to_llvm_code_model;
3234
use crate::callee::get_fn;
33-
use crate::common::AsCCharPtr;
35+
use crate::common::{self, AsCCharPtr};
3436
use crate::debuginfo::metadata::apply_vcall_visibility_metadata;
3537
use crate::llvm::{Metadata, MetadataType};
3638
use crate::type_::Type;
3739
use crate::value::Value;
3840
use crate::{attributes, coverageinfo, debuginfo, llvm, llvm_util};
3941

42+
/// `TyCtxt` (and related cache datastructures) can't be move between threads.
43+
/// However, there are various cx related functions which we want to be available to the builder and
44+
/// other compiler pieces. Here we define a small subset which has enough information and can be
45+
/// moved around more freely.
46+
pub(crate) struct SimpleCx<'ll> {
47+
pub llmod: &'ll llvm::Module,
48+
pub llcx: &'ll llvm::Context,
49+
}
50+
51+
impl<'ll> Borrow<SimpleCx<'ll>> for CodegenCx<'ll, '_> {
52+
fn borrow(&self) -> &SimpleCx<'ll> {
53+
&self.scx
54+
}
55+
}
56+
57+
impl<'ll, 'tcx> Deref for CodegenCx<'ll, 'tcx> {
58+
type Target = SimpleCx<'ll>;
59+
60+
#[inline]
61+
fn deref(&self) -> &Self::Target {
62+
&self.scx
63+
}
64+
}
65+
4066
/// There is one `CodegenCx` per codegen unit. Each one has its own LLVM
4167
/// `llvm::Context` so that several codegen units may be processed in parallel.
4268
/// All other LLVM data structures in the `CodegenCx` are tied to that `llvm::Context`.
4369
pub(crate) struct CodegenCx<'ll, 'tcx> {
4470
pub tcx: TyCtxt<'tcx>,
71+
pub scx: SimpleCx<'ll>,
4572
pub use_dll_storage_attrs: bool,
4673
pub tls_model: llvm::ThreadLocalMode,
4774

48-
pub llmod: &'ll llvm::Module,
49-
pub llcx: &'ll llvm::Context,
5075
pub codegen_unit: &'tcx CodegenUnit<'tcx>,
5176

5277
/// Cache instances of monomorphic and polymorphic items
@@ -553,10 +578,9 @@ impl<'ll, 'tcx> CodegenCx<'ll, 'tcx> {
553578

554579
CodegenCx {
555580
tcx,
581+
scx: SimpleCx { llcx, llmod },
556582
use_dll_storage_attrs,
557583
tls_model,
558-
llmod,
559-
llcx,
560584
codegen_unit,
561585
instances: Default::default(),
562586
vtables: Default::default(),
@@ -600,6 +624,11 @@ impl<'ll, 'tcx> CodegenCx<'ll, 'tcx> {
600624
llvm::set_section(g, c"llvm.metadata");
601625
}
602626
}
627+
}
628+
impl<'ll> SimpleCx<'ll> {
629+
pub(crate) fn val_ty(&self, v: &'ll Value) -> &'ll Type {
630+
common::val_ty(v)
631+
}
603632

604633
pub(crate) fn get_metadata_value(&self, metadata: &'ll Metadata) -> &'ll Value {
605634
unsafe { llvm::LLVMMetadataAsValue(self.llcx, metadata) }
@@ -625,6 +654,10 @@ impl<'ll, 'tcx> CodegenCx<'ll, 'tcx> {
625654
llvm::LLVMMDStringInContext2(self.llcx, name.as_ptr() as *const c_char, name.len())
626655
})
627656
}
657+
658+
pub(crate) fn type_kind(&self, ty: &'ll Type) -> TypeKind {
659+
unsafe { llvm::LLVMRustGetTypeKind(ty).to_generic() }
660+
}
628661
}
629662

630663
impl<'ll, 'tcx> MiscCodegenMethods<'tcx> for CodegenCx<'ll, 'tcx> {
@@ -1176,6 +1209,20 @@ impl CodegenCx<'_, '_> {
11761209
}
11771210
}
11781211

1212+
// This is a duplication of the set_metadata function above. However, so far it's the only one
1213+
// shared between both contexts, so it doesn't seem worth it to make the Cx generic like we did it
1214+
// for the Builder.
1215+
impl SimpleCx<'_> {
1216+
#[allow(unused)]
1217+
/// A wrapper for [`llvm::LLVMSetMetadata`], but it takes `Metadata` as a parameter instead of `Value`.
1218+
pub(crate) fn set_metadata<'a>(&self, val: &'a Value, kind_id: MetadataType, md: &'a Metadata) {
1219+
unsafe {
1220+
let node = llvm::LLVMMetadataAsValue(&self.llcx, md);
1221+
llvm::LLVMSetMetadata(val, kind_id as c_uint, node);
1222+
}
1223+
}
1224+
}
1225+
11791226
impl HasDataLayout for CodegenCx<'_, '_> {
11801227
#[inline]
11811228
fn data_layout(&self) -> &TargetDataLayout {

‎compiler/rustc_codegen_llvm/src/declare.rs

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,26 +21,26 @@ use tracing::debug;
2121

2222
use crate::abi::{FnAbi, FnAbiLlvmExt};
2323
use crate::common::AsCCharPtr;
24-
use crate::context::CodegenCx;
24+
use crate::context::{CodegenCx, SimpleCx};
2525
use crate::llvm::AttributePlace::Function;
2626
use crate::llvm::Visibility;
2727
use crate::type_::Type;
2828
use crate::value::Value;
2929
use crate::{attributes, llvm};
3030

31-
/// Declare a function.
31+
/// Declare a function with a SimpleCx.
3232
///
3333
/// If there’s a value with the same name already declared, the function will
3434
/// update the declaration and return existing Value instead.
35-
pub(crate) fn declare_raw_fn<'ll>(
36-
cx: &CodegenCx<'ll, '_>,
35+
pub(crate) fn declare_simple_fn<'ll>(
36+
cx: &SimpleCx<'ll>,
3737
name: &str,
3838
callconv: llvm::CallConv,
3939
unnamed: llvm::UnnamedAddr,
4040
visibility: llvm::Visibility,
4141
ty: &'ll Type,
4242
) -> &'ll Value {
43-
debug!("declare_raw_fn(name={:?}, ty={:?})", name, ty);
43+
debug!("declare_simple_fn(name={:?}, ty={:?})", name, ty);
4444
let llfn = unsafe {
4545
llvm::LLVMRustGetOrInsertFunction(cx.llmod, name.as_c_char_ptr(), name.len(), ty)
4646
};
@@ -49,6 +49,24 @@ pub(crate) fn declare_raw_fn<'ll>(
4949
llvm::SetUnnamedAddress(llfn, unnamed);
5050
llvm::set_visibility(llfn, visibility);
5151

52+
llfn
53+
}
54+
55+
/// Declare a function.
56+
///
57+
/// If there’s a value with the same name already declared, the function will
58+
/// update the declaration and return existing Value instead.
59+
pub(crate) fn declare_raw_fn<'ll, 'tcx>(
60+
cx: &CodegenCx<'ll, 'tcx>,
61+
name: &str,
62+
callconv: llvm::CallConv,
63+
unnamed: llvm::UnnamedAddr,
64+
visibility: llvm::Visibility,
65+
ty: &'ll Type,
66+
) -> &'ll Value {
67+
debug!("declare_raw_fn(name={:?}, ty={:?})", name, ty);
68+
let llfn = declare_simple_fn(cx, name, callconv, unnamed, visibility, ty);
69+
5270
let mut attrs = SmallVec::<[_; 4]>::new();
5371

5472
if cx.tcx.sess.opts.cg.no_redzone.unwrap_or(cx.tcx.sess.target.disable_redzone) {

‎compiler/rustc_codegen_llvm/src/intrinsic.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1081,11 +1081,11 @@ fn codegen_emcc_try<'ll>(
10811081

10821082
// Helper function to give a Block to a closure to codegen a shim function.
10831083
// This is currently primarily used for the `try` intrinsic functions above.
1084-
fn gen_fn<'ll, 'tcx>(
1085-
cx: &CodegenCx<'ll, 'tcx>,
1084+
fn gen_fn<'a, 'll, 'tcx>(
1085+
cx: &'a CodegenCx<'ll, 'tcx>,
10861086
name: &str,
10871087
rust_fn_sig: ty::PolyFnSig<'tcx>,
1088-
codegen: &mut dyn FnMut(Builder<'_, 'll, 'tcx>),
1088+
codegen: &mut dyn FnMut(Builder<'a, 'll, 'tcx>),
10891089
) -> (&'ll Type, &'ll Value) {
10901090
let fn_abi = cx.fn_abi_of_fn_ptr(rust_fn_sig, ty::List::empty());
10911091
let llty = fn_abi.llvm_type(cx);
@@ -1104,9 +1104,9 @@ fn gen_fn<'ll, 'tcx>(
11041104
// catch exceptions.
11051105
//
11061106
// This function is only generated once and is then cached.
1107-
fn get_rust_try_fn<'ll, 'tcx>(
1108-
cx: &CodegenCx<'ll, 'tcx>,
1109-
codegen: &mut dyn FnMut(Builder<'_, 'll, 'tcx>),
1107+
fn get_rust_try_fn<'a, 'll, 'tcx>(
1108+
cx: &'a CodegenCx<'ll, 'tcx>,
1109+
codegen: &mut dyn FnMut(Builder<'a, 'll, 'tcx>),
11101110
) -> (&'ll Type, &'ll Value) {
11111111
if let Some(llfn) = cx.rust_try_fn.get() {
11121112
return llfn;

‎compiler/rustc_codegen_llvm/src/lib.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -237,7 +237,6 @@ impl WriteBackendMethods for LlvmCodegenBackend {
237237
/// Generate autodiff rules
238238
fn autodiff(
239239
cgcx: &CodegenContext<Self>,
240-
tcx: TyCtxt<'_>,
241240
module: &ModuleCodegen<Self::Module>,
242241
diff_fncs: Vec<AutoDiffItem>,
243242
config: &ModuleConfig,
@@ -246,7 +245,7 @@ impl WriteBackendMethods for LlvmCodegenBackend {
246245
let dcx = cgcx.create_dcx();
247246
return Err(dcx.handle().emit_almost_fatal(AutoDiffWithoutLTO));
248247
}
249-
builder::autodiff::differentiate(module, cgcx, tcx, diff_fncs, config)
248+
builder::autodiff::differentiate(module, cgcx, diff_fncs, config)
250249
}
251250
}
252251

‎compiler/rustc_codegen_llvm/src/type_.rs

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ use rustc_middle::ty::{self, Ty};
1111
use rustc_target::callconv::{CastTarget, FnAbi, Reg};
1212

1313
use crate::abi::{FnAbiLlvmExt, LlvmType};
14-
use crate::context::CodegenCx;
14+
use crate::context::{CodegenCx, SimpleCx};
1515
pub(crate) use crate::llvm::Type;
1616
use crate::llvm::{Bool, False, Metadata, True};
1717
use crate::type_of::LayoutLlvmExt;
@@ -35,7 +35,8 @@ impl fmt::Debug for Type {
3535
}
3636
}
3737

38-
impl<'ll> CodegenCx<'ll, '_> {
38+
impl<'ll> CodegenCx<'ll, '_> {}
39+
impl<'ll> SimpleCx<'ll> {
3940
pub(crate) fn type_named_struct(&self, name: &str) -> &'ll Type {
4041
let name = SmallCStr::new(name);
4142
unsafe { llvm::LLVMStructCreateNamed(self.llcx, name.as_ptr()) }
@@ -44,11 +45,9 @@ impl<'ll> CodegenCx<'ll, '_> {
4445
pub(crate) fn set_struct_body(&self, ty: &'ll Type, els: &[&'ll Type], packed: bool) {
4546
unsafe { llvm::LLVMStructSetBody(ty, els.as_ptr(), els.len() as c_uint, packed as Bool) }
4647
}
47-
4848
pub(crate) fn type_void(&self) -> &'ll Type {
4949
unsafe { llvm::LLVMVoidTypeInContext(self.llcx) }
5050
}
51-
5251
pub(crate) fn type_token(&self) -> &'ll Type {
5352
unsafe { llvm::LLVMTokenTypeInContext(self.llcx) }
5453
}
@@ -75,7 +74,8 @@ impl<'ll> CodegenCx<'ll, '_> {
7574
args
7675
}
7776
}
78-
77+
}
78+
impl<'ll, 'tcx> CodegenCx<'ll, 'tcx> {
7979
pub(crate) fn type_bool(&self) -> &'ll Type {
8080
self.type_i8()
8181
}
@@ -120,7 +120,8 @@ impl<'ll> CodegenCx<'ll, '_> {
120120
assert_eq!(size % unit_size, 0);
121121
self.type_array(self.type_from_integer(unit), size / unit_size)
122122
}
123-
123+
}
124+
impl<'ll> SimpleCx<'ll> {
124125
pub(crate) fn type_variadic_func(&self, args: &[&'ll Type], ret: &'ll Type) -> &'ll Type {
125126
unsafe { llvm::LLVMFunctionType(ret, args.as_ptr(), args.len() as c_uint, True) }
126127
}

‎compiler/rustc_codegen_ssa/src/back/lto.rs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ use std::sync::Arc;
44
use rustc_ast::expand::autodiff_attrs::AutoDiffItem;
55
use rustc_data_structures::memmap::Mmap;
66
use rustc_errors::FatalError;
7-
use rustc_middle::ty::TyCtxt;
87

98
use super::write::CodegenContext;
109
use crate::ModuleCodegen;
@@ -89,13 +88,12 @@ impl<B: WriteBackendMethods> LtoModuleCodegen<B> {
8988
pub unsafe fn autodiff(
9089
self,
9190
cgcx: &CodegenContext<B>,
92-
tcx: TyCtxt<'_>,
9391
diff_fncs: Vec<AutoDiffItem>,
9492
config: &ModuleConfig,
9593
) -> Result<LtoModuleCodegen<B>, FatalError> {
9694
match &self {
9795
LtoModuleCodegen::Fat(module) => {
98-
B::autodiff(cgcx, tcx, &module, diff_fncs, config)?;
96+
B::autodiff(cgcx, &module, diff_fncs, config)?;
9997
}
10098
_ => panic!("autodiff called with non-fat LTO module"),
10199
}

‎compiler/rustc_codegen_ssa/src/traits/write.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
use rustc_ast::expand::autodiff_attrs::AutoDiffItem;
22
use rustc_errors::{DiagCtxtHandle, FatalError};
33
use rustc_middle::dep_graph::WorkProduct;
4-
use rustc_middle::ty::TyCtxt;
54

65
use crate::back::lto::{LtoModuleCodegen, SerializedModule, ThinModule};
76
use crate::back::write::{CodegenContext, FatLtoInput, ModuleConfig};
@@ -65,7 +64,6 @@ pub trait WriteBackendMethods: 'static + Sized + Clone {
6564
fn serialize_module(module: ModuleCodegen<Self::Module>) -> (String, Self::ModuleBuffer);
6665
fn autodiff(
6766
cgcx: &CodegenContext<Self>,
68-
tcx: TyCtxt<'_>,
6967
module: &ModuleCodegen<Self::Module>,
7068
diff_fncs: Vec<AutoDiffItem>,
7169
config: &ModuleConfig,

0 commit comments

Comments
 (0)
Please sign in to comment.