54#define DEBUG_TYPE "phi-node-elimination"
59 cl::desc(
"Disable critical edge splitting "
60 "during PHI elimination"));
65 cl::desc(
"Split all critical edges during "
70 cl::desc(
"Do not use an early exit if isLiveOutPastPHIs returns true."));
74class PHIEliminationImpl {
90 bool AllEdgesCritical);
108 using BBVRegPair = std::pair<unsigned, Register>;
112 VRegPHIUse VRegPHIUseCount;
122 using LoweredPHIMap =
124 LoweredPHIMap LoweredPHIs;
128 std::vector<SparseBitVector<>> LiveOutSets;
144 SI = SIWrapper ? &SIWrapper->getSI() :
nullptr;
145 LIS = LISWrapper ? &LISWrapper->getLIS() :
nullptr;
146 MLI = MLIWrapper ? &MLIWrapper->getLI() :
nullptr;
147 MDT = MDTWrapper ? &MDTWrapper->getDomTree() :
nullptr;
148 PDT = PDTWrapper ? &PDTWrapper->getPostDomTree() :
nullptr;
149 MBPI = MBPIWrapper ? &MBPIWrapper->getMBPI() :
nullptr;
154 : SI(AM.getCachedResult<SlotIndexesAnalysis>(MF)),
155 LIS(AM.getCachedResult<LiveIntervalsAnalysis>(MF)),
156 MLI(AM.getCachedResult<MachineLoopAnalysis>(MF)),
157 MDT(AM.getCachedResult<MachineDominatorTreeAnalysis>(MF)),
158 PDT(AM.getCachedResult<MachinePostDominatorTreeAnalysis>(MF)),
159 MBPI(AM.getCachedResult<MachineBranchProbabilityAnalysis>(MF)),
160 MBFI(AM.getCachedResult<MachineBlockFrequencyAnalysis>(MF)) {}
169 PHIElimination() : MachineFunctionPass(ID) {}
172 PHIEliminationImpl Impl(
this);
176 MachineFunctionProperties getSetProperties()
const override {
177 return MachineFunctionProperties().setNoPHIs();
180 void getAnalysisUsage(AnalysisUsage &AU)
const override;
188 PHIEliminationImpl Impl(MF, MFAM);
203STATISTIC(NumCriticalEdgesSplit,
"Number of critical edges split");
206char PHIElimination::ID = 0;
211 "Eliminate PHI nodes for register allocation",
false,
220void PHIElimination::getAnalysisUsage(
AnalysisUsage &AU)
const {
238 MachineDomTreeUpdater::UpdateStrategy::Lazy);
264 SI->removeMachineInstrFromMaps(*
DefMI);
270 for (
auto &
I : LoweredPHIs) {
272 SI->removeMachineInstrFromMaps(*
I.first);
273 MF.deleteMachineInstr(
I.first);
287 PHISrcRegsToShrink.clear();
290 VRegPHIUseCount.clear();
292 MF.getProperties().setNoPHIs();
314 if (Pred->succ_size() < 2) {
315 AllEdgesCritical =
false;
321 LowerPHINode(
MBB, LastPHIIt, AllEdgesCritical);
331 if (!DI.isImplicitDef())
349 bool AllEdgesCritical) {
364 bool EliminateNow =
true;
365 bool reusedIncoming =
false;
376 TII->get(TargetOpcode::IMPLICIT_DEF), DestReg);
383 if (AllEdgesCritical)
384 Entry = &LoweredPHIs[MPhi];
385 if (Entry && *Entry) {
387 IncomingReg = *
Entry;
388 reusedIncoming =
true;
396 EliminateNow =
false;
397 *
Entry = IncomingReg;
402 PHICopy =
TII->createPHIDestinationCopy(
419 DestCopyIndex =
SI->insertMachineInstrInMaps(*PHICopy);
423 "Expected a valid SlotIndex if LIS is available.");
434 MBBStartIndex, DestCopyIndex.
getRegSlot(), IncomingVNI));
438 assert(!DestLI.
empty() &&
"PHIs should have non-empty LiveIntervals.");
451 for (
auto LR : ToUpdate) {
452 auto DestSegment = LR->find(MBBStartIndex);
453 assert(DestSegment != LR->end() &&
454 "PHI destination must be live in block");
456 if (LR->endIndex().isDead()) {
460 VNInfo *OrigDestVNI = LR->getVNInfoAt(DestSegment->start);
461 assert(OrigDestVNI &&
"PHI destination should be live at block entry.");
462 LR->removeSegment(DestSegment->start, DestSegment->start.getDeadSlot());
464 LR->removeValNo(OrigDestVNI);
471 if (DestSegment->start > NewStart) {
472 VNInfo *VNI = LR->getVNInfoAt(DestSegment->start);
473 assert(VNI &&
"value should be defined for known segment");
476 }
else if (DestSegment->start < NewStart) {
477 assert(DestSegment->start >= MBBStartIndex);
479 LR->removeSegment(DestSegment->start, NewStart);
481 VNInfo *DestVNI = LR->getVNInfoAt(NewStart);
482 assert(DestVNI &&
"PHI destination should be live at its definition.");
483 DestVNI->
def = NewStart;
491 --VRegPHIUseCount[BBVRegPair(
501 for (
int i = NumSrcs - 1; i >= 0; --i) {
507 "Machine PHI Operands must all be virtual registers!");
516 if (!MBBsInsertedInto.
insert(&opBlock).second)
520 if (SrcRegDef &&
TII->isUnspillableTerminator(SrcRegDef)) {
523 "Expected operand 0 to be a reg def!");
527 "Expected a single use from UnspillableTerminator");
551 if (!reusedIncoming && IncomingReg) {
558 TII->get(TargetOpcode::IMPLICIT_DEF), IncomingReg);
563 ImpDefs.insert(
DefMI);
567 NewSrcInstr =
TII->createPHISourceCopy(opBlock, InsertPos,
nullptr,
568 SrcReg, SrcSubReg, IncomingReg);
572 if (
SI && NewSrcInstr)
573 SI->insertMachineInstrInMaps(*NewSrcInstr);
579 "Expected SI to be available to insert new MI if LIS is available");
584 !VRegPHIUseCount[BBVRegPair(opBlock.
getNumber(), SrcReg)]) {
587 PHISrcRegsToShrink.insert(SrcReg);
595 if (VNI && VNI->
def != startIdx) {
605 if (
Term->readsRegister(SrcReg,
nullptr))
609 if (KillInst == opBlock.
end()) {
612 if (reusedIncoming || !IncomingReg) {
614 KillInst = InsertPos;
615 while (KillInst != opBlock.
begin()) {
617 if (KillInst->isDebugInstr())
619 if (KillInst->readsRegister(SrcReg,
nullptr))
624 KillInst = std::prev(InsertPos);
627 assert(KillInst->readsRegister(SrcReg,
nullptr) &&
628 "Cannot find kill instruction");
641 SI->removeMachineInstrFromMaps(*MPhi);
642 MF.deleteMachineInstr(MPhi);
651 for (
const auto &
MBB : MF) {
652 for (
const auto &BBI :
MBB) {
655 for (
unsigned i = 1, e = BBI.getNumOperands(); i != e; i += 2) {
656 if (!BBI.getOperand(i).isUndef()) {
657 ++VRegPHIUseCount[BBVRegPair(
658 BBI.getOperand(i + 1).getMBB()->getNumber(),
659 BBI.getOperand(i).getReg())];
674 bool IsLoopHeader = CurLoop && &
MBB == CurLoop->
getHeader();
678 BBI != BBE && BBI->isPHI(); ++BBI) {
679 for (
unsigned i = 1, e = BBI->getNumOperands(); i != e; i += 2) {
700 bool ShouldSplit = isLiveOutPastPHIs(
Reg, PreMBB);
717 ShouldSplit = ShouldSplit && !isLiveIn(
Reg, &
MBB);
720 if (!ShouldSplit && CurLoop != PreLoop) {
722 dbgs() <<
"Split wouldn't help, maybe avoid loop copies?\n";
724 dbgs() <<
"PreLoop: " << *PreLoop;
726 dbgs() <<
"CurLoop: " << *CurLoop;
732 ShouldSplit = PreLoop && !PreLoop->
contains(CurLoop);
736 if (LiveOutSets.empty())
737 computeLiveOutSets(MF);
752 ++NumCriticalEdgesSplit;
758void PHIEliminationImpl::computeLiveOutSets(
const MachineFunction &MF) {
760 for (
unsigned Idx = 0, NumVRegs = MRI->
getNumVirtRegs(); Idx != NumVRegs;
774 assert(LIS &&
"isLiveIn() requires LiveIntervals");
778bool PHIEliminationImpl::isLiveOutPastPHIs(
Register Reg,
780 assert(LIS &&
"isLiveOutPastPHIs() requires LiveIntervals");
MachineInstrBuilder MachineInstrBuilder & DefMI
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
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.
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(Register 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)
static bool isLiveOut(const MachineBasicBlock &MBB, unsigned Reg)
This file defines the SmallPtrSet class.
This file defines the SmallSet class.
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
Represent the analysis usage information of a pass.
A live range for subregisters.
LiveInterval - This class represents the liveness of a register, or stack slot.
bool hasSubRanges() const
Returns true if subregister liveness information is available.
iterator_range< subrange_iterator > subranges()
bool hasInterval(Register Reg) const
SlotIndex getMBBStartIdx(const MachineBasicBlock *mbb) const
Return the first index in the given basic block.
LiveInterval & getOrCreateEmptyInterval(Register Reg)
Return an existing interval for Reg.
SlotIndex getInstructionIndex(const MachineInstr &Instr) const
Returns the base index of the given instruction.
VNInfo::Allocator & getVNInfoAllocator()
SlotIndex getMBBEndIdx(const MachineBasicBlock *mbb) const
Return the last index in the given basic block.
LiveInterval & getInterval(Register Reg)
void removeInterval(Register Reg)
Interval removal.
LLVM_ABI 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.
LLVM_ABI bool shrinkToUses(LiveInterval *li, SmallVectorImpl< MachineInstr * > *dead=nullptr)
After removing some uses of a register, shrink its live range to just the remaining uses.
MachineBasicBlock * getMBBFromIndex(SlotIndex index) const
bool isLiveInToMBB(const LiveRange &LR, const MachineBasicBlock *mbb) const
LLVM_ABI iterator addSegment(Segment S)
Add the specified Segment to this range, merging segments as appropriate.
bool liveAt(SlotIndex index) const
SlotIndex endIndex() const
endNumber - return the maximum point of the range of the whole, exclusive.
VNInfo * getNextValue(SlotIndex Def, VNInfo::Allocator &VNInfoAllocator)
getNextValue - Create a new value number and return it.
LLVM_ABI 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 this loop.
BlockT * getHeader() const
LoopT * getLoopFor(const BlockT *BB) const
Return the inner most loop that BB lives in.
const MachineBlockFrequencyInfo & getMBFI() const
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...
LLVM_ABI 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.
MachineBasicBlock * SplitCriticalEdge(MachineBasicBlock *Succ, Pass &P, MachineDomTreeUpdater *MDTU=nullptr)
iterator_range< succ_iterator > successors()
iterator_range< pred_iterator > predecessors()
MachineInstrBundleIterator< MachineInstr > iterator
MachineBlockFrequencyInfo pass uses BlockFrequencyInfoImpl implementation to estimate machine basic b...
LLVM_ABI void onEdgeSplit(const MachineBasicBlock &NewPredecessor, const MachineBasicBlock &NewSuccessor, const MachineBranchProbabilityInfo &MBPI)
incrementally calculate block frequencies when we split edges, to avoid full CFG traversal.
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.
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.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
unsigned getNumBlockIDs() const
getNumBlockIDs - Return the number of MBB ID's allocated.
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
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.
const MachineOperand & getOperand(unsigned i) const
LLVM_ABI MachineInstrBundleIterator< MachineInstr > eraseFromParent()
Unlink 'this' from the containing basic block and delete it.
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 setIsDead(bool Val=true)
LLVM_ABI void setReg(Register Reg)
Change the register this operand corresponds to.
Register getReg() const
getReg - Returns the register number.
MachinePostDominatorTree - an analysis pass wrapper for DominatorTree used to compute the post-domina...
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.
LLVM_ABI LLVM_READONLY MachineInstr * getVRegDef(Register Reg) const
getVRegDef - Return the machine instr that defines the specified virtual register or null if none is ...
iterator_range< def_instr_iterator > def_instructions(Register Reg) const
bool use_nodbg_empty(Register RegNo) const
use_nodbg_empty - Return true if there are no non-Debug instructions using the specified register.
LLVM_ABI Register createVirtualRegister(const TargetRegisterClass *RegClass, StringRef Name="")
createVirtualRegister - Create and return a new virtual register in the function with the specified r...
unsigned getNumVirtRegs() const
getNumVirtRegs - Return the number of virtual registers created.
bool use_empty(Register RegNo) const
use_empty - Return true if there are no instructions using the specified register.
LLVM_ABI PreservedAnalyses run(MachineFunction &MF, MachineFunctionAnalysisManager &MFAM)
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.
bool isValid() const
Returns true if this is a valid index.
SlotIndex getRegSlot(bool EC=false) const
Returns the register use/def slot in the current instruction for a normal or early-clobber def.
bool isDead() const
isDead - Returns true if this is a dead def kill slot.
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...
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.
virtual const TargetInstrInfo * getInstrInfo() const
VNInfo - Value Number Information.
SlotIndex def
The index of the defining instruction.
NodeTy * getNextNode()
Get the next node, or nullptr for the list tail.
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.
AnalysisManager< MachineFunction > MachineFunctionAnalysisManager
LLVM_ABI PreservedAnalyses getMachineFunctionPassPreservedAnalyses()
Returns the minimum set of Analyses that all machine function passes must preserve.
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
MachineBasicBlock::iterator findPHICopyInsertPoint(MachineBasicBlock *MBB, MachineBasicBlock *SuccMBB, Register SrcReg)
findPHICopyInsertPoint - Find a safe place in MBB to insert a copy from SrcReg when following the CFG...
LLVM_ABI unsigned SplitAllCriticalEdges(Function &F, const CriticalEdgeSplittingOptions &Options=CriticalEdgeSplittingOptions())
Loop over all of the edges in the CFG, breaking critical edges as they are found.
LLVM_ABI char & PHIEliminationID
PHIElimination - This pass eliminates machine instruction PHI nodes by inserting copy instructions.
LLVM_ABI 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.
LLVM_ABI Printable printMBBReference(const MachineBasicBlock &MBB)
Prints a machine basic block reference.
MCRegisterClass TargetRegisterClass
This represents a simple continuous liveness interval for a value.