[llvm] 01f4510 - [LLVM-C] Upstream `LLVMGetOrInsertFunction` from rustc (#162235)

via llvm-commits llvm-commits at lists.llvm.org
Tue Oct 7 07:49:43 PDT 2025


Author: AMS21
Date: 2025-10-07T14:49:39Z
New Revision: 01f4510118b8a9a3ca1f7f1e4b19bd2e918c7dc0

URL: https://github.com/llvm/llvm-project/commit/01f4510118b8a9a3ca1f7f1e4b19bd2e918c7dc0
DIFF: https://github.com/llvm/llvm-project/commit/01f4510118b8a9a3ca1f7f1e4b19bd2e918c7dc0.diff

LOG: [LLVM-C] Upstream `LLVMGetOrInsertFunction` from rustc (#162235)

Add `LLVMGetOrInsertFunction` to the C API as a thin wrapper over
`Module::getOrInsertFunction`, upstreamed from
[rustc](https://github.com/rust-lang/rust/blob/d773bd07d63a74adcf25ea5f4aae986be94cac5e/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp#L203).
It provides a single-call way to get or create a function declaration,
avoiding `LLVMGetNamedFunction` + `LLVMAddFunction` and is more
idiomatic.

Added: 
    

Modified: 
    llvm/docs/ReleaseNotes.md
    llvm/include/llvm-c/Core.h
    llvm/lib/IR/Core.cpp
    llvm/unittests/IR/FunctionTest.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/docs/ReleaseNotes.md b/llvm/docs/ReleaseNotes.md
index 94c9c2cdbc34c..79d93d08b8398 100644
--- a/llvm/docs/ReleaseNotes.md
+++ b/llvm/docs/ReleaseNotes.md
@@ -146,6 +146,8 @@ Changes to the Python bindings
 Changes to the C API
 --------------------
 
+* Add `LLVMGetOrInsertFunction` to get or insert a function, replacing the combination of `LLVMGetNamedFunction` and `LLVMAddFunction`.
+
 Changes to the CodeGen infrastructure
 -------------------------------------
 

diff  --git a/llvm/include/llvm-c/Core.h b/llvm/include/llvm-c/Core.h
index d02cf984167c9..3d22f85911e78 100644
--- a/llvm/include/llvm-c/Core.h
+++ b/llvm/include/llvm-c/Core.h
@@ -1206,6 +1206,22 @@ LLVM_C_ABI unsigned LLVMGetDebugLocColumn(LLVMValueRef Val);
 LLVM_C_ABI LLVMValueRef LLVMAddFunction(LLVMModuleRef M, const char *Name,
                                         LLVMTypeRef FunctionTy);
 
+/**
+ * Obtain or insert a function into a module.
+ *
+ * If a function with the specified name already exists in the module, it
+ * is returned. Otherwise, a new function is created in the module with the
+ * specified name and type and is returned.
+ *
+ * The returned value corresponds to a llvm::Function instance.
+ *
+ * @see llvm::Module::getOrInsertFunction()
+ */
+LLVM_C_ABI LLVMValueRef LLVMGetOrInsertFunction(LLVMModuleRef M,
+                                                const char *Name,
+                                                size_t NameLen,
+                                                LLVMTypeRef FunctionTy);
+
 /**
  * Obtain a Function value from a Module by its name.
  *

diff  --git a/llvm/lib/IR/Core.cpp b/llvm/lib/IR/Core.cpp
index df0c85b87ba60..3f1cc1e4e6d0e 100644
--- a/llvm/lib/IR/Core.cpp
+++ b/llvm/lib/IR/Core.cpp
@@ -2403,6 +2403,14 @@ LLVMValueRef LLVMAddFunction(LLVMModuleRef M, const char *Name,
                                GlobalValue::ExternalLinkage, Name, unwrap(M)));
 }
 
+LLVMValueRef LLVMGetOrInsertFunction(LLVMModuleRef M, const char *Name,
+                                     size_t NameLen, LLVMTypeRef FunctionTy) {
+  return wrap(unwrap(M)
+                  ->getOrInsertFunction(StringRef(Name, NameLen),
+                                        unwrap<FunctionType>(FunctionTy))
+                  .getCallee());
+}
+
 LLVMValueRef LLVMGetNamedFunction(LLVMModuleRef M, const char *Name) {
   return wrap(unwrap(M)->getFunction(Name));
 }

diff  --git a/llvm/unittests/IR/FunctionTest.cpp b/llvm/unittests/IR/FunctionTest.cpp
index 7ba7584e22976..8ed76999dc13d 100644
--- a/llvm/unittests/IR/FunctionTest.cpp
+++ b/llvm/unittests/IR/FunctionTest.cpp
@@ -625,4 +625,23 @@ TEST(FunctionTest, Personality) {
   EXPECT_FALSE(LLVMHasPersonalityFn(wrap(F)));
 }
 
+TEST(FunctionTest, LLVMGetOrInsertFunction) {
+  LLVMContext Ctx;
+  Module M("test", Ctx);
+  Type *Int8Ty = Type::getInt8Ty(Ctx);
+  FunctionType *FTy = FunctionType::get(Int8Ty, false);
+
+  // Create the function using the C API
+  LLVMValueRef FuncRef = LLVMGetOrInsertFunction(wrap(&M), "F", 1, wrap(FTy));
+
+  // Verify that the returned value is a function and has the correct type
+  Function *Func = unwrap<Function>(FuncRef);
+  EXPECT_EQ(Func->getName(), "F");
+  EXPECT_EQ(Func->getFunctionType(), FTy);
+
+  // Call LLVMGetOrInsertFunction again to ensure it returns the same function
+  LLVMValueRef FuncRef2 = LLVMGetOrInsertFunction(wrap(&M), "F", 1, wrap(FTy));
+  EXPECT_EQ(FuncRef, FuncRef2);
+}
+
 } // end namespace


        


More information about the llvm-commits mailing list