42 raw_ostream &operator<< (raw_ostream &OS, const Print<Liveness::RefMap> &
P) {
44 for (
auto &
I :
P.Obj) {
45 OS <<
' ' <<
PrintReg(
I.first, &
P.G.getTRI()) <<
'{';
46 for (
auto J =
I.second.begin(),
E =
I.second.end(); J !=
E; ) {
106 if (
NodeId RD = SNA.Addr->getReachingDef())
115 for (
unsigned i = 0;
i < DefQ.
size(); ++
i) {
137 if (!IsPhi && !DFG.
alias(RefRR,
TA.Addr->getRegRef(DFG)))
140 Owners.
insert(
TA.Addr->getOwner(DFG).Id);
182 std::vector<NodeId> Tmp(Owners.
begin(), Owners.
end());
183 std::sort(Tmp.begin(), Tmp.end(),
Less);
206 if (!FullChain && RRs.hasCoverOf(RefRR))
221 if (FullChain || IsPhi || !RRs.hasCoverOf(QR))
224 RDefs.insert(RDefs.end(), Ds.begin(), Ds.end());
228 uint16_t
Flags = DA.Addr->getFlags();
231 RRs.insert(DA.Addr->getRegRef(DFG));
238 RDefs.resize(std::distance(RDefs.begin(),
remove_if(RDefs, DeadP)));
252 DefRRs.
insert(DA.Addr->getRegRef(DFG));
262 TmpDefs.insert(R.Id);
267 Result.insert(DA.Id);
271 if (Visited.count(PA.
Id))
273 Visited.insert(PA.
Id);
277 Result.insert(
T.begin(),
T.end());
305 U = UA.Addr->getSibling();
326 Uses.insert(T.begin(), T.end());
340 Phis.insert(Phis.end(), Ps.begin(), Ps.end());
344 std::map<NodeId,std::map<NodeId,RegisterAggr>> PhiUp;
345 std::vector<NodeId> PhiUQ;
351 RefMap &RealUses = RealUseMap[PhiA.Id];
352 NodeList PhiRefs = PhiA.Addr->members(DFG);
362 PhiDefs.insert(R.Id);
370 for (
unsigned i = 0;
i < DefQ.
size(); ++
i) {
415 return PhiDefs.count(DA.Id);
417 for (
auto UI = RealUses.begin(), UE = RealUses.end(); UI != UE; ) {
423 for (
auto I = Uses.begin(),
E = Uses.end();
I !=
E; ) {
429 if (
any_of(RDs, InPhiDefs))
435 UI = RealUses.erase(UI);
442 if (!RealUses.empty())
443 PhiUQ.push_back(PhiA.Id);
452 for (
auto I : PhiRefs) {
462 std::map<NodeId,NodeId> FirstUse;
465 SeenUses.insert(VA.Id);
469 NodeId RP = DA.Addr->getOwner(DFG).Id;
470 NodeId FU = FirstUse.insert({
RP,VA.Id}).first->second;
471 std::map<NodeId,RegisterAggr> &M = PhiUp[FU];
474 M.insert(std::make_pair(RP, DefRRs));
476 F->second.insert(DefRRs);
478 DefRRs.
insert(DA.Addr->getRegRef(DFG));
485 dbgs() <<
"Phi-up-to-phi map with intervening defs:\n";
486 for (
auto I : PhiUp) {
488 for (
auto R :
I.second)
518 for (
unsigned i = 0;
i < PhiUQ.size(); ++
i) {
521 RefMap &RUM = RealUseMap[PA.Id];
524 std::map<NodeId,RegisterAggr> &PUM = PhiUp[UA.Id];
526 for (
const std::pair<NodeId,RegisterAggr> &
P : PUM) {
527 bool Changed =
false;
542 for (
const std::pair<RegisterId,NodeRefSet> &
T : RUM) {
546 for (std::pair<NodeId,LaneBitmask> V :
T.second) {
552 Changed |= RS.insert({V.first,SS.Mask}).second;
558 PhiUQ.push_back(
P.first);
564 dbgs() <<
"Real use map:\n";
565 for (
auto I : RealUseMap) {
589 NBMap.
insert(std::make_pair(RA.Id, BB));
590 NBMap.
insert(std::make_pair(IA.Id, BB));
599 auto F1 = MDF.
find(&
B);
603 for (
unsigned i = 0;
i < IDFB.size(); ++
i) {
604 auto F2 = MDF.
find(IDFB[
i]);
606 IDFB.insert(F2->second.begin(), F2->second.end());
610 IDF[&
B].insert(IDFB.begin(), IDFB.end());
614 for (
auto S :
I.second)
615 IIDF[S].insert(
I.first);
627 for (
const RefMap::value_type &S : RealUseMap[
P.Id])
628 LON[S.first].insert(S.second.begin(), S.second.end());
632 dbgs() <<
"Phi live-on-entry map:\n";
633 for (
auto &
I : PhiLON)
634 dbgs() <<
"block #" <<
I.first->getNumber() <<
" -> "
644 RefMap &RUs = RealUseMap[PA.Id];
657 RefMap &LOX = PhiLOX[PrA.Addr->getCode()];
660 for (
const std::pair<RegisterId,NodeRefSet> &
T : RUs) {
663 for (std::pair<NodeId,LaneBitmask>
P :
T.second)
677 dbgs() <<
"Phi live-on-exit map:\n";
678 for (
auto &
I : PhiLOX)
679 dbgs() <<
"block #" <<
I.first->getNumber() <<
" -> "
684 traverse(&MF.front(), LiveIn);
687 auto &EntryIn = LiveMap[&MF.front()];
694 std::vector<RegisterRef> LV;
695 for (
auto I =
B.livein_begin(),
E =
B.livein_end();
I !=
E; ++
I)
697 std::sort(LV.begin(), LV.end());
698 dbgs() <<
"BB#" <<
B.getNumber() <<
"\t rec = {";
705 for (std::pair<RegisterId,LaneBitmask>
P : LiveMap[&
B]) {
713 if ((M &
P.second).any())
718 std::sort(LV.begin(), LV.end());
719 dbgs() <<
"\tcomp = {";
730 for (
auto &
B : DFG.
getMF()) {
732 std::vector<unsigned>
T;
733 for (
auto I =
B.livein_begin(),
E =
B.livein_end();
I !=
E; ++
I)
734 T.push_back(
I->PhysReg);
738 auto &LiveIns = LiveMap[&
B];
739 for (
auto I : LiveIns) {
747 for (
auto &
B : DFG.
getMF())
762 if ((M &
I.LaneMask).any())
770 CopyLiveIns(B, LiveIn);
772 CopyLiveIns(
SI, Live);
785 if (!
Op.isReg() || !
Op.isDef() ||
Op.isImplicit())
787 unsigned R =
Op.getReg();
794 if (!
Op.isReg() || !
Op.isUse())
796 unsigned R =
Op.getReg();
830 auto F = NBMap.
find(RN);
831 if (
F != NBMap.
end())
869 LiveIn[S.first].insert(S.second.begin(), S.second.end());
874 <<
" after recursion into: {";
876 dbgs() <<
' ' <<
I->getBlock()->getNumber();
885 LiveIn[S.first].insert(S.second.begin(), S.second.end());
888 dbgs() <<
"after LOX\n";
900 RefMap LiveInCopy = LiveIn;
903 for (
const std::pair<RegisterId,NodeRefSet> &
LE : LiveInCopy) {
925 LRef.Mask =
OR.second;
933 if (RRs.insert(DA.Addr->getRegRef(DFG)).hasCoverOf(LRef))
953 L.insert(LRef).clear(RRs);
955 NewDefs.insert({
TA.Id,L.begin()->second});
962 RRs.insert(
TA.Addr->getRegRef(DFG));
964 if (RRs.hasCoverOf(LRef))
973 dbgs() <<
"after defs in block\n";
979 for (
auto I : DFG.
getFunc().Addr->findBlock(B, DFG).Addr->members(DFG)) {
988 if (getBlockWithRef(
D.Id) !=
B)
989 LiveIn[RR.
Reg].insert({
D.Id,RR.
Mask});
994 dbgs() <<
"after uses in block\n";
1002 RefMap &LON = PhiLON[
B];
1003 for (
auto &R : LON) {
1005 for (
auto P : R.second)
1011 dbgs() <<
"after phi uses in block\n";
1016 for (
auto C : IIDF[B]) {
1018 for (
const std::pair<RegisterId,NodeRefSet> &S : LiveIn)
1019 for (
auto R : S.second)
1020 if (MDT.properlyDominates(getBlockWithRef(R.first),
C))
1026 void Liveness::emptify(RefMap &M) {
1027 for (
auto I = M.begin(),
E = M.end();
I !=
E; )
1028 I =
I->second.empty() ? M.erase(
I) : std::next(
I);
NodeList members(const DataFlowGraph &G) const
MachineFunction & getMF() const
RegisterRef restrictRef(RegisterRef AR, RegisterRef BR) const
bool alias(RegisterRef RA, RegisterRef RB) const
iterator_range< livein_iterator > liveins() const
bool isValid() const
isValid - returns true if this iterator is not yet at the end.
NodeId getReachedDef() const
livein_iterator livein_end() const
uint16_t getFlags() const
int getNumber() const
MachineBasicBlocks are uniquely numbered at the function level, unless they're not in a MachineFuncti...
auto remove_if(R &&Range, UnaryPredicate P) -> decltype(std::begin(Range))
Provide wrappers to std::remove_if which take ranges instead of having to pass begin/end explicitly...
std::set< NodeRef > NodeRefSet
static bool IsPreservingDef(const NodeAddr< DefNode * > DA)
uint16_t MCPhysReg
An unsigned integer type large enough to represent all physical registers, but not necessarily virtua...
bool isValid() const
Returns true if this iterator is not yet at the end.
LaneBitmask getSubRegIndexLaneMask(unsigned SubIdx) const
Return a bitmask representing the parts of a register that are covered by SubIdx. ...
iterator_range< mop_iterator > operands()
iterator end()
Get an iterator to the end of the SetVector.
static bool isCoverOf(RegisterRef RA, RegisterRef RB, const TargetRegisterInfo &TRI)
size_type size() const
Determine the number of elements in the SetVector.
iterator_range< succ_iterator > successors()
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
void clearKillInfo()
Clears kill flags on all operands.
struct fuzzer::@269 Flags
NodeList getRelatedRefs(NodeAddr< InstrNode * > IA, NodeAddr< RefNode * > RA) const
NodeId getReachedUse() const
static GCRegistry::Add< StatepointGC > D("statepoint-example","an example strategy for statepoint")
std::vector< NodeAddr< NodeBase * > > NodeList
MachineDomTreeNode * getNode(MachineBasicBlock *BB) const
getNode - return the (Post)DominatorTree node for the specified basic block.
unsigned getNumRegs() const
Return the number of registers this target has (useful for sizing arrays holding per register informa...
bool insert(const value_type &X)
Insert a new element into the SetVector.
std::map< RegisterId, NodeRefSet > RefMap
iterator begin()
Get an iterator to the beginning of the SetVector.
Base class for the actual dominator tree node.
NodeList getAllReachingDefs(RegisterRef RefRR, NodeAddr< RefNode * > RefA, bool FullChain, const RegisterAggr &DefRRs)
static GCRegistry::Add< OcamlGC > B("ocaml","ocaml 3.10-compatible GC")
Printable PrintReg(unsigned Reg, const TargetRegisterInfo *TRI=nullptr, unsigned SubRegIdx=0)
Prints virtual and physical registers with or without a TRI instance.
NodeAddr< NodeBase * > getOwner(const DataFlowGraph &G)
reverse_iterator rbegin()
NodeList members_if(Predicate P, const DataFlowGraph &G) const
static GCRegistry::Add< CoreCLRGC > E("coreclr","CoreCLR-compatible GC")
bool isDebugValue() const
INITIALIZE_PASS(HexagonEarlyIfConversion,"hexagon-eif","Hexagon early if conversion", false, false) bool HexagonEarlyIfConversion MachineBasicBlock * SB
static bool IsRef(const NodeAddr< NodeBase * > BA)
bool hasCoverOf(RegisterRef RR) const
Iterator that enumerates the sub-registers of a Reg and the associated sub-register indices...
static ManagedStatic< OptionRegistry > OR
MCRegAliasIterator enumerates all registers aliasing Reg.
bool any_of(R &&Range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly...
static bool IsCode(const NodeAddr< NodeBase * > BA)
MCSubRegIterator enumerates all sub-registers of Reg.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
NodeId getPredecessor() const
iterator find(MachineBasicBlock *B)
std::pair< NodeId, LaneBitmask > NodeRef
NodeSet getAllReachedUses(RegisterRef RefRR, NodeAddr< DefNode * > DefA, const RegisterAggr &DefRRs)
unsigned getSubReg() const
Returns current sub-register.
RegisterAggr & insert(RegisterRef RR)
NodeId getSibling() const
NodeSet getAllReachingDefsRec(RegisterRef RefRR, NodeAddr< RefNode * > RefA, NodeSet &Visited, const NodeSet &Defs)
livein_iterator livein_begin() const
static GCRegistry::Add< ShadowStackGC > C("shadow-stack","Very portable GC for uncooperative code generators")
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
std::set< NodeId > NodeSet
NodeAddr< FuncNode * > getFunc() const
RegisterRef getRegRef(const DataFlowGraph &G) const
static bool IsUse(const NodeAddr< NodeBase * > BA)
unsigned getSubRegIndex() const
Returns sub-register index of the current sub-register.
Representation of each machine instruction.
NodeAddr< NodeBase * > getOwner(const DataFlowGraph &G)
static bool isPhysicalRegister(unsigned Reg)
Return true if the specified register number is in the physical register namespace.
RegisterRef clearIn(RegisterRef RR) const
size_type count(const key_type &key) const
Count the number of elements of a given key in the SetVector.
iterator find(const KeyT &Val)
MachineBasicBlock * getCode() const
RegisterRef normalizeRef(RegisterRef RR) const
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
A vector that has set insertion semantics.
NodeAddr< T > addr(NodeId N) const
NodeId getReachingDef() const
This class implements an extremely fast bulk output stream that can only output to a stream...
bool dominates(const MachineDomTreeNode *A, const MachineDomTreeNode *B) const
static GCRegistry::Add< ErlangGC > A("erlang","erlang-compatible garbage collector")