10946e70aSDimitry Andric //===- RDFLiveness.h --------------------------------------------*- C++ -*-===// 20946e70aSDimitry Andric // 30946e70aSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40946e70aSDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50946e70aSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60946e70aSDimitry Andric // 70946e70aSDimitry Andric //===----------------------------------------------------------------------===// 80946e70aSDimitry Andric // 90946e70aSDimitry Andric // Recalculate the liveness information given a data flow graph. 100946e70aSDimitry Andric // This includes block live-ins and kill flags. 110946e70aSDimitry Andric 12fe6060f1SDimitry Andric #ifndef LLVM_CODEGEN_RDFLIVENESS_H 13fe6060f1SDimitry Andric #define LLVM_CODEGEN_RDFLIVENESS_H 140946e70aSDimitry Andric 150946e70aSDimitry Andric #include "RDFGraph.h" 160946e70aSDimitry Andric #include "RDFRegisters.h" 170946e70aSDimitry Andric #include "llvm/ADT/DenseMap.h" 180946e70aSDimitry Andric #include "llvm/MC/LaneBitmask.h" 190946e70aSDimitry Andric #include <map> 200946e70aSDimitry Andric #include <set> 21e8d8bef9SDimitry Andric #include <unordered_map> 22e8d8bef9SDimitry Andric #include <unordered_set> 230946e70aSDimitry Andric #include <utility> 240946e70aSDimitry Andric 250946e70aSDimitry Andric namespace llvm { 260946e70aSDimitry Andric 270946e70aSDimitry Andric class MachineBasicBlock; 280946e70aSDimitry Andric class MachineDominanceFrontier; 290946e70aSDimitry Andric class MachineDominatorTree; 300946e70aSDimitry Andric class MachineRegisterInfo; 310946e70aSDimitry Andric class TargetRegisterInfo; 320946e70aSDimitry Andric 33e8d8bef9SDimitry Andric namespace rdf { 34e8d8bef9SDimitry Andric namespace detail { 35e8d8bef9SDimitry Andric 36e8d8bef9SDimitry Andric using NodeRef = std::pair<NodeId, LaneBitmask>; 37e8d8bef9SDimitry Andric 38e8d8bef9SDimitry Andric } // namespace detail 39e8d8bef9SDimitry Andric } // namespace rdf 40e8d8bef9SDimitry Andric } // namespace llvm 41e8d8bef9SDimitry Andric 42e8d8bef9SDimitry Andric namespace std { 43e8d8bef9SDimitry Andric 44e8d8bef9SDimitry Andric template <> struct hash<llvm::rdf::detail::NodeRef> { 45e8d8bef9SDimitry Andric std::size_t operator()(llvm::rdf::detail::NodeRef R) const { 46e8d8bef9SDimitry Andric return std::hash<llvm::rdf::NodeId>{}(R.first) ^ 47e8d8bef9SDimitry Andric std::hash<llvm::LaneBitmask::Type>{}(R.second.getAsInteger()); 48e8d8bef9SDimitry Andric } 49e8d8bef9SDimitry Andric }; 50e8d8bef9SDimitry Andric 51e8d8bef9SDimitry Andric } // namespace std 52e8d8bef9SDimitry Andric 53*06c3fb27SDimitry Andric namespace llvm::rdf { 540946e70aSDimitry Andric 550946e70aSDimitry Andric struct Liveness { 560946e70aSDimitry Andric public: 57*06c3fb27SDimitry Andric using LiveMapType = RegisterAggrMap<MachineBasicBlock *>; 58e8d8bef9SDimitry Andric using NodeRef = detail::NodeRef; 59e8d8bef9SDimitry Andric using NodeRefSet = std::unordered_set<NodeRef>; 60e8d8bef9SDimitry Andric using RefMap = std::unordered_map<RegisterId, NodeRefSet>; 610946e70aSDimitry Andric 620946e70aSDimitry Andric Liveness(MachineRegisterInfo &mri, const DataFlowGraph &g) 630946e70aSDimitry Andric : DFG(g), TRI(g.getTRI()), PRI(g.getPRI()), MDT(g.getDT()), 640946e70aSDimitry Andric MDF(g.getDF()), LiveMap(g.getPRI()), Empty(), NoRegs(g.getPRI()) {} 650946e70aSDimitry Andric 660946e70aSDimitry Andric NodeList getAllReachingDefs(RegisterRef RefRR, NodeAddr<RefNode *> RefA, 67*06c3fb27SDimitry Andric bool TopShadows, bool FullChain, 68*06c3fb27SDimitry Andric const RegisterAggr &DefRRs); 690946e70aSDimitry Andric 700946e70aSDimitry Andric NodeList getAllReachingDefs(NodeAddr<RefNode *> RefA) { 71*06c3fb27SDimitry Andric return getAllReachingDefs(RefA.Addr->getRegRef(DFG), RefA, false, false, 72*06c3fb27SDimitry Andric NoRegs); 730946e70aSDimitry Andric } 740946e70aSDimitry Andric 750946e70aSDimitry Andric NodeList getAllReachingDefs(RegisterRef RefRR, NodeAddr<RefNode *> RefA) { 760946e70aSDimitry Andric return getAllReachingDefs(RefRR, RefA, false, false, NoRegs); 770946e70aSDimitry Andric } 780946e70aSDimitry Andric 790946e70aSDimitry Andric NodeSet getAllReachedUses(RegisterRef RefRR, NodeAddr<DefNode *> DefA, 800946e70aSDimitry Andric const RegisterAggr &DefRRs); 810946e70aSDimitry Andric 820946e70aSDimitry Andric NodeSet getAllReachedUses(RegisterRef RefRR, NodeAddr<DefNode *> DefA) { 830946e70aSDimitry Andric return getAllReachedUses(RefRR, DefA, NoRegs); 840946e70aSDimitry Andric } 850946e70aSDimitry Andric 860946e70aSDimitry Andric std::pair<NodeSet, bool> getAllReachingDefsRec(RegisterRef RefRR, 87*06c3fb27SDimitry Andric NodeAddr<RefNode *> RefA, 88*06c3fb27SDimitry Andric NodeSet &Visited, 89*06c3fb27SDimitry Andric const NodeSet &Defs); 900946e70aSDimitry Andric 910946e70aSDimitry Andric NodeAddr<RefNode *> getNearestAliasedRef(RegisterRef RefRR, 920946e70aSDimitry Andric NodeAddr<InstrNode *> IA); 930946e70aSDimitry Andric 940946e70aSDimitry Andric LiveMapType &getLiveMap() { return LiveMap; } 950946e70aSDimitry Andric const LiveMapType &getLiveMap() const { return LiveMap; } 960946e70aSDimitry Andric 970946e70aSDimitry Andric const RefMap &getRealUses(NodeId P) const { 980946e70aSDimitry Andric auto F = RealUseMap.find(P); 990946e70aSDimitry Andric return F == RealUseMap.end() ? Empty : F->second; 1000946e70aSDimitry Andric } 1010946e70aSDimitry Andric 1020946e70aSDimitry Andric void computePhiInfo(); 1030946e70aSDimitry Andric void computeLiveIns(); 1040946e70aSDimitry Andric void resetLiveIns(); 1050946e70aSDimitry Andric void resetKills(); 1060946e70aSDimitry Andric void resetKills(MachineBasicBlock *B); 1070946e70aSDimitry Andric 1080946e70aSDimitry Andric void trace(bool T) { Trace = T; } 1090946e70aSDimitry Andric 1100946e70aSDimitry Andric private: 1110946e70aSDimitry Andric const DataFlowGraph &DFG; 1120946e70aSDimitry Andric const TargetRegisterInfo &TRI; 1130946e70aSDimitry Andric const PhysicalRegisterInfo &PRI; 1140946e70aSDimitry Andric const MachineDominatorTree &MDT; 1150946e70aSDimitry Andric const MachineDominanceFrontier &MDF; 1160946e70aSDimitry Andric LiveMapType LiveMap; 1170946e70aSDimitry Andric const RefMap Empty; 1180946e70aSDimitry Andric const RegisterAggr NoRegs; 1190946e70aSDimitry Andric bool Trace = false; 1200946e70aSDimitry Andric 1210946e70aSDimitry Andric // Cache of mapping from node ids (for RefNodes) to the containing 1220946e70aSDimitry Andric // basic blocks. Not computing it each time for each node reduces 1230946e70aSDimitry Andric // the liveness calculation time by a large fraction. 124e8d8bef9SDimitry Andric DenseMap<NodeId, MachineBasicBlock *> NBMap; 1250946e70aSDimitry Andric 1260946e70aSDimitry Andric // Phi information: 1270946e70aSDimitry Andric // 1280946e70aSDimitry Andric // RealUseMap 1290946e70aSDimitry Andric // map: NodeId -> (map: RegisterId -> NodeRefSet) 1300946e70aSDimitry Andric // phi id -> (map: register -> set of reached non-phi uses) 131e8d8bef9SDimitry Andric DenseMap<NodeId, RefMap> RealUseMap; 1320946e70aSDimitry Andric 1330946e70aSDimitry Andric // Inverse iterated dominance frontier. 1340946e70aSDimitry Andric std::map<MachineBasicBlock *, std::set<MachineBasicBlock *>> IIDF; 1350946e70aSDimitry Andric 1360946e70aSDimitry Andric // Live on entry. 1370946e70aSDimitry Andric std::map<MachineBasicBlock *, RefMap> PhiLON; 1380946e70aSDimitry Andric 1390946e70aSDimitry Andric // Phi uses are considered to be located at the end of the block that 1400946e70aSDimitry Andric // they are associated with. The reaching def of a phi use dominates the 1410946e70aSDimitry Andric // block that the use corresponds to, but not the block that contains 1420946e70aSDimitry Andric // the phi itself. To include these uses in the liveness propagation (up 1430946e70aSDimitry Andric // the dominator tree), create a map: block -> set of uses live on exit. 1440946e70aSDimitry Andric std::map<MachineBasicBlock *, RefMap> PhiLOX; 1450946e70aSDimitry Andric 1460946e70aSDimitry Andric MachineBasicBlock *getBlockWithRef(NodeId RN) const; 1470946e70aSDimitry Andric void traverse(MachineBasicBlock *B, RefMap &LiveIn); 1480946e70aSDimitry Andric void emptify(RefMap &M); 1490946e70aSDimitry Andric 150*06c3fb27SDimitry Andric std::pair<NodeSet, bool> 151*06c3fb27SDimitry Andric getAllReachingDefsRecImpl(RegisterRef RefRR, NodeAddr<RefNode *> RefA, 152*06c3fb27SDimitry Andric NodeSet &Visited, const NodeSet &Defs, 1530946e70aSDimitry Andric unsigned Nest, unsigned MaxNest); 1540946e70aSDimitry Andric }; 1550946e70aSDimitry Andric 1560946e70aSDimitry Andric raw_ostream &operator<<(raw_ostream &OS, const Print<Liveness::RefMap> &P); 1570946e70aSDimitry Andric 158*06c3fb27SDimitry Andric } // end namespace llvm::rdf 1590946e70aSDimitry Andric 160fe6060f1SDimitry Andric #endif // LLVM_CODEGEN_RDFLIVENESS_H 161