48#define DEBUG_TYPE "phi-node-elimination"
53 cl::desc(
"Disable critical edge splitting "
54 "during PHI elimination"));
59 cl::desc(
"Split all critical edges during "
64 cl::desc(
"Do not use an early exit if isLiveOutPastPHIs returns true."));
68class PHIEliminationImpl {
81 bool AllEdgesCritical);
100 using BBVRegPair = std::pair<unsigned, Register>;
104 VRegPHIUse VRegPHIUseCount;
110 using LoweredPHIMap =
112 LoweredPHIMap LoweredPHIs;
124 LV = LVWrapper ? &LVWrapper->getLV() :
nullptr;
125 LIS = LISWrapper ? &LISWrapper->getLIS() :
nullptr;
126 MLI = MLIWrapper ? &MLIWrapper->getLI() :
nullptr;
127 MDT = MDTWrapper ? &MDTWrapper->getDomTree() :
nullptr;
148 PHIEliminationImpl Impl(
this);
154 MachineFunctionProperties::Property::NoPHIs);
165 PHIEliminationImpl Impl(MF, MFAM);
166 bool Changed = Impl.run(MF);
179STATISTIC(NumCriticalEdgesSplit,
"Number of critical edges split");
182char PHIElimination::ID = 0;
187 "Eliminate PHI nodes for register allocation",
false,
193void PHIElimination::getAnalysisUsage(
AnalysisUsage &AU)
const {
206 bool Changed =
false;
212 std::vector<SparseBitVector<>> LiveInSets;
214 LiveInSets.resize(MF.
size());
225 while (AliveBlockItr != EndItr) {
226 unsigned BlockNum = *(AliveBlockItr++);
227 LiveInSets[BlockNum].set(
Index);
232 if (
VI.Kills.size() > 1 ||
233 (!
VI.Kills.empty() &&
VI.Kills.front()->getParent() != DefMBB))
234 for (
auto *
MI :
VI.Kills)
235 LiveInSets[
MI->getParent()->getNumber()].set(
Index);
240 Changed |= SplitPHIEdges(MF,
MBB, MLI, (LV ? &LiveInSets :
nullptr));
252 Changed |= EliminatePHINodes(MF,
MBB);
257 if (
MRI->use_nodbg_empty(DefReg)) {
265 for (
auto &
I : LoweredPHIs) {
268 MF.deleteMachineInstr(
I.first);
277 VRegPHIUseCount.clear();
301 if (Pred->succ_size() < 2) {
302 AllEdgesCritical =
false;
308 LowerPHINode(
MBB, LastPHIIt, AllEdgesCritical);
318 if (!DI.isImplicitDef())
336 bool AllEdgesCritical) {
351 unsigned IncomingReg = 0;
352 bool EliminateNow =
true;
353 bool reusedIncoming =
false;
364 TII->get(TargetOpcode::IMPLICIT_DEF), DestReg);
370 unsigned *
Entry =
nullptr;
371 if (AllEdgesCritical)
372 Entry = &LoweredPHIs[MPhi];
373 if (Entry && *Entry) {
375 IncomingReg = *
Entry;
376 reusedIncoming =
true;
384 EliminateNow =
false;
385 *
Entry = IncomingReg;
390 PHICopy =
TII->createPHIDestinationCopy(
410 bool IsPHICopyAfterOldKill =
false;
412 if (reusedIncoming && (OldKill =
VI.findKill(&
MBB))) {
424 IsPHICopyAfterOldKill =
true;
433 if (IsPHICopyAfterOldKill) {
435 LV->removeVirtualRegisterKilled(IncomingReg, *OldKill);
444 if (!OldKill || IsPHICopyAfterOldKill)
445 LV->addVirtualRegisterKilled(IncomingReg, *PHICopy);
451 LV->removeVirtualRegistersKilled(*MPhi);
455 LV->addVirtualRegisterDead(DestReg, *PHICopy);
456 LV->removeVirtualRegisterDead(DestReg, *MPhi);
474 MBBStartIndex, DestCopyIndex.
getRegSlot(), IncomingVNI));
478 assert(!DestLI.
empty() &&
"PHIs should have non-empty LiveIntervals.");
486 for (
auto LR : ToUpdate) {
487 auto DestSegment = LR->find(MBBStartIndex);
488 assert(DestSegment != LR->end() &&
489 "PHI destination must be live in block");
491 if (LR->endIndex().isDead()) {
495 VNInfo *OrigDestVNI = LR->getVNInfoAt(DestSegment->start);
496 assert(OrigDestVNI &&
"PHI destination should be live at block entry.");
497 LR->removeSegment(DestSegment->start, DestSegment->start.getDeadSlot());
499 LR->removeValNo(OrigDestVNI);
506 if (DestSegment->start > NewStart) {
507 VNInfo *VNI = LR->getVNInfoAt(DestSegment->start);
508 assert(VNI &&
"value should be defined for known segment");
511 }
else if (DestSegment->start < NewStart) {
512 assert(DestSegment->start >= MBBStartIndex);
514 LR->removeSegment(DestSegment->start, NewStart);
516 VNInfo *DestVNI = LR->getVNInfoAt(NewStart);
517 assert(DestVNI &&
"PHI destination should be live at its definition.");
518 DestVNI->
def = NewStart;
526 --VRegPHIUseCount[BBVRegPair(
536 for (
int i = NumSrcs - 1; i >= 0; --i) {
542 "Machine PHI Operands must all be virtual registers!");
551 if (!MBBsInsertedInto.
insert(&opBlock).second)
555 if (SrcRegDef &&
TII->isUnspillableTerminator(SrcRegDef)) {
558 "Expected operand 0 to be a reg def!");
562 "Expected a single use from UnspillableTerminator");
583 if (!reusedIncoming && IncomingReg) {
590 TII->get(TargetOpcode::IMPLICIT_DEF), IncomingReg);
595 ImpDefs.insert(
DefMI);
599 NewSrcInstr =
TII->createPHISourceCopy(opBlock, InsertPos,
nullptr,
600 SrcReg, SrcSubReg, IncomingReg);
607 if (LV && !SrcUndef &&
608 !VRegPHIUseCount[BBVRegPair(opBlock.
getNumber(), SrcReg)] &&
609 !LV->isLiveOut(SrcReg, opBlock)) {
629 if (
Term->readsRegister(SrcReg,
nullptr))
633 if (KillInst == opBlock.
end()) {
636 if (reusedIncoming || !IncomingReg) {
638 KillInst = InsertPos;
639 while (KillInst != opBlock.
begin()) {
641 if (KillInst->isDebugInstr())
643 if (KillInst->readsRegister(SrcReg,
nullptr))
648 KillInst = NewSrcInstr;
651 assert(KillInst->readsRegister(SrcReg,
nullptr) &&
652 "Cannot find kill instruction");
655 LV->addVirtualRegisterKilled(SrcReg, *KillInst);
658 unsigned opBlockNum = opBlock.
getNumber();
659 LV->getVarInfo(SrcReg).AliveBlocks.reset(opBlockNum);
669 !VRegPHIUseCount[BBVRegPair(opBlock.
getNumber(), SrcReg)]) {
678 if (VNI && VNI->
def != startIdx) {
688 if (
Term->readsRegister(SrcReg,
nullptr))
692 if (KillInst == opBlock.
end()) {
695 if (reusedIncoming || !IncomingReg) {
697 KillInst = InsertPos;
698 while (KillInst != opBlock.
begin()) {
700 if (KillInst->isDebugInstr())
702 if (KillInst->readsRegister(SrcReg,
nullptr))
707 KillInst = std::prev(InsertPos);
710 assert(KillInst->readsRegister(SrcReg,
nullptr) &&
711 "Cannot find kill instruction");
738 for (
const auto &
MBB : MF) {
739 for (
const auto &BBI :
MBB) {
742 for (
unsigned i = 1, e = BBI.getNumOperands(); i != e; i += 2) {
743 if (!BBI.getOperand(i).isUndef()) {
744 ++VRegPHIUseCount[BBVRegPair(
745 BBI.getOperand(i + 1).getMBB()->getNumber(),
746 BBI.getOperand(i).getReg())];
753bool PHIEliminationImpl::SplitPHIEdges(
760 bool IsLoopHeader = CurLoop && &
MBB == CurLoop->
getHeader();
762 bool Changed =
false;
764 BBI != BBE && BBI->isPHI(); ++BBI) {
765 for (
unsigned i = 1, e = BBI->getNumOperands(); i != e; i += 2) {
786 bool ShouldSplit = isLiveOutPastPHIs(Reg, PreMBB);
803 ShouldSplit = ShouldSplit && !isLiveIn(Reg, &
MBB);
806 if (!ShouldSplit && CurLoop != PreLoop) {
808 dbgs() <<
"Split wouldn't help, maybe avoid loop copies?\n";
810 dbgs() <<
"PreLoop: " << *PreLoop;
812 dbgs() <<
"CurLoop: " << *CurLoop;
818 ShouldSplit = PreLoop && !PreLoop->
contains(CurLoop);
828 ++NumCriticalEdgesSplit;
836 "isLiveIn() requires either LiveVariables or LiveIntervals");
840 return LV->isLiveIn(Reg, *
MBB);
843bool PHIEliminationImpl::isLiveOutPastPHIs(
Register Reg,
846 "isLiveOutPastPHIs() requires either LiveVariables or LiveIntervals");
859 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)
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.
Represent the analysis usage information of a pass.
void recalculate(ParentType &Func)
recalculate - compute a dominator tree for the given function
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.
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()
MachineBasicBlock * SplitCriticalEdge(MachineBasicBlock *Succ, Pass &P, std::vector< SparseBitVector<> > *LiveInSets=nullptr)
Split the critical edge from this block to the given successor block, and return the newly created bl...
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...
MachineDominatorTree & getBase()
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.