diff options
| author | robot-piglet <[email protected]> | 2025-03-05 13:38:11 +0300 |
|---|---|---|
| committer | robot-piglet <[email protected]> | 2025-03-05 13:49:53 +0300 |
| commit | 9eed360f02de773a5ed2de5d2a3e81fc7f06acfa (patch) | |
| tree | 744a4054e64eb443073c7c6ad36b29cedcf9c2e6 /contrib/libs/llvm14/lib/CodeGen/PHIElimination.cpp | |
| parent | c141a5c40bda2eed1a68b0626ffdae5fd19359a6 (diff) | |
Intermediate changes
commit_hash:2ec2671384dd8e604d41bc5c52c2f7858e4afea6
Diffstat (limited to 'contrib/libs/llvm14/lib/CodeGen/PHIElimination.cpp')
| -rw-r--r-- | contrib/libs/llvm14/lib/CodeGen/PHIElimination.cpp | 761 |
1 files changed, 0 insertions, 761 deletions
diff --git a/contrib/libs/llvm14/lib/CodeGen/PHIElimination.cpp b/contrib/libs/llvm14/lib/CodeGen/PHIElimination.cpp deleted file mode 100644 index 7693ab417de..00000000000 --- a/contrib/libs/llvm14/lib/CodeGen/PHIElimination.cpp +++ /dev/null @@ -1,761 +0,0 @@ -//===- PhiElimination.cpp - Eliminate PHI nodes by inserting copies -------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// -// -// This pass eliminates machine instruction PHI nodes by inserting copy -// instructions. This destroys SSA information, but is the desired input for -// some register allocators. -// -//===----------------------------------------------------------------------===// - -#include "PHIEliminationUtils.h" -#include "llvm/ADT/DenseMap.h" -#include "llvm/ADT/SmallPtrSet.h" -#include "llvm/ADT/Statistic.h" -#include "llvm/Analysis/LoopInfo.h" -#include "llvm/CodeGen/LiveInterval.h" -#include "llvm/CodeGen/LiveIntervals.h" -#include "llvm/CodeGen/LiveVariables.h" -#include "llvm/CodeGen/MachineBasicBlock.h" -#include "llvm/CodeGen/MachineDominators.h" -#include "llvm/CodeGen/MachineFunction.h" -#include "llvm/CodeGen/MachineFunctionPass.h" -#include "llvm/CodeGen/MachineInstr.h" -#include "llvm/CodeGen/MachineInstrBuilder.h" -#include "llvm/CodeGen/MachineLoopInfo.h" -#include "llvm/CodeGen/MachineOperand.h" -#include "llvm/CodeGen/MachineRegisterInfo.h" -#include "llvm/CodeGen/SlotIndexes.h" -#include "llvm/CodeGen/TargetInstrInfo.h" -#include "llvm/CodeGen/TargetLowering.h" -#include "llvm/CodeGen/TargetOpcodes.h" -#include "llvm/CodeGen/TargetPassConfig.h" -#include "llvm/CodeGen/TargetRegisterInfo.h" -#include "llvm/CodeGen/TargetSubtargetInfo.h" -#include "llvm/Pass.h" -#include "llvm/Support/CommandLine.h" -#include "llvm/Support/Debug.h" -#include "llvm/Support/raw_ostream.h" -#include <cassert> -#include <iterator> -#include <utility> - -using namespace llvm; - -#define DEBUG_TYPE "phi-node-elimination" - -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")); - -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.")); - -namespace { - - class PHIElimination : public MachineFunctionPass { - MachineRegisterInfo *MRI; // Machine register information - LiveVariables *LV; - LiveIntervals *LIS; - - public: - static char ID; // Pass identification, replacement for typeid - - PHIElimination() : MachineFunctionPass(ID) { - initializePHIEliminationPass(*PassRegistry::getPassRegistry()); - } - - bool runOnMachineFunction(MachineFunction &MF) override; - void getAnalysisUsage(AnalysisUsage &AU) const override; - - private: - /// EliminatePHINodes - Eliminate phi nodes by inserting copy instructions - /// in predecessor basic blocks. - bool EliminatePHINodes(MachineFunction &MF, MachineBasicBlock &MBB); - - void LowerPHINode(MachineBasicBlock &MBB, - MachineBasicBlock::iterator LastPHIIt); - - /// analyzePHINodes - Gather information about the PHI nodes in - /// here. In particular, we want to map the number of uses of a virtual - /// register which is used in a PHI node. We map that to the BB the - /// vreg is coming from. This is used later to determine when the vreg - /// is killed in the BB. - void analyzePHINodes(const MachineFunction& MF); - - /// Split critical edges where necessary for good coalescer performance. - bool SplitPHIEdges(MachineFunction &MF, MachineBasicBlock &MBB, - MachineLoopInfo *MLI, - std::vector<SparseBitVector<>> *LiveInSets); - - // These functions are temporary abstractions around LiveVariables and - // LiveIntervals, so they can go away when LiveVariables does. - bool isLiveIn(Register Reg, const MachineBasicBlock *MBB); - bool isLiveOutPastPHIs(Register Reg, const MachineBasicBlock *MBB); - - using BBVRegPair = std::pair<unsigned, Register>; - using VRegPHIUse = DenseMap<BBVRegPair, unsigned>; - - // Count the number of non-undef PHI uses of each register in each BB. - VRegPHIUse VRegPHIUseCount; - - // Defs of PHI sources which are implicit_def. - SmallPtrSet<MachineInstr*, 4> ImpDefs; - - // Map reusable lowered PHI node -> incoming join register. - using LoweredPHIMap = - DenseMap<MachineInstr*, unsigned, MachineInstrExpressionTrait>; - LoweredPHIMap LoweredPHIs; - }; - -} // end anonymous namespace - -STATISTIC(NumLowered, "Number of phis lowered"); -STATISTIC(NumCriticalEdgesSplit, "Number of critical edges split"); -STATISTIC(NumReused, "Number of reused lowered phis"); - -char PHIElimination::ID = 0; - -char& llvm::PHIEliminationID = PHIElimination::ID; - -INITIALIZE_PASS_BEGIN(PHIElimination, DEBUG_TYPE, - "Eliminate PHI nodes for register allocation", - false, false) -INITIALIZE_PASS_DEPENDENCY(LiveVariables) -INITIALIZE_PASS_END(PHIElimination, DEBUG_TYPE, - "Eliminate PHI nodes for register allocation", false, false) - -void PHIElimination::getAnalysisUsage(AnalysisUsage &AU) const { - AU.addUsedIfAvailable<LiveVariables>(); - AU.addPreserved<LiveVariables>(); - AU.addPreserved<SlotIndexes>(); - AU.addPreserved<LiveIntervals>(); - AU.addPreserved<MachineDominatorTree>(); - AU.addPreserved<MachineLoopInfo>(); - MachineFunctionPass::getAnalysisUsage(AU); -} - -bool PHIElimination::runOnMachineFunction(MachineFunction &MF) { - MRI = &MF.getRegInfo(); - LV = getAnalysisIfAvailable<LiveVariables>(); - LIS = getAnalysisIfAvailable<LiveIntervals>(); - - bool Changed = false; - - // Split critical edges to help the coalescer. - if (!DisableEdgeSplitting && (LV || LIS)) { - // A set of live-in regs for each MBB which is used to update LV - // efficiently also with large functions. - std::vector<SparseBitVector<>> LiveInSets; - if (LV) { - LiveInSets.resize(MF.size()); - for (unsigned Index = 0, e = MRI->getNumVirtRegs(); Index != e; ++Index) { - // Set the bit for this register for each MBB where it is - // live-through or live-in (killed). - unsigned VirtReg = Register::index2VirtReg(Index); - MachineInstr *DefMI = MRI->getVRegDef(VirtReg); - if (!DefMI) - continue; - LiveVariables::VarInfo &VI = LV->getVarInfo(VirtReg); - SparseBitVector<>::iterator AliveBlockItr = VI.AliveBlocks.begin(); - SparseBitVector<>::iterator EndItr = VI.AliveBlocks.end(); - while (AliveBlockItr != EndItr) { - unsigned BlockNum = *(AliveBlockItr++); - LiveInSets[BlockNum].set(Index); - } - // The register is live into an MBB in which it is killed but not - // defined. See comment for VarInfo in LiveVariables.h. - MachineBasicBlock *DefMBB = DefMI->getParent(); - if (VI.Kills.size() > 1 || - (!VI.Kills.empty() && VI.Kills.front()->getParent() != DefMBB)) - for (auto *MI : VI.Kills) - LiveInSets[MI->getParent()->getNumber()].set(Index); - } - } - - MachineLoopInfo *MLI = getAnalysisIfAvailable<MachineLoopInfo>(); - for (auto &MBB : MF) - Changed |= SplitPHIEdges(MF, MBB, MLI, (LV ? &LiveInSets : nullptr)); - } - - // This pass takes the function out of SSA form. - MRI->leaveSSA(); - - // Populate VRegPHIUseCount - analyzePHINodes(MF); - - // Eliminate PHI instructions by inserting copies into predecessor blocks. - for (auto &MBB : MF) - Changed |= EliminatePHINodes(MF, MBB); - - // Remove dead IMPLICIT_DEF instructions. - for (MachineInstr *DefMI : ImpDefs) { - Register DefReg = DefMI->getOperand(0).getReg(); - if (MRI->use_nodbg_empty(DefReg)) { - if (LIS) - LIS->RemoveMachineInstrFromMaps(*DefMI); - DefMI->eraseFromParent(); - } - } - - // Clean up the lowered PHI instructions. - for (auto &I : LoweredPHIs) { - if (LIS) - LIS->RemoveMachineInstrFromMaps(*I.first); - MF.deleteMachineInstr(I.first); - } - - // TODO: we should use the incremental DomTree updater here. - if (Changed) - if (auto *MDT = getAnalysisIfAvailable<MachineDominatorTree>()) - MDT->getBase().recalculate(MF); - - LoweredPHIs.clear(); - ImpDefs.clear(); - VRegPHIUseCount.clear(); - - MF.getProperties().set(MachineFunctionProperties::Property::NoPHIs); - - return Changed; -} - -/// EliminatePHINodes - Eliminate phi nodes by inserting copy instructions in -/// predecessor basic blocks. -bool PHIElimination::EliminatePHINodes(MachineFunction &MF, - MachineBasicBlock &MBB) { - if (MBB.empty() || !MBB.front().isPHI()) - return false; // Quick exit for basic blocks without PHIs. - - // Get an iterator to the last PHI node. - MachineBasicBlock::iterator LastPHIIt = - std::prev(MBB.SkipPHIsAndLabels(MBB.begin())); - - while (MBB.front().isPHI()) - LowerPHINode(MBB, LastPHIIt); - - return true; -} - -/// Return true if all defs of VirtReg are implicit-defs. -/// This includes registers with no defs. -static bool isImplicitlyDefined(unsigned VirtReg, - const MachineRegisterInfo &MRI) { - for (MachineInstr &DI : MRI.def_instructions(VirtReg)) - if (!DI.isImplicitDef()) - return false; - return true; -} - -/// Return true if all sources of the phi node are implicit_def's, or undef's. -static bool allPhiOperandsUndefined(const MachineInstr &MPhi, - const MachineRegisterInfo &MRI) { - for (unsigned I = 1, E = MPhi.getNumOperands(); I != E; I += 2) { - const MachineOperand &MO = MPhi.getOperand(I); - if (!isImplicitlyDefined(MO.getReg(), MRI) && !MO.isUndef()) - return false; - } - return true; -} -/// LowerPHINode - Lower the PHI node at the top of the specified block. -void PHIElimination::LowerPHINode(MachineBasicBlock &MBB, - MachineBasicBlock::iterator LastPHIIt) { - ++NumLowered; - - MachineBasicBlock::iterator AfterPHIsIt = std::next(LastPHIIt); - - // Unlink the PHI node from the basic block, but don't delete the PHI yet. - MachineInstr *MPhi = MBB.remove(&*MBB.begin()); - - unsigned NumSrcs = (MPhi->getNumOperands() - 1) / 2; - Register DestReg = MPhi->getOperand(0).getReg(); - assert(MPhi->getOperand(0).getSubReg() == 0 && "Can't handle sub-reg PHIs"); - bool isDead = MPhi->getOperand(0).isDead(); - - // Create a new register for the incoming PHI arguments. - MachineFunction &MF = *MBB.getParent(); - unsigned IncomingReg = 0; - bool reusedIncoming = false; // Is IncomingReg reused from an earlier PHI? - - // Insert a register to register copy at the top of the current block (but - // after any remaining phi nodes) which copies the new incoming register - // into the phi node destination. - MachineInstr *PHICopy = nullptr; - const TargetInstrInfo *TII = MF.getSubtarget().getInstrInfo(); - if (allPhiOperandsUndefined(*MPhi, *MRI)) - // If all sources of a PHI node are implicit_def or undef uses, just emit an - // implicit_def instead of a copy. - PHICopy = BuildMI(MBB, AfterPHIsIt, MPhi->getDebugLoc(), - TII->get(TargetOpcode::IMPLICIT_DEF), DestReg); - else { - // Can we reuse an earlier PHI node? This only happens for critical edges, - // typically those created by tail duplication. - unsigned &entry = LoweredPHIs[MPhi]; - if (entry) { - // An identical PHI node was already lowered. Reuse the incoming register. - IncomingReg = entry; - reusedIncoming = true; - ++NumReused; - LLVM_DEBUG(dbgs() << "Reusing " << printReg(IncomingReg) << " for " - << *MPhi); - } else { - const TargetRegisterClass *RC = MF.getRegInfo().getRegClass(DestReg); - entry = IncomingReg = MF.getRegInfo().createVirtualRegister(RC); - } - // Give the target possiblity to handle special cases fallthrough otherwise - PHICopy = TII->createPHIDestinationCopy(MBB, AfterPHIsIt, MPhi->getDebugLoc(), - IncomingReg, DestReg); - } - - if (MPhi->peekDebugInstrNum()) { - // If referred to by debug-info, store where this PHI was. - MachineFunction *MF = MBB.getParent(); - unsigned ID = MPhi->peekDebugInstrNum(); - auto P = MachineFunction::DebugPHIRegallocPos(&MBB, IncomingReg, 0); - auto Res = MF->DebugPHIPositions.insert({ID, P}); - assert(Res.second); - (void)Res; - } - - // Update live variable information if there is any. - if (LV) { - if (IncomingReg) { - LiveVariables::VarInfo &VI = LV->getVarInfo(IncomingReg); - - // Increment use count of the newly created virtual register. - LV->setPHIJoin(IncomingReg); - - MachineInstr *OldKill = nullptr; - bool IsPHICopyAfterOldKill = false; - - if (reusedIncoming && (OldKill = VI.findKill(&MBB))) { - // Calculate whether the PHICopy is after the OldKill. - // In general, the PHICopy is inserted as the first non-phi instruction - // by default, so it's before the OldKill. But some Target hooks for - // createPHIDestinationCopy() may modify the default insert position of - // PHICopy. - for (auto I = MBB.SkipPHIsAndLabels(MBB.begin()), E = MBB.end(); - I != E; ++I) { - if (I == PHICopy) - break; - - if (I == OldKill) { - IsPHICopyAfterOldKill = true; - break; - } - } - } - - // When we are reusing the incoming register and it has been marked killed - // by OldKill, if the PHICopy is after the OldKill, we should remove the - // killed flag from OldKill. - if (IsPHICopyAfterOldKill) { - LLVM_DEBUG(dbgs() << "Remove old kill from " << *OldKill); - LV->removeVirtualRegisterKilled(IncomingReg, *OldKill); - LLVM_DEBUG(MBB.dump()); - } - - // Add information to LiveVariables to know that the first used incoming - // value or the resued incoming value whose PHICopy is after the OldKIll - // is killed. Note that because the value is defined in several places - // (once each for each incoming block), the "def" block and instruction - // fields for the VarInfo is not filled in. - if (!OldKill || IsPHICopyAfterOldKill) - LV->addVirtualRegisterKilled(IncomingReg, *PHICopy); - } - - // Since we are going to be deleting the PHI node, if it is the last use of - // any registers, or if the value itself is dead, we need to move this - // information over to the new copy we just inserted. - LV->removeVirtualRegistersKilled(*MPhi); - - // If the result is dead, update LV. - if (isDead) { - LV->addVirtualRegisterDead(DestReg, *PHICopy); - LV->removeVirtualRegisterDead(DestReg, *MPhi); - } - } - - // Update LiveIntervals for the new copy or implicit def. - if (LIS) { - SlotIndex DestCopyIndex = LIS->InsertMachineInstrInMaps(*PHICopy); - - SlotIndex MBBStartIndex = LIS->getMBBStartIdx(&MBB); - if (IncomingReg) { - // Add the region from the beginning of MBB to the copy instruction to - // IncomingReg's live interval. - LiveInterval &IncomingLI = LIS->createEmptyInterval(IncomingReg); - VNInfo *IncomingVNI = IncomingLI.getVNInfoAt(MBBStartIndex); - if (!IncomingVNI) - IncomingVNI = IncomingLI.getNextValue(MBBStartIndex, - LIS->getVNInfoAllocator()); - IncomingLI.addSegment(LiveInterval::Segment(MBBStartIndex, - DestCopyIndex.getRegSlot(), - IncomingVNI)); - } - - LiveInterval &DestLI = LIS->getInterval(DestReg); - assert(!DestLI.empty() && "PHIs should have nonempty LiveIntervals."); - if (DestLI.endIndex().isDead()) { - // A dead PHI's live range begins and ends at the start of the MBB, but - // the lowered copy, which will still be dead, needs to begin and end at - // the copy instruction. - VNInfo *OrigDestVNI = DestLI.getVNInfoAt(MBBStartIndex); - assert(OrigDestVNI && "PHI destination should be live at block entry."); - DestLI.removeSegment(MBBStartIndex, MBBStartIndex.getDeadSlot()); - DestLI.createDeadDef(DestCopyIndex.getRegSlot(), - LIS->getVNInfoAllocator()); - DestLI.removeValNo(OrigDestVNI); - } else { - // Otherwise, remove the region from the beginning of MBB to the copy - // instruction from DestReg's live interval. - DestLI.removeSegment(MBBStartIndex, DestCopyIndex.getRegSlot()); - VNInfo *DestVNI = DestLI.getVNInfoAt(DestCopyIndex.getRegSlot()); - assert(DestVNI && "PHI destination should be live at its definition."); - DestVNI->def = DestCopyIndex.getRegSlot(); - } - } - - // Adjust the VRegPHIUseCount map to account for the removal of this PHI node. - for (unsigned i = 1; i != MPhi->getNumOperands(); i += 2) { - if (!MPhi->getOperand(i).isUndef()) { - --VRegPHIUseCount[BBVRegPair( - MPhi->getOperand(i + 1).getMBB()->getNumber(), - MPhi->getOperand(i).getReg())]; - } - } - - // Now loop over all of the incoming arguments, changing them to copy into the - // IncomingReg register in the corresponding predecessor basic block. - SmallPtrSet<MachineBasicBlock*, 8> MBBsInsertedInto; - for (int i = NumSrcs - 1; i >= 0; --i) { - Register SrcReg = MPhi->getOperand(i * 2 + 1).getReg(); - unsigned SrcSubReg = MPhi->getOperand(i*2+1).getSubReg(); - bool SrcUndef = MPhi->getOperand(i*2+1).isUndef() || - isImplicitlyDefined(SrcReg, *MRI); - assert(Register::isVirtualRegister(SrcReg) && - "Machine PHI Operands must all be virtual registers!"); - - // Get the MachineBasicBlock equivalent of the BasicBlock that is the source - // path the PHI. - MachineBasicBlock &opBlock = *MPhi->getOperand(i*2+2).getMBB(); - - // Check to make sure we haven't already emitted the copy for this block. - // This can happen because PHI nodes may have multiple entries for the same - // basic block. - if (!MBBsInsertedInto.insert(&opBlock).second) - continue; // If the copy has already been emitted, we're done. - - MachineInstr *SrcRegDef = MRI->getVRegDef(SrcReg); - if (SrcRegDef && TII->isUnspillableTerminator(SrcRegDef)) { - assert(SrcRegDef->getOperand(0).isReg() && - SrcRegDef->getOperand(0).isDef() && - "Expected operand 0 to be a reg def!"); - // Now that the PHI's use has been removed (as the instruction was - // removed) there should be no other uses of the SrcReg. - assert(MRI->use_empty(SrcReg) && - "Expected a single use from UnspillableTerminator"); - SrcRegDef->getOperand(0).setReg(IncomingReg); - - // Update LiveVariables. - if (LV) { - LiveVariables::VarInfo &SrcVI = LV->getVarInfo(SrcReg); - LiveVariables::VarInfo &IncomingVI = LV->getVarInfo(IncomingReg); - IncomingVI.AliveBlocks = std::move(SrcVI.AliveBlocks); - SrcVI.AliveBlocks.clear(); - } - - continue; - } - - // Find a safe location to insert the copy, this may be the first terminator - // in the block (or end()). - MachineBasicBlock::iterator InsertPos = - findPHICopyInsertPoint(&opBlock, &MBB, SrcReg); - - // Insert the copy. - MachineInstr *NewSrcInstr = nullptr; - if (!reusedIncoming && IncomingReg) { - if (SrcUndef) { - // The source register is undefined, so there is no need for a real - // COPY, but we still need to ensure joint dominance by defs. - // Insert an IMPLICIT_DEF instruction. - NewSrcInstr = BuildMI(opBlock, InsertPos, MPhi->getDebugLoc(), - TII->get(TargetOpcode::IMPLICIT_DEF), - IncomingReg); - - // Clean up the old implicit-def, if there even was one. - if (MachineInstr *DefMI = MRI->getVRegDef(SrcReg)) - if (DefMI->isImplicitDef()) - ImpDefs.insert(DefMI); - } else { - // Delete the debug location, since the copy is inserted into a - // different basic block. - NewSrcInstr = TII->createPHISourceCopy(opBlock, InsertPos, nullptr, - SrcReg, SrcSubReg, IncomingReg); - } - } - - // We only need to update the LiveVariables kill of SrcReg if this was the - // last PHI use of SrcReg to be lowered on this CFG edge and it is not live - // out of the predecessor. We can also ignore undef sources. - if (LV && !SrcUndef && - !VRegPHIUseCount[BBVRegPair(opBlock.getNumber(), SrcReg)] && - !LV->isLiveOut(SrcReg, opBlock)) { - // We want to be able to insert a kill of the register if this PHI (aka, - // the copy we just inserted) is the last use of the source value. Live - // variable analysis conservatively handles this by saying that the value - // is live until the end of the block the PHI entry lives in. If the value - // really is dead at the PHI copy, there will be no successor blocks which - // have the value live-in. - - // Okay, if we now know that the value is not live out of the block, we - // can add a kill marker in this block saying that it kills the incoming - // value! - - // In our final twist, we have to decide which instruction kills the - // register. In most cases this is the copy, however, terminator - // instructions at the end of the block may also use the value. In this - // case, we should mark the last such terminator as being the killing - // block, not the copy. - MachineBasicBlock::iterator KillInst = opBlock.end(); - for (MachineBasicBlock::iterator Term = InsertPos; Term != opBlock.end(); - ++Term) { - if (Term->readsRegister(SrcReg)) - KillInst = Term; - } - - if (KillInst == opBlock.end()) { - // No terminator uses the register. - - if (reusedIncoming || !IncomingReg) { - // We may have to rewind a bit if we didn't insert a copy this time. - KillInst = InsertPos; - while (KillInst != opBlock.begin()) { - --KillInst; - if (KillInst->isDebugInstr()) - continue; - if (KillInst->readsRegister(SrcReg)) - break; - } - } else { - // We just inserted this copy. - KillInst = NewSrcInstr; - } - } - assert(KillInst->readsRegister(SrcReg) && "Cannot find kill instruction"); - - // Finally, mark it killed. - LV->addVirtualRegisterKilled(SrcReg, *KillInst); - - // This vreg no longer lives all of the way through opBlock. - unsigned opBlockNum = opBlock.getNumber(); - LV->getVarInfo(SrcReg).AliveBlocks.reset(opBlockNum); - } - - if (LIS) { - if (NewSrcInstr) { - LIS->InsertMachineInstrInMaps(*NewSrcInstr); - LIS->addSegmentToEndOfBlock(IncomingReg, *NewSrcInstr); - } - - if (!SrcUndef && - !VRegPHIUseCount[BBVRegPair(opBlock.getNumber(), SrcReg)]) { - LiveInterval &SrcLI = LIS->getInterval(SrcReg); - - bool isLiveOut = false; - for (MachineBasicBlock *Succ : opBlock.successors()) { - SlotIndex startIdx = LIS->getMBBStartIdx(Succ); - VNInfo *VNI = SrcLI.getVNInfoAt(startIdx); - - // Definitions by other PHIs are not truly live-in for our purposes. - if (VNI && VNI->def != startIdx) { - isLiveOut = true; - break; - } - } - - if (!isLiveOut) { - MachineBasicBlock::iterator KillInst = opBlock.end(); - for (MachineBasicBlock::iterator Term = InsertPos; - Term != opBlock.end(); ++Term) { - if (Term->readsRegister(SrcReg)) - KillInst = Term; - } - - if (KillInst == opBlock.end()) { - // No terminator uses the register. - - if (reusedIncoming || !IncomingReg) { - // We may have to rewind a bit if we didn't just insert a copy. - KillInst = InsertPos; - while (KillInst != opBlock.begin()) { - --KillInst; - if (KillInst->isDebugInstr()) - continue; - if (KillInst->readsRegister(SrcReg)) - break; - } - } else { - // We just inserted this copy. - KillInst = std::prev(InsertPos); - } - } - assert(KillInst->readsRegister(SrcReg) && - "Cannot find kill instruction"); - - SlotIndex LastUseIndex = LIS->getInstructionIndex(*KillInst); - SrcLI.removeSegment(LastUseIndex.getRegSlot(), - LIS->getMBBEndIdx(&opBlock)); - } - } - } - } - - // Really delete the PHI instruction now, if it is not in the LoweredPHIs map. - if (reusedIncoming || !IncomingReg) { - if (LIS) - LIS->RemoveMachineInstrFromMaps(*MPhi); - MF.deleteMachineInstr(MPhi); - } -} - -/// analyzePHINodes - Gather information about the PHI nodes in here. In -/// particular, we want to map the number of uses of a virtual register which is -/// used in a PHI node. We map that to the BB the vreg is coming from. This is -/// used later to determine when the vreg is killed in the BB. -void PHIElimination::analyzePHINodes(const MachineFunction& MF) { - for (const auto &MBB : MF) { - for (const auto &BBI : MBB) { - if (!BBI.isPHI()) - break; - for (unsigned i = 1, e = BBI.getNumOperands(); i != e; i += 2) { - if (!BBI.getOperand(i).isUndef()) { - ++VRegPHIUseCount[BBVRegPair( - BBI.getOperand(i + 1).getMBB()->getNumber(), - BBI.getOperand(i).getReg())]; - } - } - } - } -} - -bool PHIElimination::SplitPHIEdges(MachineFunction &MF, - MachineBasicBlock &MBB, - MachineLoopInfo *MLI, - std::vector<SparseBitVector<>> *LiveInSets) { - if (MBB.empty() || !MBB.front().isPHI() || MBB.isEHPad()) - return false; // Quick exit for basic blocks without PHIs. - - const MachineLoop *CurLoop = MLI ? MLI->getLoopFor(&MBB) : nullptr; - bool IsLoopHeader = CurLoop && &MBB == CurLoop->getHeader(); - - bool Changed = false; - for (MachineBasicBlock::iterator BBI = MBB.begin(), BBE = MBB.end(); - BBI != BBE && BBI->isPHI(); ++BBI) { - for (unsigned i = 1, e = BBI->getNumOperands(); i != e; i += 2) { - Register Reg = BBI->getOperand(i).getReg(); - MachineBasicBlock *PreMBB = BBI->getOperand(i+1).getMBB(); - // Is there a critical edge from PreMBB to MBB? - if (PreMBB->succ_size() == 1) - continue; - - // Avoid splitting backedges of loops. It would introduce small - // out-of-line blocks into the loop which is very bad for code placement. - if (PreMBB == &MBB && !SplitAllCriticalEdges) - continue; - const MachineLoop *PreLoop = MLI ? MLI->getLoopFor(PreMBB) : nullptr; - if (IsLoopHeader && PreLoop == CurLoop && !SplitAllCriticalEdges) - continue; - - // LV doesn't consider a phi use live-out, so isLiveOut only returns true - // when the source register is live-out for some other reason than a phi - // use. That means the copy we will insert in PreMBB won't be a kill, and - // there is a risk it may not be coalesced away. - // - // If the copy would be a kill, there is no need to split the edge. - bool ShouldSplit = isLiveOutPastPHIs(Reg, PreMBB); - if (!ShouldSplit && !NoPhiElimLiveOutEarlyExit) - continue; - if (ShouldSplit) { - LLVM_DEBUG(dbgs() << printReg(Reg) << " live-out before critical edge " - << printMBBReference(*PreMBB) << " -> " - << printMBBReference(MBB) << ": " << *BBI); - } - - // If Reg is not live-in to MBB, it means it must be live-in to some - // other PreMBB successor, and we can avoid the interference by splitting - // the edge. - // - // If Reg *is* live-in to MBB, the interference is inevitable and a copy - // is likely to be left after coalescing. If we are looking at a loop - // exiting edge, split it so we won't insert code in the loop, otherwise - // don't bother. - ShouldSplit = ShouldSplit && !isLiveIn(Reg, &MBB); - - // Check for a loop exiting edge. - if (!ShouldSplit && CurLoop != PreLoop) { - LLVM_DEBUG({ - dbgs() << "Split wouldn't help, maybe avoid loop copies?\n"; - if (PreLoop) - dbgs() << "PreLoop: " << *PreLoop; - if (CurLoop) - dbgs() << "CurLoop: " << *CurLoop; - }); - // This edge could be entering a loop, exiting a loop, or it could be - // both: Jumping directly form one loop to the header of a sibling - // loop. - // Split unless this edge is entering CurLoop from an outer loop. - ShouldSplit = PreLoop && !PreLoop->contains(CurLoop); - } - if (!ShouldSplit && !SplitAllCriticalEdges) - continue; - if (!PreMBB->SplitCriticalEdge(&MBB, *this, LiveInSets)) { - LLVM_DEBUG(dbgs() << "Failed to split critical edge.\n"); - continue; - } - Changed = true; - ++NumCriticalEdgesSplit; - } - } - return Changed; -} - -bool PHIElimination::isLiveIn(Register Reg, const MachineBasicBlock *MBB) { - assert((LV || LIS) && - "isLiveIn() requires either LiveVariables or LiveIntervals"); - if (LIS) - return LIS->isLiveInToMBB(LIS->getInterval(Reg), MBB); - else - return LV->isLiveIn(Reg, *MBB); -} - -bool PHIElimination::isLiveOutPastPHIs(Register Reg, - const MachineBasicBlock *MBB) { - assert((LV || LIS) && - "isLiveOutPastPHIs() requires either LiveVariables or LiveIntervals"); - // LiveVariables considers uses in PHIs to be in the predecessor basic block, - // so that a register used only in a PHI is not live out of the block. In - // contrast, LiveIntervals considers uses in PHIs to be on the edge rather than - // in the predecessor basic block, so that a register used only in a PHI is live - // out of the block. - if (LIS) { - const LiveInterval &LI = LIS->getInterval(Reg); - for (const MachineBasicBlock *SI : MBB->successors()) - if (LI.liveAt(LIS->getMBBStartIdx(SI))) - return true; - return false; - } else { - return LV->isLiveOut(Reg, *MBB); - } -} |
