45 P.G.getPRI().print(
OS,
P.Obj);
53 uint16_t Attrs = NA.Addr->getAttrs();
120 if (
NodeId N =
P.Obj.Addr->getReachingDef())
123 if (
NodeId N =
P.Obj.Addr->getReachedDef())
126 if (
NodeId N =
P.Obj.Addr->getReachedUse())
129 if (
NodeId N =
P.Obj.Addr->getSibling())
137 if (
NodeId N =
P.Obj.Addr->getReachingDef())
140 if (
NodeId N =
P.Obj.Addr->getSibling())
148 if (
NodeId N =
P.Obj.Addr->getReachingDef())
151 if (
NodeId N =
P.Obj.Addr->getPredecessor())
154 if (
NodeId N =
P.Obj.Addr->getSibling())
160 switch (
P.Obj.Addr->getKind()) {
162 OS << PrintNode<DefNode *>(
P.Obj,
P.G);
166 OS << PrintNode<PhiUseNode *>(
P.Obj,
P.G);
168 OS << PrintNode<UseNode *>(
P.Obj,
P.G);
175 unsigned N =
P.Obj.size();
176 for (
auto I :
P.Obj) {
185 unsigned N =
P.Obj.size();
186 for (
auto I :
P.Obj) {
196template <
typename T>
struct PrintListV {
197 PrintListV(
const NodeList &L,
const DataFlowGraph &G) :
List(L),
G(
G) {}
201 const DataFlowGraph &
G;
205raw_ostream &
operator<<(raw_ostream &
OS,
const PrintListV<T> &
P) {
206 unsigned N =
P.List.size();
207 for (NodeAddr<T>
A :
P.List) {
208 OS << PrintNode<T>(
A,
P.G);
219 << PrintListV<RefNode *>(
P.Obj.Addr->members(
P.G),
P.G) <<
']';
225 unsigned Opc =
MI.getOpcode();
226 OS <<
Print(
P.Obj.Id,
P.G) <<
": " <<
P.G.getTII().getName(Opc);
228 if (
MI.isCall() ||
MI.isBranch()) {
231 return Op.isMBB() || Op.isGlobal() || Op.isSymbol();
233 if (
T !=
MI.operands_end()) {
237 else if (
T->isGlobal())
238 OS <<
T->getGlobal()->getName();
239 else if (
T->isSymbol())
240 OS <<
T->getSymbolName();
243 OS <<
" [" << PrintListV<RefNode *>(
P.Obj.Addr->members(
P.G),
P.G) <<
']';
248 switch (
P.Obj.Addr->getKind()) {
250 OS << PrintNode<PhiNode *>(
P.Obj,
P.G);
253 OS << PrintNode<StmtNode *>(
P.Obj,
P.G);
266 auto PrintBBs = [&
OS](
const std::vector<int> &Ns) ->
void {
267 unsigned N = Ns.size();
276 <<
" --- preds(" << NP <<
"): ";
278 Ns.push_back(
B->getNumber());
282 OS <<
" succs(" << NS <<
"): ";
285 Ns.push_back(
B->getNumber());
289 for (
auto I :
P.Obj.Addr->members(
P.G))
290 OS << PrintNode<InstrNode *>(
I,
P.G) <<
'\n';
297 <<
": Function: " <<
P.Obj.Addr->getCode()->getName() <<
'\n';
298 for (
auto I :
P.Obj.Addr->members(
P.G))
299 OS << PrintNode<BlockNode *>(
I,
P.G) <<
'\n';
319 for (
auto I =
P.Obj.top(),
E =
P.Obj.bottom();
I !=
E;) {
338void NodeAllocator::startNewBlock() {
340 char *
P =
static_cast<char *
>(
T);
345 assert((Blocks.size() < ((
size_t)1 << (8 *
sizeof(
NodeId) - BitsPerIndex))) &&
346 "Out of bits for block index");
350bool NodeAllocator::needNewBlock() {
354 char *ActiveBegin = Blocks.back();
356 return Index >= NodesPerBlock;
363 uint32_t ActiveB = Blocks.size() - 1;
371 uintptr_t
A =
reinterpret_cast<uintptr_t
>(
P);
372 for (
unsigned i = 0, n = Blocks.size(); i != n; ++i) {
373 uintptr_t
B =
reinterpret_cast<uintptr_t
>(Blocks[i]);
377 return makeId(i,
Idx);
430 while (NA.
Addr !=
this) {
442 DA.Addr->setReachedDef(Self);
449 DA.Addr->setReachedUse(Self);
474 NA.
Addr->setNext(Self);
492 if (MA.
Id == NA.
Id) {
503 while (MA.
Addr !=
this) {
506 MA.
Addr->setNext(NA.
Addr->getNext());
520 static auto True = [](
Node) ->
bool {
return true; };
528 while (NA.
Addr !=
this) {
550 PA.
Addr->setNext(M.Id);
557 MN =
G.addr<
NodeBase *>(M.Addr->getNext());
570 auto EqBB = [BB](
Node NA) ->
bool {
return Block(NA).Addr->getCode() == BB; };
589 unsigned OpNum)
const {
595 unsigned OpNum)
const {
601 if (
Op.isDef() &&
Op.isDead())
608 unsigned OpNum)
const {
609 if (In.isCall() || In.isReturn() || In.isInlineAsm())
614 if (O.isGlobal() || O.isSymbol())
618 if (
D.implicit_defs().empty() &&
D.implicit_uses().empty())
624 if (
Op.getSubReg() != 0)
628 Op.isDef() ?
D.implicit_defs() :
D.implicit_uses();
641 TRI(tri), PRI(tri, mf), MDT(mdt), MDF(mdf), TOI(*DefaultTOI),
649 : MF(mf),
TII(tii),
TRI(tri), PRI(tri, mf), MDT(mdt), MDF(mdf), TOI(toi),
667 Pos = DS.Stack.size();
668 while (Pos > 0 && DS.isDelimiter(DS.Stack[Pos - 1]))
685 unsigned P = nextDown(Stack.size());
692 Stack.push_back(
Def(
nullptr,
N));
700 unsigned P = Stack.size();
702 bool Found = isDelimiter(Stack[
P - 1],
N);
712unsigned DataFlowGraph::DefStack::nextUp(
unsigned P)
const {
715 unsigned SS = Stack.size();
720 IsDelim = isDelimiter(Stack[
P - 1]);
721 }
while (
P < SS && IsDelim);
727unsigned DataFlowGraph::DefStack::nextDown(
unsigned P)
const {
731 bool IsDelim = isDelimiter(Stack[
P - 1]);
735 IsDelim = isDelimiter(Stack[
P - 1]);
736 }
while (
P > 0 && IsDelim);
743RegisterAggr DataFlowGraph::getLandingPadLiveIns()
const {
744 RegisterAggr LR(
getPRI());
746 const Constant *PF =
F.hasPersonalityFn() ?
F.getPersonalityFn() :
nullptr;
748 if (
RegisterId R = TLI.getExceptionPointerRegister(PF))
749 LR.insert(RegisterRef(R));
751 if (
RegisterId R = TLI.getExceptionSelectorRegister(PF))
752 LR.insert(RegisterRef(R));
777 P.Addr->setAttrs(Attrs);
783Node DataFlowGraph::cloneNode(
const Node B) {
784 Node NA = newNode(0);
785 memcpy(NA.Addr,
B.Addr,
sizeof(NodeBase));
789 RA.Addr->setReachingDef(0);
790 RA.Addr->setSibling(0);
793 DA.Addr->setReachedDef(0);
794 DA.Addr->setReachedUse(0);
804 UA.Addr->setRegRef(&
Op, *
this);
808PhiUse DataFlowGraph::newPhiUse(
Phi Owner, RegisterRef RR,
Block PredB,
812 PUA.Addr->setRegRef(RR, *
this);
813 PUA.Addr->setPredecessor(PredB.Id);
819 DA.Addr->setRegRef(&
Op, *
this);
826 DA.Addr->setRegRef(RR, *
this);
830Phi DataFlowGraph::newPhi(
Block Owner) {
832 Owner.Addr->addPhi(PA, *
this);
836Stmt DataFlowGraph::newStmt(
Block Owner, MachineInstr *
MI) {
838 SA.Addr->setCode(
MI);
839 Owner.Addr->addMember(SA, *
this);
843Block DataFlowGraph::newBlock(
Func Owner, MachineBasicBlock *BB) {
845 BA.Addr->setCode(BB);
846 Owner.Addr->addMember(BA, *
this);
850Func DataFlowGraph::newFunc(MachineFunction *MF) {
852 FA.Addr->setCode(MF);
861 ReservedRegs =
MRI.getReservedRegs();
864 auto Insert = [](
auto &Set,
auto &&
Range) {
869 std::set<RegisterId> BaseSet;
870 if (BuildCfg.
Classes.empty()) {
881 if (SkipReserved && ReservedRegs[R])
888 if (SkipReserved && ReservedRegs[R])
894 TheFunc = newFunc(&MF);
900 Block BA = newBlock(TheFunc, &
B);
901 BlockNodes.insert(std::make_pair(&
B, BA));
903 if (
I.isDebugInstr())
915 for (std::pair<MCRegister, Register>
P :
MRI.liveins())
917 if (
MRI.tracksLiveness()) {
928 Def DA = newDef(PA, RR, PhiFlags);
929 PA.
Addr->addMember(DA, *
this);
938 if (!EHRegs.
empty()) {
956 Def DA = newDef(PA, RR, PhiFlags);
957 PA.
Addr->addMember(DA, *
this);
959 for (
Block PBA : Preds) {
960 PhiUse PUA = newPhiUse(PA, RR, PBA);
961 PA.
Addr->addMember(PUA, *
this);
971 recordDefsForDF(PhiM, BA);
977 linkBlockRefs(
DM, EA);
1003 for (
auto &
P : DefM)
1004 P.second.start_block(
B);
1012 for (
auto &
P : DefM)
1013 P.second.clear_block(
B);
1016 for (
auto I = DefM.begin(),
E = DefM.end(), NextI =
I;
I !=
E;
I = NextI) {
1017 NextI = std::next(
I);
1019 if (
I->second.empty())
1027 pushClobbers(IA, DefM);
1035 std::set<RegisterId> Defined;
1049 for (
Def DA : IA.Addr->members_if(
IsDef, *
this)) {
1050 if (Visited.count(DA.Id))
1061 DefM[RR.
Reg].push(DA);
1062 Defined.insert(RR.
Reg);
1068 if (!Defined.count(
A))
1073 Visited.insert(
T.Id);
1082 std::set<RegisterId> Defined;
1097 for (
Def DA :
IA.Addr->members_if(
IsDef, *
this)) {
1098 if (Visited.count(
DA.Id))
1104 Def PDA = Rel.front();
1105 RegisterRef RR = PDA.Addr->getRegRef(*
this);
1109 if (!Defined.insert(RR.Reg).second) {
1110 MachineInstr *
MI =
Stmt(IA).Addr->getCode();
1111 dbgs() <<
"Multiple definitions of register: " <<
Print(RR, *
this)
1119 DefM[RR.Reg].push(DA);
1129 Visited.insert(
T.Id);
1143 }
while (
RA.Id != 0 &&
RA.Id != Start);
1148void DataFlowGraph::reset() {
1151 TrackedUnits.clear();
1152 ReservedRegs.
clear();
1165 auto IsRelated = [
this,
RA](
Ref TA) ->
bool {
1166 if (TA.Addr->getKind() !=
RA.Addr->getKind())
1169 RA.Addr->getRegRef(*
this))) {
1177 auto Cond = [&IsRelated,
RA](
Ref TA) ->
bool {
1178 return IsRelated(TA) && &
RA.Addr->getOp() == &TA.Addr->getOp();
1180 return RA.Addr->getNextRef(RR,
Cond,
true, *
this);
1184 auto Cond = [&IsRelated,
RA](
Ref TA) ->
bool {
1190 return PhiUse(TA).Addr->getPredecessor() ==
1193 return RA.Addr->getNextRef(RR,
Cond,
true, *
this);
1201template <
typename Predicate>
1202std::pair<Ref, Ref> DataFlowGraph::locateNextRef(
Instr IA,
Ref RA,
1203 Predicate
P)
const {
1210 if (NA.
Id == 0 || NA.
Id == Start)
1217 if (NA.
Id != 0 && NA.
Id != Start)
1218 return std::make_pair(
RA, NA);
1219 return std::make_pair(
RA,
Ref());
1228 auto IsShadow = [Flags](
Ref TA) ->
bool {
1229 return TA.Addr->getFlags() == Flags;
1231 auto Loc = locateNextRef(IA,
RA, IsShadow);
1232 if (Loc.second.Id != 0 || !Create)
1236 Ref NA = cloneNode(
RA);
1238 IA.Addr->addMemberAfter(Loc.first, NA, *
this);
1245 Stmt SA = newStmt(BA, &In);
1251 if (In.isBranch()) {
1253 if (
Op.isGlobal() ||
Op.isSymbol())
1258 if (In.isIndirectBranch())
1264 auto isDefUndef = [
this](
const MachineInstr &In, RegisterRef DR) ->
bool {
1267 for (
const MachineOperand &
Op : In.all_uses()) {
1268 if (
Op.getReg() == 0 ||
Op.isUndef())
1271 if (
getPRI().alias(DR, UR))
1277 bool IsCall = isCall(In);
1278 unsigned NumOps =
In.getNumOperands();
1286 for (
unsigned OpN = 0; OpN < NumOps; ++OpN) {
1287 MachineOperand &
Op =
In.getOperand(OpN);
1288 if (!
Op.isReg() || !
Op.isDef() ||
Op.isImplicit())
1291 if (!R || !
R.isPhysical() || !
isTracked(RegisterRef(R)))
1304 if (IsCall &&
Op.isDead())
1306 Def DA = newDef(SA,
Op, Flags);
1307 SA.
Addr->addMember(DA, *
this);
1308 assert(!DoneDefs.test(R));
1314 for (
unsigned OpN = 0; OpN < NumOps; ++OpN) {
1315 MachineOperand &
Op =
In.getOperand(OpN);
1316 if (!
Op.isRegMask())
1319 Def DA = newDef(SA,
Op, Flags);
1320 SA.
Addr->addMember(DA, *
this);
1323 for (
unsigned i = 1, e = TRI.
getNumRegs(); i != e; ++i) {
1326 if (!(RM[i / 32] & (1u << (i % 32))))
1327 DoneClobbers.set(i);
1333 for (
unsigned OpN = 0; OpN < NumOps; ++OpN) {
1334 MachineOperand &
Op =
In.getOperand(OpN);
1335 if (!
Op.isReg() || !
Op.isDef() || !
Op.isImplicit())
1338 if (!R || !
R.isPhysical() || !
isTracked(RegisterRef(R)) || DoneDefs.test(R))
1345 if (isDefUndef(In, RR))
1352 if (IsCall &&
Op.isDead()) {
1353 if (DoneClobbers.test(R))
1357 Def DA = newDef(SA,
Op, Flags);
1358 SA.
Addr->addMember(DA, *
this);
1362 for (
unsigned OpN = 0; OpN < NumOps; ++OpN) {
1363 MachineOperand &
Op =
In.getOperand(OpN);
1364 if (!
Op.isReg() || !
Op.isUse())
1367 if (!R || !
R.isPhysical() || !
isTracked(RegisterRef(R)))
1374 Use UA = newUse(SA,
Op, Flags);
1375 SA.
Addr->addMember(UA, *
this);
1381void DataFlowGraph::recordDefsForDF(BlockRefsMap &PhiM,
Block BA) {
1385 MachineBasicBlock *BB = BA.Addr->getCode();
1387 auto DFLoc = MDF.
find(BB);
1388 if (DFLoc == MDF.
end() || DFLoc->second.empty())
1396 RegisterAggr Defs(
getPRI());
1397 for (
Instr IA : BA.Addr->members(*
this)) {
1399 RegisterRef RR =
RA.Addr->getRegRef(*
this);
1407 SetVector<MachineBasicBlock *> IDF(
DF.begin(),
DF.end());
1408 for (
unsigned i = 0; i < IDF.size(); ++i) {
1409 auto F = MDF.
find(IDF[i]);
1411 IDF.insert(
F->second.begin(),
F->second.end());
1416 for (
auto *DB : IDF) {
1418 PhiM[DBA.Id].insert(Defs);
1424void DataFlowGraph::buildPhis(BlockRefsMap &PhiM,
Block BA) {
1427 auto HasDF = PhiM.find(BA.Id);
1428 if (HasDF == PhiM.end() || HasDF->second.empty())
1433 const MachineBasicBlock *
MBB = BA.Addr->getCode();
1434 for (MachineBasicBlock *
PB :
MBB->predecessors())
1437 const RegisterAggr &Defs = PhiM[BA.Id];
1440 for (RegisterRef RR : Defs.refs()) {
1441 Phi PA = newPhi(BA);
1442 PA.Addr->addMember(newDef(PA, RR, PhiFlags), *
this);
1445 for (
Block PBA : Preds) {
1446 PA.Addr->addMember(newPhiUse(PA, RR, PBA), *
this);
1452void DataFlowGraph::removeUnusedPhis() {
1459 SetVector<NodeId> PhiQ;
1461 for (
auto P : BA.Addr->members_if(
IsPhi, *
this))
1465 static auto HasUsedDef = [](
NodeList &Ms) ->
bool {
1470 if (
DA.Addr->getReachedDef() != 0 ||
DA.Addr->getReachedUse() != 0)
1479 while (!PhiQ.empty()) {
1480 auto PA = addr<PhiNode *>(PhiQ[0]);
1482 NodeList Refs = PA.Addr->members(*
this);
1483 if (HasUsedDef(Refs))
1485 for (
Ref RA : Refs) {
1486 if (
NodeId RD =
RA.Addr->getReachingDef()) {
1487 auto RDA = addr<DefNode *>(RD);
1488 Instr OA =
RDA.Addr->getOwner(*
this);
1492 if (
RA.Addr->isDef())
1497 Block BA = PA.Addr->getOwner(*
this);
1498 BA.Addr->removeMember(PA, *
this);
1505template <
typename T>
1506void DataFlowGraph::linkRefUp(
Instr IA, NodeAddr<T> TA, DefStack &DS) {
1509 RegisterRef RR =
TA.Addr->getRegRef(*
this);
1513 RegisterAggr Defs(
getPRI());
1515 for (
auto I =
DS.top(),
E =
DS.bottom();
I !=
E;
I.down()) {
1516 RegisterRef QR =
I->Addr->getRegRef(*
this);
1520 bool Seen = Defs.hasCoverOf(QR);
1524 bool Cover = Defs.insert(QR).hasCoverOf(RR);
1539 TAP.Addr->linkToDef(TAP.Id,
RDA);
1547template <
typename Predicate>
1554 for (
Ref RA : SA.Addr->members_if(
P, *
this)) {
1557 RegisterRef RR =
RA.Addr->getRegRef(*
this);
1564 auto F = DefM.find(RR.Reg);
1565 if (
F == DefM.end())
1567 DefStack &
DS =
F->second;
1569 linkRefUp<UseNode *>(SA,
RA, DS);
1571 linkRefUp<DefNode *>(SA,
RA, DS);
1583 auto IsClobber = [](
Ref RA) ->
bool {
1586 auto IsNoClobber = [](
Ref RA) ->
bool {
1590 assert(BA.Addr &&
"block node address is needed to create a data-flow link");
1594 for (
Instr IA : BA.Addr->members(*
this)) {
1598 linkStmtRefs(DefM, IA,
IsUse);
1599 linkStmtRefs(DefM, IA, IsClobber);
1603 pushClobbers(IA, DefM);
1606 linkStmtRefs(DefM, IA, IsNoClobber);
1613 for (
auto *
I : *
N) {
1614 MachineBasicBlock *SB =
I->getBlock();
1616 linkBlockRefs(DefM, SBA);
1620 auto IsUseForBA = [BA](
Node NA) ->
bool {
1624 return PhiUse(NA).Addr->getPredecessor() == BA.Id;
1627 RegisterAggr EHLiveIns = getLandingPadLiveIns();
1628 MachineBasicBlock *
MBB = BA.Addr->getCode();
1630 for (MachineBasicBlock *SB :
MBB->successors()) {
1631 bool IsEHPad = SB->isEHPad();
1633 for (
Instr IA : SBA.Addr->members_if(
IsPhi, *
this)) {
1637 Ref RA =
IA.Addr->getFirstMember(*
this);
1639 if (EHLiveIns.hasCoverOf(
RA.Addr->getRegRef(*
this)))
1643 for (
auto U :
IA.Addr->members_if(IsUseForBA, *
this)) {
1645 RegisterRef RR = PUA.Addr->getRegRef(*
this);
1646 linkRefUp<UseNode *>(IA, PUA, DefM[RR.Reg]);
1656void DataFlowGraph::unlinkUseDF(
Use UA) {
1657 NodeId RD = UA.Addr->getReachingDef();
1658 NodeId Sib = UA.Addr->getSibling();
1665 auto RDA = addr<DefNode *>(RD);
1666 auto TA = addr<UseNode *>(
RDA.Addr->getReachedUse());
1667 if (
TA.Id == UA.Id) {
1668 RDA.Addr->setReachedUse(Sib);
1672 while (
TA.Id != 0) {
1675 TA.Addr->setSibling(UA.Addr->getSibling());
1678 TA = addr<UseNode *>(S);
1683void DataFlowGraph::unlinkDefDF(
Def DA) {
1702 NodeId RD =
DA.Addr->getReachingDef();
1711 auto RA = addr<RefNode *>(
N);
1714 N =
RA.Addr->getSibling();
1718 NodeList ReachedDefs = getAllNodes(
DA.Addr->getReachedDef());
1719 NodeList ReachedUses = getAllNodes(
DA.Addr->getReachedUse());
1722 for (
Ref I : ReachedDefs)
1723 I.Addr->setSibling(0);
1724 for (
Ref I : ReachedUses)
1725 I.Addr->setSibling(0);
1727 for (
Def I : ReachedDefs)
1728 I.Addr->setReachingDef(RD);
1729 for (
Use I : ReachedUses)
1730 I.Addr->setReachingDef(RD);
1732 NodeId Sib =
DA.Addr->getSibling();
1739 auto RDA = addr<DefNode *>(RD);
1740 auto TA = addr<DefNode *>(
RDA.Addr->getReachedDef());
1741 if (
TA.Id ==
DA.Id) {
1744 RDA.Addr->setReachedDef(Sib);
1748 while (
TA.Id != 0) {
1751 TA.Addr->setSibling(Sib);
1754 TA = addr<DefNode *>(S);
1759 if (!ReachedDefs.empty()) {
1760 auto Last =
Def(ReachedDefs.back());
1761 Last.Addr->setSibling(
RDA.Addr->getReachedDef());
1762 RDA.Addr->setReachedDef(ReachedDefs.front().Id);
1765 if (!ReachedUses.empty()) {
1766 auto Last =
Use(ReachedUses.back());
1767 Last.Addr->setSibling(
RDA.Addr->getReachedUse());
1768 RDA.Addr->setReachedUse(ReachedUses.front().Id);
1779 for (
Ref R : S.
Addr->members(*
this)) {
1782 if (IgnoreReserved && RR.
isReg() && ReservedRegs[RR.
idx()])
1788 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.
DomTreeNodeBase< NodeT > * getNode(const NodeT *BB) const
getNode - return the (Post)DominatorTree node for the specified basic block.
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...
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)