Index: llvm/include/llvm/Analysis/StackSafetyAnalysis.h =================================================================== --- llvm/include/llvm/Analysis/StackSafetyAnalysis.h +++ llvm/include/llvm/Analysis/StackSafetyAnalysis.h @@ -73,6 +73,46 @@ bool runOnFunction(Function &F) override; }; +using StackSafetyGlobalInfo = std::map; + +/// Global-local stack safety analysis pass. +class StackSafetyGlobalAnalysis + : public AnalysisInfoMixin { + friend AnalysisInfoMixin; + static AnalysisKey Key; + +public: + using Result = StackSafetyGlobalInfo; + Result run(Module &M, ModuleAnalysisManager &AM); +}; + +/// Printer pass for the \c StackSafetyGlobalAnalysis results. +class StackSafetyGlobalPrinterPass + : public PassInfoMixin { + raw_ostream &OS; + +public: + explicit StackSafetyGlobalPrinterPass(raw_ostream &OS) : OS(OS) {} + PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM); +}; + +// This pass performs the global (interprocedural) stack safety analysis. +class StackSafetyGlobalInfoWrapperPass : public ModulePass { + StackSafetyGlobalInfo SSI; + +public: + static char ID; + + StackSafetyGlobalInfoWrapperPass(); + + const StackSafetyGlobalInfo &getResult() const { return SSI; } + + void print(raw_ostream &O, const Module *M) const override; + void getAnalysisUsage(AnalysisUsage &AU) const override; + + bool runOnModule(Module &M) override; +}; + } // end namespace llvm #endif // LLVM_ANALYSIS_STACKSAFETYANALYSIS_H Index: llvm/include/llvm/InitializePasses.h =================================================================== --- llvm/include/llvm/InitializePasses.h +++ llvm/include/llvm/InitializePasses.h @@ -371,6 +371,7 @@ void initializeStackColoringPass(PassRegistry&); void initializeStackMapLivenessPass(PassRegistry&); void initializeStackProtectorPass(PassRegistry&); +void initializeStackSafetyGlobalInfoWrapperPassPass(PassRegistry &); void initializeStackSafetyInfoWrapperPassPass(PassRegistry &); void initializeStackSlotColoringPass(PassRegistry&); void initializeStraightLineStrengthReducePass(PassRegistry&); Index: llvm/lib/Analysis/Analysis.cpp =================================================================== --- llvm/lib/Analysis/Analysis.cpp +++ llvm/lib/Analysis/Analysis.cpp @@ -77,6 +77,7 @@ initializeRegionOnlyPrinterPass(Registry); initializeSCEVAAWrapperPassPass(Registry); initializeScalarEvolutionWrapperPassPass(Registry); + initializeStackSafetyGlobalInfoWrapperPassPass(Registry); initializeStackSafetyInfoWrapperPassPass(Registry); initializeTargetTransformInfoWrapperPassPass(Registry); initializeTypeBasedAAWrapperPassPass(Registry); Index: llvm/lib/Analysis/StackSafetyAnalysis.cpp =================================================================== --- llvm/lib/Analysis/StackSafetyAnalysis.cpp +++ llvm/lib/Analysis/StackSafetyAnalysis.cpp @@ -360,6 +360,10 @@ return StackSafetyInfo(std::move(Info)); } +void print(const StackSafetyGlobalInfo &SSI, raw_ostream &O, const Module &M) { + O << "Not Implemented\n"; +} + } // end anonymous namespace StackSafetyInfo::StackSafetyInfo() = default; @@ -410,6 +414,40 @@ return false; } +AnalysisKey StackSafetyGlobalAnalysis::Key; + +StackSafetyGlobalInfo +StackSafetyGlobalAnalysis::run(Module &M, ModuleAnalysisManager &AM) { + return {}; +} + +PreservedAnalyses StackSafetyGlobalPrinterPass::run(Module &M, + ModuleAnalysisManager &AM) { + OS << "'Stack Safety Analysis' for module '" << M.getName() << "'\n"; + print(AM.getResult(M), OS, M); + return PreservedAnalyses::all(); +} + +char StackSafetyGlobalInfoWrapperPass::ID = 0; + +StackSafetyGlobalInfoWrapperPass::StackSafetyGlobalInfoWrapperPass() + : ModulePass(ID) { + initializeStackSafetyGlobalInfoWrapperPassPass( + *PassRegistry::getPassRegistry()); +} + +void StackSafetyGlobalInfoWrapperPass::print(raw_ostream &O, + const Module *M) const { + ::print(SSI, O, *M); +} + +void StackSafetyGlobalInfoWrapperPass::getAnalysisUsage( + AnalysisUsage &AU) const { + AU.addRequired(); +} + +bool StackSafetyGlobalInfoWrapperPass::runOnModule(Module &M) { return false; } + static const char LocalPassArg[] = "stack-safety-local"; static const char LocalPassName[] = "Stack Safety Local Analysis"; INITIALIZE_PASS_BEGIN(StackSafetyInfoWrapperPass, LocalPassArg, LocalPassName, @@ -417,3 +455,10 @@ INITIALIZE_PASS_DEPENDENCY(ScalarEvolutionWrapperPass) INITIALIZE_PASS_END(StackSafetyInfoWrapperPass, LocalPassArg, LocalPassName, false, true) + +static const char GlobalPassName[] = "Stack Safety Analysis"; +INITIALIZE_PASS_BEGIN(StackSafetyGlobalInfoWrapperPass, DEBUG_TYPE, + GlobalPassName, false, false) +INITIALIZE_PASS_DEPENDENCY(StackSafetyInfoWrapperPass) +INITIALIZE_PASS_END(StackSafetyGlobalInfoWrapperPass, DEBUG_TYPE, + GlobalPassName, false, false) Index: llvm/lib/Passes/PassRegistry.def =================================================================== --- llvm/lib/Passes/PassRegistry.def +++ llvm/lib/Passes/PassRegistry.def @@ -24,6 +24,7 @@ MODULE_ANALYSIS("module-summary", ModuleSummaryIndexAnalysis()) MODULE_ANALYSIS("no-op-module", NoOpModuleAnalysis()) MODULE_ANALYSIS("profile-summary", ProfileSummaryAnalysis()) +MODULE_ANALYSIS("stack-safety", StackSafetyGlobalAnalysis()) MODULE_ANALYSIS("targetlibinfo", TargetLibraryAnalysis()) MODULE_ANALYSIS("verify", VerifierAnalysis()) MODULE_ANALYSIS("pass-instrumentation", PassInstrumentationAnalysis(PIC)) @@ -71,6 +72,7 @@ MODULE_PASS("print", PrintModulePass(dbgs())) MODULE_PASS("print-lcg", LazyCallGraphPrinterPass(dbgs())) MODULE_PASS("print-lcg-dot", LazyCallGraphDOTPrinterPass(dbgs())) +MODULE_PASS("print-stack-safety", StackSafetyGlobalPrinterPass(dbgs())) MODULE_PASS("rewrite-statepoints-for-gc", RewriteStatepointsForGC()) MODULE_PASS("rewrite-symbols", RewriteSymbolPass()) MODULE_PASS("rpo-functionattrs", ReversePostOrderFunctionAttrsPass()) Index: llvm/test/Analysis/StackSafetyAnalysis/local.ll =================================================================== --- llvm/test/Analysis/StackSafetyAnalysis/local.ll +++ llvm/test/Analysis/StackSafetyAnalysis/local.ll @@ -1,5 +1,9 @@ ; RUN: opt -S -analyze -stack-safety-local < %s | FileCheck %s ; RUN: opt -S -passes="print" -disable-output < %s 2>&1 | FileCheck %s +; RUN: opt -S -analyze -stack-safety < %s | FileCheck %s --check-prefix=GLOBAL +; RUN: opt -S -passes="print-stack-safety" -disable-output < %s 2>&1 | FileCheck %s --check-prefix=GLOBAL + +; GLOBAL: Not Implemented target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" target triple = "x86_64-unknown-linux-gnu"