mirror of
https://github.com/RPCS3/llvm.git
synced 2025-04-14 20:10:58 +00:00

a function's CFG when that CFG is unchanged. This allows transformation passes to simply claim they preserve the CFG and analysis passes to check for the CFG being preserved to remove the fanout of all analyses being listed in all passes. I've gone through and removed or cleaned up as many of the comments reminding us to do this as I could. Differential Revision: https://reviews.llvm.org/D28627 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@292054 91177308-0d34-0410-b5e6-96231b3b80d8
109 lines
3.6 KiB
C++
109 lines
3.6 KiB
C++
//===- Mem2Reg.cpp - The -mem2reg pass, a wrapper around the Utils lib ----===//
|
|
//
|
|
// The LLVM Compiler Infrastructure
|
|
//
|
|
// This file is distributed under the University of Illinois Open Source
|
|
// License. See LICENSE.TXT for details.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
//
|
|
// This pass is a simple pass wrapper around the PromoteMemToReg function call
|
|
// exposed by the Utils library.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#include "llvm/Transforms/Utils/Mem2Reg.h"
|
|
#include "llvm/ADT/Statistic.h"
|
|
#include "llvm/Analysis/AssumptionCache.h"
|
|
#include "llvm/IR/Dominators.h"
|
|
#include "llvm/IR/Function.h"
|
|
#include "llvm/IR/Instructions.h"
|
|
#include "llvm/Transforms/Scalar.h"
|
|
#include "llvm/Transforms/Utils/PromoteMemToReg.h"
|
|
#include "llvm/Transforms/Utils/UnifyFunctionExitNodes.h"
|
|
using namespace llvm;
|
|
|
|
#define DEBUG_TYPE "mem2reg"
|
|
|
|
STATISTIC(NumPromoted, "Number of alloca's promoted");
|
|
|
|
static bool promoteMemoryToRegister(Function &F, DominatorTree &DT,
|
|
AssumptionCache &AC) {
|
|
std::vector<AllocaInst *> Allocas;
|
|
BasicBlock &BB = F.getEntryBlock(); // Get the entry node for the function
|
|
bool Changed = false;
|
|
|
|
while (1) {
|
|
Allocas.clear();
|
|
|
|
// Find allocas that are safe to promote, by looking at all instructions in
|
|
// the entry node
|
|
for (BasicBlock::iterator I = BB.begin(), E = --BB.end(); I != E; ++I)
|
|
if (AllocaInst *AI = dyn_cast<AllocaInst>(I)) // Is it an alloca?
|
|
if (isAllocaPromotable(AI))
|
|
Allocas.push_back(AI);
|
|
|
|
if (Allocas.empty())
|
|
break;
|
|
|
|
PromoteMemToReg(Allocas, DT, nullptr, &AC);
|
|
NumPromoted += Allocas.size();
|
|
Changed = true;
|
|
}
|
|
return Changed;
|
|
}
|
|
|
|
PreservedAnalyses PromotePass::run(Function &F, FunctionAnalysisManager &AM) {
|
|
auto &DT = AM.getResult<DominatorTreeAnalysis>(F);
|
|
auto &AC = AM.getResult<AssumptionAnalysis>(F);
|
|
if (!promoteMemoryToRegister(F, DT, AC))
|
|
return PreservedAnalyses::all();
|
|
|
|
PreservedAnalyses PA;
|
|
PA.preserveSet<CFGAnalyses>();
|
|
return PA;
|
|
}
|
|
|
|
namespace {
|
|
struct PromoteLegacyPass : public FunctionPass {
|
|
static char ID; // Pass identification, replacement for typeid
|
|
PromoteLegacyPass() : FunctionPass(ID) {
|
|
initializePromoteLegacyPassPass(*PassRegistry::getPassRegistry());
|
|
}
|
|
|
|
// runOnFunction - To run this pass, first we calculate the alloca
|
|
// instructions that are safe for promotion, then we promote each one.
|
|
//
|
|
bool runOnFunction(Function &F) override {
|
|
if (skipFunction(F))
|
|
return false;
|
|
|
|
DominatorTree &DT = getAnalysis<DominatorTreeWrapperPass>().getDomTree();
|
|
AssumptionCache &AC =
|
|
getAnalysis<AssumptionCacheTracker>().getAssumptionCache(F);
|
|
return promoteMemoryToRegister(F, DT, AC);
|
|
}
|
|
|
|
void getAnalysisUsage(AnalysisUsage &AU) const override {
|
|
AU.addRequired<AssumptionCacheTracker>();
|
|
AU.addRequired<DominatorTreeWrapperPass>();
|
|
AU.setPreservesCFG();
|
|
}
|
|
};
|
|
} // end of anonymous namespace
|
|
|
|
char PromoteLegacyPass::ID = 0;
|
|
INITIALIZE_PASS_BEGIN(PromoteLegacyPass, "mem2reg", "Promote Memory to "
|
|
"Register",
|
|
false, false)
|
|
INITIALIZE_PASS_DEPENDENCY(AssumptionCacheTracker)
|
|
INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
|
|
INITIALIZE_PASS_END(PromoteLegacyPass, "mem2reg", "Promote Memory to Register",
|
|
false, false)
|
|
|
|
// createPromoteMemoryToRegister - Provide an entry point to create this pass.
|
|
//
|
|
FunctionPass *llvm::createPromoteMemoryToRegisterPass() {
|
|
return new PromoteLegacyPass();
|
|
}
|