diff options
| author | 2020-08-03 15:06:44 +0000 | |
|---|---|---|
| committer | 2020-08-03 15:06:44 +0000 | |
| commit | b64793999546ed8adebaeebd9d8345d18db8927d (patch) | |
| tree | 4357c27b561d73b0e089727c6ed659f2ceff5f47 /gnu/llvm/lib/CodeGen/RenameIndependentSubregs.cpp | |
| parent | Add support for UTF-8 DISPLAY-HINTs with octet length. For now only (diff) | |
| download | wireguard-openbsd-b64793999546ed8adebaeebd9d8345d18db8927d.tar.xz wireguard-openbsd-b64793999546ed8adebaeebd9d8345d18db8927d.zip | |
Remove LLVM 8.0.1 files.
Diffstat (limited to 'gnu/llvm/lib/CodeGen/RenameIndependentSubregs.cpp')
| -rw-r--r-- | gnu/llvm/lib/CodeGen/RenameIndependentSubregs.cpp | 405 |
1 files changed, 0 insertions, 405 deletions
diff --git a/gnu/llvm/lib/CodeGen/RenameIndependentSubregs.cpp b/gnu/llvm/lib/CodeGen/RenameIndependentSubregs.cpp deleted file mode 100644 index 156d1c81c23..00000000000 --- a/gnu/llvm/lib/CodeGen/RenameIndependentSubregs.cpp +++ /dev/null @@ -1,405 +0,0 @@ -//===-- RenameIndependentSubregs.cpp - Live Interval Analysis -------------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -/// Rename independent subregisters looks for virtual registers with -/// independently used subregisters and renames them to new virtual registers. -/// Example: In the following: -/// %0:sub0<read-undef> = ... -/// %0:sub1 = ... -/// use %0:sub0 -/// %0:sub0 = ... -/// use %0:sub0 -/// use %0:sub1 -/// sub0 and sub1 are never used together, and we have two independent sub0 -/// definitions. This pass will rename to: -/// %0:sub0<read-undef> = ... -/// %1:sub1<read-undef> = ... -/// use %1:sub1 -/// %2:sub1<read-undef> = ... -/// use %2:sub1 -/// use %0:sub0 -// -//===----------------------------------------------------------------------===// - -#include "LiveRangeUtils.h" -#include "PHIEliminationUtils.h" -#include "llvm/CodeGen/LiveInterval.h" -#include "llvm/CodeGen/LiveIntervals.h" -#include "llvm/CodeGen/MachineFunctionPass.h" -#include "llvm/CodeGen/MachineInstrBuilder.h" -#include "llvm/CodeGen/MachineRegisterInfo.h" -#include "llvm/CodeGen/Passes.h" -#include "llvm/CodeGen/TargetInstrInfo.h" - -using namespace llvm; - -#define DEBUG_TYPE "rename-independent-subregs" - -namespace { - -class RenameIndependentSubregs : public MachineFunctionPass { -public: - static char ID; - RenameIndependentSubregs() : MachineFunctionPass(ID) {} - - StringRef getPassName() const override { - return "Rename Disconnected Subregister Components"; - } - - void getAnalysisUsage(AnalysisUsage &AU) const override { - AU.setPreservesCFG(); - AU.addRequired<LiveIntervals>(); - AU.addPreserved<LiveIntervals>(); - AU.addRequired<SlotIndexes>(); - AU.addPreserved<SlotIndexes>(); - MachineFunctionPass::getAnalysisUsage(AU); - } - - bool runOnMachineFunction(MachineFunction &MF) override; - -private: - struct SubRangeInfo { - ConnectedVNInfoEqClasses ConEQ; - LiveInterval::SubRange *SR; - unsigned Index; - - SubRangeInfo(LiveIntervals &LIS, LiveInterval::SubRange &SR, - unsigned Index) - : ConEQ(LIS), SR(&SR), Index(Index) {} - }; - - /// Split unrelated subregister components and rename them to new vregs. - bool renameComponents(LiveInterval &LI) const; - - /// Build a vector of SubRange infos and a union find set of - /// equivalence classes. - /// Returns true if more than 1 equivalence class was found. - bool findComponents(IntEqClasses &Classes, - SmallVectorImpl<SubRangeInfo> &SubRangeInfos, - LiveInterval &LI) const; - - /// Distribute the LiveInterval segments into the new LiveIntervals - /// belonging to their class. - void distribute(const IntEqClasses &Classes, - const SmallVectorImpl<SubRangeInfo> &SubRangeInfos, - const SmallVectorImpl<LiveInterval*> &Intervals) const; - - /// Constructs main liverange and add missing undef+dead flags. - void computeMainRangesFixFlags(const IntEqClasses &Classes, - const SmallVectorImpl<SubRangeInfo> &SubRangeInfos, - const SmallVectorImpl<LiveInterval*> &Intervals) const; - - /// Rewrite Machine Operands to use the new vreg belonging to their class. - void rewriteOperands(const IntEqClasses &Classes, - const SmallVectorImpl<SubRangeInfo> &SubRangeInfos, - const SmallVectorImpl<LiveInterval*> &Intervals) const; - - - LiveIntervals *LIS; - MachineRegisterInfo *MRI; - const TargetInstrInfo *TII; -}; - -} // end anonymous namespace - -char RenameIndependentSubregs::ID; - -char &llvm::RenameIndependentSubregsID = RenameIndependentSubregs::ID; - -INITIALIZE_PASS_BEGIN(RenameIndependentSubregs, DEBUG_TYPE, - "Rename Independent Subregisters", false, false) -INITIALIZE_PASS_DEPENDENCY(SlotIndexes) -INITIALIZE_PASS_DEPENDENCY(LiveIntervals) -INITIALIZE_PASS_END(RenameIndependentSubregs, DEBUG_TYPE, - "Rename Independent Subregisters", false, false) - -bool RenameIndependentSubregs::renameComponents(LiveInterval &LI) const { - // Shortcut: We cannot have split components with a single definition. - if (LI.valnos.size() < 2) - return false; - - SmallVector<SubRangeInfo, 4> SubRangeInfos; - IntEqClasses Classes; - if (!findComponents(Classes, SubRangeInfos, LI)) - return false; - - // Create a new VReg for each class. - unsigned Reg = LI.reg; - const TargetRegisterClass *RegClass = MRI->getRegClass(Reg); - SmallVector<LiveInterval*, 4> Intervals; - Intervals.push_back(&LI); - LLVM_DEBUG(dbgs() << printReg(Reg) << ": Found " << Classes.getNumClasses() - << " equivalence classes.\n"); - LLVM_DEBUG(dbgs() << printReg(Reg) << ": Splitting into newly created:"); - for (unsigned I = 1, NumClasses = Classes.getNumClasses(); I < NumClasses; - ++I) { - unsigned NewVReg = MRI->createVirtualRegister(RegClass); - LiveInterval &NewLI = LIS->createEmptyInterval(NewVReg); - Intervals.push_back(&NewLI); - LLVM_DEBUG(dbgs() << ' ' << printReg(NewVReg)); - } - LLVM_DEBUG(dbgs() << '\n'); - - rewriteOperands(Classes, SubRangeInfos, Intervals); - distribute(Classes, SubRangeInfos, Intervals); - computeMainRangesFixFlags(Classes, SubRangeInfos, Intervals); - return true; -} - -bool RenameIndependentSubregs::findComponents(IntEqClasses &Classes, - SmallVectorImpl<RenameIndependentSubregs::SubRangeInfo> &SubRangeInfos, - LiveInterval &LI) const { - // First step: Create connected components for the VNInfos inside the - // subranges and count the global number of such components. - unsigned NumComponents = 0; - for (LiveInterval::SubRange &SR : LI.subranges()) { - SubRangeInfos.push_back(SubRangeInfo(*LIS, SR, NumComponents)); - ConnectedVNInfoEqClasses &ConEQ = SubRangeInfos.back().ConEQ; - - unsigned NumSubComponents = ConEQ.Classify(SR); - NumComponents += NumSubComponents; - } - // Shortcut: With only 1 subrange, the normal separate component tests are - // enough and we do not need to perform the union-find on the subregister - // segments. - if (SubRangeInfos.size() < 2) - return false; - - // Next step: Build union-find structure over all subranges and merge classes - // across subranges when they are affected by the same MachineOperand. - const TargetRegisterInfo &TRI = *MRI->getTargetRegisterInfo(); - Classes.grow(NumComponents); - unsigned Reg = LI.reg; - for (const MachineOperand &MO : MRI->reg_nodbg_operands(Reg)) { - if (!MO.isDef() && !MO.readsReg()) - continue; - unsigned SubRegIdx = MO.getSubReg(); - LaneBitmask LaneMask = TRI.getSubRegIndexLaneMask(SubRegIdx); - unsigned MergedID = ~0u; - for (RenameIndependentSubregs::SubRangeInfo &SRInfo : SubRangeInfos) { - const LiveInterval::SubRange &SR = *SRInfo.SR; - if ((SR.LaneMask & LaneMask).none()) - continue; - SlotIndex Pos = LIS->getInstructionIndex(*MO.getParent()); - Pos = MO.isDef() ? Pos.getRegSlot(MO.isEarlyClobber()) - : Pos.getBaseIndex(); - const VNInfo *VNI = SR.getVNInfoAt(Pos); - if (VNI == nullptr) - continue; - - // Map to local representant ID. - unsigned LocalID = SRInfo.ConEQ.getEqClass(VNI); - // Global ID - unsigned ID = LocalID + SRInfo.Index; - // Merge other sets - MergedID = MergedID == ~0u ? ID : Classes.join(MergedID, ID); - } - } - - // Early exit if we ended up with a single equivalence class. - Classes.compress(); - unsigned NumClasses = Classes.getNumClasses(); - return NumClasses > 1; -} - -void RenameIndependentSubregs::rewriteOperands(const IntEqClasses &Classes, - const SmallVectorImpl<SubRangeInfo> &SubRangeInfos, - const SmallVectorImpl<LiveInterval*> &Intervals) const { - const TargetRegisterInfo &TRI = *MRI->getTargetRegisterInfo(); - unsigned Reg = Intervals[0]->reg; - for (MachineRegisterInfo::reg_nodbg_iterator I = MRI->reg_nodbg_begin(Reg), - E = MRI->reg_nodbg_end(); I != E; ) { - MachineOperand &MO = *I++; - if (!MO.isDef() && !MO.readsReg()) - continue; - - auto *MI = MO.getParent(); - SlotIndex Pos = LIS->getInstructionIndex(*MI); - Pos = MO.isDef() ? Pos.getRegSlot(MO.isEarlyClobber()) - : Pos.getBaseIndex(); - unsigned SubRegIdx = MO.getSubReg(); - LaneBitmask LaneMask = TRI.getSubRegIndexLaneMask(SubRegIdx); - - unsigned ID = ~0u; - for (const SubRangeInfo &SRInfo : SubRangeInfos) { - const LiveInterval::SubRange &SR = *SRInfo.SR; - if ((SR.LaneMask & LaneMask).none()) - continue; - const VNInfo *VNI = SR.getVNInfoAt(Pos); - if (VNI == nullptr) - continue; - - // Map to local representant ID. - unsigned LocalID = SRInfo.ConEQ.getEqClass(VNI); - // Global ID - ID = Classes[LocalID + SRInfo.Index]; - break; - } - - unsigned VReg = Intervals[ID]->reg; - MO.setReg(VReg); - - if (MO.isTied() && Reg != VReg) { - /// Undef use operands are not tracked in the equivalence class, - /// but need to be updated if they are tied; take care to only - /// update the tied operand. - unsigned OperandNo = MI->getOperandNo(&MO); - unsigned TiedIdx = MI->findTiedOperandIdx(OperandNo); - MI->getOperand(TiedIdx).setReg(VReg); - - // above substitution breaks the iterator, so restart. - I = MRI->reg_nodbg_begin(Reg); - } - } - // TODO: We could attempt to recompute new register classes while visiting - // the operands: Some of the split register may be fine with less constraint - // classes than the original vreg. -} - -void RenameIndependentSubregs::distribute(const IntEqClasses &Classes, - const SmallVectorImpl<SubRangeInfo> &SubRangeInfos, - const SmallVectorImpl<LiveInterval*> &Intervals) const { - unsigned NumClasses = Classes.getNumClasses(); - SmallVector<unsigned, 8> VNIMapping; - SmallVector<LiveInterval::SubRange*, 8> SubRanges; - BumpPtrAllocator &Allocator = LIS->getVNInfoAllocator(); - for (const SubRangeInfo &SRInfo : SubRangeInfos) { - LiveInterval::SubRange &SR = *SRInfo.SR; - unsigned NumValNos = SR.valnos.size(); - VNIMapping.clear(); - VNIMapping.reserve(NumValNos); - SubRanges.clear(); - SubRanges.resize(NumClasses-1, nullptr); - for (unsigned I = 0; I < NumValNos; ++I) { - const VNInfo &VNI = *SR.valnos[I]; - unsigned LocalID = SRInfo.ConEQ.getEqClass(&VNI); - unsigned ID = Classes[LocalID + SRInfo.Index]; - VNIMapping.push_back(ID); - if (ID > 0 && SubRanges[ID-1] == nullptr) - SubRanges[ID-1] = Intervals[ID]->createSubRange(Allocator, SR.LaneMask); - } - DistributeRange(SR, SubRanges.data(), VNIMapping); - } -} - -static bool subRangeLiveAt(const LiveInterval &LI, SlotIndex Pos) { - for (const LiveInterval::SubRange &SR : LI.subranges()) { - if (SR.liveAt(Pos)) - return true; - } - return false; -} - -void RenameIndependentSubregs::computeMainRangesFixFlags( - const IntEqClasses &Classes, - const SmallVectorImpl<SubRangeInfo> &SubRangeInfos, - const SmallVectorImpl<LiveInterval*> &Intervals) const { - BumpPtrAllocator &Allocator = LIS->getVNInfoAllocator(); - const SlotIndexes &Indexes = *LIS->getSlotIndexes(); - for (size_t I = 0, E = Intervals.size(); I < E; ++I) { - LiveInterval &LI = *Intervals[I]; - unsigned Reg = LI.reg; - - LI.removeEmptySubRanges(); - - // There must be a def (or live-in) before every use. Splitting vregs may - // violate this principle as the splitted vreg may not have a definition on - // every path. Fix this by creating IMPLICIT_DEF instruction as necessary. - for (const LiveInterval::SubRange &SR : LI.subranges()) { - // Search for "PHI" value numbers in the subranges. We must find a live - // value in each predecessor block, add an IMPLICIT_DEF where it is - // missing. - for (unsigned I = 0; I < SR.valnos.size(); ++I) { - const VNInfo &VNI = *SR.valnos[I]; - if (VNI.isUnused() || !VNI.isPHIDef()) - continue; - - SlotIndex Def = VNI.def; - MachineBasicBlock &MBB = *Indexes.getMBBFromIndex(Def); - for (MachineBasicBlock *PredMBB : MBB.predecessors()) { - SlotIndex PredEnd = Indexes.getMBBEndIdx(PredMBB); - if (subRangeLiveAt(LI, PredEnd.getPrevSlot())) - continue; - - MachineBasicBlock::iterator InsertPos = - llvm::findPHICopyInsertPoint(PredMBB, &MBB, Reg); - const MCInstrDesc &MCDesc = TII->get(TargetOpcode::IMPLICIT_DEF); - MachineInstrBuilder ImpDef = BuildMI(*PredMBB, InsertPos, - DebugLoc(), MCDesc, Reg); - SlotIndex DefIdx = LIS->InsertMachineInstrInMaps(*ImpDef); - SlotIndex RegDefIdx = DefIdx.getRegSlot(); - for (LiveInterval::SubRange &SR : LI.subranges()) { - VNInfo *SRVNI = SR.getNextValue(RegDefIdx, Allocator); - SR.addSegment(LiveRange::Segment(RegDefIdx, PredEnd, SRVNI)); - } - } - } - } - - for (MachineOperand &MO : MRI->reg_nodbg_operands(Reg)) { - if (!MO.isDef()) - continue; - unsigned SubRegIdx = MO.getSubReg(); - if (SubRegIdx == 0) - continue; - // After assigning the new vreg we may not have any other sublanes living - // in and out of the instruction anymore. We need to add new dead and - // undef flags in these cases. - if (!MO.isUndef()) { - SlotIndex Pos = LIS->getInstructionIndex(*MO.getParent()); - if (!subRangeLiveAt(LI, Pos)) - MO.setIsUndef(); - } - if (!MO.isDead()) { - SlotIndex Pos = LIS->getInstructionIndex(*MO.getParent()).getDeadSlot(); - if (!subRangeLiveAt(LI, Pos)) - MO.setIsDead(); - } - } - - if (I == 0) - LI.clear(); - LIS->constructMainRangeFromSubranges(LI); - // A def of a subregister may be a use of other register lanes. Replacing - // such a def with a def of a different register will eliminate the use, - // and may cause the recorded live range to be larger than the actual - // liveness in the program IR. - LIS->shrinkToUses(&LI); - } -} - -bool RenameIndependentSubregs::runOnMachineFunction(MachineFunction &MF) { - // Skip renaming if liveness of subregister is not tracked. - MRI = &MF.getRegInfo(); - if (!MRI->subRegLivenessEnabled()) - return false; - - LLVM_DEBUG(dbgs() << "Renaming independent subregister live ranges in " - << MF.getName() << '\n'); - - LIS = &getAnalysis<LiveIntervals>(); - TII = MF.getSubtarget().getInstrInfo(); - - // Iterate over all vregs. Note that we query getNumVirtRegs() the newly - // created vregs end up with higher numbers but do not need to be visited as - // there can't be any further splitting. - bool Changed = false; - for (size_t I = 0, E = MRI->getNumVirtRegs(); I < E; ++I) { - unsigned Reg = TargetRegisterInfo::index2VirtReg(I); - if (!LIS->hasInterval(Reg)) - continue; - LiveInterval &LI = LIS->getInterval(Reg); - if (!LI.hasSubRanges()) - continue; - - Changed |= renameComponents(LI); - } - - return Changed; -} |
