diff --git a/llvm/include/llvm/Analysis/StackSafetyAnalysis.h b/llvm/include/llvm/Analysis/StackSafetyAnalysis.h index 33a4b2c149c36..df7ccac5b4b92 100644 --- a/llvm/include/llvm/Analysis/StackSafetyAnalysis.h +++ b/llvm/include/llvm/Analysis/StackSafetyAnalysis.h @@ -18,6 +18,8 @@ namespace llvm { +class AllocaInst; + /// Interface to access stack safety analysis results for single function. class StackSafetyInfo { public: @@ -38,6 +40,22 @@ class StackSafetyInfo { void print(raw_ostream &O, const GlobalValue &F) const; }; +class StackSafetyGlobalInfo { +public: + using GVToSSI = std::map; + +private: + GVToSSI SSGI; + +public: + StackSafetyGlobalInfo() = default; + StackSafetyGlobalInfo(GVToSSI SSGI) : SSGI(std::move(SSGI)) {} + + bool setMetadata(Module &M) const; + void print(raw_ostream &O) const; + void dump() const; +}; + /// StackSafetyInfo wrapper for the new pass manager. class StackSafetyAnalysis : public AnalysisInfoMixin { friend AnalysisInfoMixin; @@ -74,8 +92,6 @@ class StackSafetyInfoWrapperPass : public FunctionPass { bool runOnFunction(Function &F) override; }; -using StackSafetyGlobalInfo = std::map; - /// This pass performs the global (interprocedural) stack safety analysis (new /// pass manager). class StackSafetyGlobalAnalysis diff --git a/llvm/lib/Analysis/StackSafetyAnalysis.cpp b/llvm/lib/Analysis/StackSafetyAnalysis.cpp index d33efa5d1d042..6eeffe6066dfc 100644 --- a/llvm/lib/Analysis/StackSafetyAnalysis.cpp +++ b/llvm/lib/Analysis/StackSafetyAnalysis.cpp @@ -33,6 +33,8 @@ static cl::opt StackSafetyMaxIterations("stack-safety-max-iterations", namespace { +using GVToSSI = StackSafetyGlobalInfo::GVToSSI; + /// Rewrite an SCEV expression for a memory access address to an expression that /// represents offset from the given alloca. class AllocaOffsetRewriter : public SCEVRewriteVisitor { @@ -457,7 +459,7 @@ class StackSafetyDataFlowAnalysis { public: StackSafetyDataFlowAnalysis( Module &M, std::function FI); - StackSafetyGlobalInfo run(); + GVToSSI run(); }; StackSafetyDataFlowAnalysis::StackSafetyDataFlowAnalysis( @@ -571,19 +573,18 @@ void StackSafetyDataFlowAnalysis::verifyFixedPoint() { } #endif -StackSafetyGlobalInfo StackSafetyDataFlowAnalysis::run() { +GVToSSI StackSafetyDataFlowAnalysis::run() { runDataFlow(); LLVM_DEBUG(verifyFixedPoint()); - StackSafetyGlobalInfo SSI; + GVToSSI SSI; for (auto &F : Functions) SSI.emplace(F.first, makeSSI(F.second)); return SSI; } -bool setStackSafetyMetadata(Module &M, const StackSafetyGlobalInfo &SSGI) { +bool setStackSafetyMetadata(Module &M, const GVToSSI &SSGI) { bool Changed = false; - unsigned Width = M.getDataLayout().getPointerSizeInBits(); for (auto &F : M.functions()) { if (F.isDeclaration() || F.hasOptNone()) continue; @@ -621,23 +622,28 @@ void StackSafetyInfo::print(raw_ostream &O, const GlobalValue &F) const { Info->Info.print(O, F.getName(), dyn_cast(&F)); } -static void print(const StackSafetyGlobalInfo &SSI, raw_ostream &O, - const Module &M) { - size_t Count = 0; - for (auto &F : M.functions()) +bool StackSafetyGlobalInfo::setMetadata(Module &M) const { + return setStackSafetyMetadata(M, SSGI); +} + +void StackSafetyGlobalInfo::print(raw_ostream &O) const { + if (SSGI.empty()) + return; + const Module &M = *SSGI.begin()->first->getParent(); + for (auto &F : M.functions()) { if (!F.isDeclaration()) { - SSI.find(&F)->second.print(O, F); + SSGI.find(&F)->second.print(O, F); O << "\n"; - ++Count; } + } for (auto &A : M.aliases()) { - SSI.find(&A)->second.print(O, A); + SSGI.find(&A)->second.print(O, A); O << "\n"; - ++Count; } - assert(Count == SSI.size() && "Unexpected functions in the result"); } +LLVM_DUMP_METHOD void StackSafetyGlobalInfo::dump() const { print(dbgs()); } + AnalysisKey StackSafetyAnalysis::Key; StackSafetyInfo StackSafetyAnalysis::run(Function &F, @@ -693,14 +699,14 @@ StackSafetyGlobalAnalysis::run(Module &M, ModuleAnalysisManager &AM) { PreservedAnalyses StackSafetyGlobalPrinterPass::run(Module &M, ModuleAnalysisManager &AM) { OS << "'Stack Safety Analysis' for module '" << M.getName() << "'\n"; - print(AM.getResult(M), OS, M); + AM.getResult(M).print(OS); return PreservedAnalyses::all(); } PreservedAnalyses StackSafetyGlobalAnnotatorPass::run(Module &M, ModuleAnalysisManager &AM) { auto &SSGI = AM.getResult(M); - (void)setStackSafetyMetadata(M, SSGI); + SSGI.setMetadata(M); return PreservedAnalyses::all(); } @@ -715,7 +721,7 @@ StackSafetyGlobalInfoWrapperPass::StackSafetyGlobalInfoWrapperPass( void StackSafetyGlobalInfoWrapperPass::print(raw_ostream &O, const Module *M) const { - ::print(SSGI, O, *M); + SSGI.print(O); } void StackSafetyGlobalInfoWrapperPass::getAnalysisUsage( @@ -732,7 +738,7 @@ bool StackSafetyGlobalInfoWrapperPass::runOnModule(Module &M) { .Info; }); SSGI = SSDFA.run(); - return SetMetadata ? setStackSafetyMetadata(M, SSGI) : false; + return SetMetadata ? SSGI.setMetadata(M) : false; } ModulePass *llvm::createStackSafetyGlobalInfoWrapperPass(bool SetMetadata) {