Skip to content

Prepare call/invoke for opaque pointers #87743

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Aug 7, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions compiler/rustc_codegen_llvm/src/abi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -353,7 +353,11 @@ pub trait FnAbiLlvmExt<'tcx> {

impl<'tcx> FnAbiLlvmExt<'tcx> for FnAbi<'tcx, Ty<'tcx>> {
fn llvm_type(&self, cx: &CodegenCx<'ll, 'tcx>) -> &'ll Type {
let args_capacity: usize = self.args.iter().map(|arg|
// Ignore "extra" args from the call site for C variadic functions.
// Only the "fixed" args are part of the LLVM function signature.
let args = if self.c_variadic { &self.args[..self.fixed_count] } else { &self.args };

let args_capacity: usize = args.iter().map(|arg|
if arg.pad.is_some() { 1 } else { 0 } +
if let PassMode::Pair(_, _) = arg.mode { 2 } else { 1 }
).sum();
Expand All @@ -371,7 +375,7 @@ impl<'tcx> FnAbiLlvmExt<'tcx> for FnAbi<'tcx, Ty<'tcx>> {
}
};

for arg in &self.args {
for arg in args {
// add padding
if let Some(ty) = arg.pad {
llargument_tys.push(ty.llvm_type(cx));
Expand Down
13 changes: 10 additions & 3 deletions compiler/rustc_codegen_llvm/src/allocator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -78,8 +78,14 @@ pub(crate) unsafe fn codegen(
.enumerate()
.map(|(i, _)| llvm::LLVMGetParam(llfn, i as c_uint))
.collect::<Vec<_>>();
let ret =
llvm::LLVMRustBuildCall(llbuilder, callee, args.as_ptr(), args.len() as c_uint, None);
let ret = llvm::LLVMRustBuildCall(
llbuilder,
ty,
callee,
args.as_ptr(),
args.len() as c_uint,
None,
);
llvm::LLVMSetTailCall(ret, True);
if output.is_some() {
llvm::LLVMBuildRet(llbuilder, ret);
Expand Down Expand Up @@ -121,7 +127,8 @@ pub(crate) unsafe fn codegen(
.enumerate()
.map(|(i, _)| llvm::LLVMGetParam(llfn, i as c_uint))
.collect::<Vec<_>>();
let ret = llvm::LLVMRustBuildCall(llbuilder, callee, args.as_ptr(), args.len() as c_uint, None);
let ret =
llvm::LLVMRustBuildCall(llbuilder, ty, callee, args.as_ptr(), args.len() as c_uint, None);
llvm::LLVMSetTailCall(ret, True);
llvm::LLVMBuildRetVoid(llbuilder);
llvm::LLVMDisposeBuilder(llbuilder);
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_codegen_llvm/src/asm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -464,7 +464,7 @@ fn inline_asm_call(
alignstack,
llvm::AsmDialect::from_generic(dia),
);
let call = bx.call(v, inputs, None);
let call = bx.call(fty, v, inputs, None);

// Store mark in a metadata node so we can map LLVM errors
// back to source locations. See #17552.
Expand Down
46 changes: 24 additions & 22 deletions compiler/rustc_codegen_llvm/src/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,7 @@ impl BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {

fn invoke(
&mut self,
llty: &'ll Type,
llfn: &'ll Value,
args: &[&'ll Value],
then: &'ll BasicBlock,
Expand All @@ -208,13 +209,14 @@ impl BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
) -> &'ll Value {
debug!("invoke {:?} with args ({:?})", llfn, args);

let args = self.check_call("invoke", llfn, args);
let args = self.check_call("invoke", llty, llfn, args);
let bundle = funclet.map(|funclet| funclet.bundle());
let bundle = bundle.as_ref().map(|b| &*b.raw);

unsafe {
llvm::LLVMRustBuildInvoke(
self.llbuilder,
llty,
llfn,
args.as_ptr(),
args.len() as c_uint,
Expand Down Expand Up @@ -369,8 +371,7 @@ impl BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
},
};

let intrinsic = self.get_intrinsic(&name);
let res = self.call(intrinsic, &[lhs, rhs], None);
let res = self.call_intrinsic(name, &[lhs, rhs]);
(self.extract_value(res, 0), self.extract_value(res, 1))
}

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

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

None
Expand Down Expand Up @@ -743,8 +742,7 @@ impl BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
_ => None,
};
if let Some(name) = name {
let intrinsic = self.get_intrinsic(name);
return self.call(intrinsic, &[val], None);
return self.call_intrinsic(name, &[val]);
}
}
}
Expand All @@ -766,8 +764,7 @@ impl BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
_ => None,
};
if let Some(name) = name {
let intrinsic = self.get_intrinsic(name);
return self.call(intrinsic, &[val], None);
return self.call_intrinsic(name, &[val]);
}
}
}
Expand Down Expand Up @@ -1115,12 +1112,17 @@ impl BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
);

let llfn = unsafe { llvm::LLVMRustGetInstrProfIncrementIntrinsic(self.cx().llmod) };
let llty = self.cx.type_func(
&[self.cx.type_i8p(), self.cx.type_i64(), self.cx.type_i32(), self.cx.type_i32()],
self.cx.type_void(),
);
let args = &[fn_name, hash, num_counters, index];
let args = self.check_call("call", llfn, args);
let args = self.check_call("call", llty, llfn, args);

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

fn call(
&mut self,
llty: &'ll Type,
llfn: &'ll Value,
args: &[&'ll Value],
funclet: Option<&Funclet<'ll>>,
) -> &'ll Value {
debug!("call {:?} with args ({:?})", llfn, args);

let args = self.check_call("call", llfn, args);
let args = self.check_call("call", llty, llfn, args);
let bundle = funclet.map(|funclet| funclet.bundle());
let bundle = bundle.as_ref().map(|b| &*b.raw);

unsafe {
llvm::LLVMRustBuildCall(
self.llbuilder,
llty,
llfn,
args.as_ptr() as *const &llvm::Value,
args.len() as c_uint,
Expand Down Expand Up @@ -1313,15 +1317,10 @@ impl Builder<'a, 'll, 'tcx> {
fn check_call<'b>(
&mut self,
typ: &str,
fn_ty: &'ll Type,
llfn: &'ll Value,
args: &'b [&'ll Value],
) -> Cow<'b, [&'ll Value]> {
let mut fn_ty = self.cx.val_ty(llfn);
// Strip off pointers
while self.cx.type_kind(fn_ty) == TypeKind::Pointer {
fn_ty = self.cx.element_type(fn_ty);
}

assert!(
self.cx.type_kind(fn_ty) == TypeKind::Function,
"builder::{} not passed a function, but {:?}",
Expand Down Expand Up @@ -1362,6 +1361,11 @@ impl Builder<'a, 'll, 'tcx> {
unsafe { llvm::LLVMBuildVAArg(self.llbuilder, list, ty, UNNAMED) }
}

crate fn call_intrinsic(&mut self, intrinsic: &str, args: &[&'ll Value]) -> &'ll Value {
let (ty, f) = self.cx.get_intrinsic(intrinsic);
self.call(ty, f, args, None)
}

fn call_lifetime_intrinsic(&mut self, intrinsic: &str, ptr: &'ll Value, size: Size) {
let size = size.bytes();
if size == 0 {
Expand All @@ -1372,10 +1376,8 @@ impl Builder<'a, 'll, 'tcx> {
return;
}

let lifetime_intrinsic = self.cx.get_intrinsic(intrinsic);

let ptr = self.pointercast(ptr, self.cx.type_i8p());
self.call(lifetime_intrinsic, &[self.cx.const_u64(size), ptr], None);
self.call_intrinsic(intrinsic, &[self.cx.const_u64(size), ptr]);
}

pub(crate) fn phi(
Expand Down
14 changes: 7 additions & 7 deletions compiler/rustc_codegen_llvm/src/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -84,9 +84,9 @@ pub struct CodegenCx<'ll, 'tcx> {

eh_personality: Cell<Option<&'ll Value>>,
eh_catch_typeinfo: Cell<Option<&'ll Value>>,
pub rust_try_fn: Cell<Option<&'ll Value>>,
pub rust_try_fn: Cell<Option<(&'ll Type, &'ll Value)>>,

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

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

impl CodegenCx<'b, 'tcx> {
crate fn get_intrinsic(&self, key: &str) -> &'b Value {
crate fn get_intrinsic(&self, key: &str) -> (&'b Type, &'b Value) {
if let Some(v) = self.intrinsics.borrow().get(key).cloned() {
return v;
}
Expand All @@ -465,18 +465,18 @@ impl CodegenCx<'b, 'tcx> {
name: &'static str,
args: Option<&[&'b llvm::Type]>,
ret: &'b llvm::Type,
) -> &'b llvm::Value {
) -> (&'b llvm::Type, &'b llvm::Value) {
let fn_ty = if let Some(args) = args {
self.type_func(args, ret)
} else {
self.type_variadic_func(&[], ret)
};
let f = self.declare_cfn(name, llvm::UnnamedAddr::No, fn_ty);
self.intrinsics.borrow_mut().insert(name, f);
f
self.intrinsics.borrow_mut().insert(name, (fn_ty, f));
(fn_ty, f)
}

fn declare_intrinsic(&self, key: &str) -> Option<&'b Value> {
fn declare_intrinsic(&self, key: &str) -> Option<(&'b Type, &'b Value)> {
macro_rules! ifn {
($name:expr, fn() -> $ret:expr) => (
if key == $name {
Expand Down
Loading