49#define DEBUG_TYPE "phi-node-elimination"
54 cl::desc(
"Disable critical edge splitting "
55 "during PHI elimination"));
60 cl::desc(
"Split all critical edges during "
65 cl::desc(
"Do not use an early exit if isLiveOutPastPHIs returns true."));
69class PHIEliminationImpl {
82 bool AllEdgesCritical);
102 using BBVRegPair = std::pair<unsigned, Register>;
106 VRegPHIUse VRegPHIUseCount;
112 using LoweredPHIMap =
114 LoweredPHIMap LoweredPHIs;
126 LV = LVWrapper ? &LVWrapper->getLV() :
nullptr;
127 LIS = LISWrapper ? &LISWrapper->getLIS() :
nullptr;
128 MLI = MLIWrapper ? &MLIWrapper->getLI() :
nullptr;
129 MDT = MDTWrapper ? &MDTWrapper->getDomTree() :
nullptr;
150 PHIEliminationImpl Impl(
this);
156 MachineFunctionProperties::Property::NoPHIs);
167 PHIEliminationImpl Impl(MF, MFAM);
168 bool Changed = Impl.run(MF);
181STATISTIC(NumCriticalEdgesSplit,
"Number of critical edges split");
184char PHIElimination::ID = 0;
189 "Eliminate PHI nodes for register allocation",
false,
195void PHIElimination::getAnalysisUsage(
AnalysisUsage &AU)
const {
212 MDT = MDTWrapper ? &MDTWrapper->getDomTree() :
nullptr;
218 bool Changed =
false;
224 std::vector<SparseBitVector<>> LiveInSets;
226 LiveInSets.resize(MF.
size());
227 for (
unsigned Index = 0, e =
MRI->getNumVirtRegs(); Index != e; ++Index) {
237 while (AliveBlockItr != EndItr) {
238 unsigned BlockNum = *(AliveBlockItr++);
239 LiveInSets[BlockNum].set(Index);
244 if (
VI.Kills.size() > 1 ||
245 (!
VI.Kills.empty() &&
VI.Kills.front()->getParent() != DefMBB))
246 for (
auto *
MI :
VI.Kills)
247 LiveInSets[
MI->getParent()->getNumber()].set(Index);
253 SplitPHIEdges(MF,
MBB, MLI, (LV ? &LiveInSets :
nullptr), MDTU);
265 Changed |= EliminatePHINodes(MF,
MBB);
270 if (
MRI->use_nodbg_empty(DefReg)) {
278 for (
auto &
I : LoweredPHIs) {
281 MF.deleteMachineInstr(
I.first);
286 VRegPHIUseCount.clear();
310 if (Pred->succ_size() < 2) {
311 AllEdgesCritical =
false;
317 LowerPHINode(
MBB, LastPHIIt, AllEdgesCritical);
327 if (!DI.isImplicitDef())
345 bool AllEdgesCritical) {
360 unsigned IncomingReg = 0;
361 bool EliminateNow =
true;
362 bool reusedIncoming =
false;
373 TII->get(TargetOpcode::IMPLICIT_DEF), DestReg);
379 unsigned *
Entry =
nullptr;
380 if (AllEdgesCritical)
381 Entry = &LoweredPHIs[MPhi];
382 if (Entry && *Entry) {
384 IncomingReg = *
Entry;
385 reusedIncoming =
true;
393 EliminateNow =
false;
394 *
Entry = IncomingReg;
399 PHICopy =
TII->createPHIDestinationCopy(
419 bool IsPHICopyAfterOldKill =
false;
421 if (reusedIncoming && (OldKill =
VI.findKill(&
MBB))) {
433 IsPHICopyAfterOldKill =
true;
442 if (IsPHICopyAfterOldKill) {
444 LV->removeVirtualRegisterKilled(IncomingReg, *OldKill);
453 if (!OldKill || IsPHICopyAfterOldKill)
454 LV->addVirtualRegisterKilled(IncomingReg, *PHICopy);
460 LV->removeVirtualRegistersKilled(*MPhi);
464 LV->addVirtualRegisterDead(DestReg, *PHICopy);
465 LV->removeVirtualRegisterDead(DestReg, *MPhi);
483 MBBStartIndex, DestCopyIndex.
getRegSlot(), IncomingVNI));
487 assert(!DestLI.
empty() &&
"PHIs should have non-empty LiveIntervals.");
495 for (
auto LR : ToUpdate) {
496 auto DestSegment = LR->find(MBBStartIndex);
497 assert(DestSegment != LR->end() &&
498 "PHI destination must be live in block");
500 if (LR->endIndex().isDead()) {
504 VNInfo *OrigDestVNI = LR->getVNInfoAt(DestSegment->start);
505 assert(OrigDestVNI &&
"PHI destination should be live at block entry.");
506 LR->removeSegment(DestSegment->start, DestSegment->start.getDeadSlot());
508 LR->removeValNo(OrigDestVNI);
515 if (DestSegment->start > NewStart) {
516 VNInfo *VNI = LR->getVNInfoAt(DestSegment->start);
517 assert(VNI &&
"value should be defined for known segment");
520 }
else if (DestSegment->start < NewStart) {
521 assert(DestSegment->start >= MBBStartIndex);
523 LR->removeSegment(DestSegment->start, NewStart);
525 VNInfo *DestVNI = LR->getVNInfoAt(NewStart);
526 assert(DestVNI &&
"PHI destination should be live at its definition.");
527 DestVNI->
def = NewStart;
535 --VRegPHIUseCount[BBVRegPair(
545 for (
int i = NumSrcs - 1; i >= 0; --i) {
551 "Machine PHI Operands must all be virtual registers!");
560 if (!MBBsInsertedInto.
insert(&opBlock).second)
564 if (SrcRegDef &&
TII->isUnspillableTerminator(SrcRegDef)) {
567 "Expected operand 0 to be a reg def!");
571 "Expected a single use from UnspillableTerminator");
592 if (!reusedIncoming && IncomingReg) {
599 TII->get(TargetOpcode::IMPLICIT_DEF), IncomingReg);
604 ImpDefs.insert(
DefMI);
608 NewSrcInstr =
TII->createPHISourceCopy(opBlock, InsertPos,
nullptr,
609 SrcReg, SrcSubReg, IncomingReg);
616 if (LV && !SrcUndef &&
617 !VRegPHIUseCount[BBVRegPair(opBlock.
getNumber(), SrcReg)] &&
618 !LV->isLiveOut(SrcReg, opBlock)) {
638 if (
Term->readsRegister(SrcReg,
nullptr))
642 if (KillInst == opBlock.
end()) {
645 if (reusedIncoming || !IncomingReg) {
647 KillInst = InsertPos;
648 while (KillInst != opBlock.
begin()) {
650 if (KillInst->isDebugInstr())
652 if (KillInst->readsRegister(SrcReg,
nullptr))
657 KillInst = NewSrcInstr;
660 assert(KillInst->readsRegister(SrcReg,
nullptr) &&
661 "Cannot find kill instruction");
664 LV->addVirtualRegisterKilled(SrcReg, *KillInst);
667 unsigned opBlockNum = opBlock.
getNumber();
668 LV->getVarInfo(SrcReg).AliveBlocks.reset(opBlockNum);
678 !VRegPHIUseCount[BBVRegPair(opBlock.
getNumber(), SrcReg)]) {
687 if (VNI && VNI->
def != startIdx) {
697 if (
Term->readsRegister(SrcReg,
nullptr))
701 if (KillInst == opBlock.
end()) {
704 if (reusedIncoming || !IncomingReg) {
706 KillInst = InsertPos;
707 while (KillInst != opBlock.
begin()) {
709 if (KillInst->isDebugInstr())
711 if (KillInst->readsRegister(SrcReg,
nullptr))
716 KillInst = std::prev(InsertPos);
719 assert(KillInst->readsRegister(SrcReg,
nullptr) &&
720 "Cannot find kill instruction");
747 for (
const auto &
MBB : MF) {
748 for (
const auto &BBI :
MBB) {
751 for (
unsigned i = 1, e = BBI.getNumOperands(); i != e; i += 2) {
752 if (!BBI.getOperand(i).isUndef()) {
753 ++VRegPHIUseCount[BBVRegPair(
754 BBI.getOperand(i + 1).getMBB()->getNumber(),
755 BBI.getOperand(i).getReg())];
762bool PHIEliminationImpl::SplitPHIEdges(
769 bool IsLoopHeader = CurLoop && &
MBB == CurLoop->
getHeader();
771 bool Changed =
false;
773 BBI != BBE && BBI->isPHI(); ++BBI) {
774 for (
unsigned i = 1, e = BBI->getNumOperands(); i != e; i += 2) {
795 bool ShouldSplit = isLiveOutPastPHIs(Reg, PreMBB);
812 ShouldSplit = ShouldSplit && !isLiveIn(Reg, &
MBB);
815 if (!ShouldSplit && CurLoop != PreLoop) {
817 dbgs() <<
"Split wouldn't help, maybe avoid loop copies?\n";
819 dbgs() <<
"PreLoop: " << *PreLoop;
821 dbgs() <<
"CurLoop: " << *CurLoop;
827 ShouldSplit = PreLoop && !PreLoop->
contains(CurLoop);
837 ++NumCriticalEdgesSplit;
845 "isLiveIn() requires either LiveVariables or LiveIntervals");
849 return LV->isLiveIn(Reg, *
MBB);
852bool PHIEliminationImpl::isLiveOutPastPHIs(
Register Reg,
855 "isLiveOutPastPHIs() requires either LiveVariables or LiveIntervals");
868 return LV->isLiveOut(Reg, *
MBB);
unsigned const MachineRegisterInfo * MRI
for(const MachineOperand &MO :llvm::drop_begin(OldMI.operands(), Desc.getNumOperands()))
MachineInstrBuilder MachineInstrBuilder & DefMI
Unify divergent function exit nodes
This file defines the DenseMap class.
const HexagonInstrInfo * TII
static bool allPhiOperandsUndefined(const MachineInstr &MPhi, const MachineRegisterInfo &MRI)
Return true if all sources of the phi node are implicit_def's, or undef's.
Eliminate PHI nodes for register allocation
static cl::opt< bool > NoPhiElimLiveOutEarlyExit("no-phi-elim-live-out-early-exit", cl::init(false), cl::Hidden, cl::desc("Do not use an early exit if isLiveOutPastPHIs returns true."))
static bool isImplicitlyDefined(unsigned VirtReg, const MachineRegisterInfo &MRI)
Return true if all defs of VirtReg are implicit-defs.
static cl::opt< bool > DisableEdgeSplitting("disable-phi-elim-edge-splitting", cl::init(false), cl::Hidden, cl::desc("Disable critical edge splitting " "during PHI elimination"))
static cl::opt< bool > SplitAllCriticalEdges("phi-elim-split-all-critical-edges", cl::init(false), cl::Hidden, cl::desc("Split all critical edges during " "PHI elimination"))
#define INITIALIZE_PASS_DEPENDENCY(depName)
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
#define INITIALIZE_PASS_BEGIN(passName, arg, name, cfg, analysis)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
static bool isLiveOut(const MachineBasicBlock &MBB, unsigned Reg)
bool isDead(const MachineInstr &MI, const MachineRegisterInfo &MRI)
This file defines the SmallPtrSet class.
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
A container for analyses that lazily runs them and caches their results.
PassT::Result * getCachedResult(IRUnitT &IR) const
Get the cached result of an analysis pass for a given IR unit.
Represent the analysis usage information of a pass.
LiveInterval - This class represents the liveness of a register, or stack slot.
iterator_range< subrange_iterator > subranges()
SlotIndex getMBBStartIdx(const MachineBasicBlock *mbb) const
Return the first index in the given basic block.
SlotIndex InsertMachineInstrInMaps(MachineInstr &MI)
LiveInterval & getOrCreateEmptyInterval(Register Reg)
Return an existing interval for Reg.
SlotIndex getInstructionIndex(const MachineInstr &Instr) const
Returns the base index of the given instruction.
void RemoveMachineInstrFromMaps(MachineInstr &MI)
VNInfo::Allocator & getVNInfoAllocator()
SlotIndex getMBBEndIdx(const MachineBasicBlock *mbb) const
Return the last index in the given basic block.
LiveInterval & getInterval(Register Reg)
LiveInterval::Segment addSegmentToEndOfBlock(Register Reg, MachineInstr &startInst)
Given a register and an instruction, adds a live segment from that instruction to the end of its MBB.
bool isLiveInToMBB(const LiveRange &LR, const MachineBasicBlock *mbb) const
iterator addSegment(Segment S)
Add the specified Segment to this range, merging segments as appropriate.
bool liveAt(SlotIndex index) const
VNInfo * getNextValue(SlotIndex Def, VNInfo::Allocator &VNInfoAllocator)
getNextValue - Create a new value number and return it.
void removeSegment(SlotIndex Start, SlotIndex End, bool RemoveDeadValNo=false)
Remove the specified interval from this live range.
VNInfo * getVNInfoAt(SlotIndex Idx) const
getVNInfoAt - Return the VNInfo that is live at Idx, or NULL.
bool contains(const LoopT *L) const
Return true if the specified loop is contained within in this loop.
BlockT * getHeader() const
LoopT * getLoopFor(const BlockT *BB) const
Return the inner most loop that BB lives in.
unsigned pred_size() const
bool isEHPad() const
Returns true if the block is a landing pad.
MachineBasicBlock * SplitCriticalEdge(MachineBasicBlock *Succ, Pass &P, std::vector< SparseBitVector<> > *LiveInSets=nullptr, MachineDomTreeUpdater *MDTU=nullptr)
Split the critical edge from this block to the given successor block, and return the newly created bl...
int getNumber() const
MachineBasicBlocks are uniquely numbered at the function level, unless they're not in a MachineFuncti...
iterator SkipPHIsAndLabels(iterator I)
Return the first instruction in MBB after I that is not a PHI or a label.
MachineInstr * remove(MachineInstr *I)
Remove the unbundled instruction from the instruction list without deleting it.
unsigned succ_size() const
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
iterator_range< succ_iterator > successors()
iterator_range< pred_iterator > predecessors()
Analysis pass which computes a MachineDominatorTree.
Analysis pass which computes a MachineDominatorTree.
DominatorTree Class - Concrete subclass of DominatorTreeBase that is used to compute a normal dominat...
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.
virtual MachineFunctionProperties getSetProperties() const
virtual bool runOnMachineFunction(MachineFunction &MF)=0
runOnMachineFunction - This method must be overloaded to perform the desired machine code transformat...
Properties which a MachineFunction may have at a given point in time.
MachineFunctionProperties & set(Property P)
Location of a PHI instruction that is also a debug-info variable value, for the duration of register ...
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
void deleteMachineInstr(MachineInstr *MI)
DeleteMachineInstr - Delete the given MachineInstr.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
DenseMap< unsigned, DebugPHIRegallocPos > DebugPHIPositions
Map of debug instruction numbers to the position of their PHI instructions during register allocation...
Representation of each machine instruction.
bool isImplicitDef() const
const MachineBasicBlock * getParent() const
unsigned getNumOperands() const
Retuns the total number of operands.
unsigned peekDebugInstrNum() const
Examine the instruction number of this MachineInstr.
const DebugLoc & getDebugLoc() const
Returns the debug location id of this MachineInstr.
void eraseFromParent()
Unlink 'this' from the containing basic block and delete it.
const MachineOperand & getOperand(unsigned i) const
Analysis pass that exposes the MachineLoopInfo for a machine function.
MachineOperand class - Representation of each machine instruction operand.
unsigned getSubReg() const
bool isReg() const
isReg - Tests if this is a MO_Register operand.
MachineBasicBlock * getMBB() const
void setReg(Register Reg)
Change the register this operand corresponds to.
Register getReg() const
getReg - Returns the register number.
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
const TargetRegisterClass * getRegClass(Register Reg) const
Return the register class of the specified virtual register.
Register createVirtualRegister(const TargetRegisterClass *RegClass, StringRef Name="")
createVirtualRegister - Create and return a new virtual register in the function with the specified r...
PreservedAnalyses run(MachineFunction &MF, MachineFunctionAnalysisManager &MFAM)
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
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.
Wrapper class representing virtual and physical registers.
static Register index2VirtReg(unsigned Index)
Convert a 0-based index to a virtual register number.
constexpr bool isVirtual() const
Return true if the specified register number is in the virtual register namespace.
SlotIndex - An opaque wrapper around machine indexes.
SlotIndex getRegSlot(bool EC=false) const
Returns the register use/def slot in the current instruction for a normal or early-clobber def.
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.
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
SparseBitVectorIterator iterator
TargetInstrInfo - Interface to description of machine instruction set.
virtual const TargetInstrInfo * getInstrInfo() const
VNInfo - Value Number Information.
SlotIndex def
The index of the defining instruction.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
Reg
All possible values of the reg field in the ModR/M byte.
initializer< Ty > init(const Ty &Val)
PointerTypeMap run(const Module &M)
Compute the PointerTypeMap for the module M.
This is an optimization pass for GlobalISel generic memory operations.
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
PreservedAnalyses getMachineFunctionPassPreservedAnalyses()
Returns the minimum set of Analyses that all machine function passes must preserve.
void initializePHIEliminationPass(PassRegistry &)
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
char & PHIEliminationID
PHIElimination - This pass eliminates machine instruction PHI nodes by inserting copy instructions.
MachineBasicBlock::iterator findPHICopyInsertPoint(MachineBasicBlock *MBB, MachineBasicBlock *SuccMBB, unsigned SrcReg)
findPHICopyInsertPoint - Find a safe place in MBB to insert a copy from SrcReg when following the CFG...
Printable printReg(Register Reg, const TargetRegisterInfo *TRI=nullptr, unsigned SubIdx=0, const MachineRegisterInfo *MRI=nullptr)
Prints virtual and physical registers with or without a TRI instance.
Printable printMBBReference(const MachineBasicBlock &MBB)
Prints a machine basic block reference.
This represents a simple continuous liveness interval for a value.
VarInfo - This represents the regions where a virtual register is live in the program.
SparseBitVector AliveBlocks
AliveBlocks - Set of blocks in which this value is alive completely through.