Skip to content

Commit 6e345bd

Browse files
committed
make more things generic
1 parent ae2b41a commit 6e345bd

File tree

2 files changed

+92
-53
lines changed

2 files changed

+92
-53
lines changed

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

+72-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

@@ -37,18 +37,16 @@ use crate::type_::Type;
3737
use crate::type_of::LayoutLlvmExt;
3838
use crate::value::Value;
3939

40-
41-
pub(crate) type SBuilder<'a, 'll> = GenericBuilder<'a, 'll, SimpleCx<'ll>>;
42-
4340
#[must_use]
44-
pub(crate) struct GenericBuilder<'a, 'll, CX> {
41+
pub(crate) struct GenericBuilder<'a, 'll, CX: Borrow<SimpleCx<'ll>>> {
4542
pub llbuilder: &'ll mut llvm::Builder<'ll>,
4643
pub cx: &'a CX,
4744
}
4845

46+
pub(crate) type SBuilder<'a, 'll> = GenericBuilder<'a, 'll, SimpleCx<'ll>>;
4947
pub(crate) type Builder<'a, 'll, 'tcx> = GenericBuilder<'a, 'll, CodegenCx<'ll, 'tcx>>;
5048

51-
impl<'a, 'll, CX> Drop for GenericBuilder<'a, 'll, CX> {
49+
impl<'a, 'll, CX: Borrow<SimpleCx<'ll>>> Drop for GenericBuilder<'a, 'll, CX> {
5250
fn drop(&mut self) {
5351
unsafe {
5452
llvm::LLVMDisposeBuilder(&mut *(self.llbuilder as *mut _));
@@ -57,22 +55,49 @@ impl<'a, 'll, CX> Drop for GenericBuilder<'a, 'll, CX> {
5755
}
5856

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

69-
impl<'a, 'll> SBuilder<'a, 'll> {
7094
fn with_scx(scx: &'a SimpleCx<'ll>) -> Self {
7195
// Create a fresh builder from the simple context.
7296
let llbuilder = unsafe { llvm::LLVMCreateBuilderInContext(scx.llcx) };
7397
SBuilder { llbuilder, cx: scx }
7498
}
75-
99+
}
100+
impl<'a, 'll, CX: Borrow<SimpleCx<'ll>>> GenericBuilder<'a, 'll, CX> {
76101
pub(crate) fn bitcast(&mut self, val: &'ll Value, dest_ty: &'ll Type) -> &'ll Value {
77102
unsafe { llvm::LLVMBuildBitCast(self.llbuilder, val, dest_ty, UNNAMED) }
78103
}
@@ -88,6 +113,15 @@ impl<'a, 'll> SBuilder<'a, 'll> {
88113
llvm::LLVMBuildRet(self.llbuilder, v);
89114
}
90115
}
116+
}
117+
impl<'a, 'll> SBuilder<'a, 'll> {
118+
fn build(cx: &'a SimpleCx<'ll>, llbb: &'ll BasicBlock) -> SBuilder<'a, 'll> {
119+
let bx = SBuilder::with_scx(cx);
120+
unsafe {
121+
llvm::LLVMPositionBuilderAtEnd(bx.llbuilder, llbb);
122+
}
123+
bx
124+
}
91125

92126
fn check_call<'b>(
93127
&mut self,
@@ -129,39 +163,6 @@ impl<'a, 'll> SBuilder<'a, 'll> {
129163

130164
Cow::Owned(casted_args)
131165
}
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-
}
165166
}
166167

167168
/// Empty string, to be used where LLVM expects an instruction name, indicating
@@ -1334,6 +1335,14 @@ impl<'ll> StaticBuilderMethods for Builder<'_, 'll, '_> {
13341335
}
13351336

13361337
impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> {
1338+
fn build(cx: &'a CodegenCx<'ll, 'tcx>, llbb: &'ll BasicBlock) -> Builder<'a, 'll, 'tcx> {
1339+
let bx = Builder::with_cx(cx);
1340+
unsafe {
1341+
llvm::LLVMPositionBuilderAtEnd(bx.llbuilder, llbb);
1342+
}
1343+
bx
1344+
}
1345+
13371346
fn with_cx(cx: &'a CodegenCx<'ll, 'tcx>) -> Self {
13381347
// Create a fresh builder from the crate context.
13391348
let llbuilder = unsafe { llvm::LLVMCreateBuilderInContext(cx.llcx) };
@@ -1343,13 +1352,16 @@ impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> {
13431352
pub(crate) fn llfn(&self) -> &'ll Value {
13441353
unsafe { llvm::LLVMGetBasicBlockParent(self.llbb()) }
13451354
}
1355+
}
13461356

