1 //===- RDFLiveness.h --------------------------------------------*- C++ -*-===//
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
7 //===----------------------------------------------------------------------===//
9 // Recalculate the liveness information given a data flow graph.
10 // This includes block live-ins and kill flags.
12 #ifndef LLVM_LIB_TARGET_HEXAGON_RDFLIVENESS_H
13 #define LLVM_LIB_TARGET_HEXAGON_RDFLIVENESS_H
16 #include "RDFRegisters.h"
17 #include "llvm/ADT/DenseMap.h"
18 #include "llvm/MC/LaneBitmask.h"
25 class MachineBasicBlock
;
26 class MachineDominanceFrontier
;
27 class MachineDominatorTree
;
28 class MachineRegisterInfo
;
29 class TargetRegisterInfo
;
35 // This is really a std::map, except that it provides a non-trivial
36 // default constructor to the element accessed via [].
38 LiveMapType(const PhysicalRegisterInfo
&pri
) : Empty(pri
) {}
40 RegisterAggr
&operator[] (MachineBasicBlock
*B
) {
41 return Map
.emplace(B
, Empty
).first
->second
;
46 std::map
<MachineBasicBlock
*,RegisterAggr
> Map
;
49 using NodeRef
= std::pair
<NodeId
, LaneBitmask
>;
50 using NodeRefSet
= std::set
<NodeRef
>;
51 // RegisterId in RefMap must be normalized.
52 using RefMap
= std::map
<RegisterId
, NodeRefSet
>;
54 Liveness(MachineRegisterInfo
&mri
, const DataFlowGraph
&g
)
55 : DFG(g
), TRI(g
.getTRI()), PRI(g
.getPRI()), MDT(g
.getDT()),
56 MDF(g
.getDF()), LiveMap(g
.getPRI()), Empty(), NoRegs(g
.getPRI()) {}
58 NodeList
getAllReachingDefs(RegisterRef RefRR
, NodeAddr
<RefNode
*> RefA
,
59 bool TopShadows
, bool FullChain
, const RegisterAggr
&DefRRs
);
61 NodeList
getAllReachingDefs(NodeAddr
<RefNode
*> RefA
) {
62 return getAllReachingDefs(RefA
.Addr
->getRegRef(DFG
), RefA
, false,
66 NodeList
getAllReachingDefs(RegisterRef RefRR
, NodeAddr
<RefNode
*> RefA
) {
67 return getAllReachingDefs(RefRR
, RefA
, false, false, NoRegs
);
70 NodeSet
getAllReachedUses(RegisterRef RefRR
, NodeAddr
<DefNode
*> DefA
,
71 const RegisterAggr
&DefRRs
);
73 NodeSet
getAllReachedUses(RegisterRef RefRR
, NodeAddr
<DefNode
*> DefA
) {
74 return getAllReachedUses(RefRR
, DefA
, NoRegs
);
77 std::pair
<NodeSet
,bool> getAllReachingDefsRec(RegisterRef RefRR
,
78 NodeAddr
<RefNode
*> RefA
, NodeSet
&Visited
, const NodeSet
&Defs
);
80 NodeAddr
<RefNode
*> getNearestAliasedRef(RegisterRef RefRR
,
81 NodeAddr
<InstrNode
*> IA
);
83 LiveMapType
&getLiveMap() { return LiveMap
; }
84 const LiveMapType
&getLiveMap() const { return LiveMap
; }
86 const RefMap
&getRealUses(NodeId P
) const {
87 auto F
= RealUseMap
.find(P
);
88 return F
== RealUseMap
.end() ? Empty
: F
->second
;
91 void computePhiInfo();
92 void computeLiveIns();
95 void resetKills(MachineBasicBlock
*B
);
97 void trace(bool T
) { Trace
= T
; }
100 const DataFlowGraph
&DFG
;
101 const TargetRegisterInfo
&TRI
;
102 const PhysicalRegisterInfo
&PRI
;
103 const MachineDominatorTree
&MDT
;
104 const MachineDominanceFrontier
&MDF
;
107 const RegisterAggr NoRegs
;
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 using NodeBlockMap
= DenseMap
<NodeId
, MachineBasicBlock
*>;
119 // map: NodeId -> (map: RegisterId -> NodeRefSet)
120 // phi id -> (map: register -> set of reached non-phi uses)
121 std::map
<NodeId
, RefMap
> RealUseMap
;
123 // Inverse iterated dominance frontier.
124 std::map
<MachineBasicBlock
*,std::set
<MachineBasicBlock
*>> IIDF
;
127 std::map
<MachineBasicBlock
*,RefMap
> PhiLON
;
129 // Phi uses are considered to be located at the end of the block that
130 // they are associated with. The reaching def of a phi use dominates the
131 // block that the use corresponds to, but not the block that contains
132 // the phi itself. To include these uses in the liveness propagation (up
133 // the dominator tree), create a map: block -> set of uses live on exit.
134 std::map
<MachineBasicBlock
*,RefMap
> PhiLOX
;
136 MachineBasicBlock
*getBlockWithRef(NodeId RN
) const;
137 void traverse(MachineBasicBlock
*B
, RefMap
&LiveIn
);
138 void emptify(RefMap
&M
);
140 std::pair
<NodeSet
,bool> getAllReachingDefsRecImpl(RegisterRef RefRR
,
141 NodeAddr
<RefNode
*> RefA
, NodeSet
&Visited
, const NodeSet
&Defs
,
142 unsigned Nest
, unsigned MaxNest
);
145 raw_ostream
&operator<<(raw_ostream
&OS
, const Print
<Liveness::RefMap
> &P
);
147 } // end namespace rdf
149 } // end namespace llvm
151 #endif // LLVM_LIB_TARGET_HEXAGON_RDFLIVENESS_H