Skip to content

Commit 29ed7cc

Browse files
committed
Add callbr support to LLVM wrapper
1 parent 901ce85 commit 29ed7cc

File tree

3 files changed

+91
-0
lines changed

3 files changed

+91
-0
lines changed

compiler/rustc_codegen_llvm/src/builder.rs

+52
Original file line numberDiff line numberDiff line change
@@ -1514,6 +1514,58 @@ impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> {
15141514
}
15151515
}
15161516

1517+
pub(crate) fn callbr(
1518+
&mut self,
1519+
llty: &'ll Type,
1520+
fn_attrs: Option<&CodegenFnAttrs>,
1521+
fn_abi: Option<&FnAbi<'tcx, Ty<'tcx>>>,
1522+
llfn: &'ll Value,
1523+
args: &[&'ll Value],
1524+
default_dest: &'ll BasicBlock,
1525+
indirect_dest: &[&'ll BasicBlock],
1526+
funclet: Option<&Funclet<'ll>>,
1527+
) -> &'ll Value {
1528+
debug!("invoke {:?} with args ({:?})", llfn, args);
1529+
1530+
let args = self.check_call("callbr", llty, llfn, args);
1531+
let funclet_bundle = funclet.map(|funclet| funclet.bundle());
1532+
let funclet_bundle = funclet_bundle.as_ref().map(|b| &*b.raw);
1533+
let mut bundles: SmallVec<[_; 2]> = SmallVec::new();
1534+
if let Some(funclet_bundle) = funclet_bundle {
1535+
bundles.push(funclet_bundle);
1536+
}
1537+
1538+
// Emit CFI pointer type membership test
1539+
self.cfi_type_test(fn_attrs, fn_abi, llfn);
1540+
1541+
// Emit KCFI operand bundle
1542+
let kcfi_bundle = self.kcfi_operand_bundle(fn_attrs, fn_abi, llfn);
1543+
let kcfi_bundle = kcfi_bundle.as_ref().map(|b| &*b.raw);
1544+
if let Some(kcfi_bundle) = kcfi_bundle {
1545+
bundles.push(kcfi_bundle);
1546+
}
1547+
1548+
let callbr = unsafe {
1549+
llvm::LLVMRustBuildCallBr(
1550+
self.llbuilder,
1551+
llty,
1552+
llfn,
1553+
default_dest,
1554+
indirect_dest.as_ptr(),
1555+
indirect_dest.len() as c_uint,
1556+
args.as_ptr(),
1557+
args.len() as c_uint,
1558+
bundles.as_ptr(),
1559+
bundles.len() as c_uint,
1560+
UNNAMED,
1561+
)
1562+
};
1563+
if let Some(fn_abi) = fn_abi {
1564+
fn_abi.apply_attrs_callsite(self, callbr);
1565+
}
1566+
callbr
1567+
}
1568+
15171569
// Emits CFI pointer type membership tests.
15181570
fn cfi_type_test(
15191571
&mut self,

compiler/rustc_codegen_llvm/src/llvm/ffi.rs

+14
Original file line numberDiff line numberDiff line change
@@ -1619,6 +1619,20 @@ extern "C" {
16191619
Name: *const c_char,
16201620
) -> &'a Value;
16211621

1622+
pub fn LLVMRustBuildCallBr<'a>(
1623+
B: &Builder<'a>,
1624+
Ty: &'a Type,
1625+
Fn: &'a Value,
1626+
DefaultDest: &'a BasicBlock,
1627+
IndirectDests: *const &'a BasicBlock,
1628+
NumIndirectDests: c_uint,
1629+
Args: *const &'a Value,
1630+
NumArgs: c_uint,
1631+
OpBundles: *const &OperandBundleDef<'a>,
1632+
NumOpBundles: c_uint,
1633+
Name: *const c_char,
1634+
) -> &'a Value;
1635+
16221636
pub fn LLVMRustSetFastMath(Instr: &Value);
16231637

16241638
// Miscellaneous instructions

compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp

+25
Original file line numberDiff line numberDiff line change
@@ -1504,6 +1504,31 @@ LLVMRustBuildInvoke(LLVMBuilderRef B, LLVMTypeRef Ty, LLVMValueRef Fn,
15041504
Name));
15051505
}
15061506

1507+
extern "C" LLVMValueRef
1508+
LLVMRustBuildCallBr(LLVMBuilderRef B, LLVMTypeRef Ty, LLVMValueRef Fn,
1509+
LLVMBasicBlockRef DefaultDest,
1510+
LLVMBasicBlockRef *IndirectDests, unsigned NumIndirectDests,
1511+
LLVMValueRef *Args, unsigned NumArgs,
1512+
OperandBundleDef **OpBundles, unsigned NumOpBundles,
1513+
const char *Name) {
1514+
Value *Callee = unwrap(Fn);
1515+
FunctionType *FTy = unwrap<FunctionType>(Ty);
1516+
1517+
// FIXME: Is there a way around this?
1518+
std::vector<BasicBlock*> IndirectDestsUnwrapped;
1519+
IndirectDestsUnwrapped.reserve(NumIndirectDests);
1520+
for (unsigned i = 0; i < NumIndirectDests; ++i) {
1521+
IndirectDestsUnwrapped.push_back(unwrap(IndirectDests[i]));
1522+
}
1523+
1524+
return wrap(unwrap(B)->CreateCallBr(
1525+
FTy, Callee, unwrap(DefaultDest),
1526+
ArrayRef<BasicBlock*>(IndirectDestsUnwrapped),
1527+
ArrayRef<Value*>(unwrap(Args), NumArgs),
1528+
ArrayRef<OperandBundleDef>(*OpBundles, NumOpBundles),
1529+
Name));
1530+
}
1531+
15071532
extern "C" void LLVMRustPositionBuilderAtStart(LLVMBuilderRef B,
15081533
LLVMBasicBlockRef BB) {
15091534
auto Point = unwrap(BB)->getFirstInsertionPt();

0 commit comments

Comments
 (0)