Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
14 | pmbaty | 1 | #ifndef LLVM_CODEGEN_ASSIGNMENTTRACKINGANALYSIS_H |
2 | #define LLVM_CODEGEN_ASSIGNMENTTRACKINGANALYSIS_H |
||
3 | |||
4 | #include "llvm/IR/DebugInfoMetadata.h" |
||
5 | #include "llvm/IR/DebugLoc.h" |
||
6 | #include "llvm/Pass.h" |
||
7 | |||
8 | namespace llvm { |
||
9 | class Function; |
||
10 | class Instruction; |
||
11 | class Value; |
||
12 | class raw_ostream; |
||
13 | } // namespace llvm |
||
14 | class FunctionVarLocsBuilder; |
||
15 | |||
16 | namespace llvm { |
||
17 | /// Type wrapper for integer ID for Variables. 0 is reserved. |
||
18 | enum class VariableID : unsigned { Reserved = 0 }; |
||
19 | /// Variable location definition used by FunctionVarLocs. |
||
20 | struct VarLocInfo { |
||
21 | llvm::VariableID VariableID; |
||
22 | DIExpression *Expr = nullptr; |
||
23 | DebugLoc DL; |
||
24 | Value *V = nullptr; // TODO: Needs to be value_s_ for variadic expressions. |
||
25 | }; |
||
26 | |||
27 | /// Data structure describing the variable locations in a function. Used as the |
||
28 | /// result of the AssignmentTrackingAnalysis pass. Essentially read-only |
||
29 | /// outside of AssignmentTrackingAnalysis where it is built. |
||
30 | class FunctionVarLocs { |
||
31 | /// Maps VarLocInfo.VariableID to a DebugVariable for VarLocRecords. |
||
32 | SmallVector<DebugVariable> Variables; |
||
33 | /// List of variable location changes grouped by the instruction the |
||
34 | /// change occurs before (see VarLocsBeforeInst). The elements from |
||
35 | /// zero to SingleVarLocEnd represent variables with a single location. |
||
36 | SmallVector<VarLocInfo> VarLocRecords; |
||
37 | /// End of range of VarLocRecords that represent variables with a single |
||
38 | /// location that is valid for the entire scope. Range starts at 0. |
||
39 | unsigned SingleVarLocEnd = 0; |
||
40 | /// Maps an instruction to a range of VarLocs that start just before it. |
||
41 | DenseMap<const Instruction *, std::pair<unsigned, unsigned>> |
||
42 | VarLocsBeforeInst; |
||
43 | |||
44 | public: |
||
45 | /// Return the DILocalVariable for the location definition represented by \p |
||
46 | /// ID. |
||
47 | DILocalVariable *getDILocalVariable(const VarLocInfo *Loc) const { |
||
48 | VariableID VarID = Loc->VariableID; |
||
49 | return getDILocalVariable(VarID); |
||
50 | } |
||
51 | /// Return the DILocalVariable of the variable represented by \p ID. |
||
52 | DILocalVariable *getDILocalVariable(VariableID ID) const { |
||
53 | return const_cast<DILocalVariable *>(getVariable(ID).getVariable()); |
||
54 | } |
||
55 | /// Return the DebugVariable represented by \p ID. |
||
56 | const DebugVariable &getVariable(VariableID ID) const { |
||
57 | return Variables[static_cast<unsigned>(ID)]; |
||
58 | } |
||
59 | |||
60 | ///@name iterators |
||
61 | ///@{ |
||
62 | /// First single-location variable location definition. |
||
63 | const VarLocInfo *single_locs_begin() const { return VarLocRecords.begin(); } |
||
64 | /// One past the last single-location variable location definition. |
||
65 | const VarLocInfo *single_locs_end() const { |
||
66 | const auto *It = VarLocRecords.begin(); |
||
67 | std::advance(It, SingleVarLocEnd); |
||
68 | return It; |
||
69 | } |
||
70 | /// First variable location definition that comes before \p Before. |
||
71 | const VarLocInfo *locs_begin(const Instruction *Before) const { |
||
72 | auto Span = VarLocsBeforeInst.lookup(Before); |
||
73 | const auto *It = VarLocRecords.begin(); |
||
74 | std::advance(It, Span.first); |
||
75 | return It; |
||
76 | } |
||
77 | /// One past the last variable location definition that comes before \p |
||
78 | /// Before. |
||
79 | const VarLocInfo *locs_end(const Instruction *Before) const { |
||
80 | auto Span = VarLocsBeforeInst.lookup(Before); |
||
81 | const auto *It = VarLocRecords.begin(); |
||
82 | std::advance(It, Span.second); |
||
83 | return It; |
||
84 | } |
||
85 | ///@} |
||
86 | |||
87 | void print(raw_ostream &OS, const Function &Fn) const; |
||
88 | |||
89 | ///@{ |
||
90 | /// Non-const methods used by AssignmentTrackingAnalysis (which invalidate |
||
91 | /// analysis results if called incorrectly). |
||
92 | void init(FunctionVarLocsBuilder &Builder); |
||
93 | void clear(); |
||
94 | ///@} |
||
95 | }; |
||
96 | |||
97 | class AssignmentTrackingAnalysis : public FunctionPass { |
||
98 | std::unique_ptr<FunctionVarLocs> Results; |
||
99 | |||
100 | public: |
||
101 | static char ID; |
||
102 | |||
103 | AssignmentTrackingAnalysis(); |
||
104 | |||
105 | bool runOnFunction(Function &F) override; |
||
106 | |||
107 | static bool isRequired() { return true; } |
||
108 | |||
109 | void getAnalysisUsage(AnalysisUsage &AU) const override { |
||
110 | AU.setPreservesAll(); |
||
111 | } |
||
112 | |||
113 | const FunctionVarLocs *getResults() { return Results.get(); } |
||
114 | }; |
||
115 | |||
116 | } // end namespace llvm |
||
117 | #endif // LLVM_CODEGEN_ASSIGNMENTTRACKINGANALYSIS_H |