StackSafetyAnalysis.h 5.1 KB

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