-
Notifications
You must be signed in to change notification settings - Fork 13.5k
[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
Conversation
This adds LLVMBuildCallBr to create CallBr instructions, and getters for the CallBr-specific data. The remainder of its data, e.g. arguments/function, can be accessed using existing getters.
@llvm/pr-subscribers-llvm-ir Author: Benji Smith (Benjins) ChangesThis adds LLVMBuildCallBr to create CallBr instructions, and getters for the CallBr-specific data. The remainder of its data, e.g. arguments/function, can be accessed using existing getters. Full diff: https://github.com/llvm/llvm-project/pull/91154.diff 5 Files Affected:
diff --git a/llvm/docs/ReleaseNotes.rst b/llvm/docs/ReleaseNotes.rst
index 59c0d4dd2376dd..6312c2621f170a 100644
--- a/llvm/docs/ReleaseNotes.rst
+++ b/llvm/docs/ReleaseNotes.rst
@@ -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
-------------------------------------
diff --git a/llvm/include/llvm-c/Core.h b/llvm/include/llvm-c/Core.h
index ba02ca48257532..cd65b3c14c7b75 100644
--- a/llvm/include/llvm-c/Core.h
+++ b/llvm/include/llvm-c/Core.h
@@ -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);
+
/**
* @}
*/
@@ -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 *IndrectDests,
+ unsigned NumIndrectDests, 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,
diff --git a/llvm/lib/IR/Core.cpp b/llvm/lib/IR/Core.cpp
index 1b84527d5e8741..78563165767661 100644
--- a/llvm/lib/IR/Core.cpp
+++ b/llvm/lib/IR/Core.cpp
@@ -3031,6 +3031,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) {
@@ -3258,6 +3270,30 @@ 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 *IndrectDests,
+ unsigned NumIndrectDests, 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);
+ }
+
+ SmallVector<BasicBlock *, 8> IDs;
+ for (auto ID : ArrayRef(IndrectDests, NumIndrectDests)) {
+ BasicBlock *BB = unwrap(ID);
+ IDs.push_back(BB);
+ }
+
+ return wrap(unwrap(B)->CreateCallBr(
+ unwrap<FunctionType>(Ty), unwrap(Fn), unwrap(DefaultDest), IDs,
+ ArrayRef<Value *>(unwrap(Args), NumArgs), OBs, Name));
+}
+
LLVMValueRef LLVMBuildInvoke2(LLVMBuilderRef B, LLVMTypeRef Ty, LLVMValueRef Fn,
LLVMValueRef *Args, unsigned NumArgs,
LLVMBasicBlockRef Then, LLVMBasicBlockRef Catch,
diff --git a/llvm/test/Bindings/llvm-c/echo.ll b/llvm/test/Bindings/llvm-c/echo.ll
index 953a16b7e624e1..bb5fae0dcd12ee 100644
--- a/llvm/test/Bindings/llvm-c/echo.ll
+++ b/llvm/test/Bindings/llvm-c/echo.ll
@@ -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}
diff --git a/llvm/tools/llvm-c-test/echo.cpp b/llvm/tools/llvm-c-test/echo.cpp
index 347863638849ce..518716168c4235 100644
--- a/llvm/tools/llvm-c-test/echo.cpp
+++ b/llvm/tools/llvm-c-test/echo.cpp
@@ -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;
|
llvm/include/llvm-c/Core.h
Outdated
@@ -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 *IndrectDests, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LLVMBasicBlockRef *IndrectDests, | |
LLVMBasicBlockRef *IndirectDests, |
Here and elsewhere.
llvm/lib/IR/Core.cpp
Outdated
OBs.push_back(*OB); | ||
} | ||
|
||
SmallVector<BasicBlock *, 8> IDs; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It shouldn't be necessary to create a new vector. You should be able to do something like ArrayRef(unwrap(IndirectDests), NumIndirectDests)
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I tried this, but it looks like DEFINE_SIMPLE_CONVERSION_FUNCTIONS
only defines the single pointer conversion. Some types, e.g. LLVMTypeRef
, also define an explicit double-pointer wrap
and unwrap
, but basic blocks do not afaict
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see. In that case I think it would make sense to add the unwrap for BasicBlock**. (Maybe just as a static function inside this file?)
…ons basic block list
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
This adds LLVMBuildCallBr to create CallBr instructions, and getters for the CallBr-specific data. The remainder of its data, e.g. arguments/function, can be accessed using existing getters.