RDFLiveness.h 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186
  1. #pragma once
  2. #ifdef __GNUC__
  3. #pragma GCC diagnostic push
  4. #pragma GCC diagnostic ignored "-Wunused-parameter"
  5. #endif
  6. //===- RDFLiveness.h --------------------------------------------*- 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. // Recalculate the liveness information given a data flow graph.
  15. // This includes block live-ins and kill flags.
  16. #ifndef LLVM_CODEGEN_RDFLIVENESS_H
  17. #define LLVM_CODEGEN_RDFLIVENESS_H
  18. #include "RDFGraph.h"
  19. #include "RDFRegisters.h"
  20. #include "llvm/ADT/DenseMap.h"
  21. #include "llvm/MC/LaneBitmask.h"
  22. #include <map>
  23. #include <set>
  24. #include <unordered_map>
  25. #include <unordered_set>
  26. #include <utility>
  27. namespace llvm {
  28. class MachineBasicBlock;
  29. class MachineDominanceFrontier;
  30. class MachineDominatorTree;
  31. class MachineRegisterInfo;
  32. class TargetRegisterInfo;
  33. } // namespace llvm
  34. namespace llvm {
  35. namespace rdf {
  36. namespace detail {
  37. using NodeRef = std::pair<NodeId, LaneBitmask>;
  38. } // namespace detail
  39. } // namespace rdf
  40. } // namespace llvm
  41. namespace std {
  42. template <> struct hash<llvm::rdf::detail::NodeRef> {
  43. std::size_t operator()(llvm::rdf::detail::NodeRef R) const {
  44. return std::hash<llvm::rdf::NodeId>{}(R.first) ^
  45. std::hash<llvm::LaneBitmask::Type>{}(R.second.getAsInteger());
  46. }
  47. };
  48. } // namespace std
  49. namespace llvm {
  50. namespace rdf {
  51. struct Liveness {
  52. public:
  53. // This is really a std::map, except that it provides a non-trivial
  54. // default constructor to the element accessed via [].
  55. struct LiveMapType {
  56. LiveMapType(const PhysicalRegisterInfo &pri) : Empty(pri) {}
  57. RegisterAggr &operator[] (MachineBasicBlock *B) {
  58. return Map.emplace(B, Empty).first->second;
  59. }
  60. private:
  61. RegisterAggr Empty;
  62. std::map<MachineBasicBlock*,RegisterAggr> Map;
  63. };
  64. using NodeRef = detail::NodeRef;
  65. using NodeRefSet = std::unordered_set<NodeRef>;
  66. using RefMap = std::unordered_map<RegisterId, NodeRefSet>;
  67. Liveness(MachineRegisterInfo &mri, const DataFlowGraph &g)
  68. : DFG(g), TRI(g.getTRI()), PRI(g.getPRI()), MDT(g.getDT()),
  69. MDF(g.getDF()), LiveMap(g.getPRI()), Empty(), NoRegs(g.getPRI()) {}
  70. NodeList getAllReachingDefs(RegisterRef RefRR, NodeAddr<RefNode*> RefA,
  71. bool TopShadows, bool FullChain, const RegisterAggr &DefRRs);
  72. NodeList getAllReachingDefs(NodeAddr<RefNode*> RefA) {
  73. return getAllReachingDefs(RefA.Addr->getRegRef(DFG), RefA, false,
  74. false, NoRegs);
  75. }
  76. NodeList getAllReachingDefs(RegisterRef RefRR, NodeAddr<RefNode*> RefA) {
  77. return getAllReachingDefs(RefRR, RefA, false, false, NoRegs);
  78. }
  79. NodeSet getAllReachedUses(RegisterRef RefRR, NodeAddr<DefNode*> DefA,
  80. const RegisterAggr &DefRRs);
  81. NodeSet getAllReachedUses(RegisterRef RefRR, NodeAddr<DefNode*> DefA) {
  82. return getAllReachedUses(RefRR, DefA, NoRegs);
  83. }
  84. std::pair<NodeSet,bool> getAllReachingDefsRec(RegisterRef RefRR,
  85. NodeAddr<RefNode*> RefA, NodeSet &Visited, const NodeSet &Defs);
  86. NodeAddr<RefNode*> getNearestAliasedRef(RegisterRef RefRR,
  87. NodeAddr<InstrNode*> IA);
  88. LiveMapType &getLiveMap() { return LiveMap; }
  89. const LiveMapType &getLiveMap() const { return LiveMap; }
  90. const RefMap &getRealUses(NodeId P) const {
  91. auto F = RealUseMap.find(P);
  92. return F == RealUseMap.end() ? Empty : F->second;
  93. }
  94. void computePhiInfo();
  95. void computeLiveIns();
  96. void resetLiveIns();
  97. void resetKills();
  98. void resetKills(MachineBasicBlock *B);
  99. void trace(bool T) { Trace = T; }
  100. private:
  101. const DataFlowGraph &DFG;
  102. const TargetRegisterInfo &TRI;
  103. const PhysicalRegisterInfo &PRI;
  104. const MachineDominatorTree &MDT;
  105. const MachineDominanceFrontier &MDF;
  106. LiveMapType LiveMap;
  107. const RefMap Empty;
  108. const RegisterAggr NoRegs;
  109. bool Trace = false;
  110. // Cache of mapping from node ids (for RefNodes) to the containing
  111. // basic blocks. Not computing it each time for each node reduces
  112. // the liveness calculation time by a large fraction.
  113. DenseMap<NodeId, MachineBasicBlock *> NBMap;
  114. // Phi information:
  115. //
  116. // RealUseMap
  117. // map: NodeId -> (map: RegisterId -> NodeRefSet)
  118. // phi id -> (map: register -> set of reached non-phi uses)
  119. DenseMap<NodeId, RefMap> RealUseMap;
  120. // Inverse iterated dominance frontier.
  121. std::map<MachineBasicBlock*,std::set<MachineBasicBlock*>> IIDF;
  122. // Live on entry.
  123. std::map<MachineBasicBlock*,RefMap> PhiLON;
  124. // Phi uses are considered to be located at the end of the block that
  125. // they are associated with. The reaching def of a phi use dominates the
  126. // block that the use corresponds to, but not the block that contains
  127. // the phi itself. To include these uses in the liveness propagation (up
  128. // the dominator tree), create a map: block -> set of uses live on exit.
  129. std::map<MachineBasicBlock*,RefMap> PhiLOX;
  130. MachineBasicBlock *getBlockWithRef(NodeId RN) const;
  131. void traverse(MachineBasicBlock *B, RefMap &LiveIn);
  132. void emptify(RefMap &M);
  133. std::pair<NodeSet,bool> getAllReachingDefsRecImpl(RegisterRef RefRR,
  134. NodeAddr<RefNode*> RefA, NodeSet &Visited, const NodeSet &Defs,
  135. unsigned Nest, unsigned MaxNest);
  136. };
  137. raw_ostream &operator<<(raw_ostream &OS, const Print<Liveness::RefMap> &P);
  138. } // end namespace rdf
  139. } // end namespace llvm
  140. #endif // LLVM_CODEGEN_RDFLIVENESS_H
  141. #ifdef __GNUC__
  142. #pragma GCC diagnostic pop
  143. #endif