1//===-- llvm/CodeGen/AssignmentTrackingAnalysis.h --------------*- 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#ifndef LLVM_CODEGEN_ASSIGNMENTTRACKINGANALYSIS_H
10#define LLVM_CODEGEN_ASSIGNMENTTRACKINGANALYSIS_H
11
12#include "llvm/IR/DebugInfoMetadata.h"
13#include "llvm/IR/DebugLoc.h"
14#include "llvm/IR/IntrinsicInst.h"
15#include "llvm/IR/PassManager.h"
16#include "llvm/Pass.h"
17
18namespace llvm {
19class Instruction;
20class raw_ostream;
21} // namespace llvm
22class FunctionVarLocsBuilder;
23
24namespace llvm {
25/// Type wrapper for integer ID for Variables. 0 is reserved.
26enum class VariableID : unsigned { Reserved = 0 };
27/// Variable location definition used by FunctionVarLocs.
28struct VarLocInfo {
29 llvm::VariableID VariableID;
30 DIExpression *Expr = nullptr;
31 DebugLoc DL;
32 RawLocationWrapper Values = RawLocationWrapper();
33};
34
35/// Data structure describing the variable locations in a function. Used as the
36/// result of the AssignmentTrackingAnalysis pass. Essentially read-only
37/// outside of AssignmentTrackingAnalysis where it is built.
38class FunctionVarLocs {
39 /// Maps VarLocInfo.VariableID to a DebugVariable for VarLocRecords.
40 SmallVector<DebugVariable> Variables;
41 /// List of variable location changes grouped by the instruction the
42 /// change occurs before (see VarLocsBeforeInst). The elements from
43 /// zero to SingleVarLocEnd represent variables with a single location.
44 SmallVector<VarLocInfo> VarLocRecords;
45 /// End of range of VarLocRecords that represent variables with a single
46 /// location that is valid for the entire scope. Range starts at 0.
47 unsigned SingleVarLocEnd = 0;
48 /// Maps an instruction to a range of VarLocs that start just before it.
49 DenseMap<const Instruction *, std::pair<unsigned, unsigned>>
50 VarLocsBeforeInst;
51
52public:
53 /// Return the DILocalVariable for the location definition represented by \p
54 /// ID.
55 DILocalVariable *getDILocalVariable(const VarLocInfo *Loc) const {
56 VariableID VarID = Loc->VariableID;
57 return getDILocalVariable(ID: VarID);
58 }
59 /// Return the DILocalVariable of the variable represented by \p ID.
60 DILocalVariable *getDILocalVariable(VariableID ID) const {
61 return const_cast<DILocalVariable *>(getVariable(ID).getVariable());
62 }
63 /// Return the DebugVariable represented by \p ID.
64 const DebugVariable &getVariable(VariableID ID) const {
65 return Variables[static_cast<unsigned>(ID)];
66 }
67
68 ///@name iterators
69 ///@{
70 /// First single-location variable location definition.
71 const VarLocInfo *single_locs_begin() const { return VarLocRecords.begin(); }
72 /// One past the last single-location variable location definition.
73 const VarLocInfo *single_locs_end() const {
74 const auto *It = VarLocRecords.begin();
75 std::advance(i&: It, n: SingleVarLocEnd);
76 return It;
77 }
78 /// First variable location definition that comes before \p Before.
79 const VarLocInfo *locs_begin(const Instruction *Before) const {
80 auto Span = VarLocsBeforeInst.lookup(Val: Before);
81 const auto *It = VarLocRecords.begin();
82 std::advance(i&: It, n: Span.first);
83 return It;
84 }
85 /// One past the last variable location definition that comes before \p
86 /// Before.
87 const VarLocInfo *locs_end(const Instruction *Before) const {
88 auto Span = VarLocsBeforeInst.lookup(Val: Before);
89 const auto *It = VarLocRecords.begin();
90 std::advance(i&: It, n: Span.second);
91 return It;
92 }
93 ///@}
94
95 void print(raw_ostream &OS, const Function &Fn) const;
96
97 ///@{
98 /// Non-const methods used by AssignmentTrackingAnalysis (which invalidate
99 /// analysis results if called incorrectly).
100 void init(FunctionVarLocsBuilder &Builder);
101 void clear();
102 ///@}
103};
104
105class DebugAssignmentTrackingAnalysis
106 : public AnalysisInfoMixin<DebugAssignmentTrackingAnalysis> {
107 friend AnalysisInfoMixin<DebugAssignmentTrackingAnalysis>;
108 static AnalysisKey Key;
109
110public:
111 using Result = FunctionVarLocs;
112 Result run(Function &F, FunctionAnalysisManager &FAM);
113};
114
115class DebugAssignmentTrackingPrinterPass
116 : public PassInfoMixin<DebugAssignmentTrackingPrinterPass> {
117 raw_ostream &OS;
118
119public:
120 DebugAssignmentTrackingPrinterPass(raw_ostream &OS) : OS(OS) {}
121 PreservedAnalyses run(Function &F, FunctionAnalysisManager &FAM);
122};
123
124class AssignmentTrackingAnalysis : public FunctionPass {
125 std::unique_ptr<FunctionVarLocs> Results;
126
127public:
128 static char ID;
129
130 AssignmentTrackingAnalysis();
131
132 bool runOnFunction(Function &F) override;
133
134 static bool isRequired() { return true; }
135
136 void getAnalysisUsage(AnalysisUsage &AU) const override {
137 AU.setPreservesAll();
138 }
139
140 const FunctionVarLocs *getResults() { return Results.get(); }
141};
142
143} // end namespace llvm
144#endif // LLVM_CODEGEN_ASSIGNMENTTRACKINGANALYSIS_H
145

source code of llvm/include/llvm/CodeGen/AssignmentTrackingAnalysis.h