mirror of
https://github.com/RPCSX/llvm.git
synced 2024-12-02 16:56:50 +00:00
Force RegisterStandardPasses to construct std::function in the IPO library.
Summary: Fixes an issue using RegisterStandardPasses from a statically linked object before PassManagerBuilder::addGlobalExtension is called from a dynamic library. Reviewers: efriedma, theraven Reviewed By: efriedma Subscribers: mehdi_amini, mgorny, llvm-commits Differential Revision: https://reviews.llvm.org/D33515 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@305303 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
7cc2615d1b
commit
4ed42e9451
@ -60,9 +60,10 @@ class PassManagerBuilder {
|
||||
public:
|
||||
/// Extensions are passed the builder itself (so they can see how it is
|
||||
/// configured) as well as the pass manager to add stuff to.
|
||||
typedef std::function<void(const PassManagerBuilder &Builder,
|
||||
legacy::PassManagerBase &PM)>
|
||||
ExtensionFn;
|
||||
typedef void ExtensionProc(const PassManagerBuilder &Builder,
|
||||
legacy::PassManagerBase &PM);
|
||||
typedef std::function<ExtensionProc> ExtensionFn;
|
||||
|
||||
enum ExtensionPointTy {
|
||||
/// EP_EarlyAsPossible - This extension point allows adding passes before
|
||||
/// any other transformations, allowing them to see the code as it is coming
|
||||
@ -179,7 +180,7 @@ public:
|
||||
/// Adds an extension that will be used by all PassManagerBuilder instances.
|
||||
/// This is intended to be used by plugins, to register a set of
|
||||
/// optimisations to run automatically.
|
||||
static void addGlobalExtension(ExtensionPointTy Ty, ExtensionFn Fn);
|
||||
static void addGlobalExtension(ExtensionPointTy Ty, ExtensionProc Fn);
|
||||
void addExtension(ExtensionPointTy Ty, ExtensionFn Fn);
|
||||
|
||||
private:
|
||||
@ -208,10 +209,12 @@ public:
|
||||
/// used by optimizer plugins to allow all front ends to transparently use
|
||||
/// them. Create a static instance of this class in your plugin, providing a
|
||||
/// private function that the PassManagerBuilder can use to add your passes.
|
||||
/// Currently limited to real functions to avoid crashes when used within the
|
||||
/// main executable before a loaded plugin has a chance to use this.
|
||||
struct RegisterStandardPasses {
|
||||
RegisterStandardPasses(PassManagerBuilder::ExtensionPointTy Ty,
|
||||
PassManagerBuilder::ExtensionFn Fn) {
|
||||
PassManagerBuilder::addGlobalExtension(Ty, std::move(Fn));
|
||||
PassManagerBuilder::ExtensionProc Fn) {
|
||||
PassManagerBuilder::addGlobalExtension(Ty, Fn);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -198,10 +198,9 @@ PassManagerBuilder::~PassManagerBuilder() {
|
||||
static ManagedStatic<SmallVector<std::pair<PassManagerBuilder::ExtensionPointTy,
|
||||
PassManagerBuilder::ExtensionFn>, 8> > GlobalExtensions;
|
||||
|
||||
void PassManagerBuilder::addGlobalExtension(
|
||||
PassManagerBuilder::ExtensionPointTy Ty,
|
||||
PassManagerBuilder::ExtensionFn Fn) {
|
||||
GlobalExtensions->push_back(std::make_pair(Ty, std::move(Fn)));
|
||||
void PassManagerBuilder::addGlobalExtension(ExtensionPointTy Ty,
|
||||
ExtensionProc Fn) {
|
||||
GlobalExtensions->push_back(std::make_pair(Ty, Fn));
|
||||
}
|
||||
|
||||
void PassManagerBuilder::addExtension(ExtensionPointTy Ty, ExtensionFn Fn) {
|
||||
|
@ -1,4 +1,4 @@
|
||||
set(LLVM_LINK_COMPONENTS Support)
|
||||
set(LLVM_LINK_COMPONENTS Support IPO)
|
||||
|
||||
add_library(DynamicLibraryLib STATIC ExportedFuncs.cxx)
|
||||
|
||||
|
@ -12,6 +12,7 @@
|
||||
#include "llvm/Support/FileSystem.h"
|
||||
#include "llvm/Support/ManagedStatic.h"
|
||||
#include "llvm/Support/Path.h"
|
||||
#include "llvm/Transforms/IPO/PassManagerBuilder.h"
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
#include "PipSqueak.h"
|
||||
@ -52,6 +53,28 @@ template <class T> static void* PtrFunc(T *Func) {
|
||||
return Tmp.P;
|
||||
}
|
||||
|
||||
static void
|
||||
NoPassRegistration(const PassManagerBuilder &, legacy::PassManagerBase &) {
|
||||
}
|
||||
|
||||
static RegisterStandardPasses LocalPass(PassManagerBuilder::EP_LoopOptimizerEnd,
|
||||
NoPassRegistration);
|
||||
|
||||
typedef void (*TestPassReg)(void (*)(PassManagerBuilder::ExtensionPointTy,
|
||||
PassManagerBuilder::ExtensionProc));
|
||||
|
||||
TEST(DynamicLibrary, PassRegistration) {
|
||||
std::string Err;
|
||||
llvm_shutdown_obj Shutdown;
|
||||
DynamicLibrary DL =
|
||||
DynamicLibrary::getPermanentLibrary(LibPath().c_str(), &Err);
|
||||
EXPECT_TRUE(DL.isValid());
|
||||
EXPECT_TRUE(Err.empty());
|
||||
|
||||
TestPassReg RP = FuncPtr<TestPassReg>(DL.getAddressOfSymbol("TestPassReg"));
|
||||
RP(&PassManagerBuilder::addGlobalExtension);
|
||||
}
|
||||
|
||||
static const char *OverloadTestA() { return "OverloadCall"; }
|
||||
|
||||
std::string StdString(const char *Ptr) { return Ptr ? Ptr : ""; }
|
||||
|
@ -8,6 +8,10 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "PipSqueak.h"
|
||||
#include "llvm/Transforms/IPO/PassManagerBuilder.h"
|
||||
|
||||
#define PIPSQUEAK_TESTA_RETURN "LibCall"
|
||||
#include "ExportedFuncs.cxx"
|
||||
|
||||
struct Global {
|
||||
std::string *Str;
|
||||
@ -45,5 +49,13 @@ extern "C" PIPSQUEAK_EXPORT void TestOrder(std::vector<std::string> &V) {
|
||||
Glb.Vec = &V;
|
||||
}
|
||||
|
||||
#define PIPSQUEAK_TESTA_RETURN "LibCall"
|
||||
#include "ExportedFuncs.cxx"
|
||||
|
||||
static void LibPassRegistration(const llvm::PassManagerBuilder &,
|
||||
llvm::legacy::PassManagerBase &) {}
|
||||
|
||||
extern "C" PIPSQUEAK_EXPORT void TestPassReg(
|
||||
void (*addGlobalExtension)(llvm::PassManagerBuilder::ExtensionPointTy,
|
||||
llvm::PassManagerBuilder::ExtensionProc)) {
|
||||
addGlobalExtension(llvm::PassManagerBuilder::EP_EarlyAsPossible,
|
||||
LibPassRegistration);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user