Skip to content

Commit 574d375

Browse files
committed
Auto merge of #87743 - cuviper:opaque-calls, r=nikic
Prepare call/invoke for opaque pointers Rather than relying on `getPointerElementType()` from LLVM function pointers, we now pass the function type explicitly when building `call` or `invoke` instructions.
2 parents 399ab46 + a292390 commit 574d375

File tree

14 files changed

+168
-148
lines changed

14 files changed

+168
-148
lines changed

compiler/rustc_codegen_llvm/src/abi.rs

+6-2
Original file line numberDiff line numberDiff line change
@@ -353,7 +353,11 @@ pub trait FnAbiLlvmExt<'tcx> {
353353

354354
impl<'tcx> FnAbiLlvmExt<'tcx> for FnAbi<'tcx, Ty<'tcx>> {
355355
fn llvm_type(&self, cx: &CodegenCx<'ll, 'tcx>) -> &'ll Type {
356-
let args_capacity: usize = self.args.iter().map(|arg|
356+
// Ignore "extra" args from the call site for C variadic functions.
357+
// Only the "fixed" args are part of the LLVM function signature.
358+
let args = if self.c_variadic { &self.args[..self.fixed_count] } else { &self.args };
359+
360+
let args_capacity: usize = args.iter().map(|arg|
357361
if arg.pad.is_some() { 1 } else { 0 } +
358362
if let PassMode::Pair(_, _) = arg.mode { 2 } else { 1 }
359363
).sum();
@@ -371,7 +375,7 @@ impl<'tcx> FnAbiLlvmExt<'tcx> for FnAbi<'tcx, Ty<'tcx>> {
371375
}
372376
};
373377

374-
for arg in &self.args {
378+
for arg in args {
375379
// add padding
376380
if let Some(ty) = arg.pad {
377381
llargument_tys.push(ty.llvm_type(cx));

compiler/rustc_codegen_llvm/src/allocator.rs

+10-3
Original file line numberDiff line numberDiff line change
@@ -78,8 +78,14 @@ pub(crate) unsafe fn codegen(
7878
.enumerate()
7979
.map(|(i, _)| llvm::LLVMGetParam(llfn, i as c_uint))
8080
.collect::<Vec<_>>();
81-
let ret =
82-
llvm::LLVMRustBuildCall(llbuilder, callee, args.as_ptr(), args.len() as c_uint, None);
81+
let ret = llvm::LLVMRustBuildCall(
82+
llbuilder,
83+
ty,
84+
callee,
85+
args.as_ptr(),
86+
args.len() as c_uint,
87+
None,
88+
);
8389
llvm::LLVMSetTailCall(ret, True);
8490
if output.is_some() {
8591
llvm::LLVMBuildRet(llbuilder, ret);
@@ -121,7 +127,8 @@ pub(crate) unsafe fn codegen(
121127
.enumerate()
122128
.map(|(i, _)| llvm::LLVMGetParam(llfn, i as c_uint))
123129
.collect::<Vec<_>>();
124-
let ret = llvm::LLVMRustBuildCall(llbuilder, callee, args.as_ptr(), args.len() as c_uint, None);
130+
let ret =
131+
llvm::LLVMRustBuildCall(llbuilder, ty, callee, args.as_ptr(), args.len() as c_uint, None);
125132
llvm::LLVMSetTailCall(ret, True);
126133
llvm::LLVMBuildRetVoid(llbuilder);
127134
llvm::LLVMDisposeBuilder(llbuilder);

compiler/rustc_codegen_llvm/src/asm.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -464,7 +464,7 @@ fn inline_asm_call(
464464
alignstack,
465465
llvm::AsmDialect::from_generic(dia),
466466
);
467-
let call = bx.call(v, inputs, None);
467+
let call = bx.call(fty, v, inputs, None);
468468

469469
// Store mark in a metadata node so we can map LLVM errors
470470
// back to source locations. See #17552.

compiler/rustc_codegen_llvm/src/builder.rs

+24-22
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,7 @@ impl BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
200200

201201
fn invoke(
202202
&mut self,
203+
llty: &'ll Type,
203204
llfn: &'ll Value,
204205
args: &[&'ll Value],
205206
then: &'ll BasicBlock,
@@ -208,13 +209,14 @@ impl BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
208209
) -> &'ll Value {
209210
debug!("invoke {:?} with args ({:?})", llfn, args);
210211

211-
let args = self.check_call("invoke", llfn, args);
212+
let args = self.check_call("invoke", llty, llfn, args);
212213
let bundle = funclet.map(|funclet| funclet.bundle());
213214
let bundle = bundle.as_ref().map(|b| &*b.raw);
214215

215216
unsafe {
216217
llvm::LLVMRustBuildInvoke(
217218
self.llbuilder,
219+
llty,
218220
llfn,
219221
args.as_ptr(),
220222
args.len() as c_uint,
@@ -369,8 +371,7 @@ impl BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
369371
},
370372
};
371373

372-
let intrinsic = self.get_intrinsic(&name);
373-
let res = self.call(intrinsic, &[lhs, rhs], None);
374+
let res = self.call_intrinsic(name, &[lhs, rhs]);
374375
(self.extract_value(res, 0), self.extract_value(res, 1))
375376
}
376377

@@ -695,8 +696,7 @@ impl BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
695696
let float_width = self.cx.float_width(src_ty);
696697
let int_width = self.cx.int_width(dest_ty);
697698
let name = format!("llvm.fptoui.sat.i{}.f{}", int_width, float_width);
698-
let intrinsic = self.get_intrinsic(&name);
699-
return Some(self.call(intrinsic, &[val], None));
699+
return Some(self.call_intrinsic(&name, &[val]));
700700
}
701701

702702
None
@@ -708,8 +708,7 @@ impl BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
708708
let float_width = self.cx.float_width(src_ty);
709709
let int_width = self.cx.int_width(dest_ty);
710710
let name = format!("llvm.fptosi.sat.i{}.f{}", int_width, float_width);
711-
let intrinsic = self.get_intrinsic(&name);
712-
return Some(self.call(intrinsic, &[val], None));
711+
return Some(self.call_intrinsic(&name, &[val]));
713712
}
714713

715714
None
@@ -743,8 +742,7 @@ impl BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
743742
_ => None,
744743
};
745744
if let Some(name) = name {
746-
let intrinsic = self.get_intrinsic(name);
747-
return self.call(intrinsic, &[val], None);
745+
return self.call_intrinsic(name, &[val]);
748746
}
749747
}
750748
}
@@ -766,8 +764,7 @@ impl BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
766764
_ => None,
767765
};
768766
if let Some(name) = name {
769-
let intrinsic = self.get_intrinsic(name);
770-
return self.call(intrinsic, &[val], None);
767+
return self.call_intrinsic(name, &[val]);
771768
}
772769
}
773770
}
@@ -1115,12 +1112,17 @@ impl BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
11151112
);
11161113

11171114
let llfn = unsafe { llvm::LLVMRustGetInstrProfIncrementIntrinsic(self.cx().llmod) };
1115+
let llty = self.cx.type_func(
1116+
&[self.cx.type_i8p(), self.cx.type_i64(), self.cx.type_i32(), self.cx.type_i32()],
1117+
self.cx.type_void(),
1118+
);
11181119
let args = &[fn_name, hash, num_counters, index];
1119-
let args = self.check_call("call", llfn, args);
1120+
let args = self.check_call("call", llty, llfn, args);
11201121

11211122
unsafe {
11221123
let _ = llvm::LLVMRustBuildCall(
11231124
self.llbuilder,
1125+
llty,
11241126
llfn,
11251127
args.as_ptr() as *const &llvm::Value,
11261128
args.len() as c_uint,
@@ -1131,19 +1133,21 @@ impl BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
11311133

11321134
fn call(
11331135
&mut self,
1136+
llty: &'ll Type,
11341137
llfn: &'ll Value,
11351138
args: &[&'ll Value],
11361139
funclet: Option<&Funclet<'ll>>,
11371140
) -> &'ll Value {
11381141
debug!("call {:?} with args ({:?})", llfn, args);
11391142

1140-
let args = self.check_call("call", llfn, args);
1143+
let args = self.check_call("call", llty, llfn, args);
11411144
let bundle = funclet.map(|funclet| funclet.bundle());
11421145
let bundle = bundle.as_ref().map(|b| &*b.raw);
11431146

11441147
unsafe {
11451148
llvm::LLVMRustBuildCall(
11461149
self.llbuilder,
1150+
llty,
11471151
llfn,
11481152
args.as_ptr() as *const &llvm::Value,
11491153
args.len() as c_uint,
@@ -1313,15 +1317,10 @@ impl Builder<'a, 'll, 'tcx> {
13131317
fn check_call<'b>(
13141318
&mut self,
13151319
typ: &str,
1320+
fn_ty: &'ll Type,
13161321
llfn: &'ll Value,
13171322
args: &'b [&'ll Value],
13181323
) -> Cow<'b, [&'ll Value]> {
1319-
let mut fn_ty = self.cx.val_ty(llfn);
1320-
// Strip off pointers
1321-
while self.cx.type_kind(fn_ty) == TypeKind::Pointer {
1322-
fn_ty = self.cx.element_type(fn_ty);
1323-
}
1324-
13251324
assert!(
13261325
self.cx.type_kind(fn_ty) == TypeKind::Function,
13271326
"builder::{} not passed a function, but {:?}",
@@ -1362,6 +1361,11 @@ impl Builder<'a, 'll, 'tcx> {
13621361
unsafe { llvm::LLVMBuildVAArg(self.llbuilder, list, ty, UNNAMED) }
13631362
}
13641363

1364+
crate fn call_intrinsic(&mut self, intrinsic: &str, args: &[&'ll Value]) -> &'ll Value {
1365+
let (ty, f) = self.cx.get_intrinsic(intrinsic);
1366+
self.call(ty, f, args, None)
1367+
}
1368+
13651369
fn call_lifetime_intrinsic(&mut self, intrinsic: &str, ptr: &'ll Value, size: Size) {
13661370
let size = size.bytes();
13671371
if size == 0 {
@@ -1372,10 +1376,8 @@ impl Builder<'a, 'll, 'tcx> {
13721376
return;
13731377
}
13741378

1375-
let lifetime_intrinsic = self.cx.get_intrinsic(intrinsic);
1376-
13771379
let ptr = self.pointercast(ptr, self.cx.type_i8p());
1378-
self.call(lifetime_intrinsic, &[self.cx.const_u64(size), ptr], None);
1380+
self.call_intrinsic(intrinsic, &[self.cx.const_u64(size), ptr]);
13791381
}
13801382

13811383
pub(crate) fn phi(

compiler/rustc_codegen_llvm/src/context.rs

+7-7
Original file line numberDiff line numberDiff line change
@@ -84,9 +84,9 @@ pub struct CodegenCx<'ll, 'tcx> {
8484

8585
eh_personality: Cell<Option<&'ll Value>>,
8686
eh_catch_typeinfo: Cell<Option<&'ll Value>>,
87-
pub rust_try_fn: Cell<Option<&'ll Value>>,
87+
pub rust_try_fn: Cell<Option<(&'ll Type, &'ll Value)>>,
8888

89-
intrinsics: RefCell<FxHashMap<&'static str, &'ll Value>>,
89+
intrinsics: RefCell<FxHashMap<&'static str, (&'ll Type, &'ll Value)>>,
9090

9191
/// A counter that is used for generating local symbol names
9292
local_gen_sym_counter: Cell<usize>,
@@ -452,7 +452,7 @@ impl MiscMethods<'tcx> for CodegenCx<'ll, 'tcx> {
452452
}
453453

454454
impl CodegenCx<'b, 'tcx> {
455-
crate fn get_intrinsic(&self, key: &str) -> &'b Value {
455+
crate fn get_intrinsic(&self, key: &str) -> (&'b Type, &'b Value) {
456456
if let Some(v) = self.intrinsics.borrow().get(key).cloned() {
457457
return v;
458458
}
@@ -465,18 +465,18 @@ impl CodegenCx<'b, 'tcx> {
465465
name: &'static str,
466466
args: Option<&[&'b llvm::Type]>,
467467
ret: &'b llvm::Type,
468-
) -> &'b llvm::Value {
468+
) -> (&'b llvm::Type, &'b llvm::Value) {
469469
let fn_ty = if let Some(args) = args {
470470
self.type_func(args, ret)
471471
} else {
472472
self.type_variadic_func(&[], ret)
473473
};
474474
let f = self.declare_cfn(name, llvm::UnnamedAddr::No, fn_ty);
475-
self.intrinsics.borrow_mut().insert(name, f);
476-
f
475+
self.intrinsics.borrow_mut().insert(name, (fn_ty, f));
476+
(fn_ty, f)
477477
}
478478

479-
fn declare_intrinsic(&self, key: &str) -> Option<&'b Value> {
479+
fn declare_intrinsic(&self, key: &str) -> Option<(&'b Type, &'b Value)> {
480480
macro_rules! ifn {
481481
($name:expr, fn() -> $ret:expr) => (
482482
if key == $name {

0 commit comments

Comments
 (0)