diff --git a/llvm/include/llvm/InitializePasses.h b/llvm/include/llvm/InitializePasses.h index 1374880b6a716..e50cb0dd7541a 100644 --- a/llvm/include/llvm/InitializePasses.h +++ b/llvm/include/llvm/InitializePasses.h @@ -256,6 +256,7 @@ void initializeRegAllocFastPass(PassRegistry &); void initializeRegAllocPriorityAdvisorAnalysisPass(PassRegistry &); void initializeRegAllocScoringPass(PassRegistry &); void initializeRegBankSelectPass(PassRegistry &); +void initializeRegToMemWrapperPassPass(PassRegistry &); void initializeRegUsageInfoCollectorPass(PassRegistry &); void initializeRegUsageInfoPropagationPass(PassRegistry &); void initializeRegionInfoPassPass(PassRegistry &); diff --git a/llvm/include/llvm/LinkAllPasses.h b/llvm/include/llvm/LinkAllPasses.h index 92b59a66567c9..3516b47d29ef3 100644 --- a/llvm/include/llvm/LinkAllPasses.h +++ b/llvm/include/llvm/LinkAllPasses.h @@ -98,6 +98,7 @@ struct ForcePassLinking { (void)llvm::createNaryReassociatePass(); (void)llvm::createObjCARCContractPass(); (void)llvm::createPromoteMemoryToRegisterPass(); + (void)llvm::createRegToMemWrapperPass(); (void)llvm::createPostDomOnlyPrinterWrapperPassPass(); (void)llvm::createPostDomPrinterWrapperPassPass(); (void)llvm::createPostDomOnlyViewerWrapperPassPass(); diff --git a/llvm/include/llvm/Transforms/Utils.h b/llvm/include/llvm/Transforms/Utils.h index 677cc3d128c3a..ff306dbe35803 100644 --- a/llvm/include/llvm/Transforms/Utils.h +++ b/llvm/include/llvm/Transforms/Utils.h @@ -81,6 +81,14 @@ extern char &LCSSAID; // FunctionPass *createPromoteMemoryToRegisterPass(); +//===----------------------------------------------------------------------===// +// +// RegToMemWrapperPass - This pass is used to demote registers to memory +// references. In basically undoes the PromoteMemoryToRegister pass to make cfg +// hacking easier. +// +FunctionPass *createRegToMemWrapperPass(); + //===----------------------------------------------------------------------===// // // LoopSimplify - Insert Pre-header blocks into the CFG for every function in diff --git a/llvm/lib/Transforms/Scalar/Reg2Mem.cpp b/llvm/lib/Transforms/Scalar/Reg2Mem.cpp index ebc5075aa36fe..30b27cb19b4ad 100644 --- a/llvm/lib/Transforms/Scalar/Reg2Mem.cpp +++ b/llvm/lib/Transforms/Scalar/Reg2Mem.cpp @@ -25,6 +25,7 @@ #include "llvm/IR/InstIterator.h" #include "llvm/IR/Instructions.h" #include "llvm/IR/PassManager.h" +#include "llvm/InitializePasses.h" #include "llvm/Transforms/Scalar.h" #include "llvm/Transforms/Utils.h" #include "llvm/Transforms/Utils/BasicBlockUtils.h" @@ -105,3 +106,45 @@ PreservedAnalyses RegToMemPass::run(Function &F, FunctionAnalysisManager &AM) { PA.preserve(); return PA; } + +namespace llvm { + +void initializeRegToMemWrapperPassPass(PassRegistry &); + +class RegToMemWrapperPass : public FunctionPass { +public: + static char ID; + + RegToMemWrapperPass() : FunctionPass(ID) {} + + void getAnalysisUsage(AnalysisUsage &AU) const override { + AU.setPreservesAll(); + + AU.addPreserved(); + AU.addRequired(); + + AU.addPreserved(); + AU.addRequired(); + } + + bool runOnFunction(Function &F) override { + DominatorTree *DT = &getAnalysis().getDomTree(); + LoopInfo *LI = &getAnalysis().getLoopInfo(); + + unsigned N = SplitAllCriticalEdges(F, CriticalEdgeSplittingOptions(DT, LI)); + bool Changed = runPass(F); + return N != 0 || Changed; + } +}; +} // namespace llvm + +INITIALIZE_PASS_BEGIN(RegToMemWrapperPass, "reg2mem", "", true, true) +INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass); +INITIALIZE_PASS_DEPENDENCY(LoopInfoWrapperPass); +INITIALIZE_PASS_END(RegToMemWrapperPass, "reg2mem", "", true, true) + +char RegToMemWrapperPass::ID = 0; + +FunctionPass *llvm::createRegToMemWrapperPass() { + return new RegToMemWrapperPass(); +}