62 raw_ostream &operator<< (raw_ostream &OS, const Print<Liveness::RefMap> &
P) {
64 for (
auto &
I :
P.Obj) {
65 OS <<
' ' <<
printReg(
I.first, &
P.G.getTRI()) <<
'{';
66 for (
auto J =
I.second.begin(),
E =
I.second.end(); J !=
E; ) {
127 auto SNA = DFG.addr<
RefNode*>(Start);
128 if (
NodeId RD = SNA.Addr->getReachingDef())
131 for (
auto S : DFG.getRelatedRefs(RefA.
Addr->
getOwner(DFG), RefA))
142 for (
unsigned i = 0; i < DefQ.
size(); ++i) {
148 if (!DFG.IsPreservingDef(
TA))
153 for (
auto S : DFG.getRelatedRefs(
TA.Addr->getOwner(DFG),
TA))
164 if (!IsPhi && !PRI.alias(RefRR,
TA.Addr->getRegRef(DFG)))
167 Owners.
insert(
TA.Addr->getOwner(DFG).Id);
186 return MDT.dominates(BB, BA);
198 return MDT.dominates(CB, CA);
209 std::vector<NodeId> Tmp(Owners.
begin(), Owners.
end());
248 if (FullChain || IsPhi || !RRs.
hasCoverOf(QR))
251 RDefs.
insert(RDefs.
end(), Ds.begin(), Ds.end());
255 uint16_t Flags = DA.Addr->getFlags();
258 RRs.
insert(DA.Addr->getRegRef(DFG));
270 std::pair<NodeSet,bool>
273 return getAllReachingDefsRecImpl(RefRR, RefA, Visited, Defs, 0,
MaxRecNest);
276 std::pair<NodeSet,bool>
278 NodeSet &Visited,
const NodeSet &Defs,
unsigned Nest,
unsigned MaxNest) {
285 const auto DA = DFG.addr<
const DefNode*>(
D);
287 DefRRs.
insert(DA.Addr->getRegRef(DFG));
290 NodeList RDs = getAllReachingDefs(RefRR, RefA,
false,
true, DefRRs);
292 return { Defs,
true };
297 TmpDefs.insert(R.Id);
302 Result.insert(DA.Id);
306 if (Visited.count(PA.
Id))
308 Visited.insert(PA.
Id);
311 const auto &
T = getAllReachingDefsRecImpl(RefRR, U, Visited, TmpDefs,
314 return {
T.first,
false };
315 Result.insert(
T.first.begin(),
T.first.end());
319 return { Result,
true };
332 return T.Id == FindId;
346 if (!PRI.alias(R.Addr->getRegRef(DFG), RefRR))
367 if ((
N =
N->getIDom()))
368 BA = DFG.findBlock(
N->getBlock());
395 auto UA = DFG.addr<
UseNode*>(U);
398 if (PRI.alias(RefRR, UR) && !DefRRs.
hasCoverOf(UR))
401 U = UA.Addr->getSibling();
411 if (DefRRs.
hasCoverOf(DR) || !PRI.alias(RefRR, DR))
414 if (DFG.IsPreservingDef(DA)) {
416 T = getAllReachedUses(RefRR, DA, DefRRs);
420 T = getAllReachedUses(RefRR, DA, NewDefRRs);
422 Uses.insert(T.begin(), T.end());
435 Phis.
insert(Phis.
end(), Ps.begin(), Ps.end());
439 std::map<NodeId,std::map<NodeId,RegisterAggr>> PhiUp;
440 std::vector<NodeId> PhiUQ;
441 std::map<NodeId,RegisterAggr> PhiDRs;
447 RefMap &RealUses = RealUseMap[PhiA.Id];
448 NodeList PhiRefs = PhiA.Addr->members(DFG);
458 DRs.
insert(R.Addr->getRegRef(DFG));
460 PhiDefs.insert(R.Id);
462 PhiDRs.insert(std::make_pair(PhiA.Id, DRs));
469 for (
unsigned i = 0; i < DefQ.
size(); ++i) {
490 for (
auto T : DFG.getRelatedRefs(A.
Addr->
getOwner(DFG), A)) {
513 for (
auto UI = RealUses.begin(), UE = RealUses.end(); UI != UE; ) {
520 for (std::pair<NodeId,LaneBitmask>
I : Uses) {
521 auto UA = DFG.addr<
UseNode*>(
I.first);
528 if (PhiDefs.count(DA.Id))
530 Covered.
insert(DA.Addr->getRegRef(DFG));
536 UI->second.insert({
I.first, S.
Mask});
539 UI = UI->second.empty() ? RealUses.erase(UI) : std::next(UI);
544 if (!RealUses.empty())
545 PhiUQ.push_back(PhiA.Id);
554 for (
auto I : PhiRefs) {
562 NodeList Ds = getAllReachingDefs(UR, PUA,
true,
false, NoRegs);
568 std::map<NodeId,RegisterAggr> &M = PhiUp[PUA.
Id];
571 M.insert(std::make_pair(RP, DefRRs));
573 F->second.insert(DefRRs);
575 DefRRs.
insert(
D.Addr->getRegRef(DFG));
584 dbgs() <<
"Phi-up-to-phi map with intervening defs:\n";
585 for (
auto I : PhiUp) {
587 for (
auto R :
I.second)
617 for (
unsigned i = 0; i < PhiUQ.size(); ++i) {
618 auto PA = DFG.addr<
PhiNode*>(PhiUQ[i]);
620 RefMap &RUM = RealUseMap[PA.Id];
623 std::map<NodeId,RegisterAggr> &PUM = PhiUp[UA.Id];
624 RegisterRef UR = PRI.normalize(UA.Addr->getRegRef(DFG));
625 for (
const std::pair<NodeId,RegisterAggr> &
P : PUM) {
626 bool Changed =
false;
641 for (
const std::pair<RegisterId,NodeRefSet> &
T : RUM) {
650 for (std::pair<NodeId,LaneBitmask> V :
T.second) {
656 Changed |= RS.insert({V.first,SS.Mask}).
second;
662 PhiUQ.push_back(
P.first);
668 dbgs() <<
"Real use map:\n";
669 for (
auto I : RealUseMap) {
692 NBMap.
insert(std::make_pair(
RA.Id, BB));
693 NBMap.insert(std::make_pair(IA.Id, BB));
702 auto F1 = MDF.find(&
B);
706 for (
unsigned i = 0; i < IDFB.size(); ++i) {
707 auto F2 = MDF.find(IDFB[i]);
709 IDFB.
insert(F2->second.begin(), F2->second.end());
713 IDF[&
B].insert(IDFB.begin(), IDFB.end());
717 for (
auto S :
I.second)
718 IIDF[S].insert(
I.first);
730 for (
const RefMap::value_type &S : RealUseMap[
P.Id])
731 LON[S.first].
insert(S.second.begin(), S.second.end());
735 dbgs() <<
"Phi live-on-entry map:\n";
736 for (
auto &
I : PhiLON)
737 dbgs() <<
"block #" <<
I.first->getNumber() <<
" -> " 747 RefMap &RUs = RealUseMap[PA.Id];
752 for (
auto U : PA.Addr->members_if(DFG.IsRef<
NodeAttrs::Use>, DFG)) {
753 if (!SeenUses.insert(U.Id).second)
771 RefMap &LOX = PhiLOX[PrA.Addr->getCode()];
773 for (
const std::pair<RegisterId,NodeRefSet> &RS : RUs) {
775 for (std::pair<NodeId,LaneBitmask>
P : RS.second) {
780 NodeList Ds = getAllReachingDefs(S, PUA,
true,
false, NoRegs);
786 LOX[S.
Reg].insert({
D.Id, TM});
792 SeenUses.insert(
T.Id);
798 dbgs() <<
"Phi live-on-exit map:\n";
799 for (
auto &
I : PhiLOX)
800 dbgs() <<
"block #" <<
I.first->getNumber() <<
" -> " 805 traverse(&MF.front(), LiveIn);
808 LiveMap[&MF.front()].insert(DFG.getLiveIns());
813 std::vector<RegisterRef> LV;
814 for (
auto I =
B.livein_begin(),
E =
B.livein_end();
I !=
E; ++
I)
828 dbgs() <<
"\tcomp = {";
838 for (
auto &
B : DFG.getMF()) {
840 std::vector<unsigned>
T;
841 for (
auto I =
B.livein_begin(),
E =
B.livein_end();
I !=
E; ++
I)
842 T.push_back(
I->PhysReg);
855 for (
auto &
B : DFG.getMF())
869 if ((M &
I.LaneMask).any())
877 CopyLiveIns(B, LiveIn);
879 CopyLiveIns(
SI, Live);
892 if (!
Op.isReg() || !
Op.isDef() ||
Op.isImplicit())
894 unsigned R =
Op.getReg();
901 if (!
Op.isReg() || !
Op.isUse() ||
Op.isUndef())
903 unsigned R =
Op.getReg();
924 auto F = NBMap.find(RN);
925 if (
F != NBMap.end())
962 LiveIn[S.first].insert(S.second.begin(), S.second.end());
967 <<
" after recursion into: {";
969 dbgs() <<
' ' <<
I->getBlock()->getNumber();
978 LiveIn[S.first].insert(S.second.begin(), S.second.end());
981 dbgs() <<
"after LOX\n";
993 RefMap LiveInCopy = LiveIn;
996 for (
const std::pair<RegisterId,NodeRefSet> &
LE : LiveInCopy) {
1020 if (!DFG.IsPreservingDef(DA)) {
1026 if (RRs.
insert(DA.Addr->getRegRef(DFG)).hasCoverOf(LRef))
1047 NewDefs.insert({
TA.Id,T.
Mask});
1054 RRs.
insert(
TA.Addr->getRegRef(DFG));
1065 dbgs() <<
"after defs in block\n";
1071 for (
auto I : DFG.getFunc().Addr->findBlock(B, DFG).Addr->members(DFG)) {
1078 RegisterRef RR = PRI.normalize(UA.Addr->getRegRef(DFG));
1080 if (getBlockWithRef(
D.Id) !=
B)
1081 LiveIn[RR.
Reg].insert({D.Id,RR.Mask});
1086 dbgs() <<
"after uses in block\n";
1095 for (
auto &R : LON) {
1097 for (
auto P : R.second)
1103 dbgs() <<
"after phi uses in block\n";
1108 for (
auto C : IIDF[B]) {
1110 for (
const std::pair<RegisterId,NodeRefSet> &S : LiveIn)
1111 for (
auto R : S.second)
1112 if (MDT.properlyDominates(getBlockWithRef(R.first),
C))
1117 void Liveness::emptify(
RefMap &M) {
1118 for (
auto I = M.begin(),
E = M.end();
I !=
E; )
1119 I =
I->second.empty() ? M.erase(
I) : std::next(
I);
bool hasCoverOf(RegisterRef RR) const
NodeId getReachedUse() const
A common definition of LaneBitmask for use in TableGen and CodeGen.
uint16_t getFlags() const
static cl::opt< unsigned > MaxRecNest("rdf-liveness-max-rec", cl::init(25), cl::Hidden, cl::desc("Maximum recursion level"))
This class represents lattice values for constants.
size_type size() const
Determine the number of elements in the SetVector.
bool hasAliasOf(RegisterRef RR) const
std::pair< NodeSet, bool > getAllReachingDefsRec(RegisterRef RefRR, NodeAddr< RefNode *> RefA, NodeSet &Visited, const NodeSet &Defs)
unsigned const TargetRegisterInfo * TRI
iterator_range< mop_iterator > operands()
RegisterRef intersectWith(RegisterRef RR) const
rr_iterator rr_begin() const
iterator end()
Get an iterator to the end of the SetVector.
RegisterRef clearIn(RegisterRef RR) const
iterator_range< succ_iterator > successors()
SI optimize exec mask operations pre RA
void clearKillInfo()
Clears kill flags on all operands.
Printable printMBBReference(const MachineBasicBlock &MBB)
Prints a machine basic block reference.
Printable printReg(unsigned Reg, const TargetRegisterInfo *TRI=nullptr, unsigned SubIdx=0, const MachineRegisterInfo *MRI=nullptr)
Prints virtual and physical registers with or without a TRI instance.
A Use represents the edge between a Value definition and its users.
RegisterRef getRegRef(const DataFlowGraph &G) const
NodeAddr< RefNode * > getNearestAliasedRef(RegisterRef RefRR, NodeAddr< InstrNode *> IA)
Find the nearest ref node aliased to RefRR, going upwards in the data flow, starting from the instruc...
bool insert(const value_type &X)
Insert a new element into the SetVector.
unsigned getSubRegIndex() const
Returns sub-register index of the current sub-register.
iterator begin()
Get an iterator to the beginning of the SetVector.
Base class for the actual dominator tree node.
instr_iterator insert(instr_iterator I, MachineInstr *M)
Insert MI into the instruction list before I, possibly inside a bundle.
reverse_iterator rbegin()
NodeAddr< NodeBase * > getOwner(const DataFlowGraph &G)
size_type count(const key_type &key) const
Count the number of elements of a given key in the SetVector.
uint16_t MCPhysReg
An unsigned integer type large enough to represent all physical registers, but not necessarily virtua...
initializer< Ty > init(const Ty &Val)
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
unsigned getSubReg() const
Returns current sub-register.
rr_iterator rr_end() const
Iterator that enumerates the sub-registers of a Reg and the associated sub-register indices...
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
LLVM_ATTRIBUTE_ALWAYS_INLINE iterator begin()
static ManagedStatic< OptionRegistry > OR
MCRegAliasIterator enumerates all registers aliasing Reg.
RegisterRef makeRegRef() const
constexpr bool none() const
NodeId getPredecessor() const
auto find_if(R &&Range, UnaryPredicate P) -> decltype(adl_begin(Range))
Provide wrappers to std::find_if which take ranges instead of having to pass begin/end explicitly...
auto remove_if(R &&Range, UnaryPredicate P) -> decltype(adl_begin(Range))
Provide wrappers to std::remove_if which take ranges instead of having to pass begin/end explicitly...
NodeList members_if(Predicate P, const DataFlowGraph &G) const
MCSubRegIterator enumerates all sub-registers of Reg.
bool isDebugInstr() const
NodeList members(const DataFlowGraph &G) const
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
void sort(IteratorTy Start, IteratorTy End)
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
RegisterAggr & insert(RegisterRef RR)
bool isValid() const
Returns true if this iterator is not yet at the end.
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small...
NodeList getAllReachingDefs(RegisterRef RefRR, NodeAddr< RefNode *> RefA, bool TopShadows, bool FullChain, const RegisterAggr &DefRRs)
std::pair< NodeId, LaneBitmask > NodeRef
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
std::map< RegisterId, NodeRefSet > RefMap
bool isValid() const
isValid - returns true if this iterator is not yet at the end.
NodeId getReachedDef() const
iterator insert(iterator I, T &&Elt)
std::set< NodeId > NodeSet
Representation of each machine instruction.
NodeId getReachingDef() const
NodeAddr< NodeBase * > getOwner(const DataFlowGraph &G)
static bool isPhysicalRegister(unsigned Reg)
Return true if the specified register number is in the physical register namespace.
LLVM_ATTRIBUTE_ALWAYS_INLINE iterator end()
static ValueLatticeElement intersect(const ValueLatticeElement &A, const ValueLatticeElement &B)
Combine two sets of facts about the same value into a single set of facts.
LLVM_NODISCARD bool empty() const
std::set< NodeRef > NodeRefSet
NodeSet getAllReachedUses(RegisterRef RefRR, NodeAddr< DefNode *> DefA, const RegisterAggr &DefRRs)
iterator_range< livein_iterator > liveins() const
reverse_iterator rbegin()
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
static bool isCoverOf(RegisterRef RA, RegisterRef RB, const PhysicalRegisterInfo &PRI)
A vector that has set insertion semantics.
MachineBasicBlock * getCode() const
This class implements an extremely fast bulk output stream that can only output to a stream...
NodeId getSibling() const