1357+
impl<'a, 'll, CX: Borrow<SimpleCx<'ll>>> GenericBuilder<'a, 'll, CX> {
13471358
fn position_at_start(&mut self, llbb: &'ll BasicBlock) {
13481359
unsafe {
13491360
llvm::LLVMRustPositionBuilderAtStart(self.llbuilder, llbb);
13501361
}
13511362
}
1352-
1363+
}
1364+
impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> {
13531365
fn align_metadata(&mut self, load: &'ll Value, align: Align) {
13541366
unsafe {
13551367
let md = [llvm::LLVMValueAsMetadata(self.cx.const_u64(align.bytes()))];
@@ -1371,7 +1383,8 @@ impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> {
13711383
self.set_metadata(inst, llvm::MD_unpredictable, md);
13721384
}
13731385
}
1374-
1386+
}
1387+
impl<'a, 'll, CX: Borrow<SimpleCx<'ll>>> GenericBuilder<'a, 'll, CX> {
13751388
pub(crate) fn minnum(&mut self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value {
13761389
unsafe { llvm::LLVMRustBuildMinNum(self.llbuilder, lhs, rhs) }
13771390
}
@@ -1472,7 +1485,9 @@ impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> {
14721485
let ret = unsafe { llvm::LLVMBuildCatchRet(self.llbuilder, funclet.cleanuppad(), unwind) };
14731486
ret.expect("LLVM does not have support for catchret")
14741487
}
1488+
}
14751489

1490+
impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> {
14761491
fn check_call<'b>(
14771492
&mut self,
14781493
typ: &str,
@@ -1513,11 +1528,13 @@ impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> {
15131528

15141529
Cow::Owned(casted_args)
15151530
}
1516-
1531+
}
1532+
impl<'a, 'll, CX: Borrow<SimpleCx<'ll>>> GenericBuilder<'a, 'll, CX> {
15171533
pub(crate) fn va_arg(&mut self, list: &'ll Value, ty: &'ll Type) -> &'ll Value {
15181534
unsafe { llvm::LLVMBuildVAArg(self.llbuilder, list, ty, UNNAMED) }
15191535
}
1520-
1536+
}
1537+
impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> {
15211538
pub(crate) fn call_intrinsic(&mut self, intrinsic: &str, args: &[&'ll Value]) -> &'ll Value {
15221539
let (ty, f) = self.cx.get_intrinsic(intrinsic);
15231540
self.call(ty, None, None, f, args, None, None)
@@ -1535,7 +1552,8 @@ impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> {
15351552

15361553
self.call_intrinsic(intrinsic, &[self.cx.const_u64(size), ptr]);
15371554
}
1538-
1555+
}
1556+
impl<'a, 'll, CX: Borrow<SimpleCx<'ll>>> GenericBuilder<'a, 'll, CX> {
15391557
pub(crate) fn phi(
15401558
&mut self,
15411559
ty: &'ll Type,
@@ -1555,7 +1573,8 @@ impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> {
15551573
llvm::LLVMAddIncoming(phi, &val, &bb, 1 as c_uint);
15561574
}
15571575
}
1558-
1576+
}
1577+
impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> {
15591578
fn fptoint_sat(&mut self, signed: bool, val: &'ll Value, dest_ty: &'ll Type) -> &'ll Value {
15601579
let src_ty = self.cx.val_ty(val);
15611580
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

+20
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,12 @@ 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+
5157
impl<'ll, 'tcx> Deref for CodegenCx<'ll, 'tcx> {
5258
type Target = SimpleCx<'ll>;
5359

@@ -1203,6 +1209,20 @@ impl CodegenCx<'_, '_> {
12031209
}
12041210
}
12051211

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+
12061226
impl HasDataLayout for CodegenCx<'_, '_> {
12071227
#[inline]
12081228
fn data_layout(&self) -> &TargetDataLayout {

0 commit comments

Comments
 (0)