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();
208 OS << PrintNode<T>(
A,
P.G);
218 OS <<
Print(
P.Obj.Id,
P.G) <<
": phi ["
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);
256 OS <<
"instr? " <<
Print(
P.Obj.Id,
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;
365 Node NA = {
reinterpret_cast<NodeBase *
>(ActiveEnd), makeId(ActiveB, Index)};
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) {
441 RefData.Sib = DA.Addr->getReachedDef();
442 DA.Addr->setReachedDef(Self);
448 RefData.Sib = DA.Addr->getReachedUse();
449 DA.Addr->setReachedUse(Self);
492 if (MA.
Id == NA.
Id) {
503 while (MA.
Addr !=
this) {
520 static auto True = [](
Node) ->
bool {
return true; };
528 while (NA.
Addr !=
this) {
557 MN =
G.addr<
NodeBase *>(M.Addr->getNext());
589 unsigned OpNum)
const {
590 return TII.isPredicated(In);
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;
747 const TargetLowering &TLI = *MF.getSubtarget().getTargetLowering();
748 if (
RegisterId R = TLI.getExceptionPointerRegister(PF))
749 LR.insert(RegisterRef(R));
751 if (
RegisterId R = TLI.getExceptionSelectorRegister(PF))
752 LR.insert(RegisterRef(R));
763 return Memory.ptr(
N);
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);
802Use DataFlowGraph::newUse(
Instr Owner, MachineOperand &
Op, uint16_t Flags) {
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);
817Def DataFlowGraph::newDef(
Instr Owner, MachineOperand &
Op, uint16_t Flags) {
819 DA.Addr->setRegRef(&
Op, *
this);
823Def DataFlowGraph::newDef(
Instr Owner, RegisterRef RR, uint16_t Flags) {
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) {
868 if (BuildCfg.TrackRegs.empty()) {
869 std::set<RegisterId> BaseSet;
870 if (BuildCfg.Classes.empty()) {
872 for (
unsigned R = 1,
E =
getPRI().
getTRI().getNumRegs(); R !=
E; ++R)
881 if (SkipReserved && ReservedRegs[R])
887 for (
unsigned R : BuildCfg.TrackRegs) {
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())
909 Block EA = TheFunc.Addr->getEntryBlock(*
this);
910 NodeList Blocks = TheFunc.Addr->members(*
this);
915 for (std::pair<MCRegister, Register>
P :
MRI.liveins())
917 if (
MRI.tracksLiveness()) {
928 Def DA = newDef(PA, RR, PhiFlags);
938 if (!EHRegs.
empty()) {
939 for (
Block BA : Blocks) {
956 Def DA = newDef(PA, RR, PhiFlags);
959 for (
Block PBA : Preds) {
960 PhiUse PUA = newPhiUse(PA, RR, PBA);
970 BlockRefsMap PhiM(
getPRI());
971 BlockRefsMap PhiClobberM(
getPRI());
972 for (
Block BA : Blocks)
973 recordDefsForDF(PhiM, PhiClobberM, BA);
974 for (
Block BA : Blocks)
980 linkBlockRefs(
DM, PhiClobberM, EA);
1006 for (
auto &
P : DefM)
1007 P.second.start_block(
B);
1015 for (
auto &
P : DefM)
1016 P.second.clear_block(
B);
1019 for (
auto I = DefM.begin(),
E = DefM.end(), NextI =
I;
I !=
E;
I = NextI) {
1020 NextI = std::next(
I);
1022 if (
I->second.empty())
1030 pushClobbers(IA, DefM);
1038 std::set<RegisterId> Defined;
1052 for (
Def DA : IA.Addr->members_if(
IsDef, *
this)) {
1053 if (Visited.count(DA.Id))
1064 DefM[RR.
Reg].push(DA);
1065 Defined.insert(RR.
Reg);
1071 if (!Defined.count(
A))
1076 Visited.insert(
T.Id);
1085 std::set<RegisterId> Defined;
1100 for (
Def DA :
IA.Addr->members_if(
IsDef, *
this)) {
1101 if (Visited.count(
DA.Id))
1107 Def PDA = Rel.front();
1108 RegisterRef RR = PDA.Addr->getRegRef(*
this);
1112 if (!Defined.insert(RR.Reg).second) {
1114 dbgs() <<
"Multiple definitions of register: " <<
Print(RR, *
this)
1122 DefM[RR.Reg].push(DA);
1132 Visited.insert(
T.Id);
1146 }
while (
RA.Id != 0 &&
RA.Id != Start);
1151void DataFlowGraph::reset() {
1154 TrackedUnits.clear();
1155 ReservedRegs.
clear();
1168 auto IsRelated = [
this,
RA](
Ref TA) ->
bool {
1169 if (TA.Addr->getKind() !=
RA.Addr->getKind())
1171 if (!
getPRI().equal_to(TA.Addr->getRegRef(*
this),
1172 RA.Addr->getRegRef(*
this))) {
1180 auto Cond = [&IsRelated,
RA](
Ref TA) ->
bool {
1181 return IsRelated(TA) && &
RA.Addr->getOp() == &TA.Addr->getOp();
1183 return RA.Addr->getNextRef(RR,
Cond,
true, *
this);
1187 auto Cond = [&IsRelated,
RA](
Ref TA) ->
bool {
1196 return RA.Addr->getNextRef(RR,
Cond,
true, *
this);
1204template <
typename Predicate>
1205std::pair<Ref, Ref> DataFlowGraph::locateNextRef(
Instr IA,
Ref RA,
1213 if (NA.
Id == 0 || NA.
Id == Start)
1220 if (NA.
Id != 0 && NA.
Id != Start)
1221 return std::make_pair(
RA, NA);
1222 return std::make_pair(
RA,
Ref());
1231 auto IsShadow = [Flags](
Ref TA) ->
bool {
1232 return TA.Addr->getFlags() == Flags;
1234 auto Loc = locateNextRef(IA,
RA, IsShadow);
1235 if (
Loc.second.Id != 0 || !Create)
1239 Ref NA = cloneNode(
RA);
1241 IA.Addr->addMemberAfter(
Loc.first, NA, *
this);
1248 Stmt SA = newStmt(BA, &In);
1254 if (In.isBranch()) {
1256 if (
Op.isGlobal() ||
Op.isSymbol())
1261 if (In.isIndirectBranch())
1267 auto isDefUndef = [
this](
const MachineInstr &In, RegisterRef DR) ->
bool {
1270 for (
const MachineOperand &
Op : In.all_uses()) {
1271 if (
Op.getReg() == 0 ||
Op.isUndef())
1274 if (
getPRI().alias(DR, UR))
1280 bool IsCall = isCall(In);
1281 unsigned NumOps =
In.getNumOperands();
1287 BitVector DoneDefs(TRI.getNumRegs());
1289 for (
unsigned OpN = 0; OpN <
NumOps; ++OpN) {
1290 MachineOperand &
Op =
In.getOperand(OpN);
1291 if (!
Op.isReg() || !
Op.isDef() ||
Op.isImplicit())
1294 if (!R || !
R.isPhysical() || !
isTracked(RegisterRef(R)))
1297 if (TOI.isPreserving(In, OpN)) {
1303 if (TOI.isClobbering(In, OpN))
1305 if (TOI.isFixedReg(In, OpN))
1307 if (IsCall &&
Op.isDead())
1309 Def DA = newDef(SA,
Op, Flags);
1311 assert(!DoneDefs.test(R));
1316 BitVector DoneClobbers(TRI.getNumRegs());
1317 for (
unsigned OpN = 0; OpN <
NumOps; ++OpN) {
1318 MachineOperand &
Op =
In.getOperand(OpN);
1319 if (!
Op.isRegMask())
1322 Def DA = newDef(SA,
Op, Flags);
1325 const uint32_t *
RM =
Op.getRegMask();
1326 for (
unsigned i = 1, e = TRI.getNumRegs(); i != e; ++i) {
1329 if (!(RM[i / 32] & (1u << (i % 32))))
1330 DoneClobbers.set(i);
1336 for (
unsigned OpN = 0; OpN <
NumOps; ++OpN) {
1337 MachineOperand &
Op =
In.getOperand(OpN);
1338 if (!
Op.isReg() || !
Op.isDef() || !
Op.isImplicit())
1341 if (!R || !
R.isPhysical() || !
isTracked(RegisterRef(R)) || DoneDefs.test(R))
1345 if (TOI.isPreserving(In, OpN)) {
1348 if (isDefUndef(In, RR))
1351 if (TOI.isClobbering(In, OpN))
1353 if (TOI.isFixedReg(In, OpN))
1355 if (IsCall &&
Op.isDead()) {
1356 if (DoneClobbers.test(R))
1360 Def DA = newDef(SA,
Op, Flags);
1365 for (
unsigned OpN = 0; OpN <
NumOps; ++OpN) {
1366 MachineOperand &
Op =
In.getOperand(OpN);
1367 if (!
Op.isReg() || !
Op.isUse())
1370 if (!R || !
R.isPhysical() || !
isTracked(RegisterRef(R)))
1375 if (TOI.isFixedReg(In, OpN))
1377 Use UA = newUse(SA,
Op, Flags);
1385void DataFlowGraph::recordDefsForDF(BlockRefsMap &PhiM,
1386 BlockRefsMap &PhiClobberM,
Block BA) {
1390 MachineBasicBlock *BB = BA.Addr->getCode();
1392 auto DFLoc = MDF.find(BB);
1393 if (DFLoc == MDF.end() || DFLoc->second.empty())
1401 RegisterAggr Defs(
getPRI());
1402 RegisterAggr ClobberDefs(
getPRI());
1405 RegisterRef RR =
RA.Addr->getRegRef(*
this);
1411 else if (RR.isMask())
1412 ClobberDefs.insert(RR);
1419 for (
unsigned i = 0; i < IDF.size(); ++i) {
1420 auto F = MDF.find(IDF[i]);
1422 IDF.insert_range(
F->second);
1427 for (
auto *DB : IDF) {
1429 PhiM[DBA.Id].insert(Defs);
1430 PhiClobberM[DBA.Id].insert(ClobberDefs);
1436void DataFlowGraph::buildPhis(BlockRefsMap &PhiM,
Block BA,
1440 auto HasDF = PhiM.find(BA.Id);
1441 if (HasDF == PhiM.end() || HasDF->second.empty())
1446 const MachineBasicBlock *
MBB = BA.Addr->getCode();
1447 for (MachineBasicBlock *
PB :
MBB->predecessors())
1450 RegisterAggr PhiDefs(
getPRI());
1453 if (!DefM.empty()) {
1455 for (
Def DA :
IA.Addr->members_if(
IsDef, *
this)) {
1456 auto DR =
DA.Addr->getRegRef(*
this);
1462 MachineRegisterInfo &
MRI = MF.getRegInfo();
1463 const RegisterAggr &Defs = PhiM[BA.Id];
1466 for (RegisterRef RR : Defs.refs()) {
1467 if (!DefM.empty()) {
1468 auto F = DefM.find(RR.Reg);
1472 if (!
MRI.isAllocatable(RR.Reg) || PhiDefs.hasCoverOf(RR) ||
1473 F == DefM.end() ||
F->second.empty())
1476 auto RDef =
F->second.top();
1481 Phi PA = newPhi(BA);
1482 PA.Addr->addMember(newDef(PA, RR, PhiFlags), *
this);
1485 for (
Block PBA : Preds) {
1486 PA.Addr->addMember(newPhiUse(PA, RR, PBA), *
this);
1492void DataFlowGraph::removeUnusedPhis() {
1499 SetVector<NodeId> PhiQ;
1501 for (
auto P : BA.Addr->members_if(
IsPhi, *
this))
1505 static auto HasUsedDef = [](
NodeList &Ms) ->
bool {
1510 if (
DA.Addr->getReachedDef() != 0 ||
DA.Addr->getReachedUse() != 0)
1519 while (!PhiQ.empty()) {
1522 NodeList Refs = PA.Addr->members(*
this);
1523 if (HasUsedDef(Refs))
1525 for (
Ref RA : Refs) {
1526 if (
NodeId RD =
RA.Addr->getReachingDef()) {
1532 if (
RA.Addr->isDef())
1545template <
typename T>
1546void DataFlowGraph::linkRefUp(
Instr IA, NodeAddr<T> TA,
DefStack &DS) {
1549 RegisterRef RR =
TA.Addr->getRegRef(*
this);
1553 RegisterAggr Defs(
getPRI());
1555 for (
auto I =
DS.top(),
E =
DS.bottom();
I !=
E;
I.down()) {
1556 RegisterRef QR =
I->Addr->getRegRef(*
this);
1560 bool Seen = Defs.hasCoverOf(QR);
1564 bool Cover = Defs.insert(QR).hasCoverOf(RR);
1587template <
typename Predicate>
1594 for (
Ref RA : SA.
Addr->members_if(
P, *
this)) {
1595 uint16_t
Kind =
RA.Addr->getKind();
1597 RegisterRef RR =
RA.Addr->getRegRef(*
this);
1604 auto F = DefM.find(RR.Reg);
1605 if (
F == DefM.end())
1609 linkRefUp<UseNode *>(SA,
RA, DS);
1611 linkRefUp<DefNode *>(SA,
RA, DS);
1619void DataFlowGraph::linkBlockRefs(
DefStackMap &DefM, BlockRefsMap &PhiClobberM,
1626 buildPhis(PhiClobberM, BA, DefM);
1631 auto IsClobber = [](
Ref RA) ->
bool {
1634 auto IsNoClobber = [](
Ref RA) ->
bool {
1638 assert(BA.Addr &&
"block node address is needed to create a data-flow link");
1646 linkStmtRefs(DefM, IA,
IsUse);
1647 linkStmtRefs(DefM, IA, IsClobber);
1651 pushClobbers(IA, DefM);
1654 linkStmtRefs(DefM, IA, IsNoClobber);
1661 for (
auto *
I : *
N) {
1662 MachineBasicBlock *SB =
I->getBlock();
1664 linkBlockRefs(DefM, PhiClobberM, SBA);
1668 auto IsUseForBA = [BA](
Node NA) ->
bool {
1675 RegisterAggr EHLiveIns = getLandingPadLiveIns();
1676 MachineBasicBlock *
MBB = BA.Addr->getCode();
1678 for (MachineBasicBlock *SB :
MBB->successors()) {
1679 bool IsEHPad = SB->isEHPad();
1685 Ref RA =
IA.Addr->getFirstMember(*
this);
1687 if (EHLiveIns.hasCoverOf(
RA.Addr->getRegRef(*
this)))
1691 for (
auto U :
IA.Addr->members_if(IsUseForBA, *
this)) {
1693 RegisterRef RR = PUA.Addr->getRegRef(*
this);
1694 linkRefUp<UseNode *>(IA, PUA, DefM[RR.Reg]);
1704void DataFlowGraph::unlinkUseDF(
Use UA) {
1705 NodeId RD = UA.Addr->getReachingDef();
1706 NodeId Sib = UA.Addr->getSibling();
1715 if (
TA.Id == UA.Id) {
1716 RDA.Addr->setReachedUse(Sib);
1720 while (
TA.Id != 0) {
1723 TA.Addr->setSibling(UA.Addr->getSibling());
1731void DataFlowGraph::unlinkDefDF(
Def DA) {
1750 NodeId RD =
DA.Addr->getReachingDef();
1762 N =
RA.Addr->getSibling();
1766 NodeList ReachedDefs = getAllNodes(
DA.Addr->getReachedDef());
1767 NodeList ReachedUses = getAllNodes(
DA.Addr->getReachedUse());
1770 for (
Ref I : ReachedDefs)
1771 I.Addr->setSibling(0);
1772 for (
Ref I : ReachedUses)
1773 I.Addr->setSibling(0);
1775 for (
Def I : ReachedDefs)
1776 I.Addr->setReachingDef(RD);
1777 for (
Use I : ReachedUses)
1778 I.Addr->setReachingDef(RD);
1780 NodeId Sib =
DA.Addr->getSibling();
1789 if (
TA.Id ==
DA.Id) {
1792 RDA.Addr->setReachedDef(Sib);
1796 while (
TA.Id != 0) {
1799 TA.Addr->setSibling(Sib);
1807 if (!ReachedDefs.empty()) {
1808 auto Last =
Def(ReachedDefs.back());
1809 Last.Addr->setSibling(
RDA.Addr->getReachedDef());
1810 RDA.Addr->setReachedDef(ReachedDefs.front().Id);
1813 if (!ReachedUses.empty()) {
1814 auto Last =
Use(ReachedUses.back());
1815 Last.Addr->setSibling(
RDA.Addr->getReachedUse());
1816 RDA.Addr->setReachedUse(ReachedUses.front().Id);
1828 Ops.push_back(&R.Addr->getOp());
1830 if (IgnoreReserved && RR.
isReg() && ReservedRegs[RR.
idx()])
1836 if (!
Op.isReg() && !
Op.isRegMask())
unsigned const MachineRegisterInfo * MRI
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
ReachingDefAnalysis & RDA
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< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static RegisterPass< DebugifyFunctionPass > DF("debugify-function", "Attach debug info to a function")
static RegisterPass< DebugifyModulePass > DM("debugify", "Attach debug info to everything")
const size_t AbstractManglingParser< Derived, Alloc >::NumOps
const AbstractManglingParser< Derived, Alloc >::OperatorInfo AbstractManglingParser< Derived, Alloc >::Ops[]
A common definition of LaneBitmask for use in TableGen and CodeGen.
Promote Memory to Register
ConstantRange Range(APInt(BitWidth, Low), APInt(BitWidth, High))
PassBuilder PB(Machine, PassOpts->PTO, std::nullopt, &PIC)
const SmallVectorImpl< MachineOperand > & Cond
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.
Describe properties that are true of each instruction in the target description file.
unsigned pred_size() const
iterator_range< livein_iterator > liveins() const
unsigned succ_size() const
iterator_range< succ_iterator > successors()
iterator_range< pred_iterator > predecessors()
DominanceFrontierBase< MachineBasicBlock, false >::DomSetType DomSetType
DominatorTree Class - Concrete subclass of DominatorTreeBase that is used to compute a normal dominat...
const MachineBasicBlock & front() const
Representation of each machine instruction.
const MachineOperand * const_mop_iterator
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.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
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< DefNode * > Def
NodeAddr< InstrNode * > Instr
NodeAddr< BlockNode * > Block
std::set< RegisterRef > RegisterSet
NodeAddr< PhiNode * > Phi
Print(const T &, const DataFlowGraph &) -> Print< T >
NodeAddr< PhiUseNode * > PhiUse
NodeAddr< StmtNode * > Stmt
NodeAddr< UseNode * > Use
static void printRefHeader(raw_ostream &OS, const Ref RA, const DataFlowGraph &G)
NodeAddr< NodeBase * > Node
raw_ostream & operator<<(raw_ostream &OS, const Print< RegisterRef > &P)
std::set< NodeId > NodeSet
SmallVector< Node, 4 > NodeList
NodeAddr< FuncNode * > Func
NodeAddr< RefNode * > Ref
bool disjoint(const std::set< T > &A, const std::set< T > &B)
constexpr from_range_t from_range
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
LLVM_ABI EHPersonality classifyEHPersonality(const Value *Pers)
See if the given exception handling personality function is one that we understand.
DomTreeNodeBase< MachineBasicBlock > MachineDomTreeNode
@ Ref
The access may reference the value stored in memory.
bool isFuncletEHPersonality(EHPersonality Pers)
Returns true if this is a personality function that invokes handler funclets (which must return to it...
@ Sub
Subtraction of integers.
uint16_t MCPhysReg
An unsigned integer type large enough to represent all physical registers, but not necessarily virtua...
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.
LLVM_ABI 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()
MachineBasicBlock * getCode() const
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
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
const TargetRegisterInfo & getTRI() const
void pushAllDefs(Instr IA, DefStackMap &DM)
NodeAddr< T > addr(NodeId N) const
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)
void setFlags(uint16_t F)
uint16_t getFlags() const
NodeId getPredecessor() const
void setRegRef(RegisterRef RR, DataFlowGraph &G)
RegisterRef getRegRef(const DataFlowGraph &G) const
Node getOwner(const DataFlowGraph &G)
iterator_range< ref_iterator > refs() const
constexpr unsigned idx() const
constexpr bool isReg() const
static constexpr bool isMaskId(unsigned Id)
static constexpr bool isRegId(unsigned Id)
MachineInstr * getCode() const
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)