1//===- StackSafetyAnalysis.h - Stack memory safety analysis -----*- C++ -*-===// 2// 3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4// See https://llvm.org/LICENSE.txt for license information. 5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6// 7//===----------------------------------------------------------------------===// 8// 9// Stack Safety Analysis detects allocas and arguments with safe access. 10// 11//===----------------------------------------------------------------------===// 12 13#ifndef LLVM_ANALYSIS_STACKSAFETYANALYSIS_H 14#define LLVM_ANALYSIS_STACKSAFETYANALYSIS_H 15 16#include "llvm/IR/ModuleSummaryIndex.h" 17#include "llvm/IR/PassManager.h" 18#include "llvm/Pass.h" 19 20namespace llvm { 21 22class AllocaInst; 23class ScalarEvolution; 24 25/// Interface to access stack safety analysis results for single function. 26class StackSafetyInfo { 27public: 28 struct InfoTy; 29 30private: 31 Function *F = nullptr; 32 std::function<ScalarEvolution &()> GetSE; 33 mutable std::unique_ptr<InfoTy> Info; 34 35public: 36 StackSafetyInfo(); 37 StackSafetyInfo(Function *F, std::function<ScalarEvolution &()> GetSE); 38 StackSafetyInfo(StackSafetyInfo &&); 39 StackSafetyInfo &operator=(StackSafetyInfo &&); 40 ~StackSafetyInfo(); 41 42 const InfoTy &getInfo() const; 43 44 // TODO: Add useful for client methods. 45 void print(raw_ostream &O) const; 46 47 /// Parameters use for a FunctionSummary. 48 /// Function collects access information of all pointer parameters. 49 /// Information includes a range of direct access of parameters by the 50 /// functions and all call sites accepting the parameter. 51 /// StackSafety assumes that missing parameter information means possibility 52 /// of access to the parameter with any offset, so we can correctly link 53 /// code without StackSafety information, e.g. non-ThinLTO. 54 std::vector<FunctionSummary::ParamAccess> 55 getParamAccesses(ModuleSummaryIndex &Index) const; 56}; 57 58class StackSafetyGlobalInfo { 59public: 60 struct InfoTy; 61 62private: 63 Module *M = nullptr; 64 std::function<const StackSafetyInfo &(Function &F)> GetSSI; 65 const ModuleSummaryIndex *Index = nullptr; 66 mutable std::unique_ptr<InfoTy> Info; 67 const InfoTy &getInfo() const; 68 69public: 70 StackSafetyGlobalInfo(); 71 StackSafetyGlobalInfo( 72 Module *M, std::function<const StackSafetyInfo &(Function &F)> GetSSI, 73 const ModuleSummaryIndex *Index); 74 StackSafetyGlobalInfo(StackSafetyGlobalInfo &&); 75 StackSafetyGlobalInfo &operator=(StackSafetyGlobalInfo &&); 76 ~StackSafetyGlobalInfo(); 77 78 bool isSafe(const AllocaInst &AI) const; 79 void print(raw_ostream &O) const; 80 void dump() const; 81}; 82 83/// StackSafetyInfo wrapper for the new pass manager. 84class StackSafetyAnalysis : public AnalysisInfoMixin<StackSafetyAnalysis> { 85 friend AnalysisInfoMixin<StackSafetyAnalysis>; 86 static AnalysisKey Key; 87 88public: 89 using Result = StackSafetyInfo; 90 StackSafetyInfo run(Function &F, FunctionAnalysisManager &AM); 91}; 92 93/// Printer pass for the \c StackSafetyAnalysis results. 94class StackSafetyPrinterPass : public PassInfoMixin<StackSafetyPrinterPass> { 95 raw_ostream &OS; 96 97public: 98 explicit StackSafetyPrinterPass(raw_ostream &OS) : OS(OS) {} 99 PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM); 100}; 101 102/// StackSafetyInfo wrapper for the legacy pass manager 103class StackSafetyInfoWrapperPass : public FunctionPass { 104 StackSafetyInfo SSI; 105 106public: 107 static char ID; 108 StackSafetyInfoWrapperPass(); 109 110 const StackSafetyInfo &getResult() const { return SSI; } 111 112 void print(raw_ostream &O, const Module *M) const override; 113 void getAnalysisUsage(AnalysisUsage &AU) const override; 114 115 bool runOnFunction(Function &F) override; 116}; 117 118/// This pass performs the global (interprocedural) stack safety analysis (new 119/// pass manager). 120class StackSafetyGlobalAnalysis 121 : public AnalysisInfoMixin<StackSafetyGlobalAnalysis> { 122 friend AnalysisInfoMixin<StackSafetyGlobalAnalysis>; 123 static AnalysisKey Key; 124 125public: 126 using Result = StackSafetyGlobalInfo; 127 Result run(Module &M, ModuleAnalysisManager &AM); 128}; 129 130/// Printer pass for the \c StackSafetyGlobalAnalysis results. 131class StackSafetyGlobalPrinterPass 132 : public PassInfoMixin<StackSafetyGlobalPrinterPass> { 133 raw_ostream &OS; 134 135public: 136 explicit StackSafetyGlobalPrinterPass(raw_ostream &OS) : OS(OS) {} 137 PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM); 138}; 139 140/// This pass performs the global (interprocedural) stack safety analysis 141/// (legacy pass manager). 142class StackSafetyGlobalInfoWrapperPass : public ModulePass { 143 StackSafetyGlobalInfo SSGI; 144 145public: 146 static char ID; 147 148 StackSafetyGlobalInfoWrapperPass(); 149 ~StackSafetyGlobalInfoWrapperPass(); 150 151 const StackSafetyGlobalInfo &getResult() const { return SSGI; } 152 153 void print(raw_ostream &O, const Module *M) const override; 154 void getAnalysisUsage(AnalysisUsage &AU) const override; 155 156 bool runOnModule(Module &M) override; 157}; 158 159bool needsParamAccessSummary(const Module &M); 160 161void generateParamAccessSummary(ModuleSummaryIndex &Index); 162 163} // end namespace llvm 164 165#endif // LLVM_ANALYSIS_STACKSAFETYANALYSIS_H 166