llvm-project/llvm/lib/Passes/PassPlugin.cpp
Philip Pfaffe e8f3ae9da0 [Plugins] Add a slim plugin API to work together with the new PM
Summary:
Add a new plugin API. This closes the gap between pass registration and out-of-tree passes for the new PassManager.

Unlike with the existing API, interaction with a plugin is always
initiated from the tools perspective. I.e., when a plugin is loaded, it
resolves and calls a well-known symbol `llvmGetPassPluginInfo` to obtain
details about the plugin. The fundamental motivation is to get rid of as
many global constructors as possible.  The API exposed by the plugin
info is kept intentionally minimal.

Reviewers: chandlerc

Reviewed By: chandlerc

Subscribers: bollu, grosser, lksbhm, mgorny, llvm-commits

Differential Revision: https://reviews.llvm.org/D35258

llvm-svn: 329273
2018-04-05 11:29:37 +00:00

51 lines
1.9 KiB
C++

//===- lib/Passes/PassPluginLoader.cpp - Load Plugins for New PM Passes ---===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include "llvm/Passes/PassPlugin.h"
#include "llvm/Support/raw_ostream.h"
using namespace llvm;
Expected<PassPlugin> PassPlugin::Load(const std::string &Filename) {
std::string Error;
auto Library =
sys::DynamicLibrary::getPermanentLibrary(Filename.c_str(), &Error);
if (!Library.isValid())
return make_error<StringError>(Twine("Could not load library '") +
Filename + "': " + Error,
inconvertibleErrorCode());
PassPlugin P{Filename, Library};
auto *getDetailsFn =
Library.SearchForAddressOfSymbol("llvmGetPassPluginInfo");
if (!getDetailsFn)
// If the symbol isn't found, this is probably a legacy plugin, which is an
// error
return make_error<StringError>(Twine("Plugin entry point not found in '") +
Filename + "'. Is this a legacy plugin?",
inconvertibleErrorCode());
P.Info = reinterpret_cast<decltype(llvmGetPassPluginInfo) *>(getDetailsFn)();
if (P.Info.APIVersion != LLVM_PLUGIN_API_VERSION)
return make_error<StringError>(
Twine("Wrong API version on plugin '") + Filename + "'. Got version " +
Twine(P.Info.APIVersion) + ", supported version is " +
Twine(LLVM_PLUGIN_API_VERSION) + ".",
inconvertibleErrorCode());
if (!P.Info.RegisterPassBuilderCallbacks)
return make_error<StringError>(Twine("Empty entry callback in plugin '") +
Filename + "'.'",
inconvertibleErrorCode());
return P;
}