21#define DEBUG_TYPE "reaching-defs-analysis"
39 OS <<
"Reaching definitions for for machine function: " << MF.
getName()
46 "Reaching Definitions Analysis",
false,
true)
59 MachineFunctionAnalysisManager::Invalidator &) {
63 return !PAC.preserved() &&
106 int DefFrameIndex = 0;
107 int SrcFrameIndex = 0;
108 if (
TII->isStoreToStackSlot(
MI, DefFrameIndex) ||
109 TII->isStackSlotCopy(
MI, DefFrameIndex, SrcFrameIndex))
110 return DefFrameIndex == FrameIndex;
116 assert(MBBNumber < MBBReachingDefs.numBlockIDs() &&
117 "Unexpected basic block number.");
118 assert(LiveRegs.empty() &&
"LiveRegs should be empty on BB entry");
119 MBBReachingDefs.startBasicBlock(MBBNumber, NumRegUnits);
126 LiveRegs.assign(NumRegUnits, ReachingDefDefaultVal);
128 for (MCRegUnit Unit : TRI->regunits(LI.PhysReg)) {
132 if (LiveRegs[
static_cast<unsigned>(Unit)] != FunctionLiveInMarker) {
133 LiveRegs[
static_cast<unsigned>(
Unit)] = FunctionLiveInMarker;
134 MBBReachingDefs.append(MBBNumber, Unit, FunctionLiveInMarker);
143 bool Initialized =
false;
145 assert(
unsigned(pred->getNumber()) < MBBOutRegsInfos.size() &&
146 "Should have pre-allocated MBBInfos for all MBBs");
147 const LiveRegsDefInfo &Incoming = MBBOutRegsInfos[pred->getNumber()];
150 if (Incoming.empty())
161 for (
unsigned Unit = 0;
Unit != NumRegUnits; ++
Unit)
162 LiveRegs[Unit] = std::max(LiveRegs[Unit], Incoming[Unit]);
166 LiveRegs.assign(NumRegUnits, ReachingDefDefaultVal);
169 for (
unsigned Unit = 0;
Unit != NumRegUnits; ++
Unit)
170 if (LiveRegs[Unit] != ReachingDefDefaultVal)
171 MBBReachingDefs.append(MBBNumber,
static_cast<MCRegUnit
>(Unit),
176 assert(!LiveRegs.empty() &&
"Must enter basic block first.");
178 assert(MBBNumber < MBBOutRegsInfos.size() &&
179 "Unexpected basic block number.");
181 MBBOutRegsInfos[MBBNumber] = LiveRegs;
187 for (
int &OutLiveReg : MBBOutRegsInfos[MBBNumber])
188 if (OutLiveReg != ReachingDefDefaultVal)
189 OutLiveReg -= CurInstr;
194 assert(!
MI->isDebugInstr() &&
"Won't process debug instructions");
196 unsigned MBBNumber =
MI->getParent()->getNumber();
197 assert(MBBNumber < MBBReachingDefs.numBlockIDs() &&
198 "Unexpected basic block number.");
200 for (
auto &MO :
MI->operands()) {
205 MBBFrameObjsReachingDefs[{MBBNumber,
FrameIndex}].push_back(CurInstr);
209 for (MCRegUnit Unit : TRI->regunits(MO.getReg().asMCReg())) {
215 if (LiveRegs[
static_cast<unsigned>(Unit)] != CurInstr) {
216 LiveRegs[
static_cast<unsigned>(
Unit)] = CurInstr;
217 MBBReachingDefs.append(MBBNumber, Unit, CurInstr);
221 InstIds[
MI] = CurInstr;
227 assert(MBBNumber < MBBReachingDefs.numBlockIDs() &&
228 "Unexpected basic block number.");
233 int NumInsts = std::distance(NonDbgInsts.begin(), NonDbgInsts.end());
238 assert(
unsigned(pred->getNumber()) < MBBOutRegsInfos.size() &&
239 "Should have pre-allocated MBBInfos for all MBBs");
240 const LiveRegsDefInfo &Incoming = MBBOutRegsInfos[pred->getNumber()];
242 if (Incoming.empty())
245 for (
unsigned Unit = 0;
Unit != NumRegUnits; ++
Unit) {
247 if (Def == ReachingDefDefaultVal)
250 auto Defs = MBBReachingDefs.defs(MBBNumber,
static_cast<MCRegUnit
>(Unit));
251 if (!Defs.empty() && Defs.front() < 0) {
252 if (Defs.front() >= Def)
256 MBBReachingDefs.replaceFront(MBBNumber,
static_cast<MCRegUnit
>(Unit),
260 MBBReachingDefs.prepend(MBBNumber,
static_cast<MCRegUnit
>(Unit), Def);
265 if (MBBOutRegsInfos[MBBNumber][Unit] < Def - NumInsts)
266 MBBOutRegsInfos[MBBNumber][
Unit] =
Def - NumInsts;
271void ReachingDefInfo::processBasicBlock(
273 MachineBasicBlock *
MBB = TraversedMBB.
MBB;
275 << (!TraversedMBB.
IsDone ?
": incomplete\n"
276 :
": all preds known\n"));
280 reprocessBasicBlock(
MBB);
284 enterBasicBlock(
MBB);
285 for (MachineInstr &
MI :
288 leaveBasicBlock(
MBB);
296 LLVM_DEBUG(
dbgs() <<
"********** REACHING DEFINITION ANALYSIS **********\n");
309 InstToNumMap[&
MI] = Num;
321 int FrameIndex = MO.getIndex();
323 }
else if (MO.isReg()) {
343 OS << InstToNumMap[&
MI] <<
": " <<
MI <<
"\n";
355 MBBOutRegsInfos.clear();
356 MBBReachingDefs.clear();
357 MBBFrameObjsReachingDefs.clear();
369 NumRegUnits = TRI->getNumRegUnits();
370 NumStackObjects = MF->getFrameInfo().getNumObjects();
371 ObjectIndexBegin = MF->getFrameInfo().getObjectIndexBegin();
372 MBBReachingDefs.init(MF->getNumBlockIDs());
374 MBBOutRegsInfos.resize(MF->getNumBlockIDs());
376 TraversedMBBOrder = Traversal.
traverse(*MF);
382 processBasicBlock(TraversedMBB);
385 for (
unsigned MBBNumber = 0, NumBlockIDs = MF->getNumBlockIDs();
386 MBBNumber != NumBlockIDs; ++MBBNumber) {
387 for (
unsigned Unit = 0; Unit != NumRegUnits; ++Unit) {
388 int LastDef = ReachingDefDefaultVal;
390 MBBReachingDefs.defs(MBBNumber,
static_cast<MCRegUnit
>(Unit))) {
391 assert(Def > LastDef &&
"Defs must be sorted and unique");
400 assert(InstIds.count(
MI) &&
"Unexpected machine instuction.");
401 int InstId = InstIds.lookup(
MI);
402 int DefRes = ReachingDefDefaultVal;
403 unsigned MBBNumber =
MI->getParent()->getNumber();
404 assert(MBBNumber < MBBReachingDefs.numBlockIDs() &&
405 "Unexpected basic block number.");
406 int LatestDef = ReachingDefDefaultVal;
410 int FrameIndex = Reg.stackSlotIndex();
411 auto Lookup = MBBFrameObjsReachingDefs.find({MBBNumber, FrameIndex});
412 if (
Lookup == MBBFrameObjsReachingDefs.end())
414 auto &Defs =
Lookup->second;
415 for (
int Def : Defs) {
420 LatestDef = std::max(LatestDef, DefRes);
424 for (MCRegUnit Unit : TRI->regunits(Reg)) {
425 for (
int Def : MBBReachingDefs.defs(MBBNumber, Unit)) {
430 LatestDef = std::max(LatestDef, DefRes);
446 if (ParentA != ParentB)
454 assert(
static_cast<size_t>(
MBB->getNumber()) <
456 "Unexpected basic block number.");
457 assert(InstId <
static_cast<int>(
MBB->size()) &&
458 "Unexpected instruction id.");
463 for (
auto &
MI : *
MBB) {
464 auto F = InstIds.find(&
MI);
465 if (
F != InstIds.end() &&
F->second == InstId)
473 assert(InstIds.count(
MI) &&
"Unexpected machine instuction.");
482 InstSet &
Uses)
const {
485 while (++
MI !=
MBB->end()) {
486 if (
MI->isDebugInstr())
491 if (getReachingLocalMIDef(&*
MI, Reg) != Def)
494 for (
auto &MO :
MI->operands()) {
506 InstSet &
Uses)
const {
509 for (
auto &MO :
MI.operands()) {
517 auto Last =
MBB->getLastNonDebugInstr();
524 InstSet &
Uses)
const {
537 while (!ToVisit.
empty()) {
549 InstSet &Defs)
const {
555 for (
auto *
MBB :
MI->getParent()->predecessors())
560 InstSet &Defs)
const {
566 InstSet &Defs, BlockSet &VisitedBBs)
const {
572 LiveRegs.addLiveOuts(*
MBB);
573 if (Reg.isPhysical() && LiveRegs.available(Reg))
579 for (
auto *Pred :
MBB->predecessors())
587 if (LocalDef && InstIds.lookup(LocalDef) < InstIds.lookup(
MI))
598 if (Incoming.
size() == 1 && (*Incoming.
begin())->getParent() != Parent)
599 return *Incoming.
begin();
604 unsigned Idx)
const {
605 assert(
MI->getOperand(Idx).isReg() &&
"Expected register operand");
618 LiveRegs.addLiveOuts(*
MBB);
621 if (!LiveRegs.available(Reg))
628 LiveRegs.stepBackward(
Last);
629 if (!LiveRegs.available(Reg))
630 return InstIds.lookup(&
Last) > InstIds.lookup(
MI);
637 auto Last =
MBB->getLastNonDebugInstr();
643 return Def == getReachingLocalMIDef(
MI, Reg);
652 LiveRegs.addLiveOuts(*
MBB);
653 if (Reg.isPhysical() && LiveRegs.available(Reg))
656 auto Last =
MBB->getLastNonDebugInstr();
662 for (
auto &MO :
Last->operands())
672 LiveRegs.addLiveOuts(*
MBB);
673 if (Reg.isPhysical() && LiveRegs.available(Reg))
676 auto Last =
MBB->getLastNonDebugInstr();
682 int FrameIndex = Reg.stackSlotIndex();
686 for (
auto &MO :
Last->operands())
692 return Def < 0 ? nullptr : getInstFromId(
MBB, Def);
696 return MI.mayLoadOrStore() ||
MI.mayRaiseFPException() ||
697 MI.hasUnmodeledSideEffects() ||
MI.isTerminator() ||
698 MI.isCall() ||
MI.isBarrier() ||
MI.isBranch() ||
MI.isReturn();
704template <
typename Iterator>
709 SmallSet<Register, 2> Defs;
723 for (
auto I = ++Iterator(From),
E = Iterator(To);
I !=
E; ++
I) {
726 for (
auto &MO :
I->operands())
727 if (MO.isReg() && MO.getReg() && Defs.
count(MO.getReg()))
737 for (
auto I = Iterator(From), E = From->
getParent()->
end();
I != E; ++
I)
739 return isSafeToMove<Iterator>(From, To);
749 return isSafeToMove<Iterator>(From, To);
777 for (
auto &MO :
MI->operands()) {
784 for (
auto *
I :
Uses) {
796 InstSet &
Dead)
const {
802 unsigned LiveDefs = 0;
803 for (
auto &MO : Def->operands()) {
818 for (
auto &MO :
MI->operands()) {
822 if (
IsDead(Def, MO.getReg()))
836 if (
auto *Def = getReachingLocalMIDef(
MI, Reg)) {
849 for (
auto E =
MBB->end();
I != E; ++
I) {
852 for (
auto &MO :
I->operands())
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
ReachingDefInfo InstSet InstSet & Ignore
ReachingDefInfo InstSet & ToRemove
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
const HexagonInstrInfo * TII
Register 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 isValidReg(const MachineOperand &MO)
static bool isFIDef(const MachineInstr &MI, int FrameIndex, const TargetInstrInfo *TII)
static bool isValidRegDef(const MachineOperand &MO)
static bool isValidRegDefOf(const MachineOperand &MO, Register Reg, const TargetRegisterInfo *TRI)
static bool isValidRegUse(const MachineOperand &MO)
Remove Loads Into Fake Uses
This file defines generic set operations that may be used on set's of different types,...
This file defines the SmallSet class.
static int Lookup(ArrayRef< TableEntry > Table, unsigned Opcode)
This templated class represents "all analyses that operate over <aparticular IR unit>" (e....
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
Represent the analysis usage information of a pass.
void setPreservesAll()
Set by analyses that do not transform their input at all.
Represents analyses that only rely on functions' control flow.
A set of register units used to track register liveness.
This class provides the basic blocks traversal order used by passes like ReachingDefAnalysis and Exec...
LLVM_ABI TraversalOrder traverse(MachineFunction &MF)
unsigned numBlockIDs() const
An RAII based helper class to modify MachineFunctionProperties when running pass.
instr_iterator instr_begin()
iterator_range< livein_iterator > liveins() const
int getNumber() const
MachineBasicBlocks are uniquely numbered at the function level, unless they're not in a MachineFuncti...
MachineInstrBundleIterator< MachineInstr, true > reverse_iterator
instr_iterator instr_end()
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
iterator_range< pred_iterator > predecessors()
MachineInstrBundleIterator< MachineInstr > iterator
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
Properties which a MachineFunction may have at a given point in time.
StringRef getName() const
getName - Return the name of the corresponding LLVM function.
const MachineBasicBlock & front() const
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.
A set of analyses that are preserved following a run of a transformation pass.
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
PreservedAnalysisChecker getChecker() const
Build a checker for this PreservedAnalyses and the specified analysis type.
LLVM_ABI Result run(MachineFunction &MF, MachineFunctionAnalysisManager &MFAM)
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
bool runOnMachineFunction(MachineFunction &F) override
runOnMachineFunction - This method must be overloaded to perform the desired machine code transformat...
MachineFunctionProperties getRequiredProperties() const override
This class provides the reaching def analysis.
LLVM_ABI MachineInstr * getUniqueReachingMIDef(MachineInstr *MI, Register Reg) const
If a single MachineInstr creates the reaching definition, then return it.
LLVM_ABI bool isReachingDefLiveOut(MachineInstr *MI, Register Reg) const
Return whether the reaching def for MI also is live out of its parent block.
LLVM_ABI bool isSafeToMoveForwards(MachineInstr *From, MachineInstr *To) const
Return whether From can be moved forwards to just before To.
LLVM_ABI int getReachingDef(MachineInstr *MI, Register Reg) const
Provides the instruction id of the closest reaching def instruction of Reg that reaches MI,...
LLVM_ABI void run(MachineFunction &mf)
LLVM_ABI void getReachingLocalUses(MachineInstr *MI, Register Reg, InstSet &Uses) const
Provides the uses, in the same block as MI, of register that MI defines.
LLVM_ABI int getClearance(MachineInstr *MI, Register Reg) const
Provides the clearance - the number of instructions since the closest reaching def instuction of Reg ...
LLVM_ABI bool isRegDefinedAfter(MachineInstr *MI, Register Reg) const
Return whether the given register is defined after MI.
LLVM_ABI void init()
Initialize data structures.
LLVM_ABI void print(raw_ostream &OS)
LLVM_ABI bool hasLocalDefBefore(MachineInstr *MI, Register Reg) const
Provide whether the register has been defined in the same basic block as, and before,...
LLVM_ABI void reset()
Re-run the analysis.
LLVM_ABI void getGlobalUses(MachineInstr *MI, Register Reg, InstSet &Uses) const
Collect the users of the value stored in Reg, which is defined by MI.
LLVM_ABI void releaseMemory()
LLVM_ABI MachineInstr * getMIOperand(MachineInstr *MI, unsigned Idx) const
If a single MachineInstr creates the reaching definition, for MIs operand at Idx, then return it.
LLVM_ABI void getLiveOuts(MachineBasicBlock *MBB, Register Reg, InstSet &Defs, BlockSet &VisitedBBs) const
Search MBB for a definition of Reg and insert it into Defs.
LLVM_ABI void traverse()
Traverse the machine function, mapping definitions.
LLVM_ABI ReachingDefInfo()
LLVM_ABI bool isSafeToMoveBackwards(MachineInstr *From, MachineInstr *To) const
Return whether From can be moved backwards to just after To.
LLVM_ABI void collectKilledOperands(MachineInstr *MI, InstSet &Dead) const
Assuming MI is dead, recursively search the incoming operands which are killed by MI and collect thos...
LLVM_ABI ~ReachingDefInfo()
LLVM_ABI bool hasSameReachingDef(MachineInstr *A, MachineInstr *B, Register Reg) const
Return whether A and B use the same def of Reg.
LLVM_ABI 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.
LLVM_ABI void getGlobalReachingDefs(MachineInstr *MI, Register Reg, InstSet &Defs) const
Collect all possible definitions of the value stored in Reg, which is used by MI.
LLVM_ABI bool isSafeToRemove(MachineInstr *MI, InstSet &ToRemove) const
Return whether removing this instruction will have no effect on the program, returning the redundant ...
LLVM_ABI 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...
LLVM_ABI bool invalidate(MachineFunction &F, const PreservedAnalyses &PA, MachineFunctionAnalysisManager::Invalidator &)
Handle invalidation explicitly.
LLVM_ABI 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.
LLVM_ABI bool isSafeToDefRegAt(MachineInstr *MI, Register Reg) const
Return whether a MachineInstr could be inserted at MI and safely define the given register without af...
LLVM_ABI PreservedAnalyses run(MachineFunction &MF, MachineFunctionAnalysisManager &MFAM)
Wrapper class representing virtual and physical registers.
static Register index2StackSlot(int FI)
Convert a frame index to a stack slot register value.
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.
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 TargetInstrInfo * getInstrInfo() const
virtual const TargetRegisterInfo * getRegisterInfo() const =0
Return the target's register information.
This class implements an extremely fast bulk output stream that can only output to a stream.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
NodeAddr< DefNode * > Def
This is an optimization pass for GlobalISel generic memory operations.
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.
LLVM_ABI Printable printRegUnit(MCRegUnit Unit, const TargetRegisterInfo *TRI)
Create Printable object to print register units on a raw_ostream.
AnalysisManager< MachineFunction > MachineFunctionAnalysisManager
void sort(IteratorTy Start, IteratorTy End)
LLVM_ABI 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,...
LLVM_ABI Printable printMBBReference(const MachineBasicBlock &MBB)
Prints a machine basic block reference.
A special type used by analysis passes to provide an address that identifies that particular analysis...
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.