[llvm] r203391 - [PM] Switch new pass manager from polymorphic_ptr to unique_ptr now that
Aaron Ballman
aaron at aaronballman.com
Sun Mar 9 07:43:54 PDT 2014
This seems to have broken my MSVC 2013 build.
185> PassManagerTest.cpp
185>D:\Program Files (x86)\Microsoft Visual Studio
12.0\VC\include\xmemory0(593): error C2280:
'std::unique_ptr<llvm::FunctionPassManager::FunctionPassConcept,std::default_delete<_Ty>>::unique_ptr(const
std::unique_ptr<_Ty,std::default_delete<_Ty>> &)' : attempting to
reference a deleted function
185> with
185> [
185> _Ty=llvm::FunctionPassManager::FunctionPassConcept
185> ] (E:\llvm\llvm\unittests\IR\PassManagerTest.cpp)
185> D:\Program Files (x86)\Microsoft Visual Studio
12.0\VC\include\memory(1486) : see declaration of
'std::unique_ptr<llvm::FunctionPassManager::FunctionPassConcept,std::default_delete<_Ty>>::unique_ptr'
185> with
185> [
185> _Ty=llvm::FunctionPassManager::FunctionPassConcept
185> ]
185> D:\Program Files (x86)\Microsoft Visual Studio
12.0\VC\include\xmemory0(592) : while compiling class template member
function 'void std::allocator<_Ty>::construct(_Ty *,const _Ty &)'
185> with
185> [
185>
_Ty=std::unique_ptr<llvm::FunctionPassManager::FunctionPassConcept,std::default_delete<llvm::FunctionPassManager::FunctionPassConcept>>
185> ]
185> D:\Program Files (x86)\Microsoft Visual Studio
12.0\VC\include\xmemory0(723) : see reference to function template
instantiation 'void std::allocator<_Ty>::construct(_Ty *,const _Ty &)'
being compiled
185> with
185> [
185>
_Ty=std::unique_ptr<llvm::FunctionPassManager::FunctionPassConcept,std::default_delete<llvm::FunctionPassManager::FunctionPassConcept>>
185> ]
185> D:\Program Files (x86)\Microsoft Visual Studio
12.0\VC\include\type_traits(572) : see reference to class template
instantiation 'std::allocator<_Ty>' being compiled
185> with
185> [
185>
_Ty=std::unique_ptr<llvm::FunctionPassManager::FunctionPassConcept,std::default_delete<llvm::FunctionPassManager::FunctionPassConcept>>
185> ]
185> D:\Program Files (x86)\Microsoft Visual Studio
12.0\VC\include\vector(650) : see reference to class template
instantiation 'std::is_empty<_Alloc>' being compiled
185> with
185> [
185>
_Alloc=std::allocator<std::unique_ptr<llvm::FunctionPassManager::FunctionPassConcept,std::default_delete<llvm::FunctionPassManager::FunctionPassConcept>>>
185> ]
185> E:\llvm\llvm\include\llvm/IR/PassManager.h(437) : see
reference to class template instantiation
'std::vector<std::unique_ptr<llvm::FunctionPassManager::FunctionPassConcept,std::default_delete<_Ty>>,std::allocator<std::unique_ptr<_Ty,std::default_delete<_Ty>>>>'
being compiled
185> with
185> [
185> _Ty=llvm::FunctionPassManager::FunctionPassConcept
185> ]
~Aaron
On Sun, Mar 9, 2014 at 7:49 AM, Chandler Carruth <chandlerc at gmail.com> wrote:
> Author: chandlerc
> Date: Sun Mar 9 06:49:53 2014
> New Revision: 203391
>
> URL: http://llvm.org/viewvc/llvm-project?rev=203391&view=rev
> Log:
> [PM] Switch new pass manager from polymorphic_ptr to unique_ptr now that
> it is available. Also make the move semantics sufficiently correct to
> tolerate move-only passes, as the PassManagers *are* move-only passes.
>
> Modified:
> llvm/trunk/include/llvm/IR/PassManager.h
> llvm/trunk/lib/IR/PassManager.cpp
> llvm/trunk/tools/opt/Passes.cpp
> llvm/trunk/unittests/IR/PassManagerTest.cpp
>
> Modified: llvm/trunk/include/llvm/IR/PassManager.h
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/PassManager.h?rev=203391&r1=203390&r2=203391&view=diff
> ==============================================================================
> --- llvm/trunk/include/llvm/IR/PassManager.h (original)
> +++ llvm/trunk/include/llvm/IR/PassManager.h Sun Mar 9 06:49:53 2014
> @@ -39,12 +39,13 @@
> #define LLVM_IR_PASS_MANAGER_H
>
> #include "llvm/ADT/DenseMap.h"
> +#include "llvm/ADT/STLExtras.h"
> #include "llvm/ADT/SmallPtrSet.h"
> -#include "llvm/ADT/polymorphic_ptr.h"
> #include "llvm/IR/Function.h"
> #include "llvm/IR/Module.h"
> #include "llvm/Support/type_traits.h"
> #include <list>
> +#include <memory>
> #include <vector>
>
> namespace llvm {
> @@ -158,7 +159,6 @@ namespace detail {
> template <typename IRUnitT, typename AnalysisManagerT> struct PassConcept {
> // Boiler plate necessary for the container of derived classes.
> virtual ~PassConcept() {}
> - virtual PassConcept *clone() = 0;
>
> /// \brief The polymorphic API which runs the pass over a given IR entity.
> ///
> @@ -205,7 +205,6 @@ template <typename IRUnitT, typename Ana
> struct PassModel<IRUnitT, AnalysisManagerT, PassT,
> true> : PassConcept<IRUnitT, AnalysisManagerT> {
> PassModel(PassT Pass) : Pass(std::move(Pass)) {}
> - PassModel *clone() override { return new PassModel(Pass); }
> PreservedAnalyses run(IRUnitT IR, AnalysisManagerT *AM) override {
> return Pass.run(IR, AM);
> }
> @@ -219,7 +218,6 @@ template <typename IRUnitT, typename Ana
> struct PassModel<IRUnitT, AnalysisManagerT, PassT,
> false> : PassConcept<IRUnitT, AnalysisManagerT> {
> PassModel(PassT Pass) : Pass(std::move(Pass)) {}
> - PassModel *clone() override { return new PassModel(Pass); }
> PreservedAnalyses run(IRUnitT IR, AnalysisManagerT *AM) override {
> return Pass.run(IR);
> }
> @@ -233,7 +231,6 @@ struct PassModel<IRUnitT, AnalysisManage
> /// to.
> template <typename IRUnitT> struct AnalysisResultConcept {
> virtual ~AnalysisResultConcept() {}
> - virtual AnalysisResultConcept *clone() = 0;
>
> /// \brief Method to try and mark a result as invalid.
> ///
> @@ -281,9 +278,6 @@ template <typename IRUnitT, typename Pas
> struct AnalysisResultModel<IRUnitT, PassT, ResultT,
> false> : AnalysisResultConcept<IRUnitT> {
> AnalysisResultModel(ResultT Result) : Result(std::move(Result)) {}
> - AnalysisResultModel *clone() override {
> - return new AnalysisResultModel(Result);
> - }
>
> /// \brief The model bases invalidation solely on being in the preserved set.
> //
> @@ -303,9 +297,6 @@ template <typename IRUnitT, typename Pas
> struct AnalysisResultModel<IRUnitT, PassT, ResultT,
> true> : AnalysisResultConcept<IRUnitT> {
> AnalysisResultModel(ResultT Result) : Result(std::move(Result)) {}
> - AnalysisResultModel *clone() override {
> - return new AnalysisResultModel(Result);
> - }
>
> /// \brief The model delegates to the \c ResultT method.
> bool invalidate(IRUnitT IR, const PreservedAnalyses &PA) override {
> @@ -322,13 +313,12 @@ struct AnalysisResultModel<IRUnitT, Pass
> template <typename IRUnitT, typename AnalysisManagerT>
> struct AnalysisPassConcept {
> virtual ~AnalysisPassConcept() {}
> - virtual AnalysisPassConcept *clone() = 0;
>
> /// \brief Method to run this analysis over a unit of IR.
> - /// \returns The analysis result object to be queried by users, the caller
> - /// takes ownership.
> - virtual AnalysisResultConcept<IRUnitT> *run(IRUnitT IR,
> - AnalysisManagerT *AM) = 0;
> + /// \returns A unique_ptr to the analysis result object to be queried by
> + /// users.
> + virtual std::unique_ptr<AnalysisResultConcept<IRUnitT>>
> + run(IRUnitT IR, AnalysisManagerT *AM) = 0;
> };
>
> /// \brief Wrapper to model the analysis pass concept.
> @@ -348,7 +338,6 @@ struct AnalysisPassModel<IRUnitT, Analys
> true> : AnalysisPassConcept<IRUnitT,
> AnalysisManagerT> {
> AnalysisPassModel(PassT Pass) : Pass(std::move(Pass)) {}
> - virtual AnalysisPassModel *clone() { return new AnalysisPassModel(Pass); }
>
> // FIXME: Replace PassT::Result with type traits when we use C++11.
> typedef AnalysisResultModel<IRUnitT, PassT, typename PassT::Result>
> @@ -357,8 +346,9 @@ struct AnalysisPassModel<IRUnitT, Analys
> /// \brief The model delegates to the \c PassT::run method.
> ///
> /// The return is wrapped in an \c AnalysisResultModel.
> - virtual ResultModelT *run(IRUnitT IR, AnalysisManagerT *AM) {
> - return new ResultModelT(Pass.run(IR, AM));
> + std::unique_ptr<AnalysisResultConcept<IRUnitT>>
> + run(IRUnitT IR, AnalysisManagerT *AM) override {
> + return make_unique<ResultModelT>(Pass.run(IR, AM));
> }
>
> PassT Pass;
> @@ -371,7 +361,6 @@ struct AnalysisPassModel<IRUnitT, Analys
> false> : AnalysisPassConcept<IRUnitT,
> AnalysisManagerT> {
> AnalysisPassModel(PassT Pass) : Pass(std::move(Pass)) {}
> - AnalysisPassModel *clone() override { return new AnalysisPassModel(Pass); }
>
> // FIXME: Replace PassT::Result with type traits when we use C++11.
> typedef AnalysisResultModel<IRUnitT, PassT, typename PassT::Result>
> @@ -380,8 +369,9 @@ struct AnalysisPassModel<IRUnitT, Analys
> /// \brief The model delegates to the \c PassT::run method.
> ///
> /// The return is wrapped in an \c AnalysisResultModel.
> - ResultModelT *run(IRUnitT IR, AnalysisManagerT *) override {
> - return new ResultModelT(Pass.run(IR));
> + std::unique_ptr<AnalysisResultConcept<IRUnitT>>
> + run(IRUnitT IR, AnalysisManagerT *) override {
> + return make_unique<ResultModelT>(Pass.run(IR));
> }
>
> PassT Pass;
> @@ -393,8 +383,6 @@ class ModuleAnalysisManager;
>
> class ModulePassManager {
> public:
> - explicit ModulePassManager() {}
> -
> /// \brief Run all of the module passes in this module pass manager over
> /// a module.
> ///
> @@ -403,7 +391,7 @@ public:
> PreservedAnalyses run(Module *M, ModuleAnalysisManager *AM = 0);
>
> template <typename ModulePassT> void addPass(ModulePassT Pass) {
> - Passes.push_back(new ModulePassModel<ModulePassT>(std::move(Pass)));
> + Passes.emplace_back(new ModulePassModel<ModulePassT>(std::move(Pass)));
> }
>
> static StringRef name() { return "ModulePassManager"; }
> @@ -415,20 +403,19 @@ private:
> struct ModulePassModel
> : detail::PassModel<Module *, ModuleAnalysisManager, PassT> {
> ModulePassModel(PassT Pass)
> - : detail::PassModel<Module *, ModuleAnalysisManager, PassT>(Pass) {}
> + : detail::PassModel<Module *, ModuleAnalysisManager, PassT>(
> + std::move(Pass)) {}
> };
>
> - std::vector<polymorphic_ptr<ModulePassConcept> > Passes;
> + std::vector<std::unique_ptr<ModulePassConcept>> Passes;
> };
>
> class FunctionAnalysisManager;
>
> class FunctionPassManager {
> public:
> - explicit FunctionPassManager() {}
> -
> template <typename FunctionPassT> void addPass(FunctionPassT Pass) {
> - Passes.push_back(new FunctionPassModel<FunctionPassT>(std::move(Pass)));
> + Passes.emplace_back(new FunctionPassModel<FunctionPassT>(std::move(Pass)));
> }
>
> PreservedAnalyses run(Function *F, FunctionAnalysisManager *AM = 0);
> @@ -443,10 +430,11 @@ private:
> struct FunctionPassModel
> : detail::PassModel<Function *, FunctionAnalysisManager, PassT> {
> FunctionPassModel(PassT Pass)
> - : detail::PassModel<Function *, FunctionAnalysisManager, PassT>(Pass) {}
> + : detail::PassModel<Function *, FunctionAnalysisManager, PassT>(
> + std::move(Pass)) {}
> };
>
> - std::vector<polymorphic_ptr<FunctionPassConcept> > Passes;
> + std::vector<std::unique_ptr<FunctionPassConcept>> Passes;
> };
>
> namespace detail {
> @@ -519,7 +507,7 @@ public:
> assert(!AnalysisPasses.count(PassT::ID()) &&
> "Registered the same analysis pass twice!");
> typedef detail::AnalysisPassModel<IRUnitT, DerivedT, PassT> PassModelT;
> - AnalysisPasses[PassT::ID()] = new PassModelT(std::move(Pass));
> + AnalysisPasses[PassT::ID()].reset(new PassModelT(std::move(Pass)));
> }
>
> /// \brief Invalidate a specific analysis pass for an IR module.
> @@ -558,7 +546,7 @@ protected:
>
> private:
> /// \brief Map type from module analysis pass ID to pass concept pointer.
> - typedef DenseMap<void *, polymorphic_ptr<PassConceptT> > AnalysisPassMapT;
> + typedef DenseMap<void *, std::unique_ptr<PassConceptT>> AnalysisPassMapT;
>
> /// \brief Collection of module analysis passes, indexed by ID.
> AnalysisPassMapT AnalysisPasses;
> @@ -593,7 +581,7 @@ private:
>
> /// \brief Map type from module analysis pass ID to pass result concept pointer.
> typedef DenseMap<void *,
> - polymorphic_ptr<detail::AnalysisResultConcept<Module *> > >
> + std::unique_ptr<detail::AnalysisResultConcept<Module *>>>
> ModuleAnalysisResultMapT;
>
> /// \brief Cache of computed module analysis results for this module.
> @@ -642,8 +630,8 @@ private:
> /// erases. Provides both the pass ID and concept pointer such that it is
> /// half of a bijection and provides storage for the actual result concept.
> typedef std::list<std::pair<
> - void *, polymorphic_ptr<detail::AnalysisResultConcept<Function *> > > >
> - FunctionAnalysisResultListT;
> + void *, std::unique_ptr<detail::AnalysisResultConcept<Function *>>>>
> + FunctionAnalysisResultListT;
>
> /// \brief Map type from function pointer to our custom list type.
> typedef DenseMap<Function *, FunctionAnalysisResultListT>
> @@ -826,7 +814,7 @@ private:
> template <typename FunctionPassT>
> ModuleToFunctionPassAdaptor<FunctionPassT>
> createModuleToFunctionPassAdaptor(FunctionPassT Pass) {
> - return ModuleToFunctionPassAdaptor<FunctionPassT>(std::move(Pass));
> + return std::move(ModuleToFunctionPassAdaptor<FunctionPassT>(std::move(Pass)));
> }
>
> }
>
> Modified: llvm/trunk/lib/IR/PassManager.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/PassManager.cpp?rev=203391&r1=203390&r2=203391&view=diff
> ==============================================================================
> --- llvm/trunk/lib/IR/PassManager.cpp (original)
> +++ llvm/trunk/lib/IR/PassManager.cpp Sun Mar 9 06:49:53 2014
> @@ -45,12 +45,12 @@ ModuleAnalysisManager::getResultImpl(voi
> ModuleAnalysisResultMapT::iterator RI;
> bool Inserted;
> std::tie(RI, Inserted) = ModuleAnalysisResults.insert(std::make_pair(
> - PassID, polymorphic_ptr<detail::AnalysisResultConcept<Module *> >()));
> + PassID, std::unique_ptr<detail::AnalysisResultConcept<Module *>>()));
>
> // If we don't have a cached result for this module, look up the pass and run
> // it to produce a result, which we then add to the cache.
> if (Inserted)
> - RI->second = lookupPass(PassID).run(M, this);
> + RI->second = std::move(lookupPass(PassID).run(M, this));
>
> return *RI->second;
> }
> @@ -122,7 +122,7 @@ FunctionAnalysisManager::getResultImpl(v
> // run it to produce a result, which we then add to the cache.
> if (Inserted) {
> FunctionAnalysisResultListT &ResultList = FunctionAnalysisResultLists[F];
> - ResultList.push_back(std::make_pair(PassID, lookupPass(PassID).run(F, this)));
> + ResultList.emplace_back(PassID, lookupPass(PassID).run(F, this));
> RI->second = std::prev(ResultList.end());
> }
>
>
> Modified: llvm/trunk/tools/opt/Passes.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/opt/Passes.cpp?rev=203391&r1=203390&r2=203391&view=diff
> ==============================================================================
> --- llvm/trunk/tools/opt/Passes.cpp (original)
> +++ llvm/trunk/tools/opt/Passes.cpp Sun Mar 9 06:49:53 2014
> @@ -101,7 +101,7 @@ static bool parseFunctionPassPipeline(Fu
> PipelineText = PipelineText.substr(1);
>
> // Add the nested pass manager with the appropriate adaptor.
> - FPM.addPass(NestedFPM);
> + FPM.addPass(std::move(NestedFPM));
> } else {
> // Otherwise try to parse a pass name.
> size_t End = PipelineText.find_first_of(",)");
> @@ -138,7 +138,7 @@ static bool parseModulePassPipeline(Modu
> PipelineText = PipelineText.substr(1);
>
> // Now add the nested manager as a module pass.
> - MPM.addPass(NestedMPM);
> + MPM.addPass(std::move(NestedMPM));
> } else if (PipelineText.startswith("function(")) {
> FunctionPassManager NestedFPM;
>
> @@ -151,7 +151,7 @@ static bool parseModulePassPipeline(Modu
> PipelineText = PipelineText.substr(1);
>
> // Add the nested pass manager with the appropriate adaptor.
> - MPM.addPass(createModuleToFunctionPassAdaptor(NestedFPM));
> + MPM.addPass(createModuleToFunctionPassAdaptor(std::move(NestedFPM)));
> } else {
> // Otherwise try to parse a pass name.
> size_t End = PipelineText.find_first_of(",)");
> @@ -185,7 +185,7 @@ bool llvm::parsePassPipeline(ModulePassM
> if (!parseFunctionPassPipeline(FPM, PipelineText, VerifyEachPass) ||
> !PipelineText.empty())
> return false;
> - MPM.addPass(createModuleToFunctionPassAdaptor(FPM));
> + MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM)));
> return true;
> }
>
> @@ -201,7 +201,7 @@ bool llvm::parsePassPipeline(ModulePassM
> if (!parseFunctionPassPipeline(FPM, PipelineText, VerifyEachPass) ||
> !PipelineText.empty())
> return false;
> - MPM.addPass(createModuleToFunctionPassAdaptor(FPM));
> + MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM)));
> return true;
> }
>
>
> Modified: llvm/trunk/unittests/IR/PassManagerTest.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/IR/PassManagerTest.cpp?rev=203391&r1=203390&r2=203391&view=diff
> ==============================================================================
> --- llvm/trunk/unittests/IR/PassManagerTest.cpp (original)
> +++ llvm/trunk/unittests/IR/PassManagerTest.cpp Sun Mar 9 06:49:53 2014
> @@ -207,59 +207,69 @@ TEST_F(PassManagerTest, Basic) {
> ModulePassManager MPM;
>
> // Count the runs over a Function.
> - FunctionPassManager FPM1;
> int FunctionPassRunCount1 = 0;
> int AnalyzedInstrCount1 = 0;
> int AnalyzedFunctionCount1 = 0;
> - FPM1.addPass(TestFunctionPass(FunctionPassRunCount1, AnalyzedInstrCount1,
> - AnalyzedFunctionCount1));
> - MPM.addPass(createModuleToFunctionPassAdaptor(FPM1));
> + {
> + FunctionPassManager FPM;
> + FPM.addPass(TestFunctionPass(FunctionPassRunCount1, AnalyzedInstrCount1,
> + AnalyzedFunctionCount1));
> + MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM)));
> + }
>
> // Count the runs over a module.
> int ModulePassRunCount = 0;
> MPM.addPass(TestModulePass(ModulePassRunCount));
>
> // Count the runs over a Function in a separate manager.
> - FunctionPassManager FPM2;
> int FunctionPassRunCount2 = 0;
> int AnalyzedInstrCount2 = 0;
> int AnalyzedFunctionCount2 = 0;
> - FPM2.addPass(TestFunctionPass(FunctionPassRunCount2, AnalyzedInstrCount2,
> - AnalyzedFunctionCount2));
> - MPM.addPass(createModuleToFunctionPassAdaptor(FPM2));
> + {
> + FunctionPassManager FPM;
> + FPM.addPass(TestFunctionPass(FunctionPassRunCount2, AnalyzedInstrCount2,
> + AnalyzedFunctionCount2));
> + MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM)));
> + }
>
> // A third function pass manager but with only preserving intervening passes
> // and with a function pass that invalidates exactly one analysis.
> MPM.addPass(TestPreservingModulePass());
> - FunctionPassManager FPM3;
> int FunctionPassRunCount3 = 0;
> int AnalyzedInstrCount3 = 0;
> int AnalyzedFunctionCount3 = 0;
> - FPM3.addPass(TestFunctionPass(FunctionPassRunCount3, AnalyzedInstrCount3,
> - AnalyzedFunctionCount3));
> - FPM3.addPass(TestInvalidationFunctionPass("f"));
> - MPM.addPass(createModuleToFunctionPassAdaptor(FPM3));
> + {
> + FunctionPassManager FPM;
> + FPM.addPass(TestFunctionPass(FunctionPassRunCount3, AnalyzedInstrCount3,
> + AnalyzedFunctionCount3));
> + FPM.addPass(TestInvalidationFunctionPass("f"));
> + MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM)));
> + }
>
> // A fourth function pass manager but with a minimal intervening passes.
> MPM.addPass(TestMinPreservingModulePass());
> - FunctionPassManager FPM4;
> int FunctionPassRunCount4 = 0;
> int AnalyzedInstrCount4 = 0;
> int AnalyzedFunctionCount4 = 0;
> - FPM4.addPass(TestFunctionPass(FunctionPassRunCount4, AnalyzedInstrCount4,
> - AnalyzedFunctionCount4));
> - MPM.addPass(createModuleToFunctionPassAdaptor(FPM4));
> + {
> + FunctionPassManager FPM;
> + FPM.addPass(TestFunctionPass(FunctionPassRunCount4, AnalyzedInstrCount4,
> + AnalyzedFunctionCount4));
> + MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM)));
> + }
>
> // A fifth function pass manager but which uses only cached results.
> - FunctionPassManager FPM5;
> int FunctionPassRunCount5 = 0;
> int AnalyzedInstrCount5 = 0;
> int AnalyzedFunctionCount5 = 0;
> - FPM5.addPass(TestInvalidationFunctionPass("f"));
> - FPM5.addPass(TestFunctionPass(FunctionPassRunCount5, AnalyzedInstrCount5,
> - AnalyzedFunctionCount5,
> - /*OnlyUseCachedResults=*/true));
> - MPM.addPass(createModuleToFunctionPassAdaptor(FPM5));
> + {
> + FunctionPassManager FPM;
> + FPM.addPass(TestInvalidationFunctionPass("f"));
> + FPM.addPass(TestFunctionPass(FunctionPassRunCount5, AnalyzedInstrCount5,
> + AnalyzedFunctionCount5,
> + /*OnlyUseCachedResults=*/true));
> + MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM)));
> + }
>
> MPM.run(M.get(), &MAM);
>
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
More information about the llvm-commits
mailing list