49#include <unordered_map>
57 cl::desc(
"Maximum recursion level"));
63 for (
const auto &
I :
P.Obj) {
64 OS <<
' ' <<
printReg(
I.first, &
P.G.getTRI()) <<
'{';
65 for (
auto J =
I.second.begin(), E =
I.second.end(); J != E;) {
124 auto SNA = DFG.addr<
RefNode *>(Start);
125 if (
NodeId RD = SNA.Addr->getReachingDef())
128 for (
auto S : DFG.getRelatedRefs(RefA.
Addr->getOwner(DFG), RefA))
139 for (
unsigned i = 0; i < DefQ.
size(); ++i) {
140 auto TA = DFG.addr<
DefNode *>(DefQ[i]);
145 if (!DFG.IsPreservingDef(TA))
150 for (
auto S : DFG.getRelatedRefs(TA.Addr->getOwner(DFG), TA))
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)))
182 Blocks[
Block(IA)].push_back(IA.Id);
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);
234 [
this](
auto A,
auto B) {
return MDT.properlyDominates(
A,
B); });
236 std::vector<NodeId> TmpInst;
238 auto &Bucket = Blocks[
MBB];
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);
318 for (NodeId
D : Defs) {
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)
343 for (
auto U : PA.Addr->members_if(DFG.IsRef<
NodeAttrs::Use>, DFG)) {
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()))
401 BA = DFG.findBlock(
N->getBlock());
406 Ins = BA.
Addr->members(DFG);
428 auto UA = DFG.addr<
UseNode *>(U);
431 if (PRI.alias(RefRR, UR) && !DefRRs.
hasCoverOf(UR))
438 for (
NodeId D = DefA.
Addr->getReachedDef(), NextD;
D != 0;
D = NextD) {
440 NextD = DA.Addr->getSibling();
444 if (DefRRs.
hasCoverOf(DR) || !PRI.alias(RefRR, DR))
447 if (DFG.IsPreservingDef(DA)) {
455 Uses.insert(
T.begin(),
T.end());
472 std::map<NodeId, std::map<NodeId, RegisterAggr>> PhiUp;
473 std::vector<NodeId> PhiUQ;
480 RefMap &RealUses = RealUseMap[PhiA.Id];
481 NodeList PhiRefs = PhiA.Addr->members(DFG);
491 DRs.
insert(R.Addr->getRegRef(DFG));
493 PhiDefs.insert(R.Id);
495 PhiDRs.
insert(std::make_pair(PhiA.Id, DRs));
502 for (
unsigned i = 0; i < DefQ.
size(); ++i) {
513 RealUses[R.Id].
insert({
A.Id, R.Mask});
515 UN =
A.Addr->getSibling();
520 NodeId DN = DA.Addr->getReachedDef();
523 for (
auto T : DFG.getRelatedRefs(
A.Addr->getOwner(DFG),
A)) {
531 DN =
A.Addr->getSibling();
546 for (
auto UI = RealUses.
begin(), UE = RealUses.
end(); UI != UE;) {
553 for (std::pair<NodeId, LaneBitmask>
I :
Uses) {
554 auto UA = DFG.addr<
UseNode *>(
I.first);
565 if (PhiDefs.count(DA.Id))
567 Covered.
insert(DA.Addr->getRegRef(DFG));
573 UI->second.insert({
I.first, S.
Mask});
583 if (!RealUses.
empty())
584 PhiUQ.push_back(PhiA.Id);
593 for (
auto I : PhiRefs) {
597 if (PUA.
Addr->getReachingDef() == 0)
606 NodeId RP =
D.Addr->getOwner(DFG).Id;
607 auto [
F, Inserted] = PhiUp[PUA.
Id].try_emplace(RP, DefRRs);
609 F->second.insert(DefRRs);
611 DefRRs.
insert(
D.Addr->getRegRef(DFG));
615 SeenUses.insert(
T.Id);
620 dbgs() <<
"Phi-up-to-phi map with intervening defs:\n";
621 for (
auto I : PhiUp) {
622 dbgs() <<
"phi " <<
Print(
I.first, DFG) <<
" -> {";
623 for (
auto R :
I.second)
655 using RefHash = std::hash<RegisterRef>;
658 std::unordered_map<RegisterRef, RegisterRef, RefHash, RefEqual>;
659 std::unordered_map<RegisterAggr, SubMap> Subs;
663 auto F =
SM.find(RR);
672 for (
unsigned i = 0; i < PhiUQ.size(); ++i) {
673 auto PA = DFG.addr<
PhiNode *>(PhiUQ[i]);
679 RefMap RUM = RealUseMap[PA.Id];
682 std::map<NodeId, RegisterAggr> &PUM = PhiUp[UA.Id];
684 for (
const std::pair<const NodeId, RegisterAggr> &
P : PUM) {
693 SubMap &
SM = Subs.try_emplace(MidDefs, 1, RefHash(), RefEqual(PRI))
701 for (
const auto &
T : RUM) {
710 for (std::pair<NodeId, LaneBitmask> V :
T.second) {
716 Changed |= RS.insert({V.first, SS.Mask}).second;
722 PhiUQ.push_back(
P.first);
728 dbgs() <<
"Real use map:\n";
729 for (
auto I : RealUseMap) {
739 dbgs() <<
" -> " <<
Print(
I.second, DFG) <<
'\n';
752 NBMap.insert(std::make_pair(
RA.Id, BB));
753 NBMap.insert(std::make_pair(IA.Id, BB));
762 auto F1 = MDF.find(&
B);
766 for (
unsigned i = 0; i < IDFB.
size(); ++i) {
767 auto F2 = MDF.find(IDFB[i]);
773 IDF[&
B].insert(IDFB.
begin(), IDFB.
end());
777 for (
auto *S :
I.second)
791 LON[S.first].
insert(S.second.begin(), S.second.end());
796 dbgs() <<
"Phi live-on-entry map:\n";
797 for (
auto &
I : PhiLON)
798 dbgs() <<
"block #" <<
I.first->getNumber() <<
" -> "
799 <<
Print(
I.second, DFG) <<
'\n';
808 RefMap &RUs = RealUseMap[PA.Id];
813 for (
auto U : PA.Addr->members_if(DFG.IsRef<
NodeAttrs::Use>, DFG)) {
814 if (!SeenUses.insert(U.Id).second)
817 if (PUA.
Addr->getReachingDef() == 0)
831 auto PrA = DFG.addr<
BlockNode *>(PUA.
Addr->getPredecessor());
832 RefMap &LOX = PhiLOX[PrA.Addr->getCode()];
834 for (
const auto &RS : RUs) {
836 for (std::pair<NodeId, LaneBitmask>
P : RS.second) {
845 TA.insert(
D.Addr->getRegRef(DFG)).intersect(S);
853 SeenUses.insert(
T.Id);
859 dbgs() <<
"Phi live-on-exit map:\n";
860 for (
auto &
I : PhiLOX)
861 dbgs() <<
"block #" <<
I.first->getNumber() <<
" -> "
862 <<
Print(
I.second, DFG) <<
'\n';
866 traverse(&MF.
front(), LiveIn);
869 LiveMap[&MF.
front()].insert(DFG.getLiveIns());
874 std::vector<RegisterRef> LV;
876 LV.push_back(
RegisterRef(LI.PhysReg, LI.LaneMask));
888 dbgs() <<
"\tcomp = {";
897 for (
auto &
B : DFG.getMF()) {
899 std::vector<MCRegister>
T;
901 T.push_back(LI.PhysReg);
907 B.addLiveIn({R.asMCReg(), R.Mask});
912 for (
auto &
B : DFG.getMF())
918 for (
auto I :
B->liveins()) {
921 LV.set(
I.PhysReg.id());
926 if ((M &
I.LaneMask).any())
933 BitVector LiveIn(TRI.getNumRegs()), Live(TRI.getNumRegs());
934 CopyLiveIns(
B, LiveIn);
935 for (
auto *
SI :
B->successors())
936 CopyLiveIns(
SI, Live);
939 if (
MI.isDebugInstr())
943 for (
auto &
Op :
MI.all_defs()) {
953 for (
MCPhysReg SR : TRI.subregs_inclusive(R))
956 for (
auto &
Op :
MI.all_uses()) {
964 if (!Live[(*AR).id()])
971 for (
MCPhysReg SR : TRI.subregs_inclusive(R))
980 auto F = NBMap.find(RN);
981 if (
F != NBMap.end())
1012 for (
auto *
I : *
N) {
1018 LiveIn[S.first].insert(S.second.begin(), S.second.end());
1023 <<
" after recursion into: {";
1025 dbgs() <<
' ' <<
I->getBlock()->getNumber();
1027 dbgs() <<
" LiveIn: " <<
Print(LiveIn, DFG) <<
'\n';
1028 dbgs() <<
" Local: " <<
Print(LiveMap[
B], DFG) <<
'\n';
1034 LiveIn[S.first].insert(S.second.begin(), S.second.end());
1037 dbgs() <<
"after LOX\n";
1038 dbgs() <<
" LiveIn: " <<
Print(LiveIn, DFG) <<
'\n';
1039 dbgs() <<
" Local: " <<
Print(LiveMap[
B], DFG) <<
'\n';
1049 RefMap LiveInCopy = LiveIn;
1052 for (
const auto &LE : LiveInCopy) {
1053 RegisterRef LRef(
LE.first);
1058 auto DA = DFG.addr<DefNode *>(
OR.first);
1059 NodeAddr<InstrNode *>
IA =
DA.Addr->getOwner(DFG);
1060 NodeAddr<BlockNode *> BA =
IA.Addr->getOwner(DFG);
1061 if (
B != BA.Addr->getCode()) {
1073 RegisterAggr RRs(PRI);
1074 LRef.Mask =
OR.second;
1076 if (!DFG.IsPreservingDef(DA)) {
1082 if (RRs.insert(
DA.Addr->getRegRef(DFG)).hasCoverOf(LRef))
1093 NodeAddr<InstrNode *> ITA =
TA.Addr->getOwner(DFG);
1094 NodeAddr<BlockNode *> BTA = ITA.Addr->getOwner(DFG);
1096 if (BTA.Addr->getCode() !=
B) {
1101 RegisterRef
T = RRs.clearIn(LRef);
1103 NewDefs.insert({
TA.Id,
T.Mask});
1110 RRs.insert(
TA.Addr->getRegRef(DFG));
1112 if (RRs.hasCoverOf(LRef))
1121 dbgs() <<
"after defs in block\n";
1122 dbgs() <<
" LiveIn: " <<
Print(LiveIn, DFG) <<
'\n';
1123 dbgs() <<
" Local: " <<
Print(LiveMap[
B], DFG) <<
'\n';
1127 for (
auto I : DFG.getFunc().Addr->findBlock(
B, DFG).Addr->members(DFG)) {
1128 NodeAddr<InstrNode *>
IA =
I;
1131 for (NodeAddr<UseNode *> UA :
IA.Addr->members_if(DFG.IsUse, DFG)) {
1134 RegisterRef RR = UA.Addr->getRegRef(DFG);
1136 if (getBlockWithRef(
D.Id) !=
B)
1137 LiveIn[RR.Id].insert({
D.Id, RR.Mask});
1142 dbgs() <<
"after uses in block\n";
1143 dbgs() <<
" LiveIn: " <<
Print(LiveIn, DFG) <<
'\n';
1144 dbgs() <<
" Local: " <<
Print(LiveMap[
B], DFG) <<
'\n';
1149 RegisterAggr &
Local = LiveMap[
B];
1151 for (
auto &R : LON) {
1153 for (
auto P :
R.second)
1155 Local.insert(RegisterRef(
R.first, M));
1159 dbgs() <<
"after phi uses in block\n";
1160 dbgs() <<
" LiveIn: " <<
Print(LiveIn, DFG) <<
'\n';
1164 for (
auto *
C : IIDF[
B]) {
1165 RegisterAggr &LiveC = LiveMap[
C];
1166 for (
const auto &S : LiveIn)
1167 for (
auto R : S.second)
1168 if (MDT.properlyDominates(getBlockWithRef(
R.first),
C))
1169 LiveC.insert(RegisterRef(S.first,
R.second));
1173void Liveness::emptify(RefMap &M) {
1174 M.remove_if([](
const auto &
P) {
return P.second.empty(); });
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
This file implements the BitVector class.
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
This file defines the DenseMap class.
A common definition of LaneBitmask for use in TableGen and CodeGen.
static constexpr unsigned SM(unsigned Version)
static cl::opt< unsigned > MaxRecNest("rdf-liveness-max-rec", cl::init(25), cl::Hidden, cl::desc("Maximum recursion level"))
Remove Loads Into Fake Uses
SI optimize exec mask operations pre RA
This file implements a set that has insertion order iteration characteristics.
This file defines the SmallSet class.
BitVector & reset()
Reset all bits in the bitvector.
BitVector & set()
Set all bits in the bitvector.
ValueT & at(const_arg_type_t< KeyT > Val)
Return the entry for the specified key, or abort if no such entry exists.
iterator find(const_arg_type_t< KeyT > Val)
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
DomTreeNodeBase< NodeT > * getNode(const NodeT *BB) const
getNode - return the (Post)DominatorTree node for the specified basic block.
MCRegAliasIterator enumerates all registers aliasing Reg.
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.
const MachineBasicBlock & front() const
void insert(iterator MBBI, MachineBasicBlock *MBB)
Representation of each machine instruction.
const MachineBasicBlock * getParent() 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.
void insert_range(Range &&R)
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.
reverse_iterator rbegin()
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)
NodeAddr< BlockNode * > Block
Print(const T &, const DataFlowGraph &) -> Print< T >
NodeAddr< UseNode * > Use
LLVM_ABI raw_ostream & operator<<(raw_ostream &OS, const Print< RegisterRef > &P)
std::set< NodeId > NodeSet
SmallVector< Node, 4 > NodeList
This is an optimization pass for GlobalISel generic memory operations.
constexpr from_range_t from_range
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)
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
DomTreeNodeBase< MachineBasicBlock > MachineDomTreeNode
uint16_t MCPhysReg
An unsigned integer type large enough to represent all physical registers, but not necessarily virtua...
DWARFExpression::Operation Op
void erase_if(Container &C, UnaryPredicate P)
Provide a container algorithm similar to C++ Library Fundamentals v2's erase_if which is equivalent t...
LLVM_ABI 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.
LLVM_ABI Printable printMBBReference(const MachineBasicBlock &MBB)
Prints a machine basic block reference.
Pair of physical register and lane mask.
NodeAddr< T > addr(NodeId N) const
LLVM_ABI NodeList getAllReachingDefs(RegisterRef RefRR, NodeAddr< RefNode * > RefA, bool TopShadows, bool FullChain, const RegisterAggr &DefRRs)
std::unordered_set< NodeRef > NodeRefSet
LLVM_ABI 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...
LLVM_ABI void resetKills()
LLVM_ABI void resetLiveIns()
DenseMap< RegisterId, NodeRefSet > RefMap
LLVM_ABI void computePhiInfo()
LLVM_ABI std::pair< NodeSet, bool > getAllReachingDefsRec(RegisterRef RefRR, NodeAddr< RefNode * > RefA, NodeSet &Visited, const NodeSet &Defs)
LLVM_ABI void computeLiveIns()
LLVM_ABI NodeSet getAllReachedUses(RegisterRef RefRR, NodeAddr< DefNode * > DefA, const RegisterAggr &DefRRs)
NodeId getSibling() const
iterator_range< ref_iterator > refs() const
LLVM_ABI RegisterAggr & insert(RegisterRef RR)
LLVM_ABI RegisterRef clearIn(RegisterRef RR) const
LLVM_ABI bool hasAliasOf(RegisterRef RR) const
LLVM_ABI RegisterRef intersectWith(RegisterRef RR) const
LLVM_ABI bool hasCoverOf(RegisterRef RR) const
static bool isCoverOf(RegisterRef RA, RegisterRef RB, const PhysicalRegisterInfo &PRI)