Skip to content

Commit 27e6ee1

Browse files
committed
Add callbr support to LLVM wrapper
1 parent 3b1dd1b commit 27e6ee1

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
@@ -1547,6 +1547,58 @@ impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> {
15471547
}
15481548
}
15491549

1550+
pub(crate) fn callbr(
1551+
&mut self,
1552+
llty: &'ll Type,
1553+
fn_attrs: Option<&CodegenFnAttrs>,
1554+
fn_abi: Option<&FnAbi<'tcx, Ty<'tcx>>>,
1555+
llfn: &'ll Value,
1556+
args: &[&'ll Value],
1557+
default_dest: &'ll BasicBlock,
1558+
indirect_dest: &[&'ll BasicBlock],
1559+
funclet: Option<&Funclet<'ll>>,
1560+
) -> &'ll Value {
1561+
debug!("invoke {:?} with args ({:?})", llfn, args);
1562+
1563+
let args = self.check_call("callbr", llty, llfn, args);
1564+
let funclet_bundle = funclet.map(|funclet| funclet.bundle());
1565+
let funclet_bundle = funclet_bundle.as_ref().map(|b| &*b.raw);
1566+
let mut bundles: SmallVec<[_; 2]> = SmallVec::new();
1567+
if let Some(funclet_bundle) = funclet_bundle {
1568+
bundles.push(funclet_bundle);
1569+
}
1570+
1571+
// Emit CFI pointer type membership test
1572+
self.cfi_type_test(fn_attrs, fn_abi, llfn);
1573+
1574+
// Emit KCFI operand bundle
1575+
let kcfi_bundle = self.kcfi_operand_bundle(fn_attrs, fn_abi, llfn);
1576+
let kcfi_bundle = kcfi_bundle.as_ref().map(|b| &*b.raw);
1577+
if let Some(kcfi_bundle) = kcfi_bundle {
1578+
bundles.push(kcfi_bundle);
1579+
}
1580+
1581+
let callbr = unsafe {
1582+
llvm::LLVMRustBuildCallBr(
1583+
self.llbuilder,
1584+
llty,
1585+
llfn,
1586+
default_dest,
1587+
indirect_dest.as_ptr(),
1588+
indirect_dest.len() as c_uint,
1589+
args.as_ptr(),
1590+
args.len() as c_uint,
1591+
bundles.as_ptr(),
1592+
bundles.len() as c_uint,
1593+
UNNAMED,
1594+
)
1595+
};
1596+
if let Some(fn_abi) = fn_abi {
1597+
fn_abi.apply_attrs_callsite(self, callbr);
1598+
}
1599+
callbr
1600+
}
1601+
15501602
// Emits CFI pointer type membership tests.
15511603
fn cfi_type_test(
15521604
&mut self,

compiler/rustc_codegen_llvm/src/llvm/ffi.rs

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

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

compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp

+25
Original file line numberDiff line numberDiff line change
@@ -1539,6 +1539,31 @@ LLVMRustBuildInvoke(LLVMBuilderRef B, LLVMTypeRef Ty, LLVMValueRef Fn,
15391539
Name));
15401540
}
15411541

1542+
extern "C" LLVMValueRef
1543+
LLVMRustBuildCallBr(LLVMBuilderRef B, LLVMTypeRef Ty, LLVMValueRef Fn,
1544+
LLVMBasicBlockRef DefaultDest,
1545+
LLVMBasicBlockRef *IndirectDests, unsigned NumIndirectDests,
1546+
LLVMValueRef *Args, unsigned NumArgs,
1547+
OperandBundleDef **OpBundles, unsigned NumOpBundles,
1548+
const char *Name) {
1549+
Value *Callee = unwrap(Fn);
1550+
FunctionType *FTy = unwrap<FunctionType>(Ty);
1551+
1552+
// FIXME: Is there a way around this?
1553+
std::vector<BasicBlock*> IndirectDestsUnwrapped;
1554+
IndirectDestsUnwrapped.reserve(NumIndirectDests);
1555+
for (unsigned i = 0; i < NumIndirectDests; ++i) {
1556+
IndirectDestsUnwrapped.push_back(unwrap(IndirectDests[i]));
1557+
}
1558+
1559+
return wrap(unwrap(B)->CreateCallBr(
1560+
FTy, Callee, unwrap(DefaultDest),
1561+
ArrayRef<BasicBlock*>(IndirectDestsUnwrapped),
1562+
ArrayRef<Value*>(unwrap(Args), NumArgs),
1563+
ArrayRef<OperandBundleDef>(*OpBundles, NumOpBundles),
1564+
Name));
1565+
}
1566+
15421567
extern "C" void LLVMRustPositionBuilderAtStart(LLVMBuilderRef B,
15431568
LLVMBasicBlockRef BB) {
15441569
auto Point = unwrap(BB)->getFirstInsertionPt();

0 commit comments

Comments
 (0)