49#include <unordered_map>
57 cl::desc(
"Maximum recursion level"));
63 for (
const auto &
I :
P.Obj) {
65 for (
auto J =
I.second.begin(), E =
I.second.end(); J != E;) {
125 if (
NodeId RD = SNA.Addr->getReachingDef())
139 for (
unsigned i = 0; i < DefQ.
size(); ++i) {
165 return BA.
Addr->getCode();
172 std::map<NodeId, NodeAddr<InstrNode *>> Owners;
173 std::map<MachineBasicBlock *, SmallVector<NodeId, 32>>
Blocks;
177 if (!IsPhi && !PRI.
alias(RefRR, TA.Addr->getRegRef(DFG)))
192 if (StmtA && StmtB) {
196 auto FA = OrdMap.
find(InA);
197 if (FA != OrdMap.
end())
198 return FA->second < OrdMap.
find(InB)->second;
200 for (
auto It = BB->
begin(), E = BB->
end(); It != E; ++It) {
209 if (!StmtA && !StmtB) {
220 OrdMap.
insert({&In, ++Pos});
224 std::vector<MachineBasicBlock *> TmpBB;
225 for (
auto &Bucket :
Blocks) {
226 TmpBB.push_back(Bucket.first);
227 if (Bucket.second.size() > 2)
228 GetOrder(*Bucket.first);
236 std::vector<NodeId> TmpInst;
239 TmpInst.insert(TmpInst.end(), Bucket.rbegin(), Bucket.rend());
281 if (FullChain || IsPhi || !RRs.
hasCoverOf(QR))
288 uint16_t Flags = DA.Addr->getFlags();
291 RRs.
insert(DA.Addr->getRegRef(DFG));
303std::pair<NodeSet, bool>
306 return getAllReachingDefsRecImpl(RefRR, RefA, Visited, Defs, 0,
MaxRecNest);
309std::pair<NodeSet, bool>
312 unsigned Nest,
unsigned MaxNest) {
317 RegisterAggr DefRRs(PRI);
319 const auto DA = DFG.
addr<
const DefNode *>(
D);
321 DefRRs.insert(DA.Addr->getRegRef(DFG));
330 for (NodeAddr<NodeBase *> R : RDs)
335 for (NodeAddr<DefNode *> DA : RDs) {
339 NodeAddr<PhiNode *> PA =
DA.Addr->getOwner(DFG);
340 if (!Visited.
insert(PA.Id).second)
344 const auto &
T = getAllReachingDefsRecImpl(RefRR, U, Visited, TmpDefs,
347 return {
T.first,
false};
348 Result.insert(
T.first.begin(),
T.first.end());
365 return T.Id == FindId;
379 if (!PRI.
alias(R.Addr->getRegRef(DFG), RefRR))
400 if ((
N =
N->getIDom()))
406 Ins = BA.
Addr->members(DFG);
434 U = UA.Addr->getSibling();
438 for (
NodeId D = DefA.
Addr->getReachedDef(), NextD;
D != 0;
D = NextD) {
440 NextD = DA.Addr->getSibling();
455 Uses.insert(
T.begin(),
T.end());
472 std::map<NodeId, std::map<NodeId, RegisterAggr>> PhiUp;
473 std::vector<NodeId> PhiUQ;
474 std::unordered_map<NodeId, RegisterAggr>
481 RefMap &RealUses = RealUseMap[PhiA.Id];
482 NodeList PhiRefs = PhiA.Addr->members(DFG);
492 DRs.
insert(R.Addr->getRegRef(DFG));
496 PhiDRs.insert(std::make_pair(PhiA.Id, DRs));
503 for (
unsigned i = 0; i < DefQ.
size(); ++i) {
514 RealUses[R.Reg].insert({
A.Id, R.Mask});
516 UN =
A.Addr->getSibling();
521 NodeId DN = DA.Addr->getReachedDef();
532 DN =
A.Addr->getSibling();
547 for (
auto UI = RealUses.begin(), UE = RealUses.end(); UI != UE;) {
554 for (std::pair<NodeId, LaneBitmask>
I :
Uses) {
560 RegisterRef R = PhiDRs.at(PhiA.Id).intersectWith(UseR);
566 if (PhiDefs.
count(DA.Id))
568 Covered.
insert(DA.Addr->getRegRef(DFG));
574 UI->second.insert({
I.first, S.
Mask});
577 UI = UI->second.empty() ? RealUses.erase(UI) : std::next(UI);
582 if (!RealUses.empty())
583 PhiUQ.push_back(PhiA.Id);
592 for (
auto I : PhiRefs) {
596 if (PUA.
Addr->getReachingDef() == 0)
605 NodeId RP =
D.Addr->getOwner(DFG).Id;
606 std::map<NodeId, RegisterAggr> &M = PhiUp[PUA.
Id];
609 M.insert(std::make_pair(RP, DefRRs));
611 F->second.insert(DefRRs);
613 DefRRs.
insert(
D.Addr->getRegRef(DFG));
622 dbgs() <<
"Phi-up-to-phi map with intervening defs:\n";
623 for (
auto I : PhiUp) {
624 dbgs() <<
"phi " <<
Print(
I.first, DFG) <<
" -> {";
625 for (
auto R :
I.second)
657 using RefHash = std::hash<RegisterRef>;
658 using RefEqual = std::equal_to<RegisterRef>;
659 using SubMap = std::unordered_map<RegisterRef, RegisterRef>;
660 std::unordered_map<RegisterAggr, SubMap> Subs;
664 auto F = SM.find(RR);
673 for (
unsigned i = 0; i < PhiUQ.size(); ++i) {
676 RefMap &RUM = RealUseMap[PA.Id];
679 std::map<NodeId, RegisterAggr> &PUM = PhiUp[UA.Id];
681 for (
const std::pair<const NodeId, RegisterAggr> &
P : PUM) {
682 bool Changed =
false;
690 if (Subs.find(MidDefs) == Subs.end()) {
691 Subs.insert({MidDefs, SubMap(1, RefHash(), RefEqual(PRI))});
693 SubMap &SM = Subs.at(MidDefs);
700 for (
const std::pair<const RegisterId, NodeRefSet> &
T : RUM) {
709 for (std::pair<NodeId, LaneBitmask> V :
T.second) {
715 Changed |= RS.insert({V.first, SS.Mask}).second;
721 PhiUQ.push_back(
P.first);
727 dbgs() <<
"Real use map:\n";
728 for (
auto I : RealUseMap) {
738 dbgs() <<
" -> " <<
Print(
I.second, DFG) <<
'\n';
751 NBMap.insert(std::make_pair(
RA.Id, BB));
752 NBMap.insert(std::make_pair(IA.Id, BB));
761 auto F1 = MDF.
find(&
B);
765 for (
unsigned i = 0; i < IDFB.
size(); ++i) {
766 auto F2 = MDF.
find(IDFB[i]);
768 IDFB.
insert(F2->second.begin(), F2->second.end());
772 IDF[&
B].insert(IDFB.
begin(), IDFB.
end());
776 for (
auto *S :
I.second)
777 IIDF[S].insert(
I.first);
789 for (
const RefMap::value_type &S : RealUseMap[
P.Id])
790 LON[S.first].insert(S.second.begin(), S.second.end());
795 dbgs() <<
"Phi live-on-entry map:\n";
796 for (
auto &
I : PhiLON)
797 dbgs() <<
"block #" <<
I.first->getNumber() <<
" -> "
798 <<
Print(
I.second, DFG) <<
'\n';
807 RefMap &RUs = RealUseMap[PA.Id];
813 if (!SeenUses.
insert(U.Id).second)
816 if (PUA.
Addr->getReachingDef() == 0)
831 RefMap &LOX = PhiLOX[PrA.Addr->getCode()];
833 for (
const std::pair<const RegisterId, NodeRefSet> &RS : RUs) {
835 for (std::pair<NodeId, LaneBitmask>
P : RS.second) {
844 TA.insert(
D.Addr->getRegRef(DFG)).intersect(S);
846 LOX[S.
Reg].insert({
D.Id, TM});
858 dbgs() <<
"Phi live-on-exit map:\n";
859 for (
auto &
I : PhiLOX)
860 dbgs() <<
"block #" <<
I.first->getNumber() <<
" -> "
861 <<
Print(
I.second, DFG) <<
'\n';
865 traverse(&MF.
front(), LiveIn);
873 std::vector<RegisterRef> LV;
875 LV.push_back(
RegisterRef(LI.PhysReg, LI.LaneMask));
887 dbgs() <<
"\tcomp = {";
896 for (
auto &
B : DFG.
getMF()) {
898 std::vector<unsigned>
T;
900 T.push_back(LI.PhysReg);
911 for (
auto &
B : DFG.
getMF())
917 for (
auto I :
B->liveins()) {
925 if ((M &
I.LaneMask).any())
933 CopyLiveIns(
B, LiveIn);
934 for (
auto *SI :
B->successors())
935 CopyLiveIns(SI,
Live);
938 if (
MI.isDebugInstr())
942 for (
auto &
Op :
MI.all_defs()) {
955 for (
auto &
Op :
MI.all_uses()) {
979 auto F = NBMap.find(RN);
980 if (
F != NBMap.end())
1011 for (
auto *
I : *
N) {
1017 LiveIn[S.first].insert(S.second.begin(), S.second.end());
1022 <<
" after recursion into: {";
1024 dbgs() <<
' ' <<
I->getBlock()->getNumber();
1026 dbgs() <<
" LiveIn: " << Print(LiveIn, DFG) <<
'\n';
1027 dbgs() <<
" Local: " << Print(LiveMap[
B], DFG) <<
'\n';
1033 LiveIn[S.first].insert(S.second.begin(), S.second.end());
1036 dbgs() <<
"after LOX\n";
1037 dbgs() <<
" LiveIn: " <<
Print(LiveIn, DFG) <<
'\n';
1038 dbgs() <<
" Local: " <<
Print(LiveMap[
B], DFG) <<
'\n';
1048 RefMap LiveInCopy = LiveIn;
1051 for (
const std::pair<const RegisterId, NodeRefSet> &LE : LiveInCopy) {
1052 RegisterRef LRef(
LE.first);
1057 auto DA = DFG.
addr<DefNode *>(
OR.first);
1058 NodeAddr<InstrNode *>
IA =
DA.Addr->getOwner(DFG);
1059 NodeAddr<BlockNode *> BA =
IA.Addr->getOwner(DFG);
1060 if (
B != BA.Addr->getCode()) {
1072 RegisterAggr RRs(PRI);
1073 LRef.Mask =
OR.second;
1081 if (RRs.insert(
DA.Addr->getRegRef(DFG)).hasCoverOf(LRef))
1092 NodeAddr<InstrNode *> ITA =
TA.Addr->getOwner(DFG);
1093 NodeAddr<BlockNode *> BTA = ITA.Addr->getOwner(DFG);
1095 if (BTA.Addr->getCode() !=
B) {
1100 RegisterRef
T = RRs.clearIn(LRef);
1102 NewDefs.insert({
TA.Id,
T.Mask});
1109 RRs.insert(
TA.Addr->getRegRef(DFG));
1111 if (RRs.hasCoverOf(LRef))
1120 dbgs() <<
"after defs in block\n";
1121 dbgs() <<
" LiveIn: " <<
Print(LiveIn, DFG) <<
'\n';
1122 dbgs() <<
" Local: " <<
Print(LiveMap[
B], DFG) <<
'\n';
1127 NodeAddr<InstrNode *>
IA =
I;
1130 for (NodeAddr<UseNode *> UA :
IA.Addr->members_if(DFG.
IsUse, DFG)) {
1133 RegisterRef RR = UA.Addr->getRegRef(DFG);
1135 if (getBlockWithRef(
D.Id) !=
B)
1136 LiveIn[RR.Reg].insert({
D.Id, RR.Mask});
1141 dbgs() <<
"after uses in block\n";
1142 dbgs() <<
" LiveIn: " <<
Print(LiveIn, DFG) <<
'\n';
1143 dbgs() <<
" Local: " <<
Print(LiveMap[
B], DFG) <<
'\n';
1148 RegisterAggr &
Local = LiveMap[
B];
1150 for (
auto &R : LON) {
1152 for (
auto P :
R.second)
1154 Local.insert(RegisterRef(
R.first, M));
1158 dbgs() <<
"after phi uses in block\n";
1159 dbgs() <<
" LiveIn: " <<
Print(LiveIn, DFG) <<
'\n';
1160 dbgs() <<
" Local: " <<
Print(Local, DFG) <<
'\n';
1163 for (
auto *
C : IIDF[
B]) {
1164 RegisterAggr &LiveC = LiveMap[
C];
1165 for (
const std::pair<const RegisterId, NodeRefSet> &S : LiveIn)
1166 for (
auto R : S.second)
1168 LiveC.insert(RegisterRef(S.first,
R.second));
1172void Liveness::emptify(RefMap &M) {
1173 for (
auto I =
M.begin(), E =
M.end();
I != E;)
1174 I =
I->second.empty() ?
M.erase(
I) : std::next(
I);
This file implements the BitVector class.
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
Looks at all the uses of the given value Returns the Liveness deduced from the uses of this value Adds all uses that cause the result to be MaybeLive to MaybeLiveRetUses If the result is Live
This file defines the DenseMap class.
DenseMap< Block *, BlockRelaxAux > Blocks
Rewrite Partial Register Uses
A common definition of LaneBitmask for use in TableGen and CodeGen.
static cl::opt< unsigned > MaxRecNest("rdf-liveness-max-rec", cl::init(25), cl::Hidden, cl::desc("Maximum recursion level"))
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
SI optimize exec mask operations pre RA
This file implements a set that has insertion order iteration characteristics.
This file defines the SmallSet class.
This class represents an Operation in the Expression.
iterator find(const_arg_type_t< KeyT > Val)
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
Base class for the actual dominator tree node.
MCRegAliasIterator enumerates all registers aliasing Reg.
iterator_range< MCSubRegIterator > subregs_inclusive(MCRegister Reg) const
Return an iterator range over all sub-registers of Reg, including Reg.
unsigned getNumRegs() const
Return the number of registers this target has (useful for sizing arrays holding per register informa...
Iterator that enumerates the sub-registers of a Reg and the associated sub-register indices.
bool isValid() const
Returns true if this iterator is not yet at the end.
unsigned getSubRegIndex() const
Returns sub-register index of the current sub-register.
MCRegister getSubReg() const
Returns current sub-register.
iterator find(MachineBasicBlock *B)
MachineDomTreeNode * getNode(MachineBasicBlock *BB) const
getNode - return the (Post)DominatorTree node for the specified basic block.
bool properlyDominates(const MachineDomTreeNode *A, const MachineDomTreeNode *B) const
const MachineBasicBlock & front() const
Representation of each machine instruction.
const MachineBasicBlock * getParent() const
A NodeSet contains a set of SUnit DAG nodes with additional information that assigns a priority to th...
unsigned count(SUnit *SU) const
Wrapper class representing virtual and physical registers.
A vector that has set insertion semantics.
size_type size() const
Determine the number of elements in the SetVector.
iterator end()
Get an iterator to the end of the SetVector.
iterator begin()
Get an iterator to the beginning of the SetVector.
bool insert(const value_type &X)
Insert a new element into the SetVector.
SmallSet - This maintains a set of unique values, optimizing for the case when the set is small (less...
size_type count(const T &V) const
count - Return 1 if the element is in the set, 0 otherwise.
std::pair< const_iterator, bool > insert(const T &V)
insert - Insert an element into the set if it isn't already there.
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
LaneBitmask getSubRegIndexLaneMask(unsigned SubIdx) const
Return a bitmask representing the parts of a register that are covered by SubIdx.
self_iterator getIterator()
This class implements an extremely fast bulk output stream that can only output to a stream.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ C
The default llvm calling convention, compatible with C.
initializer< Ty > init(const Ty &Val)
Print(const T &, const DataFlowGraph &) -> Print< T >
NodeAddr< BlockNode * > Block
raw_ostream & operator<<(raw_ostream &OS, const Print< RegisterRef > &P)
NodeAddr< UseNode * > Use
std::set< NodeId > NodeSet
This is an optimization pass for GlobalISel generic memory operations.
uint16_t MCPhysReg
An unsigned integer type large enough to represent all physical registers, but not necessarily virtua...
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
void append_range(Container &C, Range &&R)
Wrapper function to append range R to container C.
auto reverse(ContainerTy &&C)
void sort(IteratorTy Start, IteratorTy End)
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
void erase_if(Container &C, UnaryPredicate P)
Provide a container algorithm similar to C++ Library Fundamentals v2's erase_if which is equivalent t...
Printable printReg(Register Reg, const TargetRegisterInfo *TRI=nullptr, unsigned SubIdx=0, const MachineRegisterInfo *MRI=nullptr)
Prints virtual and physical registers with or without a TRI instance.
Printable printMBBReference(const MachineBasicBlock &MBB)
Prints a machine basic block reference.
Pair of physical register and lane mask.
NodeList members(const DataFlowGraph &G) const
const RegisterAggr & getLiveIns() const
static bool IsDef(const Node BA)
static bool IsPreservingDef(const Def DA)
NodeList getRelatedRefs(Instr IA, Ref RA) const
MachineFunction & getMF() const
static bool IsRef(const Node BA)
static bool IsUse(const Node BA)
static bool IsCode(const Node BA)
Block findBlock(MachineBasicBlock *BB) const
NodeAddr< T > addr(NodeId N) const
Block findBlock(const MachineBasicBlock *BB, const DataFlowGraph &G) const
NodeList getAllReachingDefs(RegisterRef RefRR, NodeAddr< RefNode * > RefA, bool TopShadows, bool FullChain, const RegisterAggr &DefRRs)
std::unordered_set< NodeRef > NodeRefSet
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...
std::pair< NodeSet, bool > getAllReachingDefsRec(RegisterRef RefRR, NodeAddr< RefNode * > RefA, NodeSet &Visited, const NodeSet &Defs)
std::unordered_map< RegisterId, NodeRefSet > RefMap
NodeSet getAllReachedUses(RegisterRef RefRR, NodeAddr< DefNode * > DefA, const RegisterAggr &DefRRs)
bool alias(RegisterRef RA, RegisterRef RB) const
RegisterRef mapTo(RegisterRef RR, unsigned R) const
iterator_range< ref_iterator > refs() const
RegisterAggr & insert(RegisterRef RR)
RegisterRef clearIn(RegisterRef RR) const
bool hasAliasOf(RegisterRef RR) const
RegisterRef intersectWith(RegisterRef RR) const
bool hasCoverOf(RegisterRef RR) const
static bool isCoverOf(RegisterRef RA, RegisterRef RB, const PhysicalRegisterInfo &PRI)