Skip to content

Commit cd220a0

Browse files
junlarsenaeubanks
authored andcommitted
[NewPM] Add C bindings for new pass manager
This patch contains the bare minimum to run the new Pass Manager from the LLVM-C APIs. It does not feature PGOOptions, PassPlugins or Debugify in its current state. Bugzilla: PR48499 Reviewed By: aeubanks Differential Revision: https://reviews.llvm.org/D102136
1 parent 2182eda commit cd220a0

File tree

5 files changed

+327
-1
lines changed

5 files changed

+327
-1
lines changed
Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
/*===-- llvm-c/Transform/PassBuilder.h - PassBuilder for LLVM C ---*- C -*-===*\
2+
|* *|
3+
|* Part of the LLVM Project, under the Apache License v2.0 with LLVM *|
4+
|* Exceptions. *|
5+
|* See https://llvm.org/LICENSE.txt for license information. *|
6+
|* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception *|
7+
|* *|
8+
|*===----------------------------------------------------------------------===*|
9+
|* *|
10+
|* This header contains the LLVM-C interface into the new pass manager *|
11+
|* *|
12+
\*===----------------------------------------------------------------------===*/
13+
14+
#ifndef LLVM_C_TRANSFORMS_PASSBUILDER_H
15+
#define LLVM_C_TRANSFORMS_PASSBUILDER_H
16+
17+
#include "llvm-c/Error.h"
18+
#include "llvm-c/TargetMachine.h"
19+
#include "llvm-c/Types.h"
20+
21+
LLVM_C_EXTERN_C_BEGIN
22+
23+
/**
24+
* A set of options passed which are attached to the Pass Manager upon run.
25+
*
26+
* This corresponds to an llvm::LLVMPassBuilderOptions instance
27+
*
28+
* The details for how the different properties of this structure are used can
29+
* be found in the source for LLVMRunPasses
30+
*/
31+
typedef struct LLVMOpaquePassBuilderOptions *LLVMPassBuilderOptionsRef;
32+
33+
/**
34+
* Construct and run a set of passes over a module
35+
*
36+
* This function takes a string with the passes that should be used. The format
37+
* of this string is the same as opt's -passes argument for the new pass
38+
* manager. Individual passes may be specified, separated by commas. Full
39+
* pipelines may also be invoked using `default<O3>` and friends. See opt for
40+
* full reference of the Passes format.
41+
*/
42+
LLVMErrorRef LLVMRunPasses(LLVMModuleRef M, const char *Passes,
43+
LLVMTargetMachineRef TM,
44+
LLVMPassBuilderOptionsRef Options);
45+
46+
/**
47+
* Create a new set of options for a PassBuilder
48+
*
49+
* Ownership of the returned instance is given to the client, and they are
50+
* responsible for it. The client should call LLVMDisposePassBuilderOptions
51+
* to free the pass builder options.
52+
*/
53+
LLVMPassBuilderOptionsRef LLVMCreatePassBuilderOptions();
54+
55+
/**
56+
* Toggle adding the VerifierPass for the PassBuilder, ensuring all functions
57+
* inside the module is valid.
58+
*/
59+
void LLVMPassBuilderOptionsSetVerifyEach(LLVMPassBuilderOptionsRef Options,
60+
LLVMBool VerifyEach);
61+
62+
/**
63+
* Toggle debug logging when running the PassBuilder
64+
*/
65+
void LLVMPassBuilderOptionsSetDebugLogging(LLVMPassBuilderOptionsRef Options,
66+
LLVMBool DebugLogging);
67+
68+
void LLVMPassBuilderOptionsSetLoopInterleaving(
69+
LLVMPassBuilderOptionsRef Options, LLVMBool LoopInterleaving);
70+
71+
void LLVMPassBuilderOptionsSetLoopVectorization(
72+
LLVMPassBuilderOptionsRef Options, LLVMBool LoopVectorization);
73+
74+
void LLVMPassBuilderOptionsSetSLPVectorization(
75+
LLVMPassBuilderOptionsRef Options, LLVMBool SLPVectorization);
76+
77+
void LLVMPassBuilderOptionsSetLoopUnrolling(LLVMPassBuilderOptionsRef Options,
78+
LLVMBool LoopUnrolling);
79+
80+
void LLVMPassBuilderOptionsSetForgetAllSCEVInLoopUnroll(
81+
LLVMPassBuilderOptionsRef Options, LLVMBool ForgetAllSCEVInLoopUnroll);
82+
83+
void LLVMPassBuilderOptionsSetCoroutines(LLVMPassBuilderOptionsRef Options,
84+
LLVMBool Coroutines);
85+
86+
void LLVMPassBuilderOptionsSetLicmMssaOptCap(LLVMPassBuilderOptionsRef Options,
87+
unsigned LicmMssaOptCap);
88+
89+
void LLVMPassBuilderOptionsSetLicmMssaNoAccForPromotionCap(
90+
LLVMPassBuilderOptionsRef Options, unsigned LicmMssaNoAccForPromotionCap);
91+
92+
void LLVMPassBuilderOptionsSetCallGraphProfile(
93+
LLVMPassBuilderOptionsRef Options, LLVMBool CallGraphProfile);
94+
95+
void LLVMPassBuilderOptionsSetMergeFunctions(LLVMPassBuilderOptionsRef Options,
96+
LLVMBool MergeFunctions);
97+
98+
/**
99+
* Dispose of a heap-allocated PassBuilderOptions instance
100+
*/
101+
void LLVMDisposePassBuilderOptions(LLVMPassBuilderOptionsRef Options);
102+
103+
LLVM_C_EXTERN_C_END
104+
105+
#endif // LLVM_C_TRANSFORMS_PASSBUILDER_H

llvm/lib/Passes/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
add_llvm_component_library(LLVMPasses
22
PassBuilder.cpp
3+
PassBuilderBindings.cpp
34
PassPlugin.cpp
45
StandardInstrumentations.cpp
56

Lines changed: 149 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,149 @@
1+
//===-------------- PassBuilder bindings for LLVM-C -----------------------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
/// \file
9+
///
10+
/// This file defines the C bindings to the new pass manager
11+
///
12+
//===----------------------------------------------------------------------===//
13+
14+
#include "llvm-c/Transforms/PassBuilder.h"
15+
#include "llvm/IR/Verifier.h"
16+
#include "llvm/Passes/PassBuilder.h"
17+
#include "llvm/Passes/StandardInstrumentations.h"
18+
#include "llvm/Support/CBindingWrapping.h"
19+
20+
using namespace llvm;
21+
22+
namespace llvm {
23+
/// Helper struct for holding a set of builder options for LLVMRunPasses. This
24+
/// structure is used to keep LLVMRunPasses backwards compatible with future
25+
/// versions in case we modify the options the new Pass Manager utilizes.
26+
class LLVMPassBuilderOptions {
27+
public:
28+
explicit LLVMPassBuilderOptions(
29+
bool DebugLogging = false, bool VerifyEach = false,
30+
PipelineTuningOptions PTO = PipelineTuningOptions())
31+
: DebugLogging(DebugLogging), VerifyEach(VerifyEach), PTO(PTO) {}
32+
33+
bool DebugLogging;
34+
bool VerifyEach;
35+
PipelineTuningOptions PTO;
36+
};
37+
} // namespace llvm
38+
39+
static TargetMachine *unwrap(LLVMTargetMachineRef P) {
40+
return reinterpret_cast<TargetMachine *>(P);
41+
}
42+
43+
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(LLVMPassBuilderOptions,
44+
LLVMPassBuilderOptionsRef)
45+
46+
LLVMErrorRef LLVMRunPasses(LLVMModuleRef M, const char *Passes,
47+
LLVMTargetMachineRef TM,
48+
LLVMPassBuilderOptionsRef Options) {
49+
TargetMachine *Machine = unwrap(TM);
50+
LLVMPassBuilderOptions *PassOpts = unwrap(Options);
51+
bool Debug = PassOpts->DebugLogging;
52+
bool VerifyEach = PassOpts->VerifyEach;
53+
54+
Module *Mod = unwrap(M);
55+
PassInstrumentationCallbacks PIC;
56+
PassBuilder PB(Debug, Machine, PassOpts->PTO, None, &PIC);
57+
58+
LoopAnalysisManager LAM(Debug);
59+
FunctionAnalysisManager FAM(Debug);
60+
CGSCCAnalysisManager CGAM(Debug);
61+
ModuleAnalysisManager MAM(Debug);
62+
PB.registerLoopAnalyses(LAM);
63+
PB.registerFunctionAnalyses(FAM);
64+
PB.registerCGSCCAnalyses(CGAM);
65+
PB.registerModuleAnalyses(MAM);
66+
PB.crossRegisterProxies(LAM, FAM, CGAM, MAM);
67+
68+
StandardInstrumentations SI(Debug, VerifyEach);
69+
SI.registerCallbacks(PIC, &FAM);
70+
ModulePassManager MPM(Debug);
71+
if (VerifyEach) {
72+
MPM.addPass(VerifierPass());
73+
}
74+
if (auto Err = PB.parsePassPipeline(MPM, Passes)) {
75+
return wrap(std::move(Err));
76+
}
77+
78+
MPM.run(*Mod, MAM);
79+
return LLVMErrorSuccess;
80+
}
81+
82+
LLVMPassBuilderOptionsRef LLVMCreatePassBuilderOptions() {
83+
return wrap(new LLVMPassBuilderOptions());
84+
}
85+
86+
void LLVMPassBuilderOptionsSetVerifyEach(LLVMPassBuilderOptionsRef Options,
87+
LLVMBool VerifyEach) {
88+
unwrap(Options)->VerifyEach = VerifyEach;
89+
}
90+
91+
void LLVMPassBuilderOptionsSetDebugLogging(LLVMPassBuilderOptionsRef Options,
92+
LLVMBool DebugLogging) {
93+
unwrap(Options)->DebugLogging = DebugLogging;
94+
}
95+
96+
void LLVMPassBuilderOptionsSetLoopInterleaving(
97+
LLVMPassBuilderOptionsRef Options, LLVMBool LoopInterleaving) {
98+
unwrap(Options)->PTO.LoopInterleaving = LoopInterleaving;
99+
}
100+
101+
void LLVMPassBuilderOptionsSetLoopVectorization(
102+
LLVMPassBuilderOptionsRef Options, LLVMBool LoopVectorization) {
103+
unwrap(Options)->PTO.LoopVectorization = LoopVectorization;
104+
}
105+
106+
void LLVMPassBuilderOptionsSetSLPVectorization(
107+
LLVMPassBuilderOptionsRef Options, LLVMBool SLPVectorization) {
108+
unwrap(Options)->PTO.SLPVectorization = SLPVectorization;
109+
}
110+
111+
void LLVMPassBuilderOptionsSetLoopUnrolling(LLVMPassBuilderOptionsRef Options,
112+
LLVMBool LoopUnrolling) {
113+
unwrap(Options)->PTO.LoopUnrolling = LoopUnrolling;
114+
}
115+
116+
void LLVMPassBuilderOptionsSetForgetAllSCEVInLoopUnroll(
117+
LLVMPassBuilderOptionsRef Options, LLVMBool ForgetAllSCEVInLoopUnroll) {
118+
unwrap(Options)->PTO.ForgetAllSCEVInLoopUnroll = ForgetAllSCEVInLoopUnroll;
119+
}
120+
121+
void LLVMPassBuilderOptionsSetCoroutines(LLVMPassBuilderOptionsRef Options,
122+
LLVMBool Coroutines) {
123+
unwrap(Options)->PTO.Coroutines = Coroutines;
124+
}
125+
126+
void LLVMPassBuilderOptionsSetLicmMssaOptCap(LLVMPassBuilderOptionsRef Options,
127+
unsigned LicmMssaOptCap) {
128+
unwrap(Options)->PTO.LicmMssaOptCap = LicmMssaOptCap;
129+
}
130+
131+
void LLVMPassBuilderOptionsSetLicmMssaNoAccForPromotionCap(
132+
LLVMPassBuilderOptionsRef Options, unsigned LicmMssaNoAccForPromotionCap) {
133+
unwrap(Options)->PTO.LicmMssaNoAccForPromotionCap =
134+
LicmMssaNoAccForPromotionCap;
135+
}
136+
137+
void LLVMPassBuilderOptionsSetCallGraphProfile(
138+
LLVMPassBuilderOptionsRef Options, LLVMBool CallGraphProfile) {
139+
unwrap(Options)->PTO.CallGraphProfile = CallGraphProfile;
140+
}
141+
142+
void LLVMPassBuilderOptionsSetMergeFunctions(LLVMPassBuilderOptionsRef Options,
143+
LLVMBool MergeFunctions) {
144+
unwrap(Options)->PTO.MergeFunctions = MergeFunctions;
145+
}
146+
147+
void LLVMDisposePassBuilderOptions(LLVMPassBuilderOptionsRef Options) {
148+
delete unwrap(Options);
149+
}

llvm/unittests/Passes/CMakeLists.txt

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# Needed by LLVM's CMake checks because this file defines multiple targets.
2-
set(LLVM_OPTIONAL_SOURCES PluginsTest.cpp TestPlugin.cpp)
2+
set(LLVM_OPTIONAL_SOURCES PluginsTest.cpp TestPlugin.cpp PassBuilderBindingsTest.cpp)
33

44
# If plugins are disabled, this test will disable itself at runtime. Otherwise,
55
# reconfiguring with plugins disabled will leave behind a stale executable.
@@ -34,3 +34,7 @@ if (NOT WIN32)
3434
add_dependencies(TestPlugin intrinsics_gen)
3535
add_dependencies(PluginsTests TestPlugin)
3636
endif()
37+
38+
set(LLVM_LINK_COMPONENTS Support Passes Core Target native)
39+
add_llvm_unittest(PassesBindingsTests PassBuilderBindingsTest.cpp)
40+
target_link_libraries(PassesBindingsTests PRIVATE LLVMTestingSupport)
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
//===- unittests/Passes/PassBuilderBindingsTest.cpp -----------------------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#include "llvm-c/Core.h"
10+
#include "llvm-c/Transforms/PassBuilder.h"
11+
#include "llvm-c/Types.h"
12+
#include "gtest/gtest.h"
13+
14+
using namespace llvm;
15+
16+
class PassBuilderCTest : public testing::Test {
17+
void SetUp() override {
18+
LLVMInitializeNativeTarget();
19+
const char *Triple = LLVMGetDefaultTargetTriple();
20+
char *Err;
21+
LLVMTargetRef Target;
22+
if (LLVMGetTargetFromTriple(Triple, &Target, &Err)) {
23+
FAIL() << "Failed to create target from default triple: " << Err;
24+
}
25+
TM = LLVMCreateTargetMachine(Target, Triple, "generic", "",
26+
LLVMCodeGenLevelDefault, LLVMRelocDefault,
27+
LLVMCodeModelDefault);
28+
Context = LLVMContextCreate();
29+
Module = LLVMModuleCreateWithNameInContext("test", Context);
30+
}
31+
32+
void TearDown() override {
33+
LLVMDisposeTargetMachine(TM);
34+
LLVMDisposeModule(Module);
35+
LLVMContextDispose(Context);
36+
}
37+
38+
public:
39+
LLVMTargetMachineRef TM;
40+
LLVMModuleRef Module;
41+
LLVMContextRef Context;
42+
};
43+
44+
TEST_F(PassBuilderCTest, Basic) {
45+
LLVMPassBuilderOptionsRef Options = LLVMCreatePassBuilderOptions();
46+
LLVMPassBuilderOptionsSetLoopUnrolling(Options, 1);
47+
LLVMPassBuilderOptionsSetVerifyEach(Options, 1);
48+
LLVMPassBuilderOptionsSetDebugLogging(Options, 0);
49+
if (LLVMErrorRef E = LLVMRunPasses(TM, Module, Options, "default<O2>")) {
50+
char *Msg = LLVMGetErrorMessage(E);
51+
LLVMConsumeError(E);
52+
LLVMDisposePassBuilderOptions(Options);
53+
FAIL() << "Failed to run passes: " << Msg;
54+
}
55+
LLVMDisposePassBuilderOptions(Options);
56+
}
57+
58+
TEST_F(PassBuilderCTest, InvalidPassIsError) {
59+
LLVMPassBuilderOptionsRef Options = LLVMCreatePassBuilderOptions();
60+
LLVMErrorRef E1 = LLVMRunPasses(TM, Module, Options, "");
61+
LLVMErrorRef E2 = LLVMRunPasses(TM, Module, Options, "does-not-exist-pass");
62+
ASSERT_TRUE(E1);
63+
ASSERT_TRUE(E2);
64+
LLVMConsumeError(E1);
65+
LLVMConsumeError(E2);
66+
LLVMDisposePassBuilderOptions(Options);
67+
}

0 commit comments

Comments
 (0)