Go to the documentation of this file.
56 auto &
TRI =
P.G.getTRI();
60 OS <<
'#' <<
P.Obj.Reg;
77 default: OS <<
"c?";
break;
93 default: OS <<
"r?";
break;
108 OS << Print<NodeId>(
RA.Id,
G) <<
'<'
117 if (
NodeId N =
P.Obj.Addr->getReachingDef())
118 OS << Print<NodeId>(
N,
P.G);
120 if (
NodeId N =
P.Obj.Addr->getReachedDef())
121 OS << Print<NodeId>(
N,
P.G);
123 if (
NodeId N =
P.Obj.Addr->getReachedUse())
124 OS << Print<NodeId>(
N,
P.G);
126 if (
NodeId N =
P.Obj.Addr->getSibling())
127 OS << Print<NodeId>(
N,
P.G);
134 if (
NodeId N =
P.Obj.Addr->getReachingDef())
135 OS << Print<NodeId>(
N,
P.G);
137 if (
NodeId N =
P.Obj.Addr->getSibling())
138 OS << Print<NodeId>(
N,
P.G);
146 if (
NodeId N =
P.Obj.Addr->getReachingDef())
147 OS << Print<NodeId>(
N,
P.G);
149 if (
NodeId N =
P.Obj.Addr->getPredecessor())
150 OS << Print<NodeId>(
N,
P.G);
152 if (
NodeId N =
P.Obj.Addr->getSibling())
153 OS << Print<NodeId>(
N,
P.G);
158 switch (
P.Obj.Addr->getKind()) {
160 OS << PrintNode<DefNode*>(
P.Obj,
P.G);
164 OS << PrintNode<PhiUseNode*>(
P.Obj,
P.G);
166 OS << PrintNode<UseNode*>(
P.Obj,
P.G);
173 unsigned N =
P.Obj.size();
174 for (
auto I :
P.Obj) {
175 OS << Print<NodeId>(
I.Id,
P.G);
183 unsigned N =
P.Obj.size();
184 for (
auto I :
P.Obj) {
185 OS << Print<NodeId>(
I,
P.G);
194 template <
typename T>
203 template <
typename T>
205 unsigned N =
P.List.size();
207 OS << PrintNode<T>(
A,
P.G);
217 OS << Print<NodeId>(
P.Obj.Id,
P.G) <<
": phi ["
218 << PrintListV<RefNode*>(
P.Obj.Addr->members(
P.G),
P.G) <<
']';
224 unsigned Opc =
MI.getOpcode();
225 OS << Print<NodeId>(
P.Obj.Id,
P.G) <<
": " <<
P.G.getTII().getName(Opc);
227 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) <<
']';
249 switch (
P.Obj.Addr->getKind()) {
251 OS << PrintNode<PhiNode*>(
P.Obj,
P.G);
254 OS << PrintNode<StmtNode*>(
P.Obj,
P.G);
266 unsigned NP =
BB->pred_size();
268 auto PrintBBs = [&OS] (std::vector<int> Ns) ->
void {
269 unsigned N = Ns.size();
278 <<
" --- preds(" << NP <<
"): ";
280 Ns.push_back(
B->getNumber());
283 unsigned NS =
BB->succ_size();
284 OS <<
" succs(" << NS <<
"): ";
287 Ns.push_back(
B->getNumber());
291 for (
auto I :
P.Obj.Addr->members(
P.G))
292 OS << PrintNode<InstrNode*>(
I,
P.G) <<
'\n';
298 <<
P.Obj.Addr->getCode()->getName() <<
'\n';
299 for (
auto I :
P.Obj.Addr->members(
P.G))
300 OS << PrintNode<BlockNode*>(
I,
P.G) <<
'\n';
308 OS << ' ' << Print<RegisterRef>(
I,
P.G);
320 for (
auto I =
P.Obj.top(),
E =
P.Obj.bottom();
I !=
E; ) {
321 OS << Print<NodeId>(
I->Id,
P.G)
342 void NodeAllocator::startNewBlock() {
344 char *
P =
static_cast<char*
>(
T);
349 assert((Blocks.size() < ((
size_t)1 << (8*
sizeof(
NodeId)-BitsPerIndex))) &&
350 "Out of bits for block index");
354 bool NodeAllocator::needNewBlock() {
358 char *ActiveBegin = Blocks.back();
360 return Index >= NodesPerBlock;
370 makeId(ActiveB,
Index) };
376 uintptr_t A =
reinterpret_cast<uintptr_t
>(
P);
377 for (
unsigned i = 0,
n = Blocks.size();
i !=
n; ++
i) {
378 uintptr_t
B =
reinterpret_cast<uintptr_t
>(Blocks[
i]);
382 return makeId(
i, Idx);
435 while (NA.
Addr !=
this) {
447 DA.Addr->setReachedDef(Self);
454 DA.Addr->setReachedUse(Self);
498 if (MA.
Id == NA.
Id) {
509 while (MA.
Addr !=
this) {
534 while (NA.
Addr !=
this) {
609 if (
Op.isDef() &&
Op.isDead())
617 if (
In.isCall() ||
In.isReturn() ||
In.isInlineAsm())
622 if (
O.isGlobal() ||
O.isSymbol())
626 if (!
D.getImplicitDefs() && !
D.getImplicitUses())
632 if (
Op.getSubReg() != 0)
635 const MCPhysReg *ImpR =
Op.isDef() ?
D.getImplicitDefs()
636 :
D.getImplicitUses();
652 : MF(mf),
TII(tii),
TRI(tri), PRI(tri, mf), MDT(mdt), MDF(mdf), TOI(toi),
670 Pos =
DS.Stack.size();
671 while (Pos > 0 &&
DS.isDelimiter(
DS.Stack[Pos-1]))
688 unsigned P = nextDown(Stack.size());
703 unsigned P = Stack.size();
705 bool Found = isDelimiter(Stack[
P-1],
N);
715 unsigned DataFlowGraph::DefStack::nextUp(
unsigned P)
const {
718 unsigned SS = Stack.size();
723 IsDelim = isDelimiter(Stack[
P-1]);
724 }
while (
P <
SS && IsDelim);
730 unsigned DataFlowGraph::DefStack::nextDown(
unsigned P)
const {
734 bool IsDelim = isDelimiter(Stack[
P-1]);
738 IsDelim = isDelimiter(Stack[
P-1]);
739 }
while (
P > 0 && IsDelim);
746 RegisterSet DataFlowGraph::getLandingPadLiveIns()
const {
749 const Constant *PF =
F.hasPersonalityFn() ?
F.getPersonalityFn()
793 RA.Addr->setReachingDef(0);
794 RA.Addr->setSibling(0);
797 DA.Addr->setReachedDef(0);
798 DA.Addr->setReachedUse(0);
825 DA.Addr->setRegRef(&
Op, *
this);
833 DA.Addr->setRegRef(RR, *
this);
875 BlockNodes.insert(std::make_pair(&
B, BA));
877 if (
I.isDebugInstr())
884 NodeList Blocks = Func.Addr->members(*
this);
891 AllRefs.insert(
RA.Addr->getRegRef(*
this));
897 for (std::pair<unsigned,unsigned>
P :
MRI.
liveins())
920 if (!EHRegs.empty()) {
951 recordDefsForDF(PhiM, BA);
953 buildPhis(PhiM, AllRefs, BA);
957 linkBlockRefs(
DM, EA);
984 P.second.start_block(
B);
993 P.second.clear_block(
B);
996 for (
auto I = DefM.begin(),
E = DefM.end(), NextI =
I;
I !=
E;
I = NextI) {
997 NextI = std::next(
I);
999 if (
I->second.empty())
1007 pushClobbers(IA, DefM);
1015 std::set<RegisterId> Defined;
1030 if (Visited.count(
DA.Id))
1041 DefM[RR.
Reg].push(
DA);
1042 Defined.insert(RR.
Reg);
1046 if (!Defined.count(A))
1051 Visited.insert(
T.Id);
1060 std::set<RegisterId> Defined;
1087 if (!Defined.insert(RR.
Reg).second) {
1089 dbgs() <<
"Multiple definitions of register: "
1097 DefM[RR.
Reg].push(
DA);
1120 }
while (
RA.Id != 0 &&
RA.Id != Start);
1125 void DataFlowGraph::reset() {
1142 if (
TA.Addr->getKind() !=
RA.Addr->getKind())
1144 if (
TA.Addr->getRegRef(*
this) !=
RA.Addr->getRegRef(*
this))
1149 return Related(
TA) &&
1150 &
RA.Addr->getOp() == &
TA.Addr->getOp();
1165 return RA.Addr->getNextRef(RR, RelatedStmt,
true, *
this);
1166 return RA.Addr->getNextRef(RR, RelatedPhi,
true, *
this);
1174 template <
typename Predicate>
1184 if (NA.
Id == 0 || NA.
Id == Start)
1191 if (NA.
Id != 0 && NA.
Id != Start)
1192 return std::make_pair(RA, NA);
1204 return TA.Addr->getFlags() == Flags;
1206 auto Loc = locateNextRef(IA,
RA, IsShadow);
1207 if (Loc.second.Id != 0 || !Create)
1224 return TA.Addr->getFlags() == Flags;
1226 return locateNextRef(IA,
RA, IsShadow).second;
1238 if (
In.isBranch()) {
1240 if (
Op.isGlobal() ||
Op.isSymbol())
1245 if (
In.isIndirectBranch())
1255 if (!
Op.isReg() ||
Op.getReg() == 0 || !
Op.isUse() ||
Op.isUndef())
1258 if (PRI.
alias(DR, UR))
1264 bool IsCall = isCall(
In);
1265 unsigned NumOps =
In.getNumOperands();
1273 for (
unsigned OpN = 0; OpN < NumOps; ++OpN) {
1275 if (!
Op.isReg() || !
Op.isDef() ||
Op.isImplicit())
1291 if (IsCall &&
Op.isDead())
1295 assert(!DoneDefs.test(R));
1301 for (
unsigned OpN = 0; OpN < NumOps; ++OpN) {
1303 if (!
Op.isRegMask())
1312 if (!(
RM[
i/32] & (1u << (
i%32))))
1313 DoneClobbers.set(
i);
1318 for (
unsigned OpN = 0; OpN < NumOps; ++OpN) {
1320 if (!
Op.isReg() || !
Op.isDef() || !
Op.isImplicit())
1330 if (isDefUndef(
In, RR))
1337 if (IsCall &&
Op.isDead()) {
1338 if (DoneClobbers.test(R))
1347 for (
unsigned OpN = 0; OpN < NumOps; ++OpN) {
1349 if (!
Op.isReg() || !
Op.isUse())
1366 void DataFlowGraph::recordDefsForDF(BlockRefsMap &PhiM,
1373 auto DFLoc = MDF.
find(
BB);
1374 if (DFLoc == MDF.
end() || DFLoc->second.empty())
1385 Defs.insert(
RA.Addr->getRegRef(*
this));
1390 for (
unsigned i = 0;
i < IDF.size(); ++
i) {
1391 auto F = MDF.
find(IDF[
i]);
1393 IDF.insert(
F->second.begin(),
F->second.end());
1398 for (
auto DB : IDF) {
1400 PhiM[DBA.
Id].insert(Defs.begin(), Defs.end());
1406 void DataFlowGraph::buildPhis(BlockRefsMap &PhiM,
RegisterSet &AllRefs,
1410 auto HasDF = PhiM.find(BA.
Id);
1411 if (HasDF == PhiM.end() || HasDF->second.empty())
1427 MaxDF.insert(MaxCoverIn(
I, HasDF->second));
1429 std::vector<RegisterRef> MaxRefs;
1431 MaxRefs.push_back(MaxCoverIn(
I, AllRefs));
1440 auto NewEnd =
std::unique(MaxRefs.begin(), MaxRefs.end());
1441 MaxRefs.erase(NewEnd, MaxRefs.end());
1444 std::vector<unsigned> &Closure) ->
bool {
1445 for (
unsigned I : Closure)
1446 if (PRI.
alias(RR, MaxRefs[
I]))
1457 while (!MaxRefs.empty()) {
1462 std::vector<unsigned> ClosureIdx = { 0 };
1463 for (
unsigned i = 1;
i != MaxRefs.size(); ++
i)
1464 if (
Aliased(MaxRefs[
i], ClosureIdx))
1465 ClosureIdx.push_back(
i);
1468 unsigned CS = ClosureIdx.size();
1472 for (
unsigned X = 0;
X != CS; ++
X) {
1480 for (
unsigned X = 0;
X != CS; ++
X) {
1488 auto Begin = MaxRefs.begin();
1490 MaxRefs.erase(Begin + Idx);
1495 void DataFlowGraph::removeUnusedPhis() {
1508 static auto HasUsedDef = [](
NodeList &Ms) ->
bool {
1513 if (
DA.Addr->getReachedDef() != 0 ||
DA.Addr->getReachedUse() != 0)
1522 while (!PhiQ.
empty()) {
1523 auto PA = addr<PhiNode*>(PhiQ[0]);
1526 if (HasUsedDef(Refs))
1529 if (
NodeId RD =
RA.Addr->getReachingDef()) {
1530 auto RDA = addr<DefNode*>(RD);
1535 if (
RA.Addr->isDef())
1548 template <
typename T>
1559 for (
auto I =
DS.top(),
E =
DS.bottom();
I !=
E;
I.down()) {
1564 bool Alias = Defs.hasAliasOf(QR);
1565 bool Cover = Defs.insert(QR).hasCoverOf(RR);
1593 template <
typename Predicate>
1611 auto F = DefM.find(RR.
Reg);
1612 if (
F == DefM.end())
1614 DefStack &
DS =
F->second;
1616 linkRefUp<UseNode*>(SA, RA,
DS);
1618 linkRefUp<DefNode*>(SA, RA,
DS);
1637 assert(BA.
Addr &&
"block node address is needed to create a data-flow link");
1645 linkStmtRefs(DefM, IA,
IsUse);
1646 linkStmtRefs(DefM, IA, IsClobber);
1650 pushClobbers(IA, DefM);
1653 linkStmtRefs(DefM, IA, IsNoClobber);
1663 linkBlockRefs(DefM, SBA);
1687 if (EHLiveIns.count(
RA.Addr->getRegRef(*
this)))
1694 linkRefUp<UseNode*>(IA, PUA, DefM[RR.
Reg]);
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) {
1726 TA = addr<UseNode*>(
S);
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());
1771 I.Addr->setSibling(0);
1773 I.Addr->setSibling(0);
1776 I.Addr->setReachingDef(RD);
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()) {
1809 Last.Addr->setSibling(
RDA.Addr->getReachedDef());
1810 RDA.Addr->setReachedDef(ReachedDefs.front().
Id);
1813 if (!ReachedUses.empty()) {
1815 Last.Addr->setSibling(
RDA.Addr->getReachedUse());
1816 RDA.Addr->setReachedUse(ReachedUses.front().
Id);
NodeId getSibling() const
static uint16_t kind(uint16_t T)
rr_iterator rr_end() const
NodeId getPredecessor() const
static void printRefHeader(raw_ostream &OS, const NodeAddr< RefNode * > RA, const DataFlowGraph &G)
std::set< RegisterRef > RegisterSet
virtual bool isClobbering(const MachineInstr &In, unsigned OpNum) const
This is an optimization pass for GlobalISel generic memory operations.
const char * getName(MCRegister RegNo) const
Return the human-readable symbolic target-specific name for the specified physical register.
We currently emits eax Perhaps this is what we really should generate is Is imull three or four cycles eax eax The current instruction priority is based on pattern complexity The former is more complex because it folds a load so the latter will not be emitted Perhaps we should use AddedComplexity to give LEA32r a higher priority We should always try to match LEA first since the LEA matching code does some estimate to determine whether the match is profitable if we care more about code then imull is better It s two bytes shorter than movl leal On a Pentium M
NodeList getRelatedRefs(NodeAddr< InstrNode * > IA, NodeAddr< RefNode * > RA) const
NodeList members_if(Predicate P, const DataFlowGraph &G) const
void Reset()
Deallocate all but the current slab and reset the current pointer to the beginning of it,...
RegisterAggr & insert(RegisterRef RR)
NodeId id(const NodeBase *P) const
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
This currently compiles esp xmm0 movsd esp eax eax esp ret We should use not the dag combiner This is because dagcombine2 needs to be able to see through the X86ISD::Wrapper which DAGCombine can t really do The code for turning x load into a single vector load is target independent and should be moved to the dag combiner The code for turning x load into a vector load can only handle a direct load from a global or a direct load from the stack It should be generalized to handle any load from P
void linkToDef(NodeId Self, NodeAddr< DefNode * > DA)
static RegisterPass< DebugifyModulePass > DM("debugify", "Attach debug info to everything")
const TargetInstrInfo & TII
virtual bool isFixedReg(const MachineInstr &In, unsigned OpNum) const
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Printable printMBBReference(const MachineBasicBlock &MBB)
Prints a machine basic block reference.
void addPhi(NodeAddr< PhiNode * > PA, const DataFlowGraph &G)
unsigned getNumRegs() const
Return the number of registers this target has (useful for sizing arrays holding per register informa...
Reg
All possible values of the reg field in the ModR/M byte.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
void unlinkUse(NodeAddr< UseNode * > UA, bool RemoveFromOwner)
void releaseBlock(NodeId B, DefStackMap &DefM)
The instances of the Type class are immutable: once they are created, they are never changed.
iterator_range< livein_iterator > liveins() const
auto reverse(ContainerTy &&C, std::enable_if_t< has_rbegin< ContainerTy >::value > *=nullptr)
virtual bool isPreserving(const MachineInstr &In, unsigned OpNum) const
virtual Register getExceptionPointerRegister(const Constant *PersonalityFn) const
If a physical register, this returns the register that receives the exception address on entry to an ...
NodeAddr< RefNode * > getNextRelated(NodeAddr< InstrNode * > IA, NodeAddr< RefNode * > RA) const
DataFlowGraph(MachineFunction &mf, const TargetInstrInfo &tii, const TargetRegisterInfo &tri, const MachineDominatorTree &mdt, const MachineDominanceFrontier &mdf, const TargetOperandInfo &toi)
iterator find(MachineBasicBlock *B)
RegisterId getRegMaskId(const uint32_t *RM) const
unsigned const TargetRegisterInfo * TRI
uint16_t getFlags() const
bool tracksLiveness() const
tracksLiveness - Returns true when tracking register liveness accurately.
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 remove(const value_type &X)
Remove an item from the set vector.
const MachineBasicBlock & front() const
TargetInstrInfo - Interface to description of machine instruction set.
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
RegisterRef getRegRef(const DataFlowGraph &G) const
static bool isRegMaskId(RegisterId R)
This class defines information used to lower LLVM code to legal SelectionDAG operators that the targe...
static bool isPhysicalRegister(unsigned Reg)
Return true if the specified register number is in the physical register namespace.
bool alias(RegisterRef RA, RegisterRef RB) const
const HexagonInstrInfo * TII
Describe properties that are true of each instruction in the target description file.
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
MachineOperand class - Representation of each machine instruction operand.
const char LLVMTargetMachineRef LLVMPassBuilderOptionsRef Options
This class implements an extremely fast bulk output stream that can only output to a stream.
Printable PrintLaneMask(LaneBitmask LaneMask)
Create Printable object to print LaneBitmasks on a raw_ostream.
static bool IsDef(const NodeAddr< NodeBase * > BA)
static bool isCoverOf(RegisterRef RA, RegisterRef RB, const PhysicalRegisterInfo &PRI)
NodeBase * ptr(NodeId N) const
void addMemberAfter(NodeAddr< NodeBase * > MA, NodeAddr< NodeBase * > NA, const DataFlowGraph &G)
A NodeSet contains a set of SUnit DAG nodes with additional information that assigns a priority to th...
void clear_block(NodeId N)
bool empty() const
Determine if the SetVector is empty or not.
static RegisterPass< DebugifyFunctionPass > DF("debugify-function", "Attach debug info to a function")
static GCMetadataPrinterRegistry::Add< ErlangGCPrinter > X("erlang", "erlang-compatible garbage collector")
void linkToDef(NodeId Self, NodeAddr< DefNode * > DA)
PassBuilder PB(Machine, PassOpts->PTO, None, &PIC)
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
RegisterRef makeRegRef(unsigned Reg, unsigned Sub) const
Predicate
Predicate - These are "(BI << 5) | BO" for various predicates.
This is an important base class in LLVM.
NodeAddr< T > addr(NodeId N) const
Representation of each machine instruction.
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
void addMember(NodeAddr< NodeBase * > NA, const DataFlowGraph &G)
RegisterRef unpack(PackedRegisterRef PR) const
virtual bool isPredicated(const MachineInstr &MI) const
Returns true if the instruction is already predicated.
NodeList members(const DataFlowGraph &G) const
MachineDomTreeNode * getNode(MachineBasicBlock *BB) const
getNode - return the (Post)DominatorTree node for the specified basic block.
void setPredecessor(NodeId B)
raw_ostream & operator<<(raw_ostream &OS, const Print< RegisterRef > &P)
void markBlock(NodeId B, DefStackMap &DefM)
ArrayRef< std::pair< MCRegister, Register > > liveins() const
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
std::set< RegisterId > getAliasSet(RegisterId Reg) const
static bool IsPhi(const NodeAddr< NodeBase * > BA)
<%struct.s * > cast struct s *S to sbyte *< sbyte * > sbyte uint cast struct s *agg result to sbyte *< sbyte * > sbyte uint cast struct s *memtmp to sbyte *< sbyte * > sbyte uint ret void llc ends up issuing two memcpy or custom lower memcpy(of small size) to be ldmia/stmia. I think option 2 is better but the current register allocator cannot allocate a chunk of registers at a time. A feasible temporary solution is to use specific physical registers at the lowering time for small(<
iterator_range< pred_iterator > predecessors()
SI optimize exec mask operations pre RA
void pushAllDefs(NodeAddr< InstrNode * > IA, DefStackMap &DM)
bool insert(const value_type &X)
Insert a new element into the SetVector.
rr_iterator rr_begin() const
NodeAddr< NodeBase * > getFirstMember(const DataFlowGraph &G) const
This class provides various memory handling functions that manipulate MemoryBlock instances.
iterator_range< succ_iterator > successors()
bool isEHPad() const
Returns true if the block is a landing pad.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
MachineFunction * getCode() const
static uint16_t type(uint16_t T)
static bool IsUse(const NodeAddr< NodeBase * > BA)
add sub stmia L5 ldr r0 bl L_printf $stub Instead of a and a wouldn t it be better to do three moves *Return an aggregate type is even return S
Base class for the actual dominator tree node.
unsigned count(SUnit *SU) const
unsigned const MachineRegisterInfo * MRI
Wrapper class representing virtual and physical registers.
auto find_if(R &&Range, UnaryPredicate P)
Provide wrappers to std::find_if which take ranges instead of having to pass begin/end explicitly.
void removeMember(NodeAddr< NodeBase * > NA, const DataFlowGraph &G)
void setRegRef(RegisterRef RR, DataFlowGraph &G)
PackedRegisterRef pack(RegisterRef RR)
void build(unsigned Options=BuildOptions::None)
virtual Register getExceptionSelectorRegister(const Constant *PersonalityFn) const
If a physical register, this returns the register that receives the exception typeid on entry to a la...
constexpr bool empty(const T &RangeOrContainer)
Test whether RangeOrContainer is empty. Similar to C++17 std::empty.
Function & getFunction()
Return the LLVM function that this machine code represents.
NodeAddr< NodeBase * > getLastMember(const DataFlowGraph &G) const
LLVM_ATTRIBUTE_RETURNS_NONNULL void * Allocate(size_t Size, Align Alignment)
Allocate space at the specified alignment.
void sort(IteratorTy Start, IteratorTy End)
void setFlags(uint16_t F)
NodeAddr< NodeBase * > getOwner(const DataFlowGraph &G)
auto unique(Range &&R, Predicate P)
NodeAddr< BlockNode * > getEntryBlock(const DataFlowGraph &G)
NodeId getReachingDef() const
DominanceFrontierBase< MachineBasicBlock, false >::DomSetType DomSetType
virtual const TargetLowering * getTargetLowering() const
void unlinkDef(NodeAddr< DefNode * > DA, bool RemoveFromOwner)
std::set< NodeId > NodeSet
ReachingDefAnalysis & RDA
MachineBasicBlock * getCode() const
static uint16_t flags(uint16_t T)
void append(NodeAddr< NodeBase * > NA)
MCRegister getSubReg(MCRegister Reg, unsigned Idx) const
Returns the physical register number of sub-register "Index" for physical register RegNo.
NodeAddr< BlockNode * > findBlock(const MachineBasicBlock *BB, const DataFlowGraph &G) const
void start_block(NodeId N)
NodeAddr< RefNode * > getNextShadow(NodeAddr< InstrNode * > IA, NodeAddr< RefNode * > RA, bool Create)
Common register allocation spilling lr str ldr sxth r3 ldr mla r4 can lr mov lr str ldr sxth r3 mla r4 and then merge mul and lr str ldr sxth r3 mla r4 It also increase the likelihood the store may become dead bb27 Successors according to LLVM BB
NodeId id(const NodeBase *P) const
DominatorTree Class - Concrete subclass of DominatorTreeBase that is used to compute a normal dominat...
The same transformation can work with an even modulo with the addition of a and shrink the compare RHS by the same amount Unless the target supports that transformation probably isn t worthwhile The transformation can also easily be made to work with non zero equality for n
A vector that has set insertion semantics.
NodeAddr< BlockNode * > findBlock(MachineBasicBlock *BB) const
static constexpr LaneBitmask getAll()
bool isFuncletEHPersonality(EHPersonality Pers)
Returns true if this is a personality function that invokes handler funclets (which must return to it...
std::unordered_map< RegisterId, DefStack > DefStackMap
NodeAddr< NodeBase * > getOwner(const DataFlowGraph &G)
NodeAddr< NodeBase * > New()