Skip to content

Commit 46de6fb

Browse files
committed
[LLVM][NewPM] Add C API for running the pipeline on a single function.
Also removes erroneous LLVMConsumeError from the pass builder tests as the string conversion already consumes the error.
1 parent 83879f4 commit 46de6fb

File tree

3 files changed

+66
-12
lines changed

3 files changed

+66
-12
lines changed

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

Lines changed: 10 additions & 0 deletions
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

Lines changed: 41 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -48,15 +48,24 @@ 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) {
51+
LLVMErrorRef RunPasses(LLVMModuleRef M, LLVMValueRef F, const char *Passes,
52+
LLVMTargetMachineRef TM,
53+
LLVMPassBuilderOptionsRef Options) {
5454
TargetMachine *Machine = unwrap(TM);
5555
LLVMPassBuilderOptions *PassOpts = unwrap(Options);
5656
bool Debug = PassOpts->DebugLogging;
5757
bool VerifyEach = PassOpts->VerifyEach;
5858

59-
Module *Mod = unwrap(M);
59+
// Determine what to run passes on.
60+
Module *Mod;
61+
Function *Fun = nullptr;
62+
if (F) {
63+
Fun = unwrap<Function>(F);
64+
Mod = Fun->getParent();
65+
} else {
66+
Mod = unwrap(M);
67+
}
68+
6069
PassInstrumentationCallbacks PIC;
6170
PassBuilder PB(Machine, PassOpts->PTO, std::nullopt, &PIC);
6271

@@ -80,18 +89,39 @@ LLVMErrorRef LLVMRunPasses(LLVMModuleRef M, const char *Passes,
8089

8190
StandardInstrumentations SI(Mod->getContext(), Debug, VerifyEach);
8291
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));
92+
93+
// Run the pipeline.
94+
if (Fun) {
95+
FunctionPassManager FPM;
96+
if (VerifyEach)
97+
FPM.addPass(VerifierPass());
98+
if (auto Err = PB.parsePassPipeline(FPM, Passes))
99+
return wrap(std::move(Err));
100+
FPM.run(*Fun, FAM);
101+
} else {
102+
ModulePassManager MPM;
103+
if (VerifyEach)
104+
MPM.addPass(VerifierPass());
105+
if (auto Err = PB.parsePassPipeline(MPM, Passes))
106+
return wrap(std::move(Err));
107+
MPM.run(*Mod, MAM);
89108
}
90109

91-
MPM.run(*Mod, MAM);
92110
return LLVMErrorSuccess;
93111
}
94112

113+
LLVMErrorRef LLVMRunPasses(LLVMModuleRef M, const char *Passes,
114+
LLVMTargetMachineRef TM,
115+
LLVMPassBuilderOptionsRef Options) {
116+
return RunPasses(M, nullptr, Passes, TM, Options);
117+
}
118+
119+
LLVMErrorRef LLVMRunPassesOnFunction(LLVMValueRef F, const char *Passes,
120+
LLVMTargetMachineRef TM,
121+
LLVMPassBuilderOptionsRef Options) {
122+
return RunPasses(nullptr, F, Passes, TM, Options);
123+
}
124+
95125
LLVMPassBuilderOptionsRef LLVMCreatePassBuilderOptions() {
96126
return wrap(new LLVMPassBuilderOptions());
97127
}

llvm/unittests/Passes/PassBuilderBindings/PassBuilderBindingsTest.cpp

Lines changed: 15 additions & 1 deletion
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)