Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-10 08:43:17

0001 //===- StackSafetyAnalysis.h - Stack memory safety analysis -----*- C++ -*-===//
0002 //
0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0004 // See https://llvm.org/LICENSE.txt for license information.
0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
0006 //
0007 //===----------------------------------------------------------------------===//
0008 //
0009 // Stack Safety Analysis detects allocas and arguments with safe access.
0010 //
0011 //===----------------------------------------------------------------------===//
0012 
0013 #ifndef LLVM_ANALYSIS_STACKSAFETYANALYSIS_H
0014 #define LLVM_ANALYSIS_STACKSAFETYANALYSIS_H
0015 
0016 #include "llvm/IR/ModuleSummaryIndex.h"
0017 #include "llvm/IR/PassManager.h"
0018 #include "llvm/Pass.h"
0019 
0020 namespace llvm {
0021 
0022 class AllocaInst;
0023 class ScalarEvolution;
0024 
0025 /// Interface to access stack safety analysis results for single function.
0026 class StackSafetyInfo {
0027 public:
0028   struct InfoTy;
0029 
0030 private:
0031   Function *F = nullptr;
0032   std::function<ScalarEvolution &()> GetSE;
0033   mutable std::unique_ptr<InfoTy> Info;
0034 
0035 public:
0036   StackSafetyInfo();
0037   StackSafetyInfo(Function *F, std::function<ScalarEvolution &()> GetSE);
0038   StackSafetyInfo(StackSafetyInfo &&);
0039   StackSafetyInfo &operator=(StackSafetyInfo &&);
0040   ~StackSafetyInfo();
0041 
0042   const InfoTy &getInfo() const;
0043 
0044   // TODO: Add useful for client methods.
0045   void print(raw_ostream &O) const;
0046 
0047   /// Parameters use for a FunctionSummary.
0048   /// Function collects access information of all pointer parameters.
0049   /// Information includes a range of direct access of parameters by the
0050   /// functions and all call sites accepting the parameter.
0051   /// StackSafety assumes that missing parameter information means possibility
0052   /// of access to the parameter with any offset, so we can correctly link
0053   /// code without StackSafety information, e.g. non-ThinLTO.
0054   std::vector<FunctionSummary::ParamAccess>
0055   getParamAccesses(ModuleSummaryIndex &Index) const;
0056 };
0057 
0058 class StackSafetyGlobalInfo {
0059 public:
0060   struct InfoTy;
0061 
0062 private:
0063   Module *M = nullptr;
0064   std::function<const StackSafetyInfo &(Function &F)> GetSSI;
0065   const ModuleSummaryIndex *Index = nullptr;
0066   mutable std::unique_ptr<InfoTy> Info;
0067   const InfoTy &getInfo() const;
0068 
0069 public:
0070   StackSafetyGlobalInfo();
0071   StackSafetyGlobalInfo(
0072       Module *M, std::function<const StackSafetyInfo &(Function &F)> GetSSI,
0073       const ModuleSummaryIndex *Index);
0074   StackSafetyGlobalInfo(StackSafetyGlobalInfo &&);
0075   StackSafetyGlobalInfo &operator=(StackSafetyGlobalInfo &&);
0076   ~StackSafetyGlobalInfo();
0077 
0078   // Whether we can prove that all accesses to this Alloca are in-range and
0079   // during its lifetime.
0080   bool isSafe(const AllocaInst &AI) const;
0081 
0082   // Returns true if the instruction can be proven to do only two types of
0083   // memory accesses:
0084   //  (1) live stack locations in-bounds or
0085   //  (2) non-stack locations.
0086   bool stackAccessIsSafe(const Instruction &I) const;
0087   void print(raw_ostream &O) const;
0088   void dump() const;
0089 };
0090 
0091 /// StackSafetyInfo wrapper for the new pass manager.
0092 class StackSafetyAnalysis : public AnalysisInfoMixin<StackSafetyAnalysis> {
0093   friend AnalysisInfoMixin<StackSafetyAnalysis>;
0094   static AnalysisKey Key;
0095 
0096 public:
0097   using Result = StackSafetyInfo;
0098   StackSafetyInfo run(Function &F, FunctionAnalysisManager &AM);
0099 };
0100 
0101 /// Printer pass for the \c StackSafetyAnalysis results.
0102 class StackSafetyPrinterPass : public PassInfoMixin<StackSafetyPrinterPass> {
0103   raw_ostream &OS;
0104 
0105 public:
0106   explicit StackSafetyPrinterPass(raw_ostream &OS) : OS(OS) {}
0107   PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
0108   static bool isRequired() { return true; }
0109 };
0110 
0111 /// StackSafetyInfo wrapper for the legacy pass manager
0112 class StackSafetyInfoWrapperPass : public FunctionPass {
0113   StackSafetyInfo SSI;
0114 
0115 public:
0116   static char ID;
0117   StackSafetyInfoWrapperPass();
0118 
0119   const StackSafetyInfo &getResult() const { return SSI; }
0120 
0121   void print(raw_ostream &O, const Module *M) const override;
0122   void getAnalysisUsage(AnalysisUsage &AU) const override;
0123 
0124   bool runOnFunction(Function &F) override;
0125 };
0126 
0127 /// This pass performs the global (interprocedural) stack safety analysis (new
0128 /// pass manager).
0129 class StackSafetyGlobalAnalysis
0130     : public AnalysisInfoMixin<StackSafetyGlobalAnalysis> {
0131   friend AnalysisInfoMixin<StackSafetyGlobalAnalysis>;
0132   static AnalysisKey Key;
0133 
0134 public:
0135   using Result = StackSafetyGlobalInfo;
0136   Result run(Module &M, ModuleAnalysisManager &AM);
0137 };
0138 
0139 /// Printer pass for the \c StackSafetyGlobalAnalysis results.
0140 class StackSafetyGlobalPrinterPass
0141     : public PassInfoMixin<StackSafetyGlobalPrinterPass> {
0142   raw_ostream &OS;
0143 
0144 public:
0145   explicit StackSafetyGlobalPrinterPass(raw_ostream &OS) : OS(OS) {}
0146   PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);
0147   static bool isRequired() { return true; }
0148 };
0149 
0150 /// This pass performs the global (interprocedural) stack safety analysis
0151 /// (legacy pass manager).
0152 class StackSafetyGlobalInfoWrapperPass : public ModulePass {
0153   StackSafetyGlobalInfo SSGI;
0154 
0155 public:
0156   static char ID;
0157 
0158   StackSafetyGlobalInfoWrapperPass();
0159   ~StackSafetyGlobalInfoWrapperPass();
0160 
0161   const StackSafetyGlobalInfo &getResult() const { return SSGI; }
0162 
0163   void print(raw_ostream &O, const Module *M) const override;
0164   void getAnalysisUsage(AnalysisUsage &AU) const override;
0165 
0166   bool runOnModule(Module &M) override;
0167 };
0168 
0169 bool needsParamAccessSummary(const Module &M);
0170 
0171 void generateParamAccessSummary(ModuleSummaryIndex &Index);
0172 
0173 } // end namespace llvm
0174 
0175 #endif // LLVM_ANALYSIS_STACKSAFETYANALYSIS_H