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);
973 recordDefsForDF(PhiM, PhiClobberM, BA);
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) {
1113 MachineInstr *
MI =
Stmt(IA).Addr->getCode();
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())
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 {
1193 return PhiUse(TA).Addr->getPredecessor() ==
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();
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)))
1307 if (IsCall &&
Op.isDead())
1309 Def DA = newDef(SA,
Op, Flags);
1310 SA.
Addr->addMember(DA, *
this);
1311 assert(!DoneDefs.test(R));
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);
1323 SA.
Addr->addMember(DA, *
this);
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))
1348 if (isDefUndef(In, RR))
1355 if (IsCall &&
Op.isDead()) {
1356 if (DoneClobbers.test(R))
1360 Def DA = newDef(SA,
Op, Flags);
1361 SA.
Addr->addMember(DA, *
this);
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)))
1377 Use UA = newUse(SA,
Op, Flags);
1378 SA.
Addr->addMember(UA, *
this);
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());
1403 for (
Instr IA : BA.Addr->members(*
this)) {
1405 RegisterRef RR =
RA.Addr->getRegRef(*
this);
1411 else if (RR.isMask())
1412 ClobberDefs.insert(RR);
1418 SetVector<MachineBasicBlock *> IDF(
DF.begin(),
DF.end());
1419 for (
unsigned i = 0; i < IDF.size(); ++i) {
1420 auto F = MDF.
find(IDF[i]);
1422 IDF.insert(
F->second.begin(),
F->second.end());
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()) {
1454 for (
Instr IA : BA.Addr->members_if(
IsPhi, *
this)) {
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()) {
1520 auto PA = addr<PhiNode *>(PhiQ[0]);
1522 NodeList Refs = PA.Addr->members(*
this);
1523 if (HasUsedDef(Refs))
1525 for (
Ref RA : Refs) {
1526 if (
NodeId RD =
RA.Addr->getReachingDef()) {
1527 auto RDA = addr<DefNode *>(RD);
1528 Instr OA =
RDA.Addr->getOwner(*
this);
1532 if (
RA.Addr->isDef())
1537 Block BA = PA.Addr->getOwner(*
this);
1538 BA.Addr->removeMember(PA, *
this);
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);
1579 TAP.Addr->linkToDef(TAP.Id,
RDA);
1587template <
typename Predicate>
1594 for (
Ref RA : SA.Addr->members_if(
P, *
this)) {
1597 RegisterRef RR =
RA.Addr->getRegRef(*
this);
1604 auto F = DefM.find(RR.Reg);
1605 if (
F == DefM.end())
1607 DefStack &
DS =
F->second;
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");
1642 for (
Instr IA : BA.Addr->members(*
this)) {
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 {
1672 return PhiUse(NA).Addr->getPredecessor() == BA.Id;
1675 RegisterAggr EHLiveIns = getLandingPadLiveIns();
1676 MachineBasicBlock *
MBB = BA.Addr->getCode();
1678 for (MachineBasicBlock *SB :
MBB->successors()) {
1679 bool IsEHPad = SB->isEHPad();
1681 for (
Instr IA : SBA.Addr->members_if(
IsPhi, *
this)) {
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();
1713 auto RDA = addr<DefNode *>(RD);
1714 auto TA = addr<UseNode *>(
RDA.Addr->getReachedUse());
1715 if (
TA.Id == UA.Id) {
1716 RDA.Addr->setReachedUse(Sib);
1720 while (
TA.Id != 0) {
1723 TA.Addr->setSibling(UA.Addr->getSibling());
1726 TA = addr<UseNode *>(S);
1731void DataFlowGraph::unlinkDefDF(
Def DA) {
1750 NodeId RD =
DA.Addr->getReachingDef();
1759 auto RA = addr<RefNode *>(
N);
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();
1787 auto RDA = addr<DefNode *>(RD);
1788 auto TA = addr<DefNode *>(
RDA.Addr->getReachedDef());
1789 if (
TA.Id ==
DA.Id) {
1792 RDA.Addr->setReachedDef(Sib);
1796 while (
TA.Id != 0) {
1799 TA.Addr->setSibling(Sib);
1802 TA = addr<DefNode *>(S);
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);
1827 for (
Ref R : S.
Addr->members(*
this)) {
1830 if (IgnoreReserved && RR.
isReg() && ReservedRegs[RR.
idx()])
1836 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)