Skip to content

Commit f73640d

Browse files
committed
make more things generic
1 parent ae2b41a commit f73640d

File tree

2 files changed

+95
-53
lines changed

2 files changed

+95
-53
lines changed

Diff for: compiler/rustc_codegen_llvm/src/builder.rs

+74-53
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

@@ -38,17 +38,16 @@ use crate::type_of::LayoutLlvmExt;
3838
use crate::value::Value;
3939

4040

41-
pub(crate) type SBuilder<'a, 'll> = GenericBuilder<'a, 'll, SimpleCx<'ll>>;
42-
4341
#[must_use]
44-
pub(crate) struct GenericBuilder<'a, 'll, CX> {
42+
pub(crate) struct GenericBuilder<'a, 'll, CX: Borrow<SimpleCx<'ll>>> {
4543
pub llbuilder: &'ll mut llvm::Builder<'ll>,
4644
pub cx: &'a CX,
4745
}
4846

47+
pub(crate) type SBuilder<'a, 'll> = GenericBuilder<'a, 'll, SimpleCx<'ll>>;
4948
pub(crate) type Builder<'a, 'll, 'tcx> = GenericBuilder<'a, 'll, CodegenCx<'ll, 'tcx>>;
5049

51-
impl<'a, 'll, CX> Drop for GenericBuilder<'a, 'll, CX> {
50+
impl<'a, 'll, CX: Borrow<SimpleCx<'ll>>> Drop for GenericBuilder<'a, 'll, CX> {
5251
fn drop(&mut self) {
5352
unsafe {
5453
llvm::LLVMDisposeBuilder(&mut *(self.llbuilder as *mut _));
@@ -57,22 +56,49 @@ impl<'a, 'll, CX> Drop for GenericBuilder<'a, 'll, CX> {
5756
}
5857

5958
impl<'a, 'll> SBuilder<'a, 'll> {
60-
fn build(cx: &'a SimpleCx<'ll>, llbb: &'ll BasicBlock) -> SBuilder<'a, 'll> {
61-
let bx = SBuilder::with_scx(cx);
62-
unsafe {
63-
llvm::LLVMPositionBuilderAtEnd(bx.llbuilder, llbb);
59+
// This impl might allow moving more functions over to the generic builder?
60+
//fn cx(&self) -> &SimpleCx<'ll> {
61+
// self.cx
62+
//}
63+
64+
fn call(
65+
&mut self,
66+
llty: &'ll Type,
67+
llfn: &'ll Value,
68+
args: &[&'ll Value],
69+
funclet: Option<&Funclet<'ll>>,
70+
) -> &'ll Value {
71+
debug!("call {:?} with args ({:?})", llfn, args);
72+
73+
let args = self.check_call("call", llty, llfn, args);
74+
let funclet_bundle = funclet.map(|funclet| funclet.bundle());
75+
let mut bundles: SmallVec<[_; 2]> = SmallVec::new();
76+
if let Some(funclet_bundle) = funclet_bundle {
77+
bundles.push(funclet_bundle);
6478
}
65-
bx
79+
80+
let call = unsafe {
81+
llvm::LLVMBuildCallWithOperandBundles(
82+
self.llbuilder,
83+
llty,
84+
llfn,
85+
args.as_ptr() as *const &llvm::Value,
86+
args.len() as c_uint,
87+
bundles.as_ptr(),
88+
bundles.len() as c_uint,
89+
c"".as_ptr(),
90+
)
91+
};
92+
call
6693
}
67-
}
6894

69-
impl<'a, 'll> SBuilder<'a, 'll> {
7095
fn with_scx(scx: &'a SimpleCx<'ll>) -> Self {
7196
// Create a fresh builder from the simple context.
7297
let llbuilder = unsafe { llvm::LLVMCreateBuilderInContext(scx.llcx) };
7398
SBuilder { llbuilder, cx: scx }
7499
}
75-
100+
}
101+
impl<'a, 'll, CX: Borrow<SimpleCx<'ll>>> GenericBuilder<'a, 'll, CX> {
76102
pub(crate) fn bitcast(&mut self, val: &'ll Value, dest_ty: &'ll Type) -> &'ll Value {
77103
unsafe { llvm::LLVMBuildBitCast(self.llbuilder, val, dest_ty, UNNAMED) }
78104
}
@@ -88,6 +114,15 @@ impl<'a, 'll> SBuilder<'a, 'll> {
88114
llvm::LLVMBuildRet(self.llbuilder, v);
89115
}
90116
}
117+
}
118+
impl<'a, 'll> SBuilder<'a, 'll> {
119+
fn build(cx: &'a SimpleCx<'ll>, llbb: &'ll BasicBlock) -> SBuilder<'a, 'll> {
120+
let bx = SBuilder::with_scx(cx);
121+
unsafe {
122+
llvm::LLVMPositionBuilderAtEnd(bx.llbuilder, llbb);
123+
}
124+
bx
125+
}
91126

92127
fn check_call<'b>(
93128
&mut self,
@@ -129,39 +164,6 @@ impl<'a, 'll> SBuilder<'a, 'll> {
129164

130165
Cow::Owned(casted_args)
131166
}
132-
133-
// This is a simplified version of the call when using the full Builder.
134-
// It can not use any tcx related arguments
135-
fn call(
136-
&mut self,
137-
llty: &'ll Type,
138-
llfn: &'ll Value,
139-
args: &[&'ll Value],
140-
funclet: Option<&Funclet<'ll>>,
141-
) -> &'ll Value {
142-
debug!("call {:?} with args ({:?})", llfn, args);
143-
144-
let args = self.check_call("call", llty, llfn, args);
145-
let funclet_bundle = funclet.map(|funclet| funclet.bundle());
146-
let mut bundles: SmallVec<[_; 2]> = SmallVec::new();
147-
if let Some(funclet_bundle) = funclet_bundle {
148-
bundles.push(funclet_bundle);
149-
}
150-
151-
let call = unsafe {
152-
llvm::LLVMBuildCallWithOperandBundles(
153-
self.llbuilder,
154-
llty,
155-
llfn,
156-
args.as_ptr() as *const &llvm::Value,
157-
args.len() as c_uint,
158-
bundles.as_ptr(),
159-
bundles.len() as c_uint,
160-
c"".as_ptr(),
161-
)
162-
};
163-
call
164-
}
165167
}
166168

167169
/// Empty string, to be used where LLVM expects an instruction name, indicating
@@ -1334,7 +1336,15 @@ impl<'ll> StaticBuilderMethods for Builder<'_, 'll, '_> {
13341336
}
13351337

13361338
impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> {
1337-
fn with_cx(cx: &'a CodegenCx<'ll, 'tcx>) -> Self {
1339+
fn build(cx: &'a CodegenCx<'ll, 'tcx>, llbb: &'ll BasicBlock) -> Builder<'a, 'll, 'tcx> {
1340+
let bx = Builder::with_cx(cx);
1341+
unsafe {
1342+
llvm::LLVMPositionBuilderAtEnd(bx.llbuilder, llbb);
1343+
}
1344+
bx
1345+
}
1346+
1347+
fn with_cx(cx: &'a CodegenCx<'ll,'tcx>) -> Self {
13381348
// Create a fresh builder from the crate context.
13391349
let llbuilder = unsafe { llvm::LLVMCreateBuilderInContext(cx.llcx) };
13401350
Builder { llbuilder, cx }
@@ -1343,13 +1353,16 @@ impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> {
13431353
pub(crate) fn llfn(&self) -> &'ll Value {
13441354
unsafe { llvm::LLVMGetBasicBlockParent(self.llbb()) }
13451355
}
1356+
}
13461357

1358+
impl<'a, 'll, CX: Borrow<SimpleCx<'ll>>> GenericBuilder<'a, 'll, CX> {
13471359
fn position_at_start(&mut self, llbb: &'ll BasicBlock) {
13481360
unsafe {
13491361
llvm::LLVMRustPositionBuilderAtStart(self.llbuilder, llbb);
13501362
}
13511363
}
1352-
1364+
}
1365+
impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> {
13531366
fn align_metadata(&mut self, load: &'ll Value, align: Align) {
13541367
unsafe {
13551368
let md = [llvm::LLVMValueAsMetadata(self.cx.const_u64(align.bytes()))];
@@ -1371,7 +1384,8 @@ impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> {
13711384
self.set_metadata(inst, llvm::MD_unpredictable, md);
13721385
}
13731386
}
1374-
1387+
}
1388+
impl<'a, 'll, CX: Borrow<SimpleCx<'ll>>> GenericBuilder<'a, 'll, CX> {
13751389
pub(crate) fn minnum(&mut self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value {
13761390
unsafe { llvm::LLVMRustBuildMinNum(self.llbuilder, lhs, rhs) }
13771391
}
@@ -1473,6 +1487,9 @@ impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> {
14731487
ret.expect("LLVM does not have support for catchret")
14741488
}
14751489

1490+
}
1491+
1492+
impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> {
14761493
fn check_call<'b>(
14771494
&mut self,
14781495
typ: &str,
@@ -1513,11 +1530,13 @@ impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> {
15131530

15141531
Cow::Owned(casted_args)
15151532
}
1516-
1533+
}
1534+
impl<'a, 'll, CX: Borrow<SimpleCx<'ll>>> GenericBuilder<'a, 'll, CX> {
15171535
pub(crate) fn va_arg(&mut self, list: &'ll Value, ty: &'ll Type) -> &'ll Value {
15181536
unsafe { llvm::LLVMBuildVAArg(self.llbuilder, list, ty, UNNAMED) }
15191537
}
1520-
1538+
}
1539+
impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> {
15211540
pub(crate) fn call_intrinsic(&mut self, intrinsic: &str, args: &[&'ll Value]) -> &'ll Value {
15221541
let (ty, f) = self.cx.get_intrinsic(intrinsic);
15231542
self.call(ty, None, None, f, args, None, None)
@@ -1535,7 +1554,8 @@ impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> {
15351554

15361555
self.call_intrinsic(intrinsic, &[self.cx.const_u64(size), ptr]);
15371556
}
1538-
1557+
}
1558+
impl<'a, 'll, CX: Borrow<SimpleCx<'ll>>> GenericBuilder<'a, 'll, CX> {
15391559
pub(crate) fn phi(
15401560
&mut self,
15411561
ty: &'ll Type,
@@ -1555,7 +1575,8 @@ impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> {
15551575
llvm::LLVMAddIncoming(phi, &val, &bb, 1 as c_uint);
15561576
}
15571577
}
1558-
1578+
}
1579+
impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> {
15591580
fn fptoint_sat(&mut self, signed: bool, val: &'ll Value, dest_ty: &'ll Type) -> &'ll Value {
15601581
let src_ty = self.cx.val_ty(val);
15611582
let (float_ty, int_ty, vector_length) = if self.cx.type_kind(src_ty) == TypeKind::Vector {

Diff for: compiler/rustc_codegen_llvm/src/context.rs

+21
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,13 @@ pub(crate) struct SimpleCx<'ll> {
4848
pub llcx: &'ll llvm::Context,
4949
}
5050

51+
impl<'ll> Borrow<SimpleCx<'ll>> for CodegenCx<'ll, '_> {
52+
fn borrow(&self) -> &SimpleCx<'ll> {
53+
&self.scx
54+
}
55+
}
56+
57+
5158
impl<'ll, 'tcx> Deref for CodegenCx<'ll, 'tcx> {
5259
type Target = SimpleCx<'ll>;
5360

@@ -1203,6 +1210,20 @@ impl CodegenCx<'_, '_> {
12031210
}
12041211
}
12051212

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

0 commit comments

Comments
 (0)