Skip to content

Commit 00def06

Browse files
authored
[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.
1 parent 74a512d commit 00def06

File tree

4 files changed

+68
-14
lines changed

4 files changed

+68
-14
lines changed

llvm/docs/ReleaseNotes.rst

+6
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,12 @@ Changes to the C API
157157
* ``LLVMGetNamedFunctionWithLength``
158158
* ``LLVMGetNamedGlobalWithLength``
159159

160+
* The new pass manager can now be invoked with a custom alias analysis pipeline, using
161+
the ``LLVMPassBuilderOptionsSetAAPipeline`` function.
162+
163+
* It is now also possible to run the new pass manager on a single function, by calling
164+
``LLVMRunPassesOnFunction`` instead of ``LLVMRunPasses``.
165+
160166
Changes to the CodeGen infrastructure
161167
-------------------------------------
162168

llvm/include/llvm-c/Transforms/PassBuilder.h

+10
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,16 @@ LLVMErrorRef LLVMRunPasses(LLVMModuleRef M, const char *Passes,
5050
LLVMTargetMachineRef TM,
5151
LLVMPassBuilderOptionsRef Options);
5252

53+
/**
54+
* Construct and run a set of passes over a function.
55+
*
56+
* This function behaves the same as LLVMRunPasses, but operates on a single
57+
* function instead of an entire module.
58+
*/
59+
LLVMErrorRef LLVMRunPassesOnFunction(LLVMValueRef F, const char *Passes,
60+
LLVMTargetMachineRef TM,
61+
LLVMPassBuilderOptionsRef Options);
62+
5363
/**
5464
* Create a new set of options for a PassBuilder
5565
*

llvm/lib/Passes/PassBuilderBindings.cpp

+37-13
Original file line numberDiff line numberDiff line change
@@ -48,15 +48,12 @@ static TargetMachine *unwrap(LLVMTargetMachineRef P) {
4848
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(LLVMPassBuilderOptions,
4949
LLVMPassBuilderOptionsRef)
5050

51-
LLVMErrorRef LLVMRunPasses(LLVMModuleRef M, const char *Passes,
52-
LLVMTargetMachineRef TM,
53-
LLVMPassBuilderOptionsRef Options) {
54-
TargetMachine *Machine = unwrap(TM);
55-
LLVMPassBuilderOptions *PassOpts = unwrap(Options);
51+
static LLVMErrorRef runPasses(Module *Mod, Function *Fun, const char *Passes,
52+
TargetMachine *Machine,
53+
LLVMPassBuilderOptions *PassOpts) {
5654
bool Debug = PassOpts->DebugLogging;
5755
bool VerifyEach = PassOpts->VerifyEach;
5856

59-
Module *Mod = unwrap(M);
6057
PassInstrumentationCallbacks PIC;
6158
PassBuilder PB(Machine, PassOpts->PTO, std::nullopt, &PIC);
6259

@@ -80,18 +77,45 @@ LLVMErrorRef LLVMRunPasses(LLVMModuleRef M, const char *Passes,
8077

8178
StandardInstrumentations SI(Mod->getContext(), Debug, VerifyEach);
8279
SI.registerCallbacks(PIC, &MAM);
83-
ModulePassManager MPM;
84-
if (VerifyEach) {
85-
MPM.addPass(VerifierPass());
86-
}
87-
if (auto Err = PB.parsePassPipeline(MPM, Passes)) {
88-
return wrap(std::move(Err));
80+
81+
// Run the pipeline.
82+
if (Fun) {
83+
FunctionPassManager FPM;
84+
if (VerifyEach)
85+
FPM.addPass(VerifierPass());
86+
if (auto Err = PB.parsePassPipeline(FPM, Passes))
87+
return wrap(std::move(Err));
88+
FPM.run(*Fun, FAM);
89+
} else {
90+
ModulePassManager MPM;
91+
if (VerifyEach)
92+
MPM.addPass(VerifierPass());
93+
if (auto Err = PB.parsePassPipeline(MPM, Passes))
94+
return wrap(std::move(Err));
95+
MPM.run(*Mod, MAM);
8996
}
9097

91-
MPM.run(*Mod, MAM);
9298
return LLVMErrorSuccess;
9399
}
94100

101+
LLVMErrorRef LLVMRunPasses(LLVMModuleRef M, const char *Passes,
102+
LLVMTargetMachineRef TM,
103+
LLVMPassBuilderOptionsRef Options) {
104+
TargetMachine *Machine = unwrap(TM);
105+
LLVMPassBuilderOptions *PassOpts = unwrap(Options);
106+
Module *Mod = unwrap(M);
107+
return runPasses(Mod, nullptr, Passes, Machine, PassOpts);
108+
}
109+
110+
LLVMErrorRef LLVMRunPassesOnFunction(LLVMValueRef F, const char *Passes,
111+
LLVMTargetMachineRef TM,
112+
LLVMPassBuilderOptionsRef Options) {
113+
TargetMachine *Machine = unwrap(TM);
114+
LLVMPassBuilderOptions *PassOpts = unwrap(Options);
115+
Function *Fun = unwrap<Function>(F);
116+
return runPasses(Fun->getParent(), Fun, Passes, Machine, PassOpts);
117+
}
118+
95119
LLVMPassBuilderOptionsRef LLVMCreatePassBuilderOptions() {
96120
return wrap(new LLVMPassBuilderOptions());
97121
}

llvm/unittests/Passes/PassBuilderBindings/PassBuilderBindingsTest.cpp

+15-1
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,9 @@ class PassBuilderCTest : public testing::Test {
3535
LLVMDisposeMessage(Triple);
3636
Context = LLVMContextCreate();
3737
Module = LLVMModuleCreateWithNameInContext("test", Context);
38+
LLVMTypeRef FT =
39+
LLVMFunctionType(LLVMVoidTypeInContext(Context), nullptr, 0, 0);
40+
Function = LLVMAddFunction(Module, "test", FT);
3841
}
3942

4043
void TearDown() override {
@@ -52,6 +55,7 @@ class PassBuilderCTest : public testing::Test {
5255
public:
5356
LLVMTargetMachineRef TM;
5457
LLVMModuleRef Module;
58+
LLVMValueRef Function;
5559
LLVMContextRef Context;
5660
};
5761

@@ -63,7 +67,6 @@ TEST_F(PassBuilderCTest, Basic) {
6367
LLVMPassBuilderOptionsSetAAPipeline(Options, "basic-aa");
6468
if (LLVMErrorRef E = LLVMRunPasses(Module, "default<O2>", TM, Options)) {
6569
char *Msg = LLVMGetErrorMessage(E);
66-
LLVMConsumeError(E);
6770
LLVMDisposePassBuilderOptions(Options);
6871
FAIL() << "Failed to run passes: " << Msg;
6972
}
@@ -80,3 +83,14 @@ TEST_F(PassBuilderCTest, InvalidPassIsError) {
8083
LLVMConsumeError(E2);
8184
LLVMDisposePassBuilderOptions(Options);
8285
}
86+
87+
TEST_F(PassBuilderCTest, Function) {
88+
LLVMPassBuilderOptionsRef Options = LLVMCreatePassBuilderOptions();
89+
if (LLVMErrorRef E =
90+
LLVMRunPassesOnFunction(Function, "no-op-function", TM, Options)) {
91+
char *Msg = LLVMGetErrorMessage(E);
92+
LLVMDisposePassBuilderOptions(Options);
93+
FAIL() << "Failed to run passes on function: " << Msg;
94+
}
95+
LLVMDisposePassBuilderOptions(Options);
96+
}

0 commit comments

Comments
 (0)