[llvm] 00def06 - [LLVM][NewPM] Add C API for running the pipeline on a single function. (#103773)
via llvm-commits
llvm-commits at lists.llvm.org
Mon Aug 19 03:34:27 PDT 2024
Author: Tim Besard
Date: 2024-08-19T12:34:23+02:00
New Revision: 00def06c6e9a0582e85bef5f3a186839c48d1ae2
URL: https://github.com/llvm/llvm-project/commit/00def06c6e9a0582e85bef5f3a186839c48d1ae2
DIFF: https://github.com/llvm/llvm-project/commit/00def06c6e9a0582e85bef5f3a186839c48d1ae2.diff
LOG: [LLVM][NewPM] Add C API for running the pipeline on a single function. (#103773)
By adding a new entrypoint, `LLVMRunPassesOnFunction`, as suggested in
https://discourse.llvm.org/t/newpm-c-api-questions/80598.
Also removes erroneous `LLVMConsumeError`s from the pass builder unit
tests as the string conversion already consumes the error, causing an
abort when the test would fail.
Added:
Modified:
llvm/docs/ReleaseNotes.rst
llvm/include/llvm-c/Transforms/PassBuilder.h
llvm/lib/Passes/PassBuilderBindings.cpp
llvm/unittests/Passes/PassBuilderBindings/PassBuilderBindingsTest.cpp
Removed:
################################################################################
diff --git a/llvm/docs/ReleaseNotes.rst b/llvm/docs/ReleaseNotes.rst
index 057bd5345fba28..d40bb2682f9ad8 100644
--- a/llvm/docs/ReleaseNotes.rst
+++ b/llvm/docs/ReleaseNotes.rst
@@ -157,6 +157,12 @@ Changes to the C API
* ``LLVMGetNamedFunctionWithLength``
* ``LLVMGetNamedGlobalWithLength``
+* The new pass manager can now be invoked with a custom alias analysis pipeline, using
+ the ``LLVMPassBuilderOptionsSetAAPipeline`` function.
+
+* It is now also possible to run the new pass manager on a single function, by calling
+ ``LLVMRunPassesOnFunction`` instead of ``LLVMRunPasses``.
+
Changes to the CodeGen infrastructure
-------------------------------------
diff --git a/llvm/include/llvm-c/Transforms/PassBuilder.h b/llvm/include/llvm-c/Transforms/PassBuilder.h
index 03a5abaa753312..d297b57cadd07d 100644
--- a/llvm/include/llvm-c/Transforms/PassBuilder.h
+++ b/llvm/include/llvm-c/Transforms/PassBuilder.h
@@ -50,6 +50,16 @@ LLVMErrorRef LLVMRunPasses(LLVMModuleRef M, const char *Passes,
LLVMTargetMachineRef TM,
LLVMPassBuilderOptionsRef Options);
+/**
+ * Construct and run a set of passes over a function.
+ *
+ * This function behaves the same as LLVMRunPasses, but operates on a single
+ * function instead of an entire module.
+ */
+LLVMErrorRef LLVMRunPassesOnFunction(LLVMValueRef F, const char *Passes,
+ LLVMTargetMachineRef TM,
+ LLVMPassBuilderOptionsRef Options);
+
/**
* Create a new set of options for a PassBuilder
*
diff --git a/llvm/lib/Passes/PassBuilderBindings.cpp b/llvm/lib/Passes/PassBuilderBindings.cpp
index 4e12dd2226c4d2..933fe89e53a94c 100644
--- a/llvm/lib/Passes/PassBuilderBindings.cpp
+++ b/llvm/lib/Passes/PassBuilderBindings.cpp
@@ -48,15 +48,12 @@ static TargetMachine *unwrap(LLVMTargetMachineRef P) {
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(LLVMPassBuilderOptions,
LLVMPassBuilderOptionsRef)
-LLVMErrorRef LLVMRunPasses(LLVMModuleRef M, const char *Passes,
- LLVMTargetMachineRef TM,
- LLVMPassBuilderOptionsRef Options) {
- TargetMachine *Machine = unwrap(TM);
- LLVMPassBuilderOptions *PassOpts = unwrap(Options);
+static LLVMErrorRef runPasses(Module *Mod, Function *Fun, const char *Passes,
+ TargetMachine *Machine,
+ LLVMPassBuilderOptions *PassOpts) {
bool Debug = PassOpts->DebugLogging;
bool VerifyEach = PassOpts->VerifyEach;
- Module *Mod = unwrap(M);
PassInstrumentationCallbacks PIC;
PassBuilder PB(Machine, PassOpts->PTO, std::nullopt, &PIC);
@@ -80,18 +77,45 @@ LLVMErrorRef LLVMRunPasses(LLVMModuleRef M, const char *Passes,
StandardInstrumentations SI(Mod->getContext(), Debug, VerifyEach);
SI.registerCallbacks(PIC, &MAM);
- ModulePassManager MPM;
- if (VerifyEach) {
- MPM.addPass(VerifierPass());
- }
- if (auto Err = PB.parsePassPipeline(MPM, Passes)) {
- return wrap(std::move(Err));
+
+ // Run the pipeline.
+ if (Fun) {
+ FunctionPassManager FPM;
+ if (VerifyEach)
+ FPM.addPass(VerifierPass());
+ if (auto Err = PB.parsePassPipeline(FPM, Passes))
+ return wrap(std::move(Err));
+ FPM.run(*Fun, FAM);
+ } else {
+ ModulePassManager MPM;
+ if (VerifyEach)
+ MPM.addPass(VerifierPass());
+ if (auto Err = PB.parsePassPipeline(MPM, Passes))
+ return wrap(std::move(Err));
+ MPM.run(*Mod, MAM);
}
- MPM.run(*Mod, MAM);
return LLVMErrorSuccess;
}
+LLVMErrorRef LLVMRunPasses(LLVMModuleRef M, const char *Passes,
+ LLVMTargetMachineRef TM,
+ LLVMPassBuilderOptionsRef Options) {
+ TargetMachine *Machine = unwrap(TM);
+ LLVMPassBuilderOptions *PassOpts = unwrap(Options);
+ Module *Mod = unwrap(M);
+ return runPasses(Mod, nullptr, Passes, Machine, PassOpts);
+}
+
+LLVMErrorRef LLVMRunPassesOnFunction(LLVMValueRef F, const char *Passes,
+ LLVMTargetMachineRef TM,
+ LLVMPassBuilderOptionsRef Options) {
+ TargetMachine *Machine = unwrap(TM);
+ LLVMPassBuilderOptions *PassOpts = unwrap(Options);
+ Function *Fun = unwrap<Function>(F);
+ return runPasses(Fun->getParent(), Fun, Passes, Machine, PassOpts);
+}
+
LLVMPassBuilderOptionsRef LLVMCreatePassBuilderOptions() {
return wrap(new LLVMPassBuilderOptions());
}
diff --git a/llvm/unittests/Passes/PassBuilderBindings/PassBuilderBindingsTest.cpp b/llvm/unittests/Passes/PassBuilderBindings/PassBuilderBindingsTest.cpp
index 2b06033f0c3fa2..4e17b1ad09e2b3 100644
--- a/llvm/unittests/Passes/PassBuilderBindings/PassBuilderBindingsTest.cpp
+++ b/llvm/unittests/Passes/PassBuilderBindings/PassBuilderBindingsTest.cpp
@@ -35,6 +35,9 @@ class PassBuilderCTest : public testing::Test {
LLVMDisposeMessage(Triple);
Context = LLVMContextCreate();
Module = LLVMModuleCreateWithNameInContext("test", Context);
+ LLVMTypeRef FT =
+ LLVMFunctionType(LLVMVoidTypeInContext(Context), nullptr, 0, 0);
+ Function = LLVMAddFunction(Module, "test", FT);
}
void TearDown() override {
@@ -52,6 +55,7 @@ class PassBuilderCTest : public testing::Test {
public:
LLVMTargetMachineRef TM;
LLVMModuleRef Module;
+ LLVMValueRef Function;
LLVMContextRef Context;
};
@@ -63,7 +67,6 @@ TEST_F(PassBuilderCTest, Basic) {
LLVMPassBuilderOptionsSetAAPipeline(Options, "basic-aa");
if (LLVMErrorRef E = LLVMRunPasses(Module, "default<O2>", TM, Options)) {
char *Msg = LLVMGetErrorMessage(E);
- LLVMConsumeError(E);
LLVMDisposePassBuilderOptions(Options);
FAIL() << "Failed to run passes: " << Msg;
}
@@ -80,3 +83,14 @@ TEST_F(PassBuilderCTest, InvalidPassIsError) {
LLVMConsumeError(E2);
LLVMDisposePassBuilderOptions(Options);
}
+
+TEST_F(PassBuilderCTest, Function) {
+ LLVMPassBuilderOptionsRef Options = LLVMCreatePassBuilderOptions();
+ if (LLVMErrorRef E =
+ LLVMRunPassesOnFunction(Function, "no-op-function", TM, Options)) {
+ char *Msg = LLVMGetErrorMessage(E);
+ LLVMDisposePassBuilderOptions(Options);
+ FAIL() << "Failed to run passes on function: " << Msg;
+ }
+ LLVMDisposePassBuilderOptions(Options);
+}
More information about the llvm-commits
mailing list