diff options
Diffstat (limited to 'contrib/llvm-project/llvm/lib/Transforms/Scalar/Reg2Mem.cpp')
-rw-r--r-- | contrib/llvm-project/llvm/lib/Transforms/Scalar/Reg2Mem.cpp | 120 |
1 files changed, 66 insertions, 54 deletions
diff --git a/contrib/llvm-project/llvm/lib/Transforms/Scalar/Reg2Mem.cpp b/contrib/llvm-project/llvm/lib/Transforms/Scalar/Reg2Mem.cpp index 0716c1320982..a49b9ad3f62b 100644 --- a/contrib/llvm-project/llvm/lib/Transforms/Scalar/Reg2Mem.cpp +++ b/contrib/llvm-project/llvm/lib/Transforms/Scalar/Reg2Mem.cpp @@ -15,17 +15,23 @@ // //===----------------------------------------------------------------------===// +#include "llvm/Transforms/Scalar/Reg2Mem.h" #include "llvm/ADT/Statistic.h" +#include "llvm/Analysis/LoopInfo.h" #include "llvm/IR/BasicBlock.h" #include "llvm/IR/CFG.h" +#include "llvm/IR/Dominators.h" #include "llvm/IR/Function.h" +#include "llvm/IR/InstIterator.h" #include "llvm/IR/Instructions.h" #include "llvm/IR/LLVMContext.h" #include "llvm/IR/Module.h" +#include "llvm/IR/PassManager.h" #include "llvm/InitializePasses.h" #include "llvm/Pass.h" #include "llvm/Transforms/Scalar.h" #include "llvm/Transforms/Utils.h" +#include "llvm/Transforms/Utils/BasicBlockUtils.h" #include "llvm/Transforms/Utils/Local.h" #include <list> using namespace llvm; @@ -35,43 +41,17 @@ using namespace llvm; STATISTIC(NumRegsDemoted, "Number of registers demoted"); STATISTIC(NumPhisDemoted, "Number of phi-nodes demoted"); -namespace { - struct RegToMem : public FunctionPass { - static char ID; // Pass identification, replacement for typeid - RegToMem() : FunctionPass(ID) { - initializeRegToMemPass(*PassRegistry::getPassRegistry()); - } - - void getAnalysisUsage(AnalysisUsage &AU) const override { - AU.addRequiredID(BreakCriticalEdgesID); - AU.addPreservedID(BreakCriticalEdgesID); - } - - bool valueEscapes(const Instruction *Inst) const { - const BasicBlock *BB = Inst->getParent(); - for (const User *U : Inst->users()) { - const Instruction *UI = cast<Instruction>(U); - if (UI->getParent() != BB || isa<PHINode>(UI)) - return true; - } - return false; - } - - bool runOnFunction(Function &F) override; - }; +static bool valueEscapes(const Instruction &Inst) { + const BasicBlock *BB = Inst.getParent(); + for (const User *U : Inst.users()) { + const Instruction *UI = cast<Instruction>(U); + if (UI->getParent() != BB || isa<PHINode>(UI)) + return true; + } + return false; } -char RegToMem::ID = 0; -INITIALIZE_PASS_BEGIN(RegToMem, "reg2mem", "Demote all values to stack slots", - false, false) -INITIALIZE_PASS_DEPENDENCY(BreakCriticalEdges) -INITIALIZE_PASS_END(RegToMem, "reg2mem", "Demote all values to stack slots", - false, false) - -bool RegToMem::runOnFunction(Function &F) { - if (F.isDeclaration() || skipFunction(F)) - return false; - +static bool runPass(Function &F) { // Insert all new allocas into entry block. BasicBlock *BBEntry = &F.getEntryBlock(); assert(pred_empty(BBEntry) && @@ -90,40 +70,72 @@ bool RegToMem::runOnFunction(Function &F) { // Find the escaped instructions. But don't create stack slots for // allocas in entry block. std::list<Instruction*> WorkList; - for (BasicBlock &ibb : F) - for (BasicBlock::iterator iib = ibb.begin(), iie = ibb.end(); iib != iie; - ++iib) { - if (!(isa<AllocaInst>(iib) && iib->getParent() == BBEntry) && - valueEscapes(&*iib)) { - WorkList.push_front(&*iib); - } - } + for (Instruction &I : instructions(F)) + if (!(isa<AllocaInst>(I) && I.getParent() == BBEntry) && valueEscapes(I)) + WorkList.push_front(&I); // Demote escaped instructions NumRegsDemoted += WorkList.size(); - for (Instruction *ilb : WorkList) - DemoteRegToStack(*ilb, false, AllocaInsertionPoint); + for (Instruction *I : WorkList) + DemoteRegToStack(*I, false, AllocaInsertionPoint); WorkList.clear(); // Find all phi's - for (BasicBlock &ibb : F) - for (BasicBlock::iterator iib = ibb.begin(), iie = ibb.end(); iib != iie; - ++iib) - if (isa<PHINode>(iib)) - WorkList.push_front(&*iib); + for (BasicBlock &BB : F) + for (auto &Phi : BB.phis()) + WorkList.push_front(&Phi); // Demote phi nodes NumPhisDemoted += WorkList.size(); - for (Instruction *ilb : WorkList) - DemotePHIToStack(cast<PHINode>(ilb), AllocaInsertionPoint); + for (Instruction *I : WorkList) + DemotePHIToStack(cast<PHINode>(I), AllocaInsertionPoint); return true; } +PreservedAnalyses RegToMemPass::run(Function &F, FunctionAnalysisManager &AM) { + auto *DT = &AM.getResult<DominatorTreeAnalysis>(F); + auto *LI = &AM.getResult<LoopAnalysis>(F); + unsigned N = SplitAllCriticalEdges(F, CriticalEdgeSplittingOptions(DT, LI)); + bool Changed = runPass(F); + if (N == 0 && !Changed) + return PreservedAnalyses::all(); + PreservedAnalyses PA; + PA.preserve<DominatorTreeAnalysis>(); + PA.preserve<LoopAnalysis>(); + return PA; +} + +namespace { +struct RegToMemLegacy : public FunctionPass { + static char ID; // Pass identification, replacement for typeid + RegToMemLegacy() : FunctionPass(ID) { + initializeRegToMemLegacyPass(*PassRegistry::getPassRegistry()); + } + + void getAnalysisUsage(AnalysisUsage &AU) const override { + AU.addRequiredID(BreakCriticalEdgesID); + AU.addPreservedID(BreakCriticalEdgesID); + } + + bool runOnFunction(Function &F) override { + if (F.isDeclaration() || skipFunction(F)) + return false; + return runPass(F); + } +}; +} // namespace + +char RegToMemLegacy::ID = 0; +INITIALIZE_PASS_BEGIN(RegToMemLegacy, "reg2mem", + "Demote all values to stack slots", false, false) +INITIALIZE_PASS_DEPENDENCY(BreakCriticalEdges) +INITIALIZE_PASS_END(RegToMemLegacy, "reg2mem", + "Demote all values to stack slots", false, false) // createDemoteRegisterToMemory - Provide an entry point to create this pass. -char &llvm::DemoteRegisterToMemoryID = RegToMem::ID; +char &llvm::DemoteRegisterToMemoryID = RegToMemLegacy::ID; FunctionPass *llvm::createDemoteRegisterToMemoryPass() { - return new RegToMem(); + return new RegToMemLegacy(); } |