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();
209 OS << PrintNode<T>(
A,
P.G);
219 OS <<
Print(
P.Obj.Id,
P.G) <<
": phi ["
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);
257 OS <<
"instr? " <<
Print(
P.Obj.Id,
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;
366 Node NA = {
reinterpret_cast<NodeBase *
>(ActiveEnd), makeId(ActiveB, Index)};
373 for (
unsigned i = 0, n = Blocks.size(); i != n; ++i) {
378 return makeId(i, Idx);
431 while (NA.
Addr !=
this) {
442 RefData.Sib = DA.Addr->getReachedDef();
443 DA.Addr->setReachedDef(Self);
449 RefData.Sib = DA.Addr->getReachedUse();
450 DA.Addr->setReachedUse(Self);
493 if (MA.
Id == NA.
Id) {
504 while (MA.
Addr !=
this) {
521 static auto True = [](
Node) ->
bool {
return true; };
529 while (NA.
Addr !=
this) {
558 MN =
G.addr<
NodeBase *>(M.Addr->getNext());
590 unsigned OpNum)
const {
591 return TII.isPredicated(In);
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;
748 const TargetLowering &TLI = *MF.getSubtarget().getTargetLowering();
749 if (
RegisterId R = TLI.getExceptionPointerRegister(
750 TLI.getTargetMachine().getExceptionModel(), PF))
751 LR.insert(RegisterRef(R));
753 if (
RegisterId R = TLI.getExceptionSelectorRegister(
754 TLI.getTargetMachine().getExceptionModel(), PF))
755 LR.insert(RegisterRef(R));
766 return Memory.ptr(
N);
780 P.Addr->setAttrs(Attrs);
786Node DataFlowGraph::cloneNode(
const Node B) {
787 Node NA = newNode(0);
788 memcpy(NA.Addr,
B.Addr,
sizeof(NodeBase));
792 RA.Addr->setReachingDef(0);
793 RA.Addr->setSibling(0);
796 DA.Addr->setReachedDef(0);
797 DA.Addr->setReachedUse(0);
805Use DataFlowGraph::newUse(
Instr Owner, MachineOperand &
Op, uint16_t Flags) {
807 UA.Addr->setRegRef(&
Op, *
this);
815 PUA.Addr->setRegRef(RR, *
this);
816 PUA.Addr->setPredecessor(PredB.Id);
820Def DataFlowGraph::newDef(
Instr Owner, MachineOperand &
Op, uint16_t Flags) {
822 DA.Addr->setRegRef(&
Op, *
this);
826Def DataFlowGraph::newDef(
Instr Owner, RegisterRef RR, uint16_t Flags) {
829 DA.Addr->setRegRef(RR, *
this);
835 Owner.Addr->addPhi(PA, *
this);
841 SA.Addr->setCode(
MI);
842 Owner.Addr->addMember(SA, *
this);
848 BA.Addr->setCode(BB);
849 Owner.Addr->addMember(BA, *
this);
855 FA.Addr->setCode(MF);
867 auto Insert = [](
auto &Set,
auto &&
Range) {
871 if (BuildCfg.TrackRegs.empty()) {
872 std::set<RegisterId> BaseSet;
873 if (BuildCfg.Classes.empty()) {
875 for (
unsigned R = 1,
E =
getPRI().
getTRI().getNumRegs(); R !=
E; ++R)
884 if (SkipReserved && ReservedRegs[R])
890 for (
unsigned R : BuildCfg.TrackRegs) {
891 if (SkipReserved && ReservedRegs[R])
897 TheFunc = newFunc(&MF);
903 Block BA = newBlock(TheFunc, &
B);
904 BlockNodes.insert(std::make_pair(&
B, BA));
906 if (
I.isDebugInstr())
912 Block EA = TheFunc.Addr->getEntryBlock(*
this);
913 NodeList Blocks = TheFunc.Addr->members(*
this);
918 for (std::pair<MCRegister, Register>
P : MRI.
liveins())
931 Def DA = newDef(PA, RR, PhiFlags);
941 if (!EHRegs.
empty()) {
942 for (
Block BA : Blocks) {
959 Def DA = newDef(PA, RR, PhiFlags);
962 for (
Block PBA : Preds) {
963 PhiUse PUA = newPhiUse(PA, RR, PBA);
973 BlockRefsMap PhiM(
getPRI());
974 BlockRefsMap PhiClobberM(
getPRI());
975 for (
Block BA : Blocks)
976 recordDefsForDF(PhiM, PhiClobberM, BA);
977 for (
Block BA : Blocks)
983 linkBlockRefs(
DM, PhiClobberM, EA);
1009 for (
auto &
P : DefM)
1010 P.second.start_block(
B);
1018 for (
auto &
P : DefM)
1019 P.second.clear_block(
B);
1022 DefM.
remove_if([](
const auto &
P) {
return P.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.
Id].push(DA);
1063 Defined.insert(RR.
Id);
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.Id).second) {
1112 dbgs() <<
"Multiple definitions of register: " <<
Print(RR, *
this)
1120 DefM[RR.Id].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 {
1194 return RA.Addr->getNextRef(RR,
Cond,
true, *
this);
1202template <
typename Predicate>
1203std::pair<Ref, Ref> DataFlowGraph::locateNextRef(
Instr IA,
Ref RA,
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();
1285 BitVector DoneDefs(TRI.getNumRegs());
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)))
1295 if (TOI.isPreserving(In, OpN)) {
1301 if (TOI.isClobbering(In, OpN))
1303 if (TOI.isFixedReg(In, OpN))
1305 if (IsCall &&
Op.isDead())
1307 Def DA = newDef(SA,
Op, Flags);
1309 assert(!DoneDefs.test(R));
1314 BitVector DoneClobbers(TRI.getNumRegs());
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);
1323 const uint32_t *
RM =
Op.getRegMask();
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))
1343 if (TOI.isPreserving(In, OpN)) {
1346 if (isDefUndef(In, RR))
1349 if (TOI.isClobbering(In, OpN))
1351 if (TOI.isFixedReg(In, OpN))
1353 if (IsCall &&
Op.isDead()) {
1354 if (DoneClobbers.test(R))
1358 Def DA = newDef(SA,
Op, Flags);
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)))
1373 if (TOI.isFixedReg(In, OpN))
1375 Use UA = newUse(SA,
Op, Flags);
1383void DataFlowGraph::recordDefsForDF(BlockRefsMap &PhiM,
1384 BlockRefsMap &PhiClobberM,
Block BA) {
1388 MachineBasicBlock *BB = BA.Addr->getCode();
1390 auto DFLoc = MDF.find(BB);
1391 if (DFLoc == MDF.end() || DFLoc->second.empty())
1399 RegisterAggr Defs(
getPRI());
1400 RegisterAggr ClobberDefs(
getPRI());
1403 RegisterRef RR =
RA.Addr->getRegRef(*
this);
1409 else if (RR.isMask())
1410 ClobberDefs.insert(RR);
1417 for (
unsigned i = 0; i < IDF.size(); ++i) {
1418 auto F = MDF.find(IDF[i]);
1420 IDF.insert_range(
F->second);
1425 for (
auto *DB : IDF) {
1427 PhiM[DBA.Id].insert(Defs);
1428 PhiClobberM[DBA.Id].insert(ClobberDefs);
1434void DataFlowGraph::buildPhis(BlockRefsMap &PhiM,
Block BA,
1438 auto HasDF = PhiM.find(BA.Id);
1439 if (HasDF == PhiM.end() || HasDF->second.empty())
1444 const MachineBasicBlock *
MBB = BA.Addr->getCode();
1445 for (MachineBasicBlock *
PB :
MBB->predecessors())
1448 RegisterAggr PhiDefs(
getPRI());
1451 if (!DefM.empty()) {
1453 for (
Def DA :
IA.Addr->members_if(
IsDef, *
this)) {
1454 auto DR =
DA.Addr->getRegRef(*
this);
1460 MachineRegisterInfo &MRI = MF.getRegInfo();
1461 const RegisterAggr &Defs = PhiM[BA.Id];
1464 for (RegisterRef RR : Defs.refs()) {
1465 if (!DefM.empty()) {
1466 auto F = DefM.find(RR.Id);
1470 if (!MRI.isAllocatable(RR.asMCReg()) || PhiDefs.hasCoverOf(RR) ||
1471 F == DefM.end() ||
F->second.empty())
1474 auto RDef =
F->second.top();
1479 Phi PA = newPhi(BA);
1480 PA.Addr->addMember(newDef(PA, RR, PhiFlags), *
this);
1483 for (
Block PBA : Preds) {
1484 PA.Addr->addMember(newPhiUse(PA, RR, PBA), *
this);
1490void DataFlowGraph::removeUnusedPhis() {
1497 SetVector<NodeId> PhiQ;
1499 for (
auto P : BA.Addr->members_if(
IsPhi, *
this))
1503 static auto HasUsedDef = [](
NodeList &Ms) ->
bool {
1508 if (
DA.Addr->getReachedDef() != 0 ||
DA.Addr->getReachedUse() != 0)
1517 while (!PhiQ.empty()) {
1520 NodeList Refs = PA.Addr->members(*
this);
1521 if (HasUsedDef(Refs))
1523 for (
Ref RA : Refs) {
1524 if (
NodeId RD =
RA.Addr->getReachingDef()) {
1530 if (
RA.Addr->isDef())
1543template <
typename T>
1544void DataFlowGraph::linkRefUp(
Instr IA, NodeAddr<T> TA,
DefStack &DS) {
1547 RegisterRef RR =
TA.Addr->getRegRef(*
this);
1551 RegisterAggr Defs(
getPRI());
1553 for (
auto I =
DS.top(),
E =
DS.bottom();
I !=
E;
I.down()) {
1554 RegisterRef QR =
I->Addr->getRegRef(*
this);
1558 bool Seen = Defs.hasCoverOf(QR);
1562 bool Cover = Defs.insert(QR).hasCoverOf(RR);
1585template <
typename Predicate>
1592 for (
Ref RA : SA.
Addr->members_if(
P, *
this)) {
1593 uint16_t
Kind =
RA.Addr->getKind();
1595 RegisterRef RR =
RA.Addr->getRegRef(*
this);
1602 auto F = DefM.find(RR.Id);
1603 if (
F == DefM.end())
1607 linkRefUp<UseNode *>(SA,
RA, DS);
1609 linkRefUp<DefNode *>(SA,
RA, DS);
1617void DataFlowGraph::linkBlockRefs(
DefStackMap &DefM, BlockRefsMap &PhiClobberM,
1624 buildPhis(PhiClobberM, BA, DefM);
1629 auto IsClobber = [](
Ref RA) ->
bool {
1632 auto IsNoClobber = [](
Ref RA) ->
bool {
1636 assert(BA.Addr &&
"block node address is needed to create a data-flow link");
1644 linkStmtRefs(DefM, IA,
IsUse);
1645 linkStmtRefs(DefM, IA, IsClobber);
1649 pushClobbers(IA, DefM);
1652 linkStmtRefs(DefM, IA, IsNoClobber);
1659 for (
auto *
I : *
N) {
1660 MachineBasicBlock *SB =
I->getBlock();
1662 linkBlockRefs(DefM, PhiClobberM, SBA);
1666 auto IsUseForBA = [BA](
Node NA) ->
bool {
1673 RegisterAggr EHLiveIns = getLandingPadLiveIns();
1674 MachineBasicBlock *
MBB = BA.Addr->getCode();
1676 for (MachineBasicBlock *SB :
MBB->successors()) {
1677 bool IsEHPad = SB->isEHPad();
1683 Ref RA =
IA.Addr->getFirstMember(*
this);
1685 if (EHLiveIns.hasCoverOf(
RA.Addr->getRegRef(*
this)))
1689 for (
auto U :
IA.Addr->members_if(IsUseForBA, *
this)) {
1691 RegisterRef RR = PUA.Addr->getRegRef(*
this);
1692 linkRefUp<UseNode *>(IA, PUA, DefM[RR.Id]);
1702void DataFlowGraph::unlinkUseDF(
Use UA) {
1703 NodeId RD = UA.Addr->getReachingDef();
1704 NodeId Sib = UA.Addr->getSibling();
1713 if (
TA.Id == UA.Id) {
1714 RDA.Addr->setReachedUse(Sib);
1718 while (
TA.Id != 0) {
1721 TA.Addr->setSibling(UA.Addr->getSibling());
1729void DataFlowGraph::unlinkDefDF(
Def DA) {
1748 NodeId RD =
DA.Addr->getReachingDef();
1760 N =
RA.Addr->getSibling();
1764 NodeList ReachedDefs = getAllNodes(
DA.Addr->getReachedDef());
1765 NodeList ReachedUses = getAllNodes(
DA.Addr->getReachedUse());
1768 for (
Ref I : ReachedDefs)
1769 I.Addr->setSibling(0);
1770 for (
Ref I : ReachedUses)
1771 I.Addr->setSibling(0);
1773 for (
Def I : ReachedDefs)
1774 I.Addr->setReachingDef(RD);
1775 for (
Use I : ReachedUses)
1776 I.Addr->setReachingDef(RD);
1778 NodeId Sib =
DA.Addr->getSibling();
1787 if (
TA.Id ==
DA.Id) {
1790 RDA.Addr->setReachedDef(Sib);
1794 while (
TA.Id != 0) {
1797 TA.Addr->setSibling(Sib);
1805 if (!ReachedDefs.empty()) {
1806 auto Last =
Def(ReachedDefs.back());
1807 Last.Addr->setSibling(RDA.Addr->getReachedDef());
1808 RDA.Addr->setReachedDef(ReachedDefs.front().Id);
1811 if (!ReachedUses.empty()) {
1812 auto Last =
Use(ReachedUses.back());
1813 Last.Addr->setSibling(RDA.Addr->getReachedUse());
1814 RDA.Addr->setReachedUse(ReachedUses.front().Id);
1826 Ops.push_back(&R.Addr->getOp());
1828 if (IgnoreReserved && RR.
isReg() && ReservedRegs[RR.
asMCReg().
id()])
1834 if (!
Op.isReg() && !
Op.isRegMask())
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
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 ManagedStatic< DebugCounterOwner > Owner
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.
Represent a constant reference to an array (0 or more elements consecutively in memory),...
void clear()
Removes all bits from the bitvector.
LLVM_ATTRIBUTE_RETURNS_NONNULL void * Allocate(size_t Size, Align Alignment)
Allocate space at the specified alignment.
bool remove_if(Predicate Pred)
Remove entries that match the given predicate.
Describe properties that are true of each instruction in the target description file.
constexpr unsigned id() const
unsigned pred_size() const
iterator_range< livein_iterator > liveins() const
unsigned succ_size() const
iterator_range< succ_iterator > successors()
iterator_range< pred_iterator > predecessors()
MachineDominanceFrontier::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,...
bool tracksLiveness() const
tracksLiveness - Returns true when tracking register liveness accurately.
const BitVector & getReservedRegs() const
getReservedRegs - Returns a reference to the frozen set of reserved registers.
ArrayRef< std::pair< MCRegister, Register > > liveins() const
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
std::set< RegisterRef, RegisterRefLess > RegisterSet
NodeAddr< BlockNode * > Block
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
LLVM_ABI 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
constexpr auto equal_to(T &&Arg)
Functor variant of std::equal_to that can be used as a UnaryPredicate in functional algorithms like a...
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.
MCRegisterClass TargetRegisterClass
Implement std::hash so that hash_code can be used in STL containers.
static constexpr LaneBitmask getAll()
MachineBasicBlock * getCode() const
LLVM_ABI void addPhi(Phi PA, const DataFlowGraph &G)
NodeList members_if(Predicate P, const DataFlowGraph &G) const
LLVM_ABI void removeMember(Node NA, const DataFlowGraph &G)
LLVM_ABI NodeList members(const DataFlowGraph &G) const
LLVM_ABI void addMember(Node NA, const DataFlowGraph &G)
LLVM_ABI Node getFirstMember(const DataFlowGraph &G) const
LLVM_ABI void addMemberAfter(Node MA, Node NA, const DataFlowGraph &G)
LLVM_ABI Node getLastMember(const DataFlowGraph &G) const
LLVM_ABI void clear_block(NodeId N)
LLVM_ABI void start_block(NodeId N)
LLVM_ABI unsigned size() const
LLVM_ABI NodeId id(const NodeBase *P) const
void unlinkUse(Use UA, bool RemoveFromOwner)
LLVM_ABI void releaseBlock(NodeId B, DefStackMap &DefM)
LLVM_ABI Ref getNextRelated(Instr IA, Ref RA) const
LLVM_ABI bool isTracked(RegisterRef RR) const
LLVM_ABI RegisterRef makeRegRef(unsigned Reg, unsigned Sub) const
static bool IsDef(const Node BA)
LLVM_ABI DataFlowGraph(MachineFunction &mf, const TargetInstrInfo &tii, const TargetRegisterInfo &tri, const MachineDominatorTree &mdt, const MachineDominanceFrontier &mdf)
LLVM_ABI Ref getNextShadow(Instr IA, Ref RA, bool Create)
static bool IsPhi(const Node BA)
LLVM_ABI NodeList getRelatedRefs(Instr IA, Ref RA) const
void unlinkDef(Def DA, bool RemoveFromOwner)
static bool IsUse(const Node BA)
const PhysicalRegisterInfo & getPRI() const
LLVM_ABI void markBlock(NodeId B, DefStackMap &DefM)
LLVM_ABI NodeBase * ptr(NodeId N) const
Block findBlock(MachineBasicBlock *BB) const
LLVM_ABI bool hasUntrackedRef(Stmt S, bool IgnoreReserved=true) const
DenseMap< RegisterId, DefStack > DefStackMap
const TargetRegisterInfo & getTRI() const
LLVM_ABI void pushAllDefs(Instr IA, DefStackMap &DM)
NodeAddr< T > addr(NodeId N) const
LLVM_ABI void linkToDef(NodeId Self, Def DA)
MachineFunction * getCode() const
LLVM_ABI Block findBlock(const MachineBasicBlock *BB, const DataFlowGraph &G) const
LLVM_ABI Block getEntryBlock(const DataFlowGraph &G)
LLVM_ABI Node getOwner(const DataFlowGraph &G)
LLVM_ABI 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)
LLVM_ABI void append(Node NA)
uint16_t getFlags() const
NodeId getPredecessor() const
LLVM_ABI void setRegRef(RegisterRef RR, DataFlowGraph &G)
LLVM_ABI RegisterRef getRegRef(const DataFlowGraph &G) const
LLVM_ABI Node getOwner(const DataFlowGraph &G)
iterator_range< ref_iterator > refs() const
constexpr bool isReg() const
static constexpr bool isMaskId(RegisterId Id)
static constexpr bool isRegId(RegisterId Id)
constexpr MCRegister asMCReg() const
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
LLVM_ABI void linkToDef(NodeId Self, Def DA)