[llvm] cd220a0 - [NewPM] Add C bindings for new pass manager
Arthur Eubanks via llvm-commits
llvm-commits at lists.llvm.org
Mon May 17 10:49:07 PDT 2021
Author: Mats Larsen
Date: 2021-05-17T10:48:45-07:00
New Revision: cd220a06782c3da13a53de2fdf10d928eef6460c
URL: https://github.com/llvm/llvm-project/commit/cd220a06782c3da13a53de2fdf10d928eef6460c
DIFF: https://github.com/llvm/llvm-project/commit/cd220a06782c3da13a53de2fdf10d928eef6460c.diff
LOG: [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
Added:
llvm/include/llvm-c/Transforms/PassBuilder.h
llvm/lib/Passes/PassBuilderBindings.cpp
llvm/unittests/Passes/PassBuilderBindingsTest.cpp
Modified:
llvm/lib/Passes/CMakeLists.txt
llvm/unittests/Passes/CMakeLists.txt
Removed:
################################################################################
diff --git a/llvm/include/llvm-c/Transforms/PassBuilder.h b/llvm/include/llvm-c/Transforms/PassBuilder.h
new file mode 100644
index 000000000000..4e32900142f2
--- /dev/null
+++ b/llvm/include/llvm-c/Transforms/PassBuilder.h
@@ -0,0 +1,105 @@
+/*===-- llvm-c/Transform/PassBuilder.h - PassBuilder for LLVM C ---*- C -*-===*\
+|* *|
+|* Part of the LLVM Project, under the Apache License v2.0 with LLVM *|
+|* Exceptions. *|
+|* See https://llvm.org/LICENSE.txt for license information. *|
+|* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception *|
+|* *|
+|*===----------------------------------------------------------------------===*|
+|* *|
+|* This header contains the LLVM-C interface into the new pass manager *|
+|* *|
+\*===----------------------------------------------------------------------===*/
+
+#ifndef LLVM_C_TRANSFORMS_PASSBUILDER_H
+#define LLVM_C_TRANSFORMS_PASSBUILDER_H
+
+#include "llvm-c/Error.h"
+#include "llvm-c/TargetMachine.h"
+#include "llvm-c/Types.h"
+
+LLVM_C_EXTERN_C_BEGIN
+
+/**
+ * A set of options passed which are attached to the Pass Manager upon run.
+ *
+ * This corresponds to an llvm::LLVMPassBuilderOptions instance
+ *
+ * The details for how the
diff erent properties of this structure are used can
+ * be found in the source for LLVMRunPasses
+ */
+typedef struct LLVMOpaquePassBuilderOptions *LLVMPassBuilderOptionsRef;
+
+/**
+ * Construct and run a set of passes over a module
+ *
+ * This function takes a string with the passes that should be used. The format
+ * of this string is the same as opt's -passes argument for the new pass
+ * manager. Individual passes may be specified, separated by commas. Full
+ * pipelines may also be invoked using `default<O3>` and friends. See opt for
+ * full reference of the Passes format.
+ */
+LLVMErrorRef LLVMRunPasses(LLVMModuleRef M, const char *Passes,
+ LLVMTargetMachineRef TM,
+ LLVMPassBuilderOptionsRef Options);
+
+/**
+ * Create a new set of options for a PassBuilder
+ *
+ * Ownership of the returned instance is given to the client, and they are
+ * responsible for it. The client should call LLVMDisposePassBuilderOptions
+ * to free the pass builder options.
+ */
+LLVMPassBuilderOptionsRef LLVMCreatePassBuilderOptions();
+
+/**
+ * Toggle adding the VerifierPass for the PassBuilder, ensuring all functions
+ * inside the module is valid.
+ */
+void LLVMPassBuilderOptionsSetVerifyEach(LLVMPassBuilderOptionsRef Options,
+ LLVMBool VerifyEach);
+
+/**
+ * Toggle debug logging when running the PassBuilder
+ */
+void LLVMPassBuilderOptionsSetDebugLogging(LLVMPassBuilderOptionsRef Options,
+ LLVMBool DebugLogging);
+
+void LLVMPassBuilderOptionsSetLoopInterleaving(
+ LLVMPassBuilderOptionsRef Options, LLVMBool LoopInterleaving);
+
+void LLVMPassBuilderOptionsSetLoopVectorization(
+ LLVMPassBuilderOptionsRef Options, LLVMBool LoopVectorization);
+
+void LLVMPassBuilderOptionsSetSLPVectorization(
+ LLVMPassBuilderOptionsRef Options, LLVMBool SLPVectorization);
+
+void LLVMPassBuilderOptionsSetLoopUnrolling(LLVMPassBuilderOptionsRef Options,
+ LLVMBool LoopUnrolling);
+
+void LLVMPassBuilderOptionsSetForgetAllSCEVInLoopUnroll(
+ LLVMPassBuilderOptionsRef Options, LLVMBool ForgetAllSCEVInLoopUnroll);
+
+void LLVMPassBuilderOptionsSetCoroutines(LLVMPassBuilderOptionsRef Options,
+ LLVMBool Coroutines);
+
+void LLVMPassBuilderOptionsSetLicmMssaOptCap(LLVMPassBuilderOptionsRef Options,
+ unsigned LicmMssaOptCap);
+
+void LLVMPassBuilderOptionsSetLicmMssaNoAccForPromotionCap(
+ LLVMPassBuilderOptionsRef Options, unsigned LicmMssaNoAccForPromotionCap);
+
+void LLVMPassBuilderOptionsSetCallGraphProfile(
+ LLVMPassBuilderOptionsRef Options, LLVMBool CallGraphProfile);
+
+void LLVMPassBuilderOptionsSetMergeFunctions(LLVMPassBuilderOptionsRef Options,
+ LLVMBool MergeFunctions);
+
+/**
+ * Dispose of a heap-allocated PassBuilderOptions instance
+ */
+void LLVMDisposePassBuilderOptions(LLVMPassBuilderOptionsRef Options);
+
+LLVM_C_EXTERN_C_END
+
+#endif // LLVM_C_TRANSFORMS_PASSBUILDER_H
diff --git a/llvm/lib/Passes/CMakeLists.txt b/llvm/lib/Passes/CMakeLists.txt
index f517136223ec..89e960f01e2e 100644
--- a/llvm/lib/Passes/CMakeLists.txt
+++ b/llvm/lib/Passes/CMakeLists.txt
@@ -1,5 +1,6 @@
add_llvm_component_library(LLVMPasses
PassBuilder.cpp
+ PassBuilderBindings.cpp
PassPlugin.cpp
StandardInstrumentations.cpp
diff --git a/llvm/lib/Passes/PassBuilderBindings.cpp b/llvm/lib/Passes/PassBuilderBindings.cpp
new file mode 100644
index 000000000000..1a344a4a4954
--- /dev/null
+++ b/llvm/lib/Passes/PassBuilderBindings.cpp
@@ -0,0 +1,149 @@
+//===-------------- PassBuilder bindings for LLVM-C -----------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+/// \file
+///
+/// This file defines the C bindings to the new pass manager
+///
+//===----------------------------------------------------------------------===//
+
+#include "llvm-c/Transforms/PassBuilder.h"
+#include "llvm/IR/Verifier.h"
+#include "llvm/Passes/PassBuilder.h"
+#include "llvm/Passes/StandardInstrumentations.h"
+#include "llvm/Support/CBindingWrapping.h"
+
+using namespace llvm;
+
+namespace llvm {
+/// Helper struct for holding a set of builder options for LLVMRunPasses. This
+/// structure is used to keep LLVMRunPasses backwards compatible with future
+/// versions in case we modify the options the new Pass Manager utilizes.
+class LLVMPassBuilderOptions {
+public:
+ explicit LLVMPassBuilderOptions(
+ bool DebugLogging = false, bool VerifyEach = false,
+ PipelineTuningOptions PTO = PipelineTuningOptions())
+ : DebugLogging(DebugLogging), VerifyEach(VerifyEach), PTO(PTO) {}
+
+ bool DebugLogging;
+ bool VerifyEach;
+ PipelineTuningOptions PTO;
+};
+} // namespace llvm
+
+static TargetMachine *unwrap(LLVMTargetMachineRef P) {
+ return reinterpret_cast<TargetMachine *>(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);
+ bool Debug = PassOpts->DebugLogging;
+ bool VerifyEach = PassOpts->VerifyEach;
+
+ Module *Mod = unwrap(M);
+ PassInstrumentationCallbacks PIC;
+ PassBuilder PB(Debug, Machine, PassOpts->PTO, None, &PIC);
+
+ LoopAnalysisManager LAM(Debug);
+ FunctionAnalysisManager FAM(Debug);
+ CGSCCAnalysisManager CGAM(Debug);
+ ModuleAnalysisManager MAM(Debug);
+ PB.registerLoopAnalyses(LAM);
+ PB.registerFunctionAnalyses(FAM);
+ PB.registerCGSCCAnalyses(CGAM);
+ PB.registerModuleAnalyses(MAM);
+ PB.crossRegisterProxies(LAM, FAM, CGAM, MAM);
+
+ StandardInstrumentations SI(Debug, VerifyEach);
+ SI.registerCallbacks(PIC, &FAM);
+ ModulePassManager MPM(Debug);
+ if (VerifyEach) {
+ MPM.addPass(VerifierPass());
+ }
+ if (auto Err = PB.parsePassPipeline(MPM, Passes)) {
+ return wrap(std::move(Err));
+ }
+
+ MPM.run(*Mod, MAM);
+ return LLVMErrorSuccess;
+}
+
+LLVMPassBuilderOptionsRef LLVMCreatePassBuilderOptions() {
+ return wrap(new LLVMPassBuilderOptions());
+}
+
+void LLVMPassBuilderOptionsSetVerifyEach(LLVMPassBuilderOptionsRef Options,
+ LLVMBool VerifyEach) {
+ unwrap(Options)->VerifyEach = VerifyEach;
+}
+
+void LLVMPassBuilderOptionsSetDebugLogging(LLVMPassBuilderOptionsRef Options,
+ LLVMBool DebugLogging) {
+ unwrap(Options)->DebugLogging = DebugLogging;
+}
+
+void LLVMPassBuilderOptionsSetLoopInterleaving(
+ LLVMPassBuilderOptionsRef Options, LLVMBool LoopInterleaving) {
+ unwrap(Options)->PTO.LoopInterleaving = LoopInterleaving;
+}
+
+void LLVMPassBuilderOptionsSetLoopVectorization(
+ LLVMPassBuilderOptionsRef Options, LLVMBool LoopVectorization) {
+ unwrap(Options)->PTO.LoopVectorization = LoopVectorization;
+}
+
+void LLVMPassBuilderOptionsSetSLPVectorization(
+ LLVMPassBuilderOptionsRef Options, LLVMBool SLPVectorization) {
+ unwrap(Options)->PTO.SLPVectorization = SLPVectorization;
+}
+
+void LLVMPassBuilderOptionsSetLoopUnrolling(LLVMPassBuilderOptionsRef Options,
+ LLVMBool LoopUnrolling) {
+ unwrap(Options)->PTO.LoopUnrolling = LoopUnrolling;
+}
+
+void LLVMPassBuilderOptionsSetForgetAllSCEVInLoopUnroll(
+ LLVMPassBuilderOptionsRef Options, LLVMBool ForgetAllSCEVInLoopUnroll) {
+ unwrap(Options)->PTO.ForgetAllSCEVInLoopUnroll = ForgetAllSCEVInLoopUnroll;
+}
+
+void LLVMPassBuilderOptionsSetCoroutines(LLVMPassBuilderOptionsRef Options,
+ LLVMBool Coroutines) {
+ unwrap(Options)->PTO.Coroutines = Coroutines;
+}
+
+void LLVMPassBuilderOptionsSetLicmMssaOptCap(LLVMPassBuilderOptionsRef Options,
+ unsigned LicmMssaOptCap) {
+ unwrap(Options)->PTO.LicmMssaOptCap = LicmMssaOptCap;
+}
+
+void LLVMPassBuilderOptionsSetLicmMssaNoAccForPromotionCap(
+ LLVMPassBuilderOptionsRef Options, unsigned LicmMssaNoAccForPromotionCap) {
+ unwrap(Options)->PTO.LicmMssaNoAccForPromotionCap =
+ LicmMssaNoAccForPromotionCap;
+}
+
+void LLVMPassBuilderOptionsSetCallGraphProfile(
+ LLVMPassBuilderOptionsRef Options, LLVMBool CallGraphProfile) {
+ unwrap(Options)->PTO.CallGraphProfile = CallGraphProfile;
+}
+
+void LLVMPassBuilderOptionsSetMergeFunctions(LLVMPassBuilderOptionsRef Options,
+ LLVMBool MergeFunctions) {
+ unwrap(Options)->PTO.MergeFunctions = MergeFunctions;
+}
+
+void LLVMDisposePassBuilderOptions(LLVMPassBuilderOptionsRef Options) {
+ delete unwrap(Options);
+}
diff --git a/llvm/unittests/Passes/CMakeLists.txt b/llvm/unittests/Passes/CMakeLists.txt
index 823bc56851fa..c78003dde991 100644
--- a/llvm/unittests/Passes/CMakeLists.txt
+++ b/llvm/unittests/Passes/CMakeLists.txt
@@ -1,5 +1,5 @@
# Needed by LLVM's CMake checks because this file defines multiple targets.
-set(LLVM_OPTIONAL_SOURCES PluginsTest.cpp TestPlugin.cpp)
+set(LLVM_OPTIONAL_SOURCES PluginsTest.cpp TestPlugin.cpp PassBuilderBindingsTest.cpp)
# If plugins are disabled, this test will disable itself at runtime. Otherwise,
# reconfiguring with plugins disabled will leave behind a stale executable.
@@ -34,3 +34,7 @@ if (NOT WIN32)
add_dependencies(TestPlugin intrinsics_gen)
add_dependencies(PluginsTests TestPlugin)
endif()
+
+set(LLVM_LINK_COMPONENTS Support Passes Core Target native)
+add_llvm_unittest(PassesBindingsTests PassBuilderBindingsTest.cpp)
+target_link_libraries(PassesBindingsTests PRIVATE LLVMTestingSupport)
\ No newline at end of file
diff --git a/llvm/unittests/Passes/PassBuilderBindingsTest.cpp b/llvm/unittests/Passes/PassBuilderBindingsTest.cpp
new file mode 100644
index 000000000000..93772c8db2cb
--- /dev/null
+++ b/llvm/unittests/Passes/PassBuilderBindingsTest.cpp
@@ -0,0 +1,67 @@
+//===- unittests/Passes/PassBuilderBindingsTest.cpp -----------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm-c/Core.h"
+#include "llvm-c/Transforms/PassBuilder.h"
+#include "llvm-c/Types.h"
+#include "gtest/gtest.h"
+
+using namespace llvm;
+
+class PassBuilderCTest : public testing::Test {
+ void SetUp() override {
+ LLVMInitializeNativeTarget();
+ const char *Triple = LLVMGetDefaultTargetTriple();
+ char *Err;
+ LLVMTargetRef Target;
+ if (LLVMGetTargetFromTriple(Triple, &Target, &Err)) {
+ FAIL() << "Failed to create target from default triple: " << Err;
+ }
+ TM = LLVMCreateTargetMachine(Target, Triple, "generic", "",
+ LLVMCodeGenLevelDefault, LLVMRelocDefault,
+ LLVMCodeModelDefault);
+ Context = LLVMContextCreate();
+ Module = LLVMModuleCreateWithNameInContext("test", Context);
+ }
+
+ void TearDown() override {
+ LLVMDisposeTargetMachine(TM);
+ LLVMDisposeModule(Module);
+ LLVMContextDispose(Context);
+ }
+
+public:
+ LLVMTargetMachineRef TM;
+ LLVMModuleRef Module;
+ LLVMContextRef Context;
+};
+
+TEST_F(PassBuilderCTest, Basic) {
+ LLVMPassBuilderOptionsRef Options = LLVMCreatePassBuilderOptions();
+ LLVMPassBuilderOptionsSetLoopUnrolling(Options, 1);
+ LLVMPassBuilderOptionsSetVerifyEach(Options, 1);
+ LLVMPassBuilderOptionsSetDebugLogging(Options, 0);
+ if (LLVMErrorRef E = LLVMRunPasses(TM, Module, Options, "default<O2>")) {
+ char *Msg = LLVMGetErrorMessage(E);
+ LLVMConsumeError(E);
+ LLVMDisposePassBuilderOptions(Options);
+ FAIL() << "Failed to run passes: " << Msg;
+ }
+ LLVMDisposePassBuilderOptions(Options);
+}
+
+TEST_F(PassBuilderCTest, InvalidPassIsError) {
+ LLVMPassBuilderOptionsRef Options = LLVMCreatePassBuilderOptions();
+ LLVMErrorRef E1 = LLVMRunPasses(TM, Module, Options, "");
+ LLVMErrorRef E2 = LLVMRunPasses(TM, Module, Options, "does-not-exist-pass");
+ ASSERT_TRUE(E1);
+ ASSERT_TRUE(E2);
+ LLVMConsumeError(E1);
+ LLVMConsumeError(E2);
+ LLVMDisposePassBuilderOptions(Options);
+}
More information about the llvm-commits
mailing list