AssignmentTrackingAnalysis.h 4.1 KB

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