Skip to content

[C API] Add getters and build function for CallBr #91154

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
May 8, 2024
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
7 changes: 7 additions & 0 deletions llvm/docs/ReleaseNotes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,13 @@ Changes to the C API

* Added ``LLVMCreateConstantRangeAttribute`` function for creating ConstantRange Attributes.

* Added the following functions for creating and accessing data for CallBr instructions:

* ``LLVMBuildCallBr``
* ``LLVMGetCallBrDefaultDest``
* ``LLVMGetCallBrNumIndirectDests``
* ``LLVMGetCallBrIndirectDest``

Changes to the CodeGen infrastructure
-------------------------------------

Expand Down
28 changes: 28 additions & 0 deletions llvm/include/llvm-c/Core.h
Original file line number Diff line number Diff line change
Expand Up @@ -3737,6 +3737,28 @@ void LLVMSetNormalDest(LLVMValueRef InvokeInst, LLVMBasicBlockRef B);
*/
void LLVMSetUnwindDest(LLVMValueRef InvokeInst, LLVMBasicBlockRef B);

/**
* Get the default destination of a CallBr instruction.
*
* @see llvm::CallBrInst::getDefaultDest()
*/
LLVMBasicBlockRef LLVMGetCallBrDefaultDest(LLVMValueRef CallBr);

/**
* Get the number of indirect destinations of a CallBr instruction.
*
* @see llvm::CallBrInst::getNumIndirectDests()

*/
unsigned LLVMGetCallBrNumIndirectDests(LLVMValueRef CallBr);

/**
* Get the indirect destination of a CallBr instruction at the given index.
*
* @see llvm::CallBrInst::getIndirectDest()
*/
LLVMBasicBlockRef LLVMGetCallBrIndirectDest(LLVMValueRef CallBr, unsigned Idx);

/**
* @}
*/
Expand Down Expand Up @@ -4023,6 +4045,12 @@ LLVMValueRef LLVMBuildSwitch(LLVMBuilderRef, LLVMValueRef V,
LLVMBasicBlockRef Else, unsigned NumCases);
LLVMValueRef LLVMBuildIndirectBr(LLVMBuilderRef B, LLVMValueRef Addr,
unsigned NumDests);
LLVMValueRef LLVMBuildCallBr(LLVMBuilderRef B, LLVMTypeRef Ty, LLVMValueRef Fn,
LLVMBasicBlockRef DefaultDest,
LLVMBasicBlockRef *IndirectDests,
unsigned NumIndirectDests, LLVMValueRef *Args,
unsigned NumArgs, LLVMOperandBundleRef *Bundles,
unsigned NumBundles, const char *Name);
LLVMValueRef LLVMBuildInvoke2(LLVMBuilderRef, LLVMTypeRef Ty, LLVMValueRef Fn,
LLVMValueRef *Args, unsigned NumArgs,
LLVMBasicBlockRef Then, LLVMBasicBlockRef Catch,
Expand Down
35 changes: 35 additions & 0 deletions llvm/lib/IR/Core.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,10 @@ using namespace llvm;

DEFINE_SIMPLE_CONVERSION_FUNCTIONS(OperandBundleDef, LLVMOperandBundleRef)

inline BasicBlock **unwrap(LLVMBasicBlockRef *BBs) {
return reinterpret_cast<BasicBlock **>(BBs);
}

#define DEBUG_TYPE "ir"

void llvm::initializeCore(PassRegistry &Registry) {
Expand Down Expand Up @@ -3031,6 +3035,18 @@ void LLVMSetUnwindDest(LLVMValueRef Invoke, LLVMBasicBlockRef B) {
unwrap<InvokeInst>(Invoke)->setUnwindDest(unwrap(B));
}

LLVMBasicBlockRef LLVMGetCallBrDefaultDest(LLVMValueRef CallBr) {
return wrap(unwrap<CallBrInst>(CallBr)->getDefaultDest());
}

unsigned LLVMGetCallBrNumIndirectDests(LLVMValueRef CallBr) {
return unwrap<CallBrInst>(CallBr)->getNumIndirectDests();
}

LLVMBasicBlockRef LLVMGetCallBrIndirectDest(LLVMValueRef CallBr, unsigned Idx) {
return wrap(unwrap<CallBrInst>(CallBr)->getIndirectDest(Idx));
}

/*--.. Operations on terminators ...........................................--*/

unsigned LLVMGetNumSuccessors(LLVMValueRef Term) {
Expand Down Expand Up @@ -3258,6 +3274,25 @@ LLVMValueRef LLVMBuildIndirectBr(LLVMBuilderRef B, LLVMValueRef Addr,
return wrap(unwrap(B)->CreateIndirectBr(unwrap(Addr), NumDests));
}

LLVMValueRef LLVMBuildCallBr(LLVMBuilderRef B, LLVMTypeRef Ty, LLVMValueRef Fn,
LLVMBasicBlockRef DefaultDest,
LLVMBasicBlockRef *IndirectDests,
unsigned NumIndirectDests, LLVMValueRef *Args,
unsigned NumArgs, LLVMOperandBundleRef *Bundles,
unsigned NumBundles, const char *Name) {

SmallVector<OperandBundleDef, 8> OBs;
for (auto *Bundle : ArrayRef(Bundles, NumBundles)) {
OperandBundleDef *OB = unwrap(Bundle);
OBs.push_back(*OB);
}

return wrap(unwrap(B)->CreateCallBr(
unwrap<FunctionType>(Ty), unwrap(Fn), unwrap(DefaultDest),
ArrayRef(unwrap(IndirectDests), NumIndirectDests),
ArrayRef<Value *>(unwrap(Args), NumArgs), OBs, Name));
}

LLVMValueRef LLVMBuildInvoke2(LLVMBuilderRef B, LLVMTypeRef Ty, LLVMValueRef Fn,
LLVMValueRef *Args, unsigned NumArgs,
LLVMBasicBlockRef Then, LLVMBasicBlockRef Catch,
Expand Down
26 changes: 26 additions & 0 deletions llvm/test/Bindings/llvm-c/echo.ll
Original file line number Diff line number Diff line change
Expand Up @@ -348,6 +348,32 @@ define void @test_func_prologue_data_01() prologue %func_prolog_struct <{ i8 235
ret void
}


define void @test_call_br_01(i32 %input) {
entry:
callbr void asm "nop", "r,!i"(i32 %input) to label %bb_01 [label %bb_02]

bb_01:
ret void
bb_02:
ret void
}

define void @test_call_br_02(i32 %input0, i32 %input1) {
entry:
; Multiple indirect destinations, operand bundles, and arguments
callbr void asm "nop", "r,r,!i,!i"(i32 %input0, i32 %input1)
["op0"(i32 %input1), "op1"(label %bb_02)]
to label %bb_01 [label %bb_03, label %bb_02]

bb_01:
ret void
bb_02:
ret void
bb_03:
ret void
}

!llvm.dbg.cu = !{!0, !2}
!llvm.module.flags = !{!3}

Expand Down
40 changes: 40 additions & 0 deletions llvm/tools/llvm-c-test/echo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -570,6 +570,46 @@ struct FunCloner {
LLVMDisposeOperandBundle(Bundle);
break;
}
case LLVMCallBr: {
LLVMTypeRef FnTy = CloneType(LLVMGetCalledFunctionType(Src));
LLVMValueRef Fn = CloneValue(LLVMGetCalledValue(Src));

LLVMBasicBlockRef DefaultDest =
DeclareBB(LLVMGetCallBrDefaultDest(Src));

// Clone indirect destinations
SmallVector<LLVMBasicBlockRef, 8> IndirectDests;
unsigned IndirectDestCount = LLVMGetCallBrNumIndirectDests(Src);
for (unsigned i = 0; i < IndirectDestCount; ++i)
IndirectDests.push_back(DeclareBB(LLVMGetCallBrIndirectDest(Src, i)));

// Clone input arguments
SmallVector<LLVMValueRef, 8> Args;
unsigned ArgCount = LLVMGetNumArgOperands(Src);
for (unsigned i = 0; i < ArgCount; ++i)
Args.push_back(CloneValue(LLVMGetOperand(Src, i)));

// Clone operand bundles
SmallVector<LLVMOperandBundleRef, 8> Bundles;
unsigned BundleCount = LLVMGetNumOperandBundles(Src);
for (unsigned i = 0; i < BundleCount; ++i) {
auto Bundle = LLVMGetOperandBundleAtIndex(Src, i);
Bundles.push_back(CloneOB(Bundle));
LLVMDisposeOperandBundle(Bundle);
}

Dst = LLVMBuildCallBr(Builder, FnTy, Fn, DefaultDest,
IndirectDests.data(), IndirectDests.size(),
Args.data(), Args.size(), Bundles.data(),
Bundles.size(), Name);

CloneAttrs(Src, Dst);

for (auto Bundle : Bundles)
LLVMDisposeOperandBundle(Bundle);

break;
}
case LLVMUnreachable:
Dst = LLVMBuildUnreachable(Builder);
break;
Expand Down
Loading