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/PassManager.h"
17 #include "llvm/Pass.h"
18 
19 namespace llvm {
20 
21 /// Interface to access stack safety analysis results for single function.
22 class StackSafetyInfo {
23 public:
24   struct FunctionInfo;
25 
26 private:
27   std::unique_ptr<FunctionInfo> Info;
28 
29 public:
30   StackSafetyInfo();
31   StackSafetyInfo(FunctionInfo &&Info);
32   StackSafetyInfo(StackSafetyInfo &&);
33   StackSafetyInfo &operator=(StackSafetyInfo &&);
34   ~StackSafetyInfo();
35 
36   FunctionInfo *getInfo() const { return Info.get(); }
37 
38   // TODO: Add useful for client methods.
39   void print(raw_ostream &O) const;
40 };
41 
42 /// StackSafetyInfo wrapper for the new pass manager.
43 class StackSafetyAnalysis : public AnalysisInfoMixin<StackSafetyAnalysis> {
44   friend AnalysisInfoMixin<StackSafetyAnalysis>;
45   static AnalysisKey Key;
46 
47 public:
48   using Result = StackSafetyInfo;
49   StackSafetyInfo run(Function &F, FunctionAnalysisManager &AM);
50 };
51 
52 /// Printer pass for the \c StackSafetyAnalysis results.
53 class StackSafetyPrinterPass : public PassInfoMixin<StackSafetyPrinterPass> {
54   raw_ostream &OS;
55 
56 public:
57   explicit StackSafetyPrinterPass(raw_ostream &OS) : OS(OS) {}
58   PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
59 };
60 
61 /// StackSafetyInfo wrapper for the legacy pass manager
62 class StackSafetyInfoWrapperPass : public FunctionPass {
63   StackSafetyInfo SSI;
64 
65 public:
66   static char ID;
67   StackSafetyInfoWrapperPass();
68 
69   const StackSafetyInfo &getResult() const { return SSI; }
70 
71   void print(raw_ostream &O, const Module *M) const override;
72   void getAnalysisUsage(AnalysisUsage &AU) const override;
73 
74   bool runOnFunction(Function &F) override;
75 };
76 
77 using StackSafetyGlobalInfo = std::map<const GlobalValue *, StackSafetyInfo>;
78 
79 /// This pass performs the global (interprocedural) stack safety analysis (new
80 /// pass manager).
81 class StackSafetyGlobalAnalysis
82     : public AnalysisInfoMixin<StackSafetyGlobalAnalysis> {
83   friend AnalysisInfoMixin<StackSafetyGlobalAnalysis>;
84   static AnalysisKey Key;
85 
86 public:
87   using Result = StackSafetyGlobalInfo;
88   Result run(Module &M, ModuleAnalysisManager &AM);
89 };
90 
91 /// Printer pass for the \c StackSafetyGlobalAnalysis results.
92 class StackSafetyGlobalPrinterPass
93     : public PassInfoMixin<StackSafetyGlobalPrinterPass> {
94   raw_ostream &OS;
95 
96 public:
97   explicit StackSafetyGlobalPrinterPass(raw_ostream &OS) : OS(OS) {}
98   PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);
99 };
100 
101 class StackSafetyGlobalAnnotatorPass
102     : public PassInfoMixin<StackSafetyGlobalAnnotatorPass> {
103 
104 public:
105   explicit StackSafetyGlobalAnnotatorPass() {}
106   PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);
107 };
108 
109 /// This pass performs the global (interprocedural) stack safety analysis
110 /// (legacy pass manager).
111 class StackSafetyGlobalInfoWrapperPass : public ModulePass {
112   StackSafetyGlobalInfo SSGI;
113   bool SetMetadata;
114 
115 public:
116   static char ID;
117 
118   StackSafetyGlobalInfoWrapperPass(bool SetMetadata = false);
119 
120   const StackSafetyGlobalInfo &getResult() const { return SSGI; }
121 
122   void print(raw_ostream &O, const Module *M) const override;
123   void getAnalysisUsage(AnalysisUsage &AU) const override;
124 
125   bool runOnModule(Module &M) override;
126 };
127 
128 ModulePass *createStackSafetyGlobalInfoWrapperPass(bool SetMetadata);
129 
130 } // end namespace llvm
131 
132 #endif // LLVM_ANALYSIS_STACKSAFETYANALYSIS_H
133