Subversion Repositories QNX 8.QNX8 LLVM/Clang compiler suite

Rev

Blame | Last modification | View Log | Download | RSS feed

  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.  
  20. namespace llvm {
  21.  
  22. class AllocaInst;
  23. class ScalarEvolution;
  24.  
  25. /// Interface to access stack safety analysis results for single function.
  26. class StackSafetyInfo {
  27. public:
  28.   struct InfoTy;
  29.  
  30. private:
  31.   Function *F = nullptr;
  32.   std::function<ScalarEvolution &()> GetSE;
  33.   mutable std::unique_ptr<InfoTy> Info;
  34.  
  35. public:
  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.  
  58. class StackSafetyGlobalInfo {
  59. public:
  60.   struct InfoTy;
  61.  
  62. private:
  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.  
  69. public:
  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.   // Whether we can prove that all accesses to this Alloca are in-range and
  79.   // during its lifetime.
  80.   bool isSafe(const AllocaInst &AI) const;
  81.  
  82.   // Returns true if the instruction can be proven to do only two types of
  83.   // memory accesses:
  84.   //  (1) live stack locations in-bounds or
  85.   //  (2) non-stack locations.
  86.   bool stackAccessIsSafe(const Instruction &I) const;
  87.   void print(raw_ostream &O) const;
  88.   void dump() const;
  89. };
  90.  
  91. /// StackSafetyInfo wrapper for the new pass manager.
  92. class StackSafetyAnalysis : public AnalysisInfoMixin<StackSafetyAnalysis> {
  93.   friend AnalysisInfoMixin<StackSafetyAnalysis>;
  94.   static AnalysisKey Key;
  95.  
  96. public:
  97.   using Result = StackSafetyInfo;
  98.   StackSafetyInfo run(Function &F, FunctionAnalysisManager &AM);
  99. };
  100.  
  101. /// Printer pass for the \c StackSafetyAnalysis results.
  102. class StackSafetyPrinterPass : public PassInfoMixin<StackSafetyPrinterPass> {
  103.   raw_ostream &OS;
  104.  
  105. public:
  106.   explicit StackSafetyPrinterPass(raw_ostream &OS) : OS(OS) {}
  107.   PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
  108. };
  109.  
  110. /// StackSafetyInfo wrapper for the legacy pass manager
  111. class StackSafetyInfoWrapperPass : public FunctionPass {
  112.   StackSafetyInfo SSI;
  113.  
  114. public:
  115.   static char ID;
  116.   StackSafetyInfoWrapperPass();
  117.  
  118.   const StackSafetyInfo &getResult() const { return SSI; }
  119.  
  120.   void print(raw_ostream &O, const Module *M) const override;
  121.   void getAnalysisUsage(AnalysisUsage &AU) const override;
  122.  
  123.   bool runOnFunction(Function &F) override;
  124. };
  125.  
  126. /// This pass performs the global (interprocedural) stack safety analysis (new
  127. /// pass manager).
  128. class StackSafetyGlobalAnalysis
  129.     : public AnalysisInfoMixin<StackSafetyGlobalAnalysis> {
  130.   friend AnalysisInfoMixin<StackSafetyGlobalAnalysis>;
  131.   static AnalysisKey Key;
  132.  
  133. public:
  134.   using Result = StackSafetyGlobalInfo;
  135.   Result run(Module &M, ModuleAnalysisManager &AM);
  136. };
  137.  
  138. /// Printer pass for the \c StackSafetyGlobalAnalysis results.
  139. class StackSafetyGlobalPrinterPass
  140.     : public PassInfoMixin<StackSafetyGlobalPrinterPass> {
  141.   raw_ostream &OS;
  142.  
  143. public:
  144.   explicit StackSafetyGlobalPrinterPass(raw_ostream &OS) : OS(OS) {}
  145.   PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);
  146. };
  147.  
  148. /// This pass performs the global (interprocedural) stack safety analysis
  149. /// (legacy pass manager).
  150. class StackSafetyGlobalInfoWrapperPass : public ModulePass {
  151.   StackSafetyGlobalInfo SSGI;
  152.  
  153. public:
  154.   static char ID;
  155.  
  156.   StackSafetyGlobalInfoWrapperPass();
  157.   ~StackSafetyGlobalInfoWrapperPass();
  158.  
  159.   const StackSafetyGlobalInfo &getResult() const { return SSGI; }
  160.  
  161.   void print(raw_ostream &O, const Module *M) const override;
  162.   void getAnalysisUsage(AnalysisUsage &AU) const override;
  163.  
  164.   bool runOnModule(Module &M) override;
  165. };
  166.  
  167. bool needsParamAccessSummary(const Module &M);
  168.  
  169. void generateParamAccessSummary(ModuleSummaryIndex &Index);
  170.  
  171. } // end namespace llvm
  172.  
  173. #endif // LLVM_ANALYSIS_STACKSAFETYANALYSIS_H
  174.