Skip to content

Commit bfd88ce

Browse files
committed
Avoid some duplication between SimpleCx and CodegenCx
1 parent d4379d2 commit bfd88ce

File tree

4 files changed

+94
-88
lines changed

4 files changed

+94
-88
lines changed

compiler/rustc_codegen_llvm/src/builder.rs

+21-33
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ use tracing::{debug, instrument};
3030

3131
use crate::abi::FnAbiLlvmExt;
3232
use crate::common::Funclet;
33-
use crate::context::{CodegenCx, SimpleCx};
33+
use crate::context::{CodegenCx, FullCx, GenericCx, SCx};
3434
use crate::llvm::{
3535
self, AtomicOrdering, AtomicRmwBinOp, BasicBlock, False, GEPNoWrapFlags, Metadata, True,
3636
};
@@ -40,15 +40,15 @@ use crate::value::Value;
4040
use crate::{attributes, llvm_util};
4141

4242
#[must_use]
43-
pub(crate) struct GenericBuilder<'a, 'll, CX: Borrow<SimpleCx<'ll>>> {
43+
pub(crate) struct GenericBuilder<'a, 'll, CX: Borrow<SCx<'ll>>> {
4444
pub llbuilder: &'ll mut llvm::Builder<'ll>,
45-
pub cx: &'a CX,
45+
pub cx: &'a GenericCx<'ll, CX>,
4646
}
4747

48-
pub(crate) type SBuilder<'a, 'll> = GenericBuilder<'a, 'll, SimpleCx<'ll>>;
49-
pub(crate) type Builder<'a, 'll, 'tcx> = GenericBuilder<'a, 'll, CodegenCx<'ll, 'tcx>>;
48+
pub(crate) type SBuilder<'a, 'll> = GenericBuilder<'a, 'll, SCx<'ll>>;
49+
pub(crate) type Builder<'a, 'll, 'tcx> = GenericBuilder<'a, 'll, FullCx<'ll, 'tcx>>;
5050

51-
impl<'a, 'll, CX: Borrow<SimpleCx<'ll>>> Drop for GenericBuilder<'a, 'll, CX> {
51+
impl<'a, 'll, CX: Borrow<SCx<'ll>>> Drop for GenericBuilder<'a, 'll, CX> {
5252
fn drop(&mut self) {
5353
unsafe {
5454
llvm::LLVMDisposeBuilder(&mut *(self.llbuilder as *mut _));
@@ -87,14 +87,15 @@ impl<'a, 'll> SBuilder<'a, 'll> {
8787
};
8888
call
8989
}
90+
}
9091

91-
fn with_scx(scx: &'a SimpleCx<'ll>) -> Self {
92+
impl<'a, 'll, CX: Borrow<SCx<'ll>>> GenericBuilder<'a, 'll, CX> {
93+
fn with_cx(scx: &'a GenericCx<'ll, CX>) -> Self {
9294
// Create a fresh builder from the simple context.
93-
let llbuilder = unsafe { llvm::LLVMCreateBuilderInContext(scx.llcx) };
94-
SBuilder { llbuilder, cx: scx }
95+
let llbuilder = unsafe { llvm::LLVMCreateBuilderInContext(scx.deref().borrow().llcx) };
96+
GenericBuilder { llbuilder, cx: scx }
9597
}
96-
}
97-
impl<'a, 'll, CX: Borrow<SimpleCx<'ll>>> GenericBuilder<'a, 'll, CX> {
98+
9899
pub(crate) fn bitcast(&mut self, val: &'ll Value, dest_ty: &'ll Type) -> &'ll Value {
99100
unsafe { llvm::LLVMBuildBitCast(self.llbuilder, val, dest_ty, UNNAMED) }
100101
}
@@ -108,16 +109,17 @@ impl<'a, 'll, CX: Borrow<SimpleCx<'ll>>> GenericBuilder<'a, 'll, CX> {
108109
llvm::LLVMBuildRet(self.llbuilder, v);
109110
}
110111
}
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);
112+
113+
fn build(cx: &'a GenericCx<'ll, CX>, llbb: &'ll BasicBlock) -> Self {
114+
let bx = Self::with_cx(cx);
115115
unsafe {
116116
llvm::LLVMPositionBuilderAtEnd(bx.llbuilder, llbb);
117117
}
118118
bx
119119
}
120+
}
120121

122+
impl<'a, 'll> SBuilder<'a, 'll> {
121123
fn check_call<'b>(
122124
&mut self,
123125
typ: &str,
@@ -1472,26 +1474,12 @@ impl<'ll> StaticBuilderMethods for Builder<'_, 'll, '_> {
14721474
}
14731475

14741476
impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> {
1475-
fn build(cx: &'a CodegenCx<'ll, 'tcx>, llbb: &'ll BasicBlock) -> Builder<'a, 'll, 'tcx> {
1476-
let bx = Builder::with_cx(cx);
1477-
unsafe {
1478-
llvm::LLVMPositionBuilderAtEnd(bx.llbuilder, llbb);
1479-
}
1480-
bx
1481-
}
1482-
1483-
fn with_cx(cx: &'a CodegenCx<'ll, 'tcx>) -> Self {
1484-
// Create a fresh builder from the crate context.
1485-
let llbuilder = unsafe { llvm::LLVMCreateBuilderInContext(cx.llcx) };
1486-
Builder { llbuilder, cx }
1487-
}
1488-
14891477
pub(crate) fn llfn(&self) -> &'ll Value {
14901478
unsafe { llvm::LLVMGetBasicBlockParent(self.llbb()) }
14911479
}
14921480
}
14931481

1494-
impl<'a, 'll, CX: Borrow<SimpleCx<'ll>>> GenericBuilder<'a, 'll, CX> {
1482+
impl<'a, 'll, CX: Borrow<SCx<'ll>>> GenericBuilder<'a, 'll, CX> {
14951483
fn position_at_start(&mut self, llbb: &'ll BasicBlock) {
14961484
unsafe {
14971485
llvm::LLVMRustPositionBuilderAtStart(self.llbuilder, llbb);
@@ -1521,7 +1509,7 @@ impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> {
15211509
}
15221510
}
15231511
}
1524-
impl<'a, 'll, CX: Borrow<SimpleCx<'ll>>> GenericBuilder<'a, 'll, CX> {
1512+
impl<'a, 'll, CX: Borrow<SCx<'ll>>> GenericBuilder<'a, 'll, CX> {
15251513
pub(crate) fn minnum(&mut self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value {
15261514
unsafe { llvm::LLVMRustBuildMinNum(self.llbuilder, lhs, rhs) }
15271515
}
@@ -1666,7 +1654,7 @@ impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> {
16661654
Cow::Owned(casted_args)
16671655
}
16681656
}
1669-
impl<'a, 'll, CX: Borrow<SimpleCx<'ll>>> GenericBuilder<'a, 'll, CX> {
1657+
impl<'a, 'll, CX: Borrow<SCx<'ll>>> GenericBuilder<'a, 'll, CX> {
16701658
pub(crate) fn va_arg(&mut self, list: &'ll Value, ty: &'ll Type) -> &'ll Value {
16711659
unsafe { llvm::LLVMBuildVAArg(self.llbuilder, list, ty, UNNAMED) }
16721660
}
@@ -1690,7 +1678,7 @@ impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> {
16901678
self.call_intrinsic(intrinsic, &[self.cx.const_u64(size), ptr]);
16911679
}
16921680
}
1693-
impl<'a, 'll, CX: Borrow<SimpleCx<'ll>>> GenericBuilder<'a, 'll, CX> {
1681+
impl<'a, 'll, CX: Borrow<SCx<'ll>>> GenericBuilder<'a, 'll, CX> {
16941682
pub(crate) fn phi(
16951683
&mut self,
16961684
ty: &'ll Type,

compiler/rustc_codegen_llvm/src/builder/autodiff.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -286,7 +286,7 @@ pub(crate) fn differentiate<'ll>(
286286
}
287287

288288
let diag_handler = cgcx.create_dcx();
289-
let cx = SimpleCx { llmod: module.module_llvm.llmod(), llcx: module.module_llvm.llcx };
289+
let cx = SimpleCx::new(module.module_llvm.llmod(), module.module_llvm.llcx);
290290

291291
// First of all, did the user try to use autodiff without using the -Zautodiff=Enable flag?
292292
if !diff_items.is_empty()

compiler/rustc_codegen_llvm/src/context.rs

+56-44
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
use std::borrow::Borrow;
22
use std::cell::{Cell, RefCell};
33
use std::ffi::{CStr, c_char, c_uint};
4+
use std::marker::PhantomData;
45
use std::ops::Deref;
56
use std::str;
67

@@ -43,18 +44,18 @@ use crate::{attributes, coverageinfo, debuginfo, llvm, llvm_util};
4344
/// However, there are various cx related functions which we want to be available to the builder and
4445
/// other compiler pieces. Here we define a small subset which has enough information and can be
4546
/// moved around more freely.
46-
pub(crate) struct SimpleCx<'ll> {
47+
pub(crate) struct SCx<'ll> {
4748
pub llmod: &'ll llvm::Module,
4849
pub llcx: &'ll llvm::Context,
4950
}
5051

51-
impl<'ll> Borrow<SimpleCx<'ll>> for CodegenCx<'ll, '_> {
52-
fn borrow(&self) -> &SimpleCx<'ll> {
52+
impl<'ll> Borrow<SCx<'ll>> for FullCx<'ll, '_> {
53+
fn borrow(&self) -> &SCx<'ll> {
5354
&self.scx
5455
}
5556
}
5657

57-
impl<'ll, 'tcx> Deref for CodegenCx<'ll, 'tcx> {
58+
impl<'ll, 'tcx> Deref for FullCx<'ll, 'tcx> {
5859
type Target = SimpleCx<'ll>;
5960

6061
#[inline]
@@ -63,10 +64,25 @@ impl<'ll, 'tcx> Deref for CodegenCx<'ll, 'tcx> {
6364
}
6465
}
6566

67+
pub(crate) struct GenericCx<'ll, T: Borrow<SCx<'ll>>>(T, PhantomData<SCx<'ll>>);
68+
69+
impl<'ll, T: Borrow<SCx<'ll>>> Deref for GenericCx<'ll, T> {
70+
type Target = T;
71+
72+
#[inline]
73+
fn deref(&self) -> &Self::Target {
74+
&self.0
75+
}
76+
}
77+
78+
pub(crate) type SimpleCx<'ll> = GenericCx<'ll, SCx<'ll>>;
79+
6680
/// There is one `CodegenCx` per codegen unit. Each one has its own LLVM
6781
/// `llvm::Context` so that several codegen units may be processed in parallel.
6882
/// All other LLVM data structures in the `CodegenCx` are tied to that `llvm::Context`.
69-
pub(crate) struct CodegenCx<'ll, 'tcx> {
83+
pub(crate) type CodegenCx<'ll, 'tcx> = GenericCx<'ll, FullCx<'ll, 'tcx>>;
84+
85+
pub(crate) struct FullCx<'ll, 'tcx> {
7086
pub tcx: TyCtxt<'tcx>,
7187
pub scx: SimpleCx<'ll>,
7288
pub use_dll_storage_attrs: bool,
@@ -581,31 +597,34 @@ impl<'ll, 'tcx> CodegenCx<'ll, 'tcx> {
581597

582598
let isize_ty = Type::ix_llcx(llcx, tcx.data_layout.pointer_size.bits());
583599

584-
CodegenCx {
585-
tcx,
586-
scx: SimpleCx { llcx, llmod },
587-
use_dll_storage_attrs,
588-
tls_model,
589-
codegen_unit,
590-
instances: Default::default(),
591-
vtables: Default::default(),
592-
const_str_cache: Default::default(),
593-
const_globals: Default::default(),
594-
statics_to_rauw: RefCell::new(Vec::new()),
595-
used_statics: RefCell::new(Vec::new()),
596-
compiler_used_statics: RefCell::new(Vec::new()),
597-
type_lowering: Default::default(),
598-
scalar_lltypes: Default::default(),
599-
isize_ty,
600-
coverage_cx,
601-
dbg_cx,
602-
eh_personality: Cell::new(None),
603-
eh_catch_typeinfo: Cell::new(None),
604-
rust_try_fn: Cell::new(None),
605-
intrinsics: Default::default(),
606-
local_gen_sym_counter: Cell::new(0),
607-
renamed_statics: Default::default(),
608-
}
600+
GenericCx(
601+
FullCx {
602+
tcx,
603+
scx: SimpleCx::new(llmod, llcx),
604+
use_dll_storage_attrs,
605+
tls_model,
606+
codegen_unit,
607+
instances: Default::default(),
608+
vtables: Default::default(),
609+
const_str_cache: Default::default(),
610+
const_globals: Default::default(),
611+
statics_to_rauw: RefCell::new(Vec::new()),
612+
used_statics: RefCell::new(Vec::new()),
613+
compiler_used_statics: RefCell::new(Vec::new()),
614+
type_lowering: Default::default(),
615+
scalar_lltypes: Default::default(),
616+
isize_ty,
617+
coverage_cx,
618+
dbg_cx,
619+
eh_personality: Cell::new(None),
620+
eh_catch_typeinfo: Cell::new(None),
621+
rust_try_fn: Cell::new(None),
622+
intrinsics: Default::default(),
623+
local_gen_sym_counter: Cell::new(0),
624+
renamed_statics: Default::default(),
625+
},
626+
PhantomData,
627+
)
609628
}
610629

611630
pub(crate) fn statics_to_rauw(&self) -> &RefCell<Vec<(&'ll Value, &'ll Value)>> {
@@ -628,7 +647,12 @@ impl<'ll, 'tcx> CodegenCx<'ll, 'tcx> {
628647
llvm::set_section(g, c"llvm.metadata");
629648
}
630649
}
650+
631651
impl<'ll> SimpleCx<'ll> {
652+
pub(crate) fn new(llmod: &'ll llvm::Module, llcx: &'ll llvm::Context) -> Self {
653+
Self(SCx { llmod, llcx }, PhantomData)
654+
}
655+
632656
pub(crate) fn val_ty(&self, v: &'ll Value) -> &'ll Type {
633657
common::val_ty(v)
634658
}
@@ -1203,25 +1227,13 @@ impl CodegenCx<'_, '_> {
12031227
name.push_str(&(idx as u64).to_base(ALPHANUMERIC_ONLY));
12041228
name
12051229
}
1206-
1207-
/// A wrapper for [`llvm::LLVMSetMetadata`], but it takes `Metadata` as a parameter instead of `Value`.
1208-
pub(crate) fn set_metadata<'a>(&self, val: &'a Value, kind_id: MetadataType, md: &'a Metadata) {
1209-
unsafe {
1210-
let node = llvm::LLVMMetadataAsValue(&self.llcx, md);
1211-
llvm::LLVMSetMetadata(val, kind_id as c_uint, node);
1212-
}
1213-
}
12141230
}
12151231

1216-
// This is a duplication of the set_metadata function above. However, so far it's the only one
1217-
// shared between both contexts, so it doesn't seem worth it to make the Cx generic like we did it
1218-
// for the Builder.
1219-
impl SimpleCx<'_> {
1220-
#[allow(unused)]
1232+
impl<'ll, CX: Borrow<SCx<'ll>>> GenericCx<'ll, CX> {
12211233
/// A wrapper for [`llvm::LLVMSetMetadata`], but it takes `Metadata` as a parameter instead of `Value`.
12221234
pub(crate) fn set_metadata<'a>(&self, val: &'a Value, kind_id: MetadataType, md: &'a Metadata) {
12231235
unsafe {
1224-
let node = llvm::LLVMMetadataAsValue(&self.llcx, md);
1236+
let node = llvm::LLVMMetadataAsValue(self.llcx(), md);
12251237
llvm::LLVMSetMetadata(val, kind_id as c_uint, node);
12261238
}
12271239
}

compiler/rustc_codegen_llvm/src/type_.rs

+16-10
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
use std::borrow::Borrow;
12
use std::{fmt, ptr};
23

34
use libc::{c_char, c_uint};
@@ -11,7 +12,7 @@ use rustc_middle::ty::{self, Ty};
1112
use rustc_target::callconv::{CastTarget, FnAbi};
1213

1314
use crate::abi::{FnAbiLlvmExt, LlvmType};
14-
use crate::context::{CodegenCx, SimpleCx};
15+
use crate::context::{CodegenCx, GenericCx, SCx};
1516
pub(crate) use crate::llvm::Type;
1617
use crate::llvm::{Bool, False, Metadata, True};
1718
use crate::type_of::LayoutLlvmExt;
@@ -36,29 +37,29 @@ impl fmt::Debug for Type {
3637
}
3738

3839
impl<'ll> CodegenCx<'ll, '_> {}
39-
impl<'ll> SimpleCx<'ll> {
40+
impl<'ll, CX: Borrow<SCx<'ll>>> GenericCx<'ll, CX> {
4041
pub(crate) fn type_named_struct(&self, name: &str) -> &'ll Type {
4142
let name = SmallCStr::new(name);
42-
unsafe { llvm::LLVMStructCreateNamed(self.llcx, name.as_ptr()) }
43+
unsafe { llvm::LLVMStructCreateNamed(self.llcx(), name.as_ptr()) }
4344
}
4445

4546
pub(crate) fn set_struct_body(&self, ty: &'ll Type, els: &[&'ll Type], packed: bool) {
4647
unsafe { llvm::LLVMStructSetBody(ty, els.as_ptr(), els.len() as c_uint, packed as Bool) }
4748
}
4849
pub(crate) fn type_void(&self) -> &'ll Type {
49-
unsafe { llvm::LLVMVoidTypeInContext(self.llcx) }
50+
unsafe { llvm::LLVMVoidTypeInContext(self.llcx()) }
5051
}
5152
pub(crate) fn type_token(&self) -> &'ll Type {
52-
unsafe { llvm::LLVMTokenTypeInContext(self.llcx) }
53+
unsafe { llvm::LLVMTokenTypeInContext(self.llcx()) }
5354
}
5455

5556
pub(crate) fn type_metadata(&self) -> &'ll Type {
56-
unsafe { llvm::LLVMMetadataTypeInContext(self.llcx) }
57+
unsafe { llvm::LLVMMetadataTypeInContext(self.llcx()) }
5758
}
5859

5960
///x Creates an integer type with the given number of bits, e.g., i24
6061
pub(crate) fn type_ix(&self, num_bits: u64) -> &'ll Type {
61-
unsafe { llvm::LLVMIntTypeInContext(self.llcx, num_bits as c_uint) }
62+
unsafe { llvm::LLVMIntTypeInContext(self.llcx(), num_bits as c_uint) }
6263
}
6364

6465
pub(crate) fn type_vector(&self, ty: &'ll Type, len: u64) -> &'ll Type {
@@ -121,19 +122,24 @@ impl<'ll, 'tcx> CodegenCx<'ll, 'tcx> {
121122
self.type_array(self.type_from_integer(unit), size / unit_size)
122123
}
123124
}
124-
impl<'ll> SimpleCx<'ll> {
125+
126+
impl<'ll, CX: Borrow<SCx<'ll>>> GenericCx<'ll, CX> {
127+
pub(crate) fn llcx(&self) -> &'ll llvm::Context {
128+
(**self).borrow().llcx
129+
}
130+
125131
pub(crate) fn type_variadic_func(&self, args: &[&'ll Type], ret: &'ll Type) -> &'ll Type {
126132
unsafe { llvm::LLVMFunctionType(ret, args.as_ptr(), args.len() as c_uint, True) }
127133
}
128134

129135
pub(crate) fn type_i1(&self) -> &'ll Type {
130-
unsafe { llvm::LLVMInt1TypeInContext(self.llcx) }
136+
unsafe { llvm::LLVMInt1TypeInContext(self.llcx()) }
131137
}
132138

133139
pub(crate) fn type_struct(&self, els: &[&'ll Type], packed: bool) -> &'ll Type {
134140
unsafe {
135141
llvm::LLVMStructTypeInContext(
136-
self.llcx,
142+
self.llcx(),
137143
els.as_ptr(),
138144
els.len() as c_uint,
139145
packed as Bool,

0 commit comments

Comments
 (0)