Add callbr support to LLVM wrapper
This commit is contained in:
parent
3b1dd1bfa9
commit
27e6ee102e
3 changed files with 91 additions and 0 deletions
|
@ -1547,6 +1547,58 @@ impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) fn callbr(
|
||||||
|
&mut self,
|
||||||
|
llty: &'ll Type,
|
||||||
|
fn_attrs: Option<&CodegenFnAttrs>,
|
||||||
|
fn_abi: Option<&FnAbi<'tcx, Ty<'tcx>>>,
|
||||||
|
llfn: &'ll Value,
|
||||||
|
args: &[&'ll Value],
|
||||||
|
default_dest: &'ll BasicBlock,
|
||||||
|
indirect_dest: &[&'ll BasicBlock],
|
||||||
|
funclet: Option<&Funclet<'ll>>,
|
||||||
|
) -> &'ll Value {
|
||||||
|
debug!("invoke {:?} with args ({:?})", llfn, args);
|
||||||
|
|
||||||
|
let args = self.check_call("callbr", llty, llfn, args);
|
||||||
|
let funclet_bundle = funclet.map(|funclet| funclet.bundle());
|
||||||
|
let funclet_bundle = funclet_bundle.as_ref().map(|b| &*b.raw);
|
||||||
|
let mut bundles: SmallVec<[_; 2]> = SmallVec::new();
|
||||||
|
if let Some(funclet_bundle) = funclet_bundle {
|
||||||
|
bundles.push(funclet_bundle);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Emit CFI pointer type membership test
|
||||||
|
self.cfi_type_test(fn_attrs, fn_abi, llfn);
|
||||||
|
|
||||||
|
// Emit KCFI operand bundle
|
||||||
|
let kcfi_bundle = self.kcfi_operand_bundle(fn_attrs, fn_abi, llfn);
|
||||||
|
let kcfi_bundle = kcfi_bundle.as_ref().map(|b| &*b.raw);
|
||||||
|
if let Some(kcfi_bundle) = kcfi_bundle {
|
||||||
|
bundles.push(kcfi_bundle);
|
||||||
|
}
|
||||||
|
|
||||||
|
let callbr = unsafe {
|
||||||
|
llvm::LLVMRustBuildCallBr(
|
||||||
|
self.llbuilder,
|
||||||
|
llty,
|
||||||
|
llfn,
|
||||||
|
default_dest,
|
||||||
|
indirect_dest.as_ptr(),
|
||||||
|
indirect_dest.len() as c_uint,
|
||||||
|
args.as_ptr(),
|
||||||
|
args.len() as c_uint,
|
||||||
|
bundles.as_ptr(),
|
||||||
|
bundles.len() as c_uint,
|
||||||
|
UNNAMED,
|
||||||
|
)
|
||||||
|
};
|
||||||
|
if let Some(fn_abi) = fn_abi {
|
||||||
|
fn_abi.apply_attrs_callsite(self, callbr);
|
||||||
|
}
|
||||||
|
callbr
|
||||||
|
}
|
||||||
|
|
||||||
// Emits CFI pointer type membership tests.
|
// Emits CFI pointer type membership tests.
|
||||||
fn cfi_type_test(
|
fn cfi_type_test(
|
||||||
&mut self,
|
&mut self,
|
||||||
|
|
|
@ -1617,6 +1617,20 @@ extern "C" {
|
||||||
Name: *const c_char,
|
Name: *const c_char,
|
||||||
) -> &'a Value;
|
) -> &'a Value;
|
||||||
|
|
||||||
|
pub fn LLVMRustBuildCallBr<'a>(
|
||||||
|
B: &Builder<'a>,
|
||||||
|
Ty: &'a Type,
|
||||||
|
Fn: &'a Value,
|
||||||
|
DefaultDest: &'a BasicBlock,
|
||||||
|
IndirectDests: *const &'a BasicBlock,
|
||||||
|
NumIndirectDests: c_uint,
|
||||||
|
Args: *const &'a Value,
|
||||||
|
NumArgs: c_uint,
|
||||||
|
OpBundles: *const &OperandBundleDef<'a>,
|
||||||
|
NumOpBundles: c_uint,
|
||||||
|
Name: *const c_char,
|
||||||
|
) -> &'a Value;
|
||||||
|
|
||||||
pub fn LLVMRustSetFastMath(Instr: &Value);
|
pub fn LLVMRustSetFastMath(Instr: &Value);
|
||||||
pub fn LLVMRustSetAlgebraicMath(Instr: &Value);
|
pub fn LLVMRustSetAlgebraicMath(Instr: &Value);
|
||||||
pub fn LLVMRustSetAllowReassoc(Instr: &Value);
|
pub fn LLVMRustSetAllowReassoc(Instr: &Value);
|
||||||
|
|
|
@ -1539,6 +1539,31 @@ LLVMRustBuildInvoke(LLVMBuilderRef B, LLVMTypeRef Ty, LLVMValueRef Fn,
|
||||||
Name));
|
Name));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extern "C" LLVMValueRef
|
||||||
|
LLVMRustBuildCallBr(LLVMBuilderRef B, LLVMTypeRef Ty, LLVMValueRef Fn,
|
||||||
|
LLVMBasicBlockRef DefaultDest,
|
||||||
|
LLVMBasicBlockRef *IndirectDests, unsigned NumIndirectDests,
|
||||||
|
LLVMValueRef *Args, unsigned NumArgs,
|
||||||
|
OperandBundleDef **OpBundles, unsigned NumOpBundles,
|
||||||
|
const char *Name) {
|
||||||
|
Value *Callee = unwrap(Fn);
|
||||||
|
FunctionType *FTy = unwrap<FunctionType>(Ty);
|
||||||
|
|
||||||
|
// FIXME: Is there a way around this?
|
||||||
|
std::vector<BasicBlock*> IndirectDestsUnwrapped;
|
||||||
|
IndirectDestsUnwrapped.reserve(NumIndirectDests);
|
||||||
|
for (unsigned i = 0; i < NumIndirectDests; ++i) {
|
||||||
|
IndirectDestsUnwrapped.push_back(unwrap(IndirectDests[i]));
|
||||||
|
}
|
||||||
|
|
||||||
|
return wrap(unwrap(B)->CreateCallBr(
|
||||||
|
FTy, Callee, unwrap(DefaultDest),
|
||||||
|
ArrayRef<BasicBlock*>(IndirectDestsUnwrapped),
|
||||||
|
ArrayRef<Value*>(unwrap(Args), NumArgs),
|
||||||
|
ArrayRef<OperandBundleDef>(*OpBundles, NumOpBundles),
|
||||||
|
Name));
|
||||||
|
}
|
||||||
|
|
||||||
extern "C" void LLVMRustPositionBuilderAtStart(LLVMBuilderRef B,
|
extern "C" void LLVMRustPositionBuilderAtStart(LLVMBuilderRef B,
|
||||||
LLVMBasicBlockRef BB) {
|
LLVMBasicBlockRef BB) {
|
||||||
auto Point = unwrap(BB)->getFirstInsertionPt();
|
auto Point = unwrap(BB)->getFirstInsertionPt();
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue