Home | History | Annotate | Download | only in CodeGen
      1 //===-- RenameIndependentSubregs.cpp - Live Interval Analysis -------------===//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 //
     10 /// Rename independent subregisters looks for virtual registers with
     11 /// independently used subregisters and renames them to new virtual registers.
     12 /// Example: In the following:
     13 ///   %vreg0:sub0<read-undef> = ...
     14 ///   %vreg0:sub1 = ...
     15 ///   use %vreg0:sub0
     16 ///   %vreg0:sub0 = ...
     17 ///   use %vreg0:sub0
     18 ///   use %vreg0:sub1
     19 /// sub0 and sub1 are never used together, and we have two independent sub0
     20 /// definitions. This pass will rename to:
     21 ///   %vreg0:sub0<read-undef> = ...
     22 ///   %vreg1:sub1<read-undef> = ...
     23 ///   use %vreg1:sub1
     24 ///   %vreg2:sub1<read-undef> = ...
     25 ///   use %vreg2:sub1
     26 ///   use %vreg0:sub0
     27 //
     28 //===----------------------------------------------------------------------===//
     29 
     30 #include "LiveRangeUtils.h"
     31 #include "PHIEliminationUtils.h"
     32 #include "llvm/CodeGen/LiveInterval.h"
     33 #include "llvm/CodeGen/LiveIntervalAnalysis.h"
     34 #include "llvm/CodeGen/MachineFunctionPass.h"
     35 #include "llvm/CodeGen/MachineRegisterInfo.h"
     36 #include "llvm/CodeGen/Passes.h"
     37 #include "llvm/Target/TargetInstrInfo.h"
     38 #include "llvm/CodeGen/MachineInstrBuilder.h"
     39 
     40 using namespace llvm;
     41 
     42 #define DEBUG_TYPE "rename-independent-subregs"
     43 
     44 namespace {
     45 
     46 class RenameIndependentSubregs : public MachineFunctionPass {
     47 public:
     48   static char ID;
     49   RenameIndependentSubregs() : MachineFunctionPass(ID) {}
     50 
     51   const char *getPassName() const override {
     52     return "Rename Disconnected Subregister Components";
     53   }
     54 
     55   void getAnalysisUsage(AnalysisUsage &AU) const override {
     56     AU.setPreservesCFG();
     57     AU.addRequired<LiveIntervals>();
     58     AU.addPreserved<LiveIntervals>();
     59     AU.addRequired<SlotIndexes>();
     60     AU.addPreserved<SlotIndexes>();
     61     MachineFunctionPass::getAnalysisUsage(AU);
     62   }
     63 
     64   bool runOnMachineFunction(MachineFunction &MF) override;
     65 
     66 private:
     67   struct SubRangeInfo {
     68     ConnectedVNInfoEqClasses ConEQ;
     69     LiveInterval::SubRange *SR;
     70     unsigned Index;
     71 
     72     SubRangeInfo(LiveIntervals &LIS, LiveInterval::SubRange &SR,
     73                  unsigned Index)
     74       : ConEQ(LIS), SR(&SR), Index(Index) {}
     75   };
     76 
     77   /// Split unrelated subregister components and rename them to new vregs.
     78   bool renameComponents(LiveInterval &LI) const;
     79 
     80   /// \brief Build a vector of SubRange infos and a union find set of
     81   /// equivalence classes.
     82   /// Returns true if more than 1 equivalence class was found.
     83   bool findComponents(IntEqClasses &Classes,
     84                       SmallVectorImpl<SubRangeInfo> &SubRangeInfos,
     85                       LiveInterval &LI) const;
     86 
     87   /// \brief Distribute the LiveInterval segments into the new LiveIntervals
     88   /// belonging to their class.
     89   void distribute(const IntEqClasses &Classes,
     90                   const SmallVectorImpl<SubRangeInfo> &SubRangeInfos,
     91                   const SmallVectorImpl<LiveInterval*> &Intervals) const;
     92 
     93   /// \brief Constructs main liverange and add missing undef+dead flags.
     94   void computeMainRangesFixFlags(const IntEqClasses &Classes,
     95       const SmallVectorImpl<SubRangeInfo> &SubRangeInfos,
     96       const SmallVectorImpl<LiveInterval*> &Intervals) const;
     97 
     98   /// Rewrite Machine Operands to use the new vreg belonging to their class.
     99   void rewriteOperands(const IntEqClasses &Classes,
    100                        const SmallVectorImpl<SubRangeInfo> &SubRangeInfos,
    101                        const SmallVectorImpl<LiveInterval*> &Intervals) const;
    102 
    103 
    104   LiveIntervals *LIS;
    105   MachineRegisterInfo *MRI;
    106   const TargetInstrInfo *TII;
    107 };
    108 
    109 } // end anonymous namespace
    110 
    111 char RenameIndependentSubregs::ID;
    112 
    113 char &llvm::RenameIndependentSubregsID = RenameIndependentSubregs::ID;
    114 
    115 INITIALIZE_PASS_BEGIN(RenameIndependentSubregs, "rename-independent-subregs",
    116                       "Rename Independent Subregisters", false, false)
    117 INITIALIZE_PASS_DEPENDENCY(SlotIndexes)
    118 INITIALIZE_PASS_DEPENDENCY(LiveIntervals)
    119 INITIALIZE_PASS_END(RenameIndependentSubregs, "rename-independent-subregs",
    120                     "Rename Independent Subregisters", false, false)
    121 
    122 bool RenameIndependentSubregs::renameComponents(LiveInterval &LI) const {
    123   // Shortcut: We cannot have split components with a single definition.
    124   if (LI.valnos.size() < 2)
    125     return false;
    126 
    127   SmallVector<SubRangeInfo, 4> SubRangeInfos;
    128   IntEqClasses Classes;
    129   if (!findComponents(Classes, SubRangeInfos, LI))
    130     return false;
    131 
    132   // Create a new VReg for each class.
    133   unsigned Reg = LI.reg;
    134   const TargetRegisterClass *RegClass = MRI->getRegClass(Reg);
    135   SmallVector<LiveInterval*, 4> Intervals;
    136   Intervals.push_back(&LI);
    137   DEBUG(dbgs() << PrintReg(Reg) << ": Found " << Classes.getNumClasses()
    138         << " equivalence classes.\n");
    139   DEBUG(dbgs() << PrintReg(Reg) << ": Splitting into newly created:");
    140   for (unsigned I = 1, NumClasses = Classes.getNumClasses(); I < NumClasses;
    141        ++I) {
    142     unsigned NewVReg = MRI->createVirtualRegister(RegClass);
    143     LiveInterval &NewLI = LIS->createEmptyInterval(NewVReg);
    144     Intervals.push_back(&NewLI);
    145     DEBUG(dbgs() << ' ' << PrintReg(NewVReg));
    146   }
    147   DEBUG(dbgs() << '\n');
    148 
    149   rewriteOperands(Classes, SubRangeInfos, Intervals);
    150   distribute(Classes, SubRangeInfos, Intervals);
    151   computeMainRangesFixFlags(Classes, SubRangeInfos, Intervals);
    152   return true;
    153 }
    154 
    155 bool RenameIndependentSubregs::findComponents(IntEqClasses &Classes,
    156     SmallVectorImpl<RenameIndependentSubregs::SubRangeInfo> &SubRangeInfos,
    157     LiveInterval &LI) const {
    158   // First step: Create connected components for the VNInfos inside the
    159   // subranges and count the global number of such components.
    160   unsigned NumComponents = 0;
    161   for (LiveInterval::SubRange &SR : LI.subranges()) {
    162     SubRangeInfos.push_back(SubRangeInfo(*LIS, SR, NumComponents));
    163     ConnectedVNInfoEqClasses &ConEQ = SubRangeInfos.back().ConEQ;
    164 
    165     unsigned NumSubComponents = ConEQ.Classify(SR);
    166     NumComponents += NumSubComponents;
    167   }
    168   // Shortcut: With only 1 subrange, the normal separate component tests are
    169   // enough and we do not need to perform the union-find on the subregister
    170   // segments.
    171   if (SubRangeInfos.size() < 2)
    172     return false;
    173 
    174   // Next step: Build union-find structure over all subranges and merge classes
    175   // across subranges when they are affected by the same MachineOperand.
    176   const TargetRegisterInfo &TRI = *MRI->getTargetRegisterInfo();
    177   Classes.grow(NumComponents);
    178   unsigned Reg = LI.reg;
    179   for (const MachineOperand &MO : MRI->reg_nodbg_operands(Reg)) {
    180     if (!MO.isDef() && !MO.readsReg())
    181       continue;
    182     unsigned SubRegIdx = MO.getSubReg();
    183     LaneBitmask LaneMask = TRI.getSubRegIndexLaneMask(SubRegIdx);
    184     unsigned MergedID = ~0u;
    185     for (RenameIndependentSubregs::SubRangeInfo &SRInfo : SubRangeInfos) {
    186       const LiveInterval::SubRange &SR = *SRInfo.SR;
    187       if ((SR.LaneMask & LaneMask) == 0)
    188         continue;
    189       SlotIndex Pos = LIS->getInstructionIndex(*MO.getParent());
    190       Pos = MO.isDef() ? Pos.getRegSlot(MO.isEarlyClobber())
    191                        : Pos.getBaseIndex();
    192       const VNInfo *VNI = SR.getVNInfoAt(Pos);
    193       if (VNI == nullptr)
    194         continue;
    195 
    196       // Map to local representant ID.
    197       unsigned LocalID = SRInfo.ConEQ.getEqClass(VNI);
    198       // Global ID
    199       unsigned ID = LocalID + SRInfo.Index;
    200       // Merge other sets
    201       MergedID = MergedID == ~0u ? ID : Classes.join(MergedID, ID);
    202     }
    203   }
    204 
    205   // Early exit if we ended up with a single equivalence class.
    206   Classes.compress();
    207   unsigned NumClasses = Classes.getNumClasses();
    208   return NumClasses > 1;
    209 }
    210 
    211 void RenameIndependentSubregs::rewriteOperands(const IntEqClasses &Classes,
    212     const SmallVectorImpl<SubRangeInfo> &SubRangeInfos,
    213     const SmallVectorImpl<LiveInterval*> &Intervals) const {
    214   const TargetRegisterInfo &TRI = *MRI->getTargetRegisterInfo();
    215   unsigned Reg = Intervals[0]->reg;;
    216   for (MachineRegisterInfo::reg_nodbg_iterator I = MRI->reg_nodbg_begin(Reg),
    217        E = MRI->reg_nodbg_end(); I != E; ) {
    218     MachineOperand &MO = *I++;
    219     if (!MO.isDef() && !MO.readsReg())
    220       continue;
    221 
    222     MachineInstr &MI = *MO.getParent();
    223 
    224     SlotIndex Pos = LIS->getInstructionIndex(MI);
    225     unsigned SubRegIdx = MO.getSubReg();
    226     LaneBitmask LaneMask = TRI.getSubRegIndexLaneMask(SubRegIdx);
    227 
    228     unsigned ID = ~0u;
    229     for (const SubRangeInfo &SRInfo : SubRangeInfos) {
    230       const LiveInterval::SubRange &SR = *SRInfo.SR;
    231       if ((SR.LaneMask & LaneMask) == 0)
    232         continue;
    233       LiveRange::const_iterator I = SR.find(Pos);
    234       if (I == SR.end())
    235         continue;
    236 
    237       const VNInfo &VNI = *I->valno;
    238       // Map to local representant ID.
    239       unsigned LocalID = SRInfo.ConEQ.getEqClass(&VNI);
    240       // Global ID
    241       ID = Classes[LocalID + SRInfo.Index];
    242       break;
    243     }
    244 
    245     unsigned VReg = Intervals[ID]->reg;
    246     MO.setReg(VReg);
    247   }
    248   // TODO: We could attempt to recompute new register classes while visiting
    249   // the operands: Some of the split register may be fine with less constraint
    250   // classes than the original vreg.
    251 }
    252 
    253 void RenameIndependentSubregs::distribute(const IntEqClasses &Classes,
    254     const SmallVectorImpl<SubRangeInfo> &SubRangeInfos,
    255     const SmallVectorImpl<LiveInterval*> &Intervals) const {
    256   unsigned NumClasses = Classes.getNumClasses();
    257   SmallVector<unsigned, 8> VNIMapping;
    258   SmallVector<LiveInterval::SubRange*, 8> SubRanges;
    259   BumpPtrAllocator &Allocator = LIS->getVNInfoAllocator();
    260   for (const SubRangeInfo &SRInfo : SubRangeInfos) {
    261     LiveInterval::SubRange &SR = *SRInfo.SR;
    262     unsigned NumValNos = SR.valnos.size();
    263     VNIMapping.clear();
    264     VNIMapping.reserve(NumValNos);
    265     SubRanges.clear();
    266     SubRanges.resize(NumClasses-1, nullptr);
    267     for (unsigned I = 0; I < NumValNos; ++I) {
    268       const VNInfo &VNI = *SR.valnos[I];
    269       unsigned LocalID = SRInfo.ConEQ.getEqClass(&VNI);
    270       unsigned ID = Classes[LocalID + SRInfo.Index];
    271       VNIMapping.push_back(ID);
    272       if (ID > 0 && SubRanges[ID-1] == nullptr)
    273         SubRanges[ID-1] = Intervals[ID]->createSubRange(Allocator, SR.LaneMask);
    274     }
    275     DistributeRange(SR, SubRanges.data(), VNIMapping);
    276   }
    277 }
    278 
    279 static bool subRangeLiveAt(const LiveInterval &LI, SlotIndex Pos) {
    280   for (const LiveInterval::SubRange &SR : LI.subranges()) {
    281     if (SR.liveAt(Pos))
    282       return true;
    283   }
    284   return false;
    285 }
    286 
    287 void RenameIndependentSubregs::computeMainRangesFixFlags(
    288     const IntEqClasses &Classes,
    289     const SmallVectorImpl<SubRangeInfo> &SubRangeInfos,
    290     const SmallVectorImpl<LiveInterval*> &Intervals) const {
    291   BumpPtrAllocator &Allocator = LIS->getVNInfoAllocator();
    292   const SlotIndexes &Indexes = *LIS->getSlotIndexes();
    293   for (size_t I = 0, E = Intervals.size(); I < E; ++I) {
    294     LiveInterval &LI = *Intervals[I];
    295     unsigned Reg = LI.reg;
    296 
    297     LI.removeEmptySubRanges();
    298 
    299     // There must be a def (or live-in) before every use. Splitting vregs may
    300     // violate this principle as the splitted vreg may not have a definition on
    301     // every path. Fix this by creating IMPLICIT_DEF instruction as necessary.
    302     for (const LiveInterval::SubRange &SR : LI.subranges()) {
    303       // Search for "PHI" value numbers in the subranges. We must find a live
    304       // value in each predecessor block, add an IMPLICIT_DEF where it is
    305       // missing.
    306       for (unsigned I = 0; I < SR.valnos.size(); ++I) {
    307         const VNInfo &VNI = *SR.valnos[I];
    308         if (VNI.isUnused() || !VNI.isPHIDef())
    309           continue;
    310 
    311         SlotIndex Def = VNI.def;
    312         MachineBasicBlock &MBB = *Indexes.getMBBFromIndex(Def);
    313         for (MachineBasicBlock *PredMBB : MBB.predecessors()) {
    314           SlotIndex PredEnd = Indexes.getMBBEndIdx(PredMBB);
    315           if (subRangeLiveAt(LI, PredEnd.getPrevSlot()))
    316             continue;
    317 
    318           MachineBasicBlock::iterator InsertPos =
    319             llvm::findPHICopyInsertPoint(PredMBB, &MBB, Reg);
    320           const MCInstrDesc &MCDesc = TII->get(TargetOpcode::IMPLICIT_DEF);
    321           MachineInstrBuilder ImpDef = BuildMI(*PredMBB, InsertPos,
    322                                                DebugLoc(), MCDesc, Reg);
    323           SlotIndex DefIdx = LIS->InsertMachineInstrInMaps(*ImpDef);
    324           SlotIndex RegDefIdx = DefIdx.getRegSlot();
    325           for (LiveInterval::SubRange &SR : LI.subranges()) {
    326             VNInfo *SRVNI = SR.getNextValue(RegDefIdx, Allocator);
    327             SR.addSegment(LiveRange::Segment(RegDefIdx, PredEnd, SRVNI));
    328           }
    329         }
    330       }
    331     }
    332 
    333     for (MachineOperand &MO : MRI->reg_nodbg_operands(Reg)) {
    334       if (!MO.isDef())
    335         continue;
    336       unsigned SubRegIdx = MO.getSubReg();
    337       if (SubRegIdx == 0)
    338         continue;
    339       // After assigning the new vreg we may not have any other sublanes living
    340       // in and out of the instruction anymore. We need to add new dead and
    341       // undef flags in these cases.
    342       if (!MO.isUndef()) {
    343         SlotIndex Pos = LIS->getInstructionIndex(*MO.getParent());
    344         if (!subRangeLiveAt(LI, Pos))
    345           MO.setIsUndef();
    346       }
    347       if (!MO.isDead()) {
    348         SlotIndex Pos = LIS->getInstructionIndex(*MO.getParent()).getDeadSlot();
    349         if (!subRangeLiveAt(LI, Pos))
    350           MO.setIsDead();
    351       }
    352     }
    353 
    354     if (I == 0)
    355       LI.clear();
    356     LIS->constructMainRangeFromSubranges(LI);
    357   }
    358 }
    359 
    360 bool RenameIndependentSubregs::runOnMachineFunction(MachineFunction &MF) {
    361   // Skip renaming if liveness of subregister is not tracked.
    362   if (!MF.getSubtarget().enableSubRegLiveness())
    363     return false;
    364 
    365   DEBUG(dbgs() << "Renaming independent subregister live ranges in "
    366         << MF.getName() << '\n');
    367 
    368   LIS = &getAnalysis<LiveIntervals>();
    369   MRI = &MF.getRegInfo();
    370   TII = MF.getSubtarget().getInstrInfo();
    371 
    372   // Iterate over all vregs. Note that we query getNumVirtRegs() the newly
    373   // created vregs end up with higher numbers but do not need to be visited as
    374   // there can't be any further splitting.
    375   bool Changed = false;
    376   for (size_t I = 0, E = MRI->getNumVirtRegs(); I < E; ++I) {
    377     unsigned Reg = TargetRegisterInfo::index2VirtReg(I);
    378     if (!LIS->hasInterval(Reg))
    379       continue;
    380     LiveInterval &LI = LIS->getInterval(Reg);
    381     if (!LI.hasSubRanges())
    382       continue;
    383 
    384     Changed |= renameComponents(LI);
    385   }
    386 
    387   return Changed;
    388 }
    389