46 P.G.getPRI().print(
OS,
P.Obj);
54 uint16_t Attrs = NA.Addr->getAttrs();
121 if (
NodeId N =
P.Obj.Addr->getReachingDef())
124 if (
NodeId N =
P.Obj.Addr->getReachedDef())
127 if (
NodeId N =
P.Obj.Addr->getReachedUse())
130 if (
NodeId N =
P.Obj.Addr->getSibling())
138 if (
NodeId N =
P.Obj.Addr->getReachingDef())
141 if (
NodeId N =
P.Obj.Addr->getSibling())
149 if (
NodeId N =
P.Obj.Addr->getReachingDef())
152 if (
NodeId N =
P.Obj.Addr->getPredecessor())
155 if (
NodeId N =
P.Obj.Addr->getSibling())
161 switch (
P.Obj.Addr->getKind()) {
163 OS << PrintNode<DefNode *>(
P.Obj,
P.G);
167 OS << PrintNode<PhiUseNode *>(
P.Obj,
P.G);
169 OS << PrintNode<UseNode *>(
P.Obj,
P.G);
176 unsigned N =
P.Obj.size();
177 for (
auto I :
P.Obj) {
186 unsigned N =
P.Obj.size();
187 for (
auto I :
P.Obj) {
197template <
typename T>
struct PrintListV {
198 PrintListV(
const NodeList &L,
const DataFlowGraph &G) :
List(L),
G(
G) {}
202 const DataFlowGraph &
G;
206raw_ostream &
operator<<(raw_ostream &
OS,
const PrintListV<T> &
P) {
207 unsigned N =
P.List.size();
208 for (NodeAddr<T>
A :
P.List) {
209 OS << PrintNode<T>(
A,
P.G);
220 << PrintListV<RefNode *>(
P.Obj.Addr->members(
P.G),
P.G) <<
']';
226 unsigned Opc =
MI.getOpcode();
227 OS <<
Print(
P.Obj.Id,
P.G) <<
": " <<
P.G.getTII().getName(Opc);
229 if (
MI.isCall() ||
MI.isBranch()) {
232 return Op.isMBB() || Op.isGlobal() || Op.isSymbol();
234 if (
T !=
MI.operands_end()) {
238 else if (
T->isGlobal())
239 OS <<
T->getGlobal()->getName();
240 else if (
T->isSymbol())
241 OS <<
T->getSymbolName();
244 OS <<
" [" << PrintListV<RefNode *>(
P.Obj.Addr->members(
P.G),
P.G) <<
']';
249 switch (
P.Obj.Addr->getKind()) {
251 OS << PrintNode<PhiNode *>(
P.Obj,
P.G);
254 OS << PrintNode<StmtNode *>(
P.Obj,
P.G);
267 auto PrintBBs = [&
OS](
const std::vector<int> &Ns) ->
void {
268 unsigned N = Ns.size();
277 <<
" --- preds(" << NP <<
"): ";
279 Ns.push_back(
B->getNumber());
283 OS <<
" succs(" << NS <<
"): ";
286 Ns.push_back(
B->getNumber());
290 for (
auto I :
P.Obj.Addr->members(
P.G))
291 OS << PrintNode<InstrNode *>(
I,
P.G) <<
'\n';
298 <<
": Function: " <<
P.Obj.Addr->getCode()->getName() <<
'\n';
299 for (
auto I :
P.Obj.Addr->members(
P.G))
300 OS << PrintNode<BlockNode *>(
I,
P.G) <<
'\n';
320 for (
auto I =
P.Obj.top(),
E =
P.Obj.bottom();
I !=
E;) {
339void NodeAllocator::startNewBlock() {
341 char *
P =
static_cast<char *
>(
T);
346 assert((Blocks.size() < ((
size_t)1 << (8 *
sizeof(
NodeId) - BitsPerIndex))) &&
347 "Out of bits for block index");
351bool NodeAllocator::needNewBlock() {
355 char *ActiveBegin = Blocks.back();
357 return Index >= NodesPerBlock;
364 uint32_t ActiveB = Blocks.size() - 1;
372 uintptr_t
A =
reinterpret_cast<uintptr_t
>(
P);
373 for (
unsigned i = 0, n = Blocks.size(); i != n; ++i) {
374 uintptr_t
B =
reinterpret_cast<uintptr_t
>(Blocks[i]);
378 return makeId(i,
Idx);
431 while (NA.
Addr !=
this) {
443 DA.Addr->setReachedDef(Self);
450 DA.Addr->setReachedUse(Self);
475 NA.
Addr->setNext(Self);
493 if (MA.
Id == NA.
Id) {
504 while (MA.
Addr !=
this) {
507 MA.
Addr->setNext(NA.
Addr->getNext());
521 static auto True = [](
Node) ->
bool {
return true; };
529 while (NA.
Addr !=
this) {
551 PA.
Addr->setNext(M.Id);
558 MN =
G.addr<
NodeBase *>(M.Addr->getNext());
571 auto EqBB = [BB](
Node NA) ->
bool {
return Block(NA).Addr->getCode() == BB; };
590 unsigned OpNum)
const {
596 unsigned OpNum)
const {
602 if (
Op.isDef() &&
Op.isDead())
609 unsigned OpNum)
const {
610 if (In.isCall() || In.isReturn() || In.isInlineAsm())
615 if (O.isGlobal() || O.isSymbol())
619 if (
D.implicit_defs().empty() &&
D.implicit_uses().empty())
625 if (
Op.getSubReg() != 0)
629 Op.isDef() ?
D.implicit_defs() :
D.implicit_uses();
642 TRI(tri), PRI(tri, mf), MDT(mdt), MDF(mdf), TOI(*DefaultTOI),
650 : MF(mf),
TII(tii),
TRI(tri), PRI(tri, mf), MDT(mdt), MDF(mdf), TOI(toi),
668 Pos = DS.Stack.size();
669 while (Pos > 0 && DS.isDelimiter(DS.Stack[Pos - 1]))
686 unsigned P = nextDown(Stack.size());
693 Stack.push_back(
Def(
nullptr,
N));
701 unsigned P = Stack.size();
703 bool Found = isDelimiter(Stack[
P - 1],
N);
713unsigned DataFlowGraph::DefStack::nextUp(
unsigned P)
const {
716 unsigned SS = Stack.size();
721 IsDelim = isDelimiter(Stack[
P - 1]);
722 }
while (
P < SS && IsDelim);
728unsigned DataFlowGraph::DefStack::nextDown(
unsigned P)
const {
732 bool IsDelim = isDelimiter(Stack[
P - 1]);
736 IsDelim = isDelimiter(Stack[
P - 1]);
737 }
while (
P > 0 && IsDelim);
744RegisterAggr DataFlowGraph::getLandingPadLiveIns()
const {
745 RegisterAggr LR(
getPRI());
747 const Constant *PF =
F.hasPersonalityFn() ?
F.getPersonalityFn() :
nullptr;
749 if (
RegisterId R = TLI.getExceptionPointerRegister(PF))
750 LR.insert(RegisterRef(R));
752 if (
RegisterId R = TLI.getExceptionSelectorRegister(PF))
753 LR.insert(RegisterRef(R));
778 P.Addr->setAttrs(Attrs);
784Node DataFlowGraph::cloneNode(
const Node B) {
785 Node NA = newNode(0);
786 memcpy(NA.Addr,
B.Addr,
sizeof(NodeBase));
790 RA.Addr->setReachingDef(0);
791 RA.Addr->setSibling(0);
794 DA.Addr->setReachedDef(0);
795 DA.Addr->setReachedUse(0);
805 UA.Addr->setRegRef(&
Op, *
this);
809PhiUse DataFlowGraph::newPhiUse(
Phi Owner, RegisterRef RR,
Block PredB,
813 PUA.Addr->setRegRef(RR, *
this);
814 PUA.Addr->setPredecessor(PredB.Id);
820 DA.Addr->setRegRef(&
Op, *
this);
827 DA.Addr->setRegRef(RR, *
this);
831Phi DataFlowGraph::newPhi(
Block Owner) {
833 Owner.Addr->addPhi(PA, *
this);
837Stmt DataFlowGraph::newStmt(
Block Owner, MachineInstr *
MI) {
839 SA.Addr->setCode(
MI);
840 Owner.Addr->addMember(SA, *
this);
844Block DataFlowGraph::newBlock(
Func Owner, MachineBasicBlock *BB) {
846 BA.Addr->setCode(BB);
847 Owner.Addr->addMember(BA, *
this);
851Func DataFlowGraph::newFunc(MachineFunction *MF) {
853 FA.Addr->setCode(MF);
862 ReservedRegs =
MRI.getReservedRegs();
865 auto Insert = [](
auto &Set,
auto &&
Range) {
870 std::set<RegisterId> BaseSet;
871 if (BuildCfg.
Classes.empty()) {
882 if (SkipReserved && ReservedRegs[R])
889 if (SkipReserved && ReservedRegs[R])
895 TheFunc = newFunc(&MF);
901 Block BA = newBlock(TheFunc, &
B);
902 BlockNodes.insert(std::make_pair(&
B, BA));
904 if (
I.isDebugInstr())
916 for (std::pair<unsigned, unsigned>
P :
MRI.liveins())
918 if (
MRI.tracksLiveness()) {
929 Def DA = newDef(PA, RR, PhiFlags);
930 PA.
Addr->addMember(DA, *
this);
939 if (!EHRegs.
empty()) {
957 Def DA = newDef(PA, RR, PhiFlags);
958 PA.
Addr->addMember(DA, *
this);
960 for (
Block PBA : Preds) {
961 PhiUse PUA = newPhiUse(PA, RR, PBA);
962 PA.
Addr->addMember(PUA, *
this);
972 recordDefsForDF(PhiM, BA);
978 linkBlockRefs(
DM, EA);
1004 for (
auto &
P : DefM)
1005 P.second.start_block(
B);
1013 for (
auto &
P : DefM)
1014 P.second.clear_block(
B);
1017 for (
auto I = DefM.begin(),
E = DefM.end(), NextI =
I;
I !=
E;
I = NextI) {
1018 NextI = std::next(
I);
1020 if (
I->second.empty())
1028 pushClobbers(IA, DefM);
1036 std::set<RegisterId> Defined;
1050 for (
Def DA : IA.Addr->members_if(
IsDef, *
this)) {
1051 if (Visited.count(DA.Id))
1062 DefM[RR.
Reg].push(DA);
1063 Defined.insert(RR.
Reg);
1069 if (!Defined.count(
A))
1074 Visited.insert(
T.Id);
1083 std::set<RegisterId> Defined;
1098 for (
Def DA :
IA.Addr->members_if(
IsDef, *
this)) {
1099 if (Visited.count(
DA.Id))
1105 Def PDA = Rel.front();
1106 RegisterRef RR = PDA.Addr->getRegRef(*
this);
1110 if (!Defined.insert(RR.Reg).second) {
1111 MachineInstr *
MI =
Stmt(IA).Addr->getCode();
1112 dbgs() <<
"Multiple definitions of register: " <<
Print(RR, *
this)
1120 DefM[RR.Reg].push(DA);
1130 Visited.insert(
T.Id);
1144 }
while (
RA.Id != 0 &&
RA.Id != Start);
1149void DataFlowGraph::reset() {
1152 TrackedUnits.clear();
1153 ReservedRegs.
clear();
1166 auto IsRelated = [
this,
RA](
Ref TA) ->
bool {
1167 if (TA.Addr->getKind() !=
RA.Addr->getKind())
1170 RA.Addr->getRegRef(*
this))) {
1178 auto Cond = [&IsRelated,
RA](
Ref TA) ->
bool {
1179 return IsRelated(TA) && &
RA.Addr->getOp() == &TA.Addr->getOp();
1181 return RA.Addr->getNextRef(RR,
Cond,
true, *
this);
1185 auto Cond = [&IsRelated,
RA](
Ref TA) ->
bool {
1191 return PhiUse(TA).Addr->getPredecessor() ==
1194 return RA.Addr->getNextRef(RR,
Cond,
true, *
this);
1202template <
typename Predicate>
1203std::pair<Ref, Ref> DataFlowGraph::locateNextRef(
Instr IA,
Ref RA,
1204 Predicate
P)
const {
1211 if (NA.
Id == 0 || NA.
Id == Start)
1218 if (NA.
Id != 0 && NA.
Id != Start)
1219 return std::make_pair(
RA, NA);
1220 return std::make_pair(
RA,
Ref());
1229 auto IsShadow = [Flags](
Ref TA) ->
bool {
1230 return TA.Addr->getFlags() == Flags;
1232 auto Loc = locateNextRef(IA,
RA, IsShadow);
1233 if (Loc.second.Id != 0 || !Create)
1237 Ref NA = cloneNode(
RA);
1239 IA.Addr->addMemberAfter(Loc.first, NA, *
this);
1246 Stmt SA = newStmt(BA, &In);
1252 if (In.isBranch()) {
1254 if (
Op.isGlobal() ||
Op.isSymbol())
1259 if (In.isIndirectBranch())
1265 auto isDefUndef = [
this](
const MachineInstr &In, RegisterRef DR) ->
bool {
1268 for (
const MachineOperand &
Op : In.all_uses()) {
1269 if (
Op.getReg() == 0 ||
Op.isUndef())
1272 if (
getPRI().alias(DR, UR))
1278 bool IsCall = isCall(In);
1279 unsigned NumOps =
In.getNumOperands();
1287 for (
unsigned OpN = 0; OpN < NumOps; ++OpN) {
1288 MachineOperand &
Op =
In.getOperand(OpN);
1289 if (!
Op.isReg() || !
Op.isDef() ||
Op.isImplicit())
1292 if (!R || !
R.isPhysical() || !
isTracked(RegisterRef(R)))
1305 if (IsCall &&
Op.isDead())
1307 Def DA = newDef(SA,
Op, Flags);
1308 SA.
Addr->addMember(DA, *
this);
1309 assert(!DoneDefs.test(R));
1315 for (
unsigned OpN = 0; OpN < NumOps; ++OpN) {
1316 MachineOperand &
Op =
In.getOperand(OpN);
1317 if (!
Op.isRegMask())
1320 Def DA = newDef(SA,
Op, Flags);
1321 SA.
Addr->addMember(DA, *
this);
1324 for (
unsigned i = 1, e = TRI.
getNumRegs(); i != e; ++i) {
1327 if (!(RM[i / 32] & (1u << (i % 32))))
1328 DoneClobbers.set(i);
1334 for (
unsigned OpN = 0; OpN < NumOps; ++OpN) {
1335 MachineOperand &
Op =
In.getOperand(OpN);
1336 if (!
Op.isReg() || !
Op.isDef() || !
Op.isImplicit())
1339 if (!R || !
R.isPhysical() || !
isTracked(RegisterRef(R)) || DoneDefs.test(R))
1346 if (isDefUndef(In, RR))
1353 if (IsCall &&
Op.isDead()) {
1354 if (DoneClobbers.test(R))
1358 Def DA = newDef(SA,
Op, Flags);
1359 SA.
Addr->addMember(DA, *
this);
1363 for (
unsigned OpN = 0; OpN < NumOps; ++OpN) {
1364 MachineOperand &
Op =
In.getOperand(OpN);
1365 if (!
Op.isReg() || !
Op.isUse())
1368 if (!R || !
R.isPhysical() || !
isTracked(RegisterRef(R)))
1375 Use UA = newUse(SA,
Op, Flags);
1376 SA.
Addr->addMember(UA, *
this);
1382void DataFlowGraph::recordDefsForDF(BlockRefsMap &PhiM,
Block BA) {
1386 MachineBasicBlock *BB = BA.Addr->getCode();
1388 auto DFLoc = MDF.
find(BB);
1389 if (DFLoc == MDF.
end() || DFLoc->second.empty())
1397 RegisterAggr Defs(
getPRI());
1398 for (
Instr IA : BA.Addr->members(*
this)) {
1400 RegisterRef RR =
RA.Addr->getRegRef(*
this);
1408 SetVector<MachineBasicBlock *> IDF(
DF.begin(),
DF.end());
1409 for (
unsigned i = 0; i < IDF.size(); ++i) {
1410 auto F = MDF.
find(IDF[i]);
1412 IDF.insert(
F->second.begin(),
F->second.end());
1417 for (
auto *DB : IDF) {
1419 PhiM[DBA.Id].insert(Defs);
1425void DataFlowGraph::buildPhis(BlockRefsMap &PhiM,
Block BA) {
1428 auto HasDF = PhiM.find(BA.Id);
1429 if (HasDF == PhiM.end() || HasDF->second.empty())
1434 const MachineBasicBlock *
MBB = BA.Addr->getCode();
1435 for (MachineBasicBlock *
PB :
MBB->predecessors())
1438 const RegisterAggr &Defs = PhiM[BA.Id];
1441 for (RegisterRef RR : Defs.refs()) {
1442 Phi PA = newPhi(BA);
1443 PA.Addr->addMember(newDef(PA, RR, PhiFlags), *
this);
1446 for (
Block PBA : Preds) {
1447 PA.Addr->addMember(newPhiUse(PA, RR, PBA), *
this);
1453void DataFlowGraph::removeUnusedPhis() {
1460 SetVector<NodeId> PhiQ;
1462 for (
auto P : BA.Addr->members_if(
IsPhi, *
this))
1466 static auto HasUsedDef = [](
NodeList &Ms) ->
bool {
1471 if (
DA.Addr->getReachedDef() != 0 ||
DA.Addr->getReachedUse() != 0)
1480 while (!PhiQ.empty()) {
1481 auto PA = addr<PhiNode *>(PhiQ[0]);
1483 NodeList Refs = PA.Addr->members(*
this);
1484 if (HasUsedDef(Refs))
1486 for (
Ref RA : Refs) {
1487 if (
NodeId RD =
RA.Addr->getReachingDef()) {
1488 auto RDA = addr<DefNode *>(RD);
1489 Instr OA =
RDA.Addr->getOwner(*
this);
1493 if (
RA.Addr->isDef())
1498 Block BA = PA.Addr->getOwner(*
this);
1499 BA.Addr->removeMember(PA, *
this);
1506template <
typename T>
1507void DataFlowGraph::linkRefUp(
Instr IA, NodeAddr<T> TA, DefStack &DS) {
1510 RegisterRef RR =
TA.Addr->getRegRef(*
this);
1514 RegisterAggr Defs(
getPRI());
1516 for (
auto I =
DS.top(),
E =
DS.bottom();
I !=
E;
I.down()) {
1517 RegisterRef QR =
I->Addr->getRegRef(*
this);
1521 bool Alias = Defs.hasAliasOf(QR);
1522 bool Cover = Defs.insert(QR).hasCoverOf(RR);
1542 TAP.Addr->linkToDef(TAP.Id,
RDA);
1550template <
typename Predicate>
1557 for (
Ref RA : SA.Addr->members_if(
P, *
this)) {
1560 RegisterRef RR =
RA.Addr->getRegRef(*
this);
1567 auto F = DefM.find(RR.Reg);
1568 if (
F == DefM.end())
1570 DefStack &
DS =
F->second;
1572 linkRefUp<UseNode *>(SA,
RA, DS);
1574 linkRefUp<DefNode *>(SA,
RA, DS);
1586 auto IsClobber = [](
Ref RA) ->
bool {
1589 auto IsNoClobber = [](
Ref RA) ->
bool {
1593 assert(BA.Addr &&
"block node address is needed to create a data-flow link");
1597 for (
Instr IA : BA.Addr->members(*
this)) {
1601 linkStmtRefs(DefM, IA,
IsUse);
1602 linkStmtRefs(DefM, IA, IsClobber);
1606 pushClobbers(IA, DefM);
1609 linkStmtRefs(DefM, IA, IsNoClobber);
1616 for (
auto *
I : *
N) {
1617 MachineBasicBlock *SB =
I->getBlock();
1619 linkBlockRefs(DefM, SBA);
1623 auto IsUseForBA = [BA](
Node NA) ->
bool {
1627 return PhiUse(NA).Addr->getPredecessor() == BA.Id;
1630 RegisterAggr EHLiveIns = getLandingPadLiveIns();
1631 MachineBasicBlock *
MBB = BA.Addr->getCode();
1633 for (MachineBasicBlock *SB :
MBB->successors()) {
1634 bool IsEHPad = SB->isEHPad();
1636 for (
Instr IA : SBA.Addr->members_if(
IsPhi, *
this)) {
1640 Ref RA =
IA.Addr->getFirstMember(*
this);
1642 if (EHLiveIns.hasCoverOf(
RA.Addr->getRegRef(*
this)))
1646 for (
auto U :
IA.Addr->members_if(IsUseForBA, *
this)) {
1648 RegisterRef RR = PUA.Addr->getRegRef(*
this);
1649 linkRefUp<UseNode *>(IA, PUA, DefM[RR.Reg]);
1659void DataFlowGraph::unlinkUseDF(
Use UA) {
1660 NodeId RD = UA.Addr->getReachingDef();
1661 NodeId Sib = UA.Addr->getSibling();
1668 auto RDA = addr<DefNode *>(RD);
1669 auto TA = addr<UseNode *>(
RDA.Addr->getReachedUse());
1670 if (
TA.Id == UA.Id) {
1671 RDA.Addr->setReachedUse(Sib);
1675 while (
TA.Id != 0) {
1678 TA.Addr->setSibling(UA.Addr->getSibling());
1681 TA = addr<UseNode *>(S);
1686void DataFlowGraph::unlinkDefDF(
Def DA) {
1705 NodeId RD =
DA.Addr->getReachingDef();
1714 auto RA = addr<RefNode *>(
N);
1717 N =
RA.Addr->getSibling();
1721 NodeList ReachedDefs = getAllNodes(
DA.Addr->getReachedDef());
1722 NodeList ReachedUses = getAllNodes(
DA.Addr->getReachedUse());
1725 for (
Ref I : ReachedDefs)
1726 I.Addr->setSibling(0);
1727 for (
Ref I : ReachedUses)
1728 I.Addr->setSibling(0);
1730 for (
Def I : ReachedDefs)
1731 I.Addr->setReachingDef(RD);
1732 for (
Use I : ReachedUses)
1733 I.Addr->setReachingDef(RD);
1735 NodeId Sib =
DA.Addr->getSibling();
1742 auto RDA = addr<DefNode *>(RD);
1743 auto TA = addr<DefNode *>(
RDA.Addr->getReachedDef());
1744 if (
TA.Id ==
DA.Id) {
1747 RDA.Addr->setReachedDef(Sib);
1751 while (
TA.Id != 0) {
1754 TA.Addr->setSibling(Sib);
1757 TA = addr<DefNode *>(S);
1762 if (!ReachedDefs.empty()) {
1763 auto Last =
Def(ReachedDefs.back());
1764 Last.Addr->setSibling(
RDA.Addr->getReachedDef());
1765 RDA.Addr->setReachedDef(ReachedDefs.front().Id);
1768 if (!ReachedUses.empty()) {
1769 auto Last =
Use(ReachedUses.back());
1770 Last.Addr->setSibling(
RDA.Addr->getReachedUse());
1771 RDA.Addr->setReachedUse(ReachedUses.front().Id);
1782 for (
Ref R : S.
Addr->members(*
this)) {
1785 if (IgnoreReserved && RR.
isReg() && ReservedRegs[RR.
idx()])
1791 if (!
Op.isReg() && !
Op.isRegMask())
unsigned const MachineRegisterInfo * MRI
ReachingDefAnalysis & RDA
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")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
Returns the sub type a function will return at a given Idx Should correspond to the result type of an ExtractValue instruction executed with just that one unsigned Idx
static RegisterPass< DebugifyFunctionPass > DF("debugify-function", "Attach debug info to a function")
static RegisterPass< DebugifyModulePass > DM("debugify", "Attach debug info to everything")
DenseMap< Block *, BlockRelaxAux > Blocks
const HexagonInstrInfo * TII
A common definition of LaneBitmask for use in TableGen and CodeGen.
unsigned const TargetRegisterInfo * TRI
ConstantRange Range(APInt(BitWidth, Low), APInt(BitWidth, High))
PassBuilder PB(Machine, PassOpts->PTO, std::nullopt, &PIC)
const SmallVectorImpl< MachineOperand > & Cond
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 describes how to lower LLVM code to machine code.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
void clear()
clear - Removes all bits from the bitvector.
LLVM_ATTRIBUTE_RETURNS_NONNULL void * Allocate(size_t Size, Align Alignment)
Allocate space at the specified alignment.
void Reset()
Deallocate all but the current slab and reset the current pointer to the beginning of it,...
This class represents an Operation in the Expression.
Describe properties that are true of each instruction in the target description file.
unsigned getNumRegs() const
Return the number of registers this target has (useful for sizing arrays holding per register informa...
unsigned pred_size() const
iterator_range< livein_iterator > liveins() const
unsigned succ_size() const
iterator_range< succ_iterator > successors()
iterator_range< pred_iterator > predecessors()
iterator find(MachineBasicBlock *B)
DominanceFrontierBase< MachineBasicBlock, false >::DomSetType DomSetType
DominatorTree Class - Concrete subclass of DominatorTreeBase that is used to compute a normal dominat...
MachineDomTreeNode * getNode(MachineBasicBlock *BB) const
getNode - return the (Post)DominatorTree node for the specified basic block.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
Function & getFunction()
Return the LLVM function that this machine code represents.
const MachineBasicBlock & front() const
Representation of each machine instruction.
MachineOperand class - Representation of each machine instruction operand.
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
Wrapper class representing virtual and physical registers.
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
TargetInstrInfo - Interface to description of machine instruction set.
virtual bool isPredicated(const MachineInstr &MI) const
Returns true if the instruction is already predicated.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
MCRegister getSubReg(MCRegister Reg, unsigned Idx) const
Returns the physical register number of sub-register "Index" for physical register RegNo.
virtual const TargetLowering * getTargetLowering() const
This class implements an extremely fast bulk output stream that can only output to a stream.
This class provides various memory handling functions that manipulate MemoryBlock instances.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
NodeAddr< InstrNode * > Instr
NodeAddr< StmtNode * > Stmt
NodeAddr< RefNode * > Ref
NodeAddr< PhiNode * > Phi
std::set< RegisterRef > RegisterSet
Print(const T &, const DataFlowGraph &) -> Print< T >
NodeAddr< PhiUseNode * > PhiUse
NodeAddr< DefNode * > Def
NodeAddr< FuncNode * > Func
NodeAddr< BlockNode * > Block
NodeAddr< NodeBase * > Node
static void printRefHeader(raw_ostream &OS, const Ref RA, const DataFlowGraph &G)
raw_ostream & operator<<(raw_ostream &OS, const Print< RegisterRef > &P)
NodeAddr< UseNode * > Use
bool disjoint(const std::set< T > &A, const std::set< T > &B)
std::set< NodeId > NodeSet
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
EHPersonality classifyEHPersonality(const Value *Pers)
See if the given exception handling personality function is one that we understand.
bool isFuncletEHPersonality(EHPersonality Pers)
Returns true if this is a personality function that invokes handler funclets (which must return to it...
DWARFExpression::Operation Op
auto find_if(R &&Range, UnaryPredicate P)
Provide wrappers to std::find_if which take ranges instead of having to pass begin/end explicitly.
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.
DomTreeNodeBase< MachineBasicBlock > MachineDomTreeNode
Printable printMBBReference(const MachineBasicBlock &MBB)
Prints a machine basic block reference.
Implement std::hash so that hash_code can be used in STL containers.
static constexpr LaneBitmask getAll()
void addPhi(Phi PA, const DataFlowGraph &G)
NodeList members_if(Predicate P, const DataFlowGraph &G) const
void removeMember(Node NA, const DataFlowGraph &G)
NodeList members(const DataFlowGraph &G) const
void addMember(Node NA, const DataFlowGraph &G)
Node getFirstMember(const DataFlowGraph &G) const
void addMemberAfter(Node MA, Node NA, const DataFlowGraph &G)
Node getLastMember(const DataFlowGraph &G) const
SmallVector< const TargetRegisterClass * > Classes
std::set< RegisterId > TrackRegs
void clear_block(NodeId N)
void start_block(NodeId N)
NodeId id(const NodeBase *P) const
void unlinkUse(Use UA, bool RemoveFromOwner)
void releaseBlock(NodeId B, DefStackMap &DefM)
Ref getNextRelated(Instr IA, Ref RA) const
bool isTracked(RegisterRef RR) const
RegisterRef makeRegRef(unsigned Reg, unsigned Sub) const
static bool IsDef(const Node BA)
DataFlowGraph(MachineFunction &mf, const TargetInstrInfo &tii, const TargetRegisterInfo &tri, const MachineDominatorTree &mdt, const MachineDominanceFrontier &mdf)
Ref getNextShadow(Instr IA, Ref RA, bool Create)
static bool IsPhi(const Node BA)
NodeList getRelatedRefs(Instr IA, Ref RA) const
void unlinkDef(Def DA, bool RemoveFromOwner)
static bool IsUse(const Node BA)
const PhysicalRegisterInfo & getPRI() const
void markBlock(NodeId B, DefStackMap &DefM)
NodeBase * ptr(NodeId N) const
Block findBlock(MachineBasicBlock *BB) const
bool hasUntrackedRef(Stmt S, bool IgnoreReserved=true) const
std::unordered_map< RegisterId, DefStack > DefStackMap
void pushAllDefs(Instr IA, DefStackMap &DM)
void linkToDef(NodeId Self, Def DA)
MachineFunction * getCode() const
Block findBlock(const MachineBasicBlock *BB, const DataFlowGraph &G) const
Block getEntryBlock(const DataFlowGraph &G)
Node getOwner(const DataFlowGraph &G)
NodeId id(const NodeBase *P) const
static uint16_t flags(uint16_t T)
static uint16_t kind(uint16_t T)
static uint16_t type(uint16_t T)
const TargetRegisterInfo & getTRI() const
bool equal_to(RegisterRef A, RegisterRef B) const
void setRegRef(RegisterRef RR, DataFlowGraph &G)
RegisterRef getRegRef(const DataFlowGraph &G) const
Node getOwner(const DataFlowGraph &G)
iterator_range< ref_iterator > refs() const
RegisterAggr & insert(RegisterRef RR)
constexpr unsigned idx() const
constexpr bool isReg() const
static constexpr bool isMaskId(unsigned Id)
static constexpr bool isRegId(unsigned Id)
virtual bool isFixedReg(const MachineInstr &In, unsigned OpNum) const
const TargetInstrInfo & TII
virtual bool isPreserving(const MachineInstr &In, unsigned OpNum) const
virtual bool isClobbering(const MachineInstr &In, unsigned OpNum) const
void linkToDef(NodeId Self, Def DA)