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();
752 EH = TLI.getTargetMachine().getExceptionModel();
753 if (
RegisterId R = TLI.getExceptionPointerRegister(EH, PF))
754 LR.insert(RegisterRef(R));
756 if (
RegisterId R = TLI.getExceptionSelectorRegister(EH, PF))
757 LR.insert(RegisterRef(R));
768 return Memory.ptr(
N);
782 P.Addr->setAttrs(Attrs);
788Node DataFlowGraph::cloneNode(
const Node B) {
789 Node NA = newNode(0);
790 memcpy(NA.Addr,
B.Addr,
sizeof(NodeBase));
794 RA.Addr->setReachingDef(0);
795 RA.Addr->setSibling(0);
798 DA.Addr->setReachedDef(0);
799 DA.Addr->setReachedUse(0);
807Use DataFlowGraph::newUse(
Instr Owner, MachineOperand &
Op, uint16_t Flags) {
809 UA.Addr->setRegRef(&
Op, *
this);
817 PUA.Addr->setRegRef(RR, *
this);
818 PUA.Addr->setPredecessor(PredB.Id);
822Def DataFlowGraph::newDef(
Instr Owner, MachineOperand &
Op, uint16_t Flags) {
824 DA.Addr->setRegRef(&
Op, *
this);
828Def DataFlowGraph::newDef(
Instr Owner, RegisterRef RR, uint16_t Flags) {
831 DA.Addr->setRegRef(RR, *
this);
837 Owner.Addr->addPhi(PA, *
this);
843 SA.Addr->setCode(
MI);
844 Owner.Addr->addMember(SA, *
this);
850 BA.Addr->setCode(BB);
851 Owner.Addr->addMember(BA, *
this);
857 FA.Addr->setCode(MF);
869 auto Insert = [](
auto &Set,
auto &&
Range) {
873 if (BuildCfg.TrackRegs.empty()) {
874 std::set<RegisterId> BaseSet;
875 if (BuildCfg.Classes.empty()) {
877 for (
unsigned R = 1,
E =
getPRI().
getTRI().getNumRegs(); R !=
E; ++R)
886 if (SkipReserved && ReservedRegs[R])
892 for (
unsigned R : BuildCfg.TrackRegs) {
893 if (SkipReserved && ReservedRegs[R])
899 TheFunc = newFunc(&MF);
905 Block BA = newBlock(TheFunc, &
B);
906 BlockNodes.insert(std::make_pair(&
B, BA));
908 if (
I.isDebugInstr())
914 Block EA = TheFunc.Addr->getEntryBlock(*
this);
915 NodeList Blocks = TheFunc.Addr->members(*
this);
920 for (std::pair<MCRegister, Register>
P : MRI.
liveins())
933 Def DA = newDef(PA, RR, PhiFlags);
943 if (!EHRegs.
empty()) {
944 for (
Block BA : Blocks) {
961 Def DA = newDef(PA, RR, PhiFlags);
964 for (
Block PBA : Preds) {
965 PhiUse PUA = newPhiUse(PA, RR, PBA);
975 BlockRefsMap PhiM(
getPRI());
976 BlockRefsMap PhiClobberM(
getPRI());
977 for (
Block BA : Blocks)
978 recordDefsForDF(PhiM, PhiClobberM, BA);
979 for (
Block BA : Blocks)
985 linkBlockRefs(
DM, PhiClobberM, EA);
1011 for (
auto &
P : DefM)
1012 P.second.start_block(
B);
1020 for (
auto &
P : DefM)
1021 P.second.clear_block(
B);
1024 DefM.
remove_if([](
const auto &
P) {
return P.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.
Id].push(DA);
1065 Defined.insert(RR.
Id);
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.Id).second) {
1114 dbgs() <<
"Multiple definitions of register: " <<
Print(RR, *
this)
1122 DefM[RR.Id].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 {
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.Id);
1472 if (!MRI.isAllocatable(RR.asMCReg()) || 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.Id);
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.Id]);
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.
asMCReg().
id()])
1836 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")
Module.h This file contains the declarations for the Module class.
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
@ Default
Not specified; resolve to the target's default model.
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)