21#define DEBUG_TYPE "reaching-defs-analysis"
32 return MO.isReg() && MO.getReg();
36 return isValidReg(MO) && MO.
isUse();
43 return TRI->regsOverlap(MO.
getReg(), Reg);
47 return isValidReg(MO) && MO.
isDef();
54 return TRI->regsOverlap(MO.
getReg(), Reg);
59 int DefFrameIndex = 0;
60 int SrcFrameIndex = 0;
62 TII->isStackSlotCopy(
MI, DefFrameIndex, SrcFrameIndex))
63 return DefFrameIndex == FrameIndex;
70 "Unexpected basic block number.");
79 LiveRegs.assign(NumRegUnits, ReachingDefDefaultVal);
88 if (LiveRegs[Unit] != -1) {
90 MBBReachingDefs.
append(MBBNumber, Unit, -1);
101 "Should have pre-allocated MBBInfos for all MBBs");
102 const LiveRegsDefInfo &
Incoming = MBBOutRegsInfos[
pred->getNumber()];
109 for (
unsigned Unit = 0; Unit != NumRegUnits; ++Unit)
110 LiveRegs[Unit] = std::max(LiveRegs[Unit],
Incoming[Unit]);
114 for (
unsigned Unit = 0; Unit != NumRegUnits; ++Unit)
115 if (LiveRegs[Unit] != ReachingDefDefaultVal)
116 MBBReachingDefs.
append(MBBNumber, Unit, LiveRegs[Unit]);
120 assert(!LiveRegs.empty() &&
"Must enter basic block first.");
123 "Unexpected basic block number.");
125 MBBOutRegsInfos[MBBNumber] = LiveRegs;
131 for (
int &OutLiveReg : MBBOutRegsInfos[MBBNumber])
132 if (OutLiveReg != ReachingDefDefaultVal)
133 OutLiveReg -= CurInstr;
138 assert(!
MI->isDebugInstr() &&
"Won't process debug instructions");
140 unsigned MBBNumber =
MI->getParent()->getNumber();
142 "Unexpected basic block number.");
144 for (
auto &MO :
MI->operands()) {
147 assert(FrameIndex >= 0 &&
"Can't handle negative frame indicies yet!");
150 if (MBBFrameObjsReachingDefs.
contains(MBBNumber)) {
151 auto Frame2InstrIdx = MBBFrameObjsReachingDefs[MBBNumber];
152 if (Frame2InstrIdx.count(FrameIndex - ObjectIndexBegin) > 0)
153 Frame2InstrIdx[
FrameIndex - ObjectIndexBegin].push_back(CurInstr);
155 Frame2InstrIdx[
FrameIndex - ObjectIndexBegin] = {CurInstr};
157 MBBFrameObjsReachingDefs[MBBNumber] = {
169 if (LiveRegs[Unit] != CurInstr) {
170 LiveRegs[Unit] = CurInstr;
171 MBBReachingDefs.
append(MBBNumber, Unit, CurInstr);
175 InstIds[
MI] = CurInstr;
182 "Unexpected basic block number.");
187 int NumInsts = std::distance(NonDbgInsts.begin(), NonDbgInsts.end());
193 "Should have pre-allocated MBBInfos for all MBBs");
194 const LiveRegsDefInfo &
Incoming = MBBOutRegsInfos[
pred->getNumber()];
199 for (
unsigned Unit = 0; Unit != NumRegUnits; ++Unit) {
201 if (Def == ReachingDefDefaultVal)
204 auto Defs = MBBReachingDefs.
defs(MBBNumber, Unit);
205 if (!Defs.empty() && Defs.front() < 0) {
206 if (Defs.front() >= Def)
213 MBBReachingDefs.
prepend(MBBNumber, Unit, Def);
218 if (MBBOutRegsInfos[MBBNumber][Unit] < Def - NumInsts)
219 MBBOutRegsInfos[MBBNumber][Unit] =
Def - NumInsts;
224void ReachingDefAnalysis::processBasicBlock(
228 << (!TraversedMBB.
IsDone ?
": incomplete\n"
229 :
": all preds known\n"));
233 reprocessBasicBlock(
MBB);
237 enterBasicBlock(
MBB);
241 leaveBasicBlock(
MBB);
245 dbgs() <<
"RDA results for " << MF.
getName() <<
"\n";
254 int FrameIndex = MO.getIndex();
256 "Can't handle negative frame indicies yet!");
258 }
else if (MO.isReg()) {
268 MO.print(
dbgs(), TRI);
275 dbgs() << Num <<
" ";
278 dbgs() << Num <<
": " <<
MI <<
"\n";
279 InstToNumMap[&
MI] = Num;
291 LLVM_DEBUG(
dbgs() <<
"********** REACHING DEFINITION ANALYSIS **********\n");
301 MBBOutRegsInfos.
clear();
302 MBBReachingDefs.
clear();
303 MBBFrameObjsReachingDefs.
clear();
322 TraversedMBBOrder = Traversal.
traverse(*MF);
328 processBasicBlock(TraversedMBB);
332 MBBNumber != NumBlockIDs; ++MBBNumber) {
333 for (
unsigned Unit = 0; Unit != NumRegUnits; ++Unit) {
334 int LastDef = ReachingDefDefaultVal;
335 for (
int Def : MBBReachingDefs.
defs(MBBNumber, Unit)) {
336 assert(Def > LastDef &&
"Defs must be sorted and unique");
345 assert(InstIds.count(
MI) &&
"Unexpected machine instuction.");
346 int InstId = InstIds.lookup(
MI);
347 int DefRes = ReachingDefDefaultVal;
348 unsigned MBBNumber =
MI->getParent()->getNumber();
350 "Unexpected basic block number.");
351 int LatestDef = ReachingDefDefaultVal;
354 int FrameIndex = Reg.stackSlotIndex();
355 for (
int Def : MBBFrameObjsReachingDefs.
lookup(MBBNumber).lookup(
356 FrameIndex - ObjectIndexBegin)) {
361 LatestDef = std::max(LatestDef, DefRes);
366 for (
int Def : MBBReachingDefs.
defs(MBBNumber, Unit)) {
371 LatestDef = std::max(LatestDef, DefRes);
387 if (ParentA != ParentB)
397 "Unexpected basic block number.");
399 "Unexpected instruction id.");
404 for (
auto &
MI : *
MBB) {
405 auto F = InstIds.find(&
MI);
406 if (
F != InstIds.end() &&
F->second == InstId)
414 assert(InstIds.count(
MI) &&
"Unexpected machine instuction.");
428 if (
MI->isDebugInstr())
433 if (getReachingLocalMIDef(&*
MI, Reg) != Def)
436 for (
auto &MO :
MI->operands()) {
451 for (
auto &MO :
MI.operands()) {
479 while (!ToVisit.
empty()) {
497 for (
auto *
MBB :
MI->getParent()->predecessors())
516 if (Reg.isPhysical() && LiveRegs.
available(Reg))
530 if (LocalDef && InstIds.lookup(LocalDef) < InstIds.lookup(
MI))
547 unsigned Idx)
const {
548 assert(
MI->getOperand(
Idx).isReg() &&
"Expected register operand");
573 return InstIds.lookup(&
Last) > InstIds.lookup(
MI);
587 return Def == getReachingLocalMIDef(
MI, Reg);
597 if (Reg.isPhysical() && LiveRegs.
available(Reg))
606 for (
auto &MO :
Last->operands())
617 if (Reg.isPhysical() && LiveRegs.
available(Reg))
625 int FrameIndex = Reg.stackSlotIndex();
632 for (
auto &MO :
Last->operands())
636 return Def < 0 ? nullptr : getInstFromId(
MBB, Def);
640 return MI.mayLoadOrStore() ||
MI.mayRaiseFPException() ||
641 MI.hasUnmodeledSideEffects() ||
MI.isTerminator() ||
642 MI.isCall() ||
MI.isBarrier() ||
MI.isBranch() ||
MI.isReturn();
648template<
typename Iterator>
656 for (
auto &MO :
From->operands()) {
668 for (
auto I = ++Iterator(
From), E = Iterator(To);
I != E; ++
I) {
671 for (
auto &MO :
I->operands())
672 if (MO.isReg() && MO.getReg() && Defs.
count(MO.getReg()))
682 for (
auto I = Iterator(
From), E =
From->getParent()->end();
I != E; ++
I)
684 return isSafeToMove<Iterator>(
From, To);
692 for (
auto I = Iterator(
From), E =
From->getParent()->rend();
I != E; ++
I)
694 return isSafeToMove<Iterator>(
From, To);
724 for (
auto &MO :
MI->operands()) {
731 for (
auto *
I :
Uses) {
749 unsigned LiveDefs = 0;
750 for (
auto &MO : Def->operands()) {
765 for (
auto &MO :
MI->operands()) {
769 if (
IsDead(Def, MO.getReg()))
784 if (
auto *Def = getReachingLocalMIDef(
MI, Reg)) {
797 for (
auto E =
MBB->
end();
I != E; ++
I) {
800 for (
auto &MO :
I->operands())
ReachingDefAnalysis InstSet & ToRemove
ReachingDefAnalysis InstSet InstSet & Ignore
BlockVerifier::State From
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
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
const HexagonInstrInfo * TII
unsigned const TargetRegisterInfo * TRI
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
static bool isValidRegUseOf(const MachineOperand &MO, Register Reg, const TargetRegisterInfo *TRI)
static bool mayHaveSideEffects(MachineInstr &MI)
static bool isFIDef(const MachineInstr &MI, int FrameIndex, const TargetInstrInfo *TII)
static bool isValidRegDef(const MachineOperand &MO)
static cl::opt< bool > PrintAllReachingDefs("print-all-reaching-defs", cl::Hidden, cl::desc("Used for test purpuses"), cl::Hidden)
static bool isValidRegDefOf(const MachineOperand &MO, Register Reg, const TargetRegisterInfo *TRI)
static bool isValidRegUse(const MachineOperand &MO)
Remove Loads Into Fake Uses
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file defines generic set operations that may be used on set's of different types,...
This file defines the SmallSet class.
ValueT lookup(const_arg_type_t< KeyT > Val) const
lookup - Return the entry for the specified key, or a default constructed value if no such entry exis...
bool contains(const_arg_type_t< KeyT > Val) const
Return true if the specified key is in the map, false otherwise.
Register isStoreToStackSlot(const MachineInstr &MI, int &FrameIndex) const override
If the specified machine instruction is a direct store to a stack slot, return the virtual or physica...
A set of register units used to track register liveness.
bool available(MCPhysReg Reg) const
Returns true if no part of physical register Reg is live.
void stepBackward(const MachineInstr &MI)
Updates liveness when stepping backwards over the instruction MI.
void addLiveOuts(const MachineBasicBlock &MBB)
Adds registers living out of block MBB.
This class provides the basic blocks traversal order used by passes like ReachingDefAnalysis and Exec...
TraversalOrder traverse(MachineFunction &MF)
void append(unsigned MBBNumber, unsigned Unit, int Def)
ArrayRef< ReachingDef > defs(unsigned MBBNumber, unsigned Unit) const
void replaceFront(unsigned MBBNumber, unsigned Unit, int Def)
void init(unsigned NumBlockIDs)
void prepend(unsigned MBBNumber, unsigned Unit, int Def)
void startBasicBlock(unsigned MBBNumber, unsigned NumRegUnits)
unsigned numBlockIDs() const
unsigned getNumRegUnits() const
Return the number of (native) register units in the target.
iterator_range< MCRegUnitIterator > regunits(MCRegister Reg) const
Returns an iterator range over all regunits for Reg.
instr_iterator instr_begin()
iterator_range< livein_iterator > liveins() const
reverse_instr_iterator instr_rbegin()
int getNumber() const
MachineBasicBlocks are uniquely numbered at the function level, unless they're not in a MachineFuncti...
reverse_instr_iterator instr_rend()
iterator getLastNonDebugInstr(bool SkipPseudoOp=true)
Returns an iterator to the last non-debug instruction in the basic block, or end().
MachineInstrBundleIterator< MachineInstr, true > reverse_iterator
instr_iterator instr_end()
iterator_range< succ_iterator > successors()
iterator_range< pred_iterator > predecessors()
MachineInstrBundleIterator< MachineInstr > iterator
bool isLiveIn(MCRegister Reg, LaneBitmask LaneMask=LaneBitmask::getAll()) const
Return true if the specified register is in the live in set.
unsigned getNumObjects() const
Return the number of objects.
int getObjectIndexBegin() const
Return the minimum frame object index.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
StringRef getName() const
getName - Return the name of the corresponding LLVM function.
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
unsigned getNumBlockIDs() const
getNumBlockIDs - Return the number of MBB ID's allocated.
Representation of each machine instruction.
const MachineBasicBlock * getParent() const
MachineOperand class - Representation of each machine instruction operand.
bool isReg() const
isReg - Tests if this is a MO_Register operand.
Register getReg() const
getReg - Returns the register number.
This class provides the reaching def analysis.
MachineInstr * getLocalLiveOutMIDef(MachineBasicBlock *MBB, Register Reg) const
Return the local MI that produces the live out value for Reg, or nullptr for a non-live out or non-lo...
void traverse()
Traverse the machine function, mapping definitions.
bool isSafeToMoveForwards(MachineInstr *From, MachineInstr *To) const
Return whether From can be moved forwards to just before To.
bool isRegUsedAfter(MachineInstr *MI, Register Reg) const
Return whether the given register is used after MI, whether it's a local use or a live out.
void releaseMemory() override
releaseMemory() - This member can be implemented by a pass if it wants to be able to release its memo...
bool isSafeToRemove(MachineInstr *MI, InstSet &ToRemove) const
Return whether removing this instruction will have no effect on the program, returning the redundant ...
MachineInstr * getMIOperand(MachineInstr *MI, unsigned Idx) const
If a single MachineInstr creates the reaching definition, for MIs operand at Idx, then return it.
void printAllReachingDefs(MachineFunction &MF)
void reset()
Re-run the analysis.
int getReachingDef(MachineInstr *MI, Register Reg) const
Provides the instruction id of the closest reaching def instruction of Reg that reaches MI,...
void init()
Initialize data structures.
void getGlobalUses(MachineInstr *MI, Register Reg, InstSet &Uses) const
Collect the users of the value stored in Reg, which is defined by MI.
void collectKilledOperands(MachineInstr *MI, InstSet &Dead) const
Assuming MI is dead, recursively search the incoming operands which are killed by MI and collect thos...
bool isSafeToMoveBackwards(MachineInstr *From, MachineInstr *To) const
Return whether From can be moved backwards to just after To.
void getLiveOuts(MachineBasicBlock *MBB, Register Reg, InstSet &Defs, BlockSet &VisitedBBs) const
Search MBB for a definition of Reg and insert it into Defs.
int getClearance(MachineInstr *MI, Register Reg) const
Provides the clearance - the number of instructions since the closest reaching def instuction of Reg ...
bool hasLocalDefBefore(MachineInstr *MI, Register Reg) const
Provide whether the register has been defined in the same basic block as, and before,...
bool isReachingDefLiveOut(MachineInstr *MI, Register Reg) const
Return whether the reaching def for MI also is live out of its parent block.
bool getLiveInUses(MachineBasicBlock *MBB, Register Reg, InstSet &Uses) const
For the given block, collect the instructions that use the live-in value of the provided register.
bool isSafeToDefRegAt(MachineInstr *MI, Register Reg) const
Return whether a MachineInstr could be inserted at MI and safely define the given register without af...
bool hasSameReachingDef(MachineInstr *A, MachineInstr *B, Register Reg) const
Return whether A and B use the same def of Reg.
void getReachingLocalUses(MachineInstr *MI, Register Reg, InstSet &Uses) const
Provides the uses, in the same block as MI, of register that MI defines.
bool isRegDefinedAfter(MachineInstr *MI, Register Reg) const
Return whether the given register is defined after MI.
MachineInstr * getUniqueReachingMIDef(MachineInstr *MI, Register Reg) const
If a single MachineInstr creates the reaching definition, then return it.
void getGlobalReachingDefs(MachineInstr *MI, Register Reg, InstSet &Defs) const
Collect all possible definitions of the value stored in Reg, which is used by MI.
bool runOnMachineFunction(MachineFunction &MF) override
runOnMachineFunction - This method must be overloaded to perform the desired machine code transformat...
Wrapper class representing virtual and physical registers.
static Register index2StackSlot(int FI)
Convert a non-negative frame index to a stack slot register value.
A templated base class for SmallPtrSet which provides the typesafe interface that is common across al...
size_type count(ConstPtrType Ptr) const
count - Return 1 if the specified pointer is in the set, 0 otherwise.
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
SmallSet - This maintains a set of unique values, optimizing for the case when the set is small (less...
size_type count(const T &V) const
count - Return 1 if the element is in the set, 0 otherwise.
std::pair< const_iterator, bool > insert(const T &V)
insert - Insert an element into the set if it isn't already there.
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...
TargetSubtargetInfo - Generic base class for all target subtargets.
virtual const TargetRegisterInfo * getRegisterInfo() const
getRegisterInfo - If register information is available, return it.
virtual const TargetInstrInfo * getInstrInfo() const
NodeAddr< DefNode * > Def
This is an optimization pass for GlobalISel generic memory operations.
Printable printRegUnit(unsigned Unit, const TargetRegisterInfo *TRI)
Create Printable object to print register units on a raw_ostream.
bool set_is_subset(const S1Ty &S1, const S2Ty &S2)
set_is_subset(A, B) - Return true iff A in B
void append_range(Container &C, Range &&R)
Wrapper function to append range R to container C.
void sort(IteratorTy Start, IteratorTy End)
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
auto instructionsWithoutDebug(IterT It, IterT End, bool SkipPseudoOp=true)
Construct a range iterator which begins at It and moves forwards until End is reached,...
Printable printMBBReference(const MachineBasicBlock &MBB)
Prints a machine basic block reference.
Incoming for lane maks phi as machine instruction, incoming register Reg and incoming block Block are...
MachineBasicBlock * MBB
The basic block.
bool IsDone
True if the block that is ready for its final round of processing.
bool PrimaryPass
True if this is the first time we process the basic block.