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