LCOV - code coverage report
Current view: top level - lib/CodeGen - DetectDeadLanes.cpp (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 143 208 68.8 %
Date: 2018-09-23 13:06:45 Functions: 14 18 77.8 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : //===- DetectDeadLanes.cpp - SubRegister Lane Usage Analysis --*- C++ -*---===//
       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             : /// \file
      11             : /// Analysis that tracks defined/used subregister lanes across COPY instructions
      12             : /// and instructions that get lowered to a COPY (PHI, REG_SEQUENCE,
      13             : /// INSERT_SUBREG, EXTRACT_SUBREG).
      14             : /// The information is used to detect dead definitions and the usage of
      15             : /// (completely) undefined values and mark the operands as such.
      16             : /// This pass is necessary because the dead/undef status is not obvious anymore
      17             : /// when subregisters are involved.
      18             : ///
      19             : /// Example:
      20             : ///    %0 = some definition
      21             : ///    %1 = IMPLICIT_DEF
      22             : ///    %2 = REG_SEQUENCE %0, sub0, %1, sub1
      23             : ///    %3 = EXTRACT_SUBREG %2, sub1
      24             : ///       = use %3
      25             : /// The %0 definition is dead and %3 contains an undefined value.
      26             : //
      27             : //===----------------------------------------------------------------------===//
      28             : 
      29             : #include <deque>
      30             : #include <vector>
      31             : 
      32             : #include "llvm/ADT/BitVector.h"
      33             : #include "llvm/ADT/SetVector.h"
      34             : #include "llvm/CodeGen/MachineFunctionPass.h"
      35             : #include "llvm/CodeGen/MachineRegisterInfo.h"
      36             : #include "llvm/CodeGen/Passes.h"
      37             : #include "llvm/CodeGen/TargetRegisterInfo.h"
      38             : #include "llvm/CodeGen/TargetSubtargetInfo.h"
      39             : #include "llvm/InitializePasses.h"
      40             : #include "llvm/Pass.h"
      41             : #include "llvm/PassRegistry.h"
      42             : #include "llvm/Support/Debug.h"
      43             : #include "llvm/Support/raw_ostream.h"
      44             : 
      45             : using namespace llvm;
      46             : 
      47             : #define DEBUG_TYPE "detect-dead-lanes"
      48             : 
      49             : namespace {
      50             : 
      51             : /// Contains a bitmask of which lanes of a given virtual register are
      52             : /// defined and which ones are actually used.
      53             : struct VRegInfo {
      54             :   LaneBitmask UsedLanes;
      55             :   LaneBitmask DefinedLanes;
      56             : };
      57             : 
      58             : class DetectDeadLanes : public MachineFunctionPass {
      59             : public:
      60             :   bool runOnMachineFunction(MachineFunction &MF) override;
      61             : 
      62             :   static char ID;
      63       19831 :   DetectDeadLanes() : MachineFunctionPass(ID) {}
      64             : 
      65       19686 :   StringRef getPassName() const override { return "Detect Dead Lanes"; }
      66             : 
      67       19670 :   void getAnalysisUsage(AnalysisUsage &AU) const override {
      68       19670 :     AU.setPreservesCFG();
      69       19670 :     MachineFunctionPass::getAnalysisUsage(AU);
      70       19670 :   }
      71             : 
      72             : private:
      73             :   /// Add used lane bits on the register used by operand \p MO. This translates
      74             :   /// the bitmask based on the operands subregister, and puts the register into
      75             :   /// the worklist if any new bits were added.
      76             :   void addUsedLanesOnOperand(const MachineOperand &MO, LaneBitmask UsedLanes);
      77             : 
      78             :   /// Given a bitmask \p UsedLanes for the used lanes on a def output of a
      79             :   /// COPY-like instruction determine the lanes used on the use operands
      80             :   /// and call addUsedLanesOnOperand() for them.
      81             :   void transferUsedLanesStep(const MachineInstr &MI, LaneBitmask UsedLanes);
      82             : 
      83             :   /// Given a use regiser operand \p Use and a mask of defined lanes, check
      84             :   /// if the operand belongs to a lowersToCopies() instruction, transfer the
      85             :   /// mask to the def and put the instruction into the worklist.
      86             :   void transferDefinedLanesStep(const MachineOperand &Use,
      87             :                                 LaneBitmask DefinedLanes);
      88             : 
      89             :   /// Given a mask \p DefinedLanes of lanes defined at operand \p OpNum
      90             :   /// of COPY-like instruction, determine which lanes are defined at the output
      91             :   /// operand \p Def.
      92             :   LaneBitmask transferDefinedLanes(const MachineOperand &Def, unsigned OpNum,
      93             :                                    LaneBitmask DefinedLanes) const;
      94             : 
      95             :   /// Given a mask \p UsedLanes used from the output of instruction \p MI
      96             :   /// determine which lanes are used from operand \p MO of this instruction.
      97             :   LaneBitmask transferUsedLanes(const MachineInstr &MI, LaneBitmask UsedLanes,
      98             :                                 const MachineOperand &MO) const;
      99             : 
     100             :   bool runOnce(MachineFunction &MF);
     101             : 
     102             :   LaneBitmask determineInitialDefinedLanes(unsigned Reg);
     103             :   LaneBitmask determineInitialUsedLanes(unsigned Reg);
     104             : 
     105             :   bool isUndefRegAtInput(const MachineOperand &MO,
     106             :                          const VRegInfo &RegInfo) const;
     107             : 
     108             :   bool isUndefInput(const MachineOperand &MO, bool *CrossCopy) const;
     109             : 
     110             :   const MachineRegisterInfo *MRI;
     111             :   const TargetRegisterInfo *TRI;
     112             : 
     113      309979 :   void PutInWorklist(unsigned RegIdx) {
     114      619958 :     if (WorklistMembers.test(RegIdx))
     115             :       return;
     116             :     WorklistMembers.set(RegIdx);
     117      238428 :     Worklist.push_back(RegIdx);
     118             :   }
     119             : 
     120             :   VRegInfo *VRegInfos;
     121             :   /// Worklist containing virtreg indexes.
     122             :   std::deque<unsigned> Worklist;
     123             :   BitVector WorklistMembers;
     124             :   /// This bitvector is set for each vreg index where the vreg is defined
     125             :   /// by an instruction where lowersToCopies()==true.
     126             :   BitVector DefinedByCopy;
     127             : };
     128             : 
     129             : } // end anonymous namespace
     130             : 
     131             : char DetectDeadLanes::ID = 0;
     132             : char &llvm::DetectDeadLanesID = DetectDeadLanes::ID;
     133             : 
     134       86873 : INITIALIZE_PASS(DetectDeadLanes, DEBUG_TYPE, "Detect Dead Lanes", false, false)
     135             : 
     136             : /// Returns true if \p MI will get lowered to a series of COPY instructions.
     137             : /// We call this a COPY-like instruction.
     138             : static bool lowersToCopies(const MachineInstr &MI) {
     139             :   // Note: We could support instructions with MCInstrDesc::isRegSequenceLike(),
     140             :   // isExtractSubRegLike(), isInsertSubregLike() in the future even though they
     141             :   // are not lowered to a COPY.
     142           0 :   switch (MI.getOpcode()) {
     143             :   case TargetOpcode::COPY:
     144             :   case TargetOpcode::PHI:
     145             :   case TargetOpcode::INSERT_SUBREG:
     146             :   case TargetOpcode::REG_SEQUENCE:
     147             :   case TargetOpcode::EXTRACT_SUBREG:
     148             :     return true;
     149             :   }
     150             :   return false;
     151             : }
     152             : 
     153      492838 : static bool isCrossCopy(const MachineRegisterInfo &MRI,
     154             :                         const MachineInstr &MI,
     155             :                         const TargetRegisterClass *DstRC,
     156             :                         const MachineOperand &MO) {
     157             :   assert(lowersToCopies(MI));
     158      492838 :   unsigned SrcReg = MO.getReg();
     159             :   const TargetRegisterClass *SrcRC = MRI.getRegClass(SrcReg);
     160      492838 :   if (DstRC == SrcRC)
     161             :     return false;
     162             : 
     163             :   unsigned SrcSubIdx = MO.getSubReg();
     164             : 
     165      433975 :   const TargetRegisterInfo &TRI = *MRI.getTargetRegisterInfo();
     166             :   unsigned DstSubIdx = 0;
     167      867950 :   switch (MI.getOpcode()) {
     168             :   case TargetOpcode::INSERT_SUBREG:
     169         358 :     if (MI.getOperandNo(&MO) == 2)
     170         322 :       DstSubIdx = MI.getOperand(3).getImm();
     171             :     break;
     172             :   case TargetOpcode::REG_SEQUENCE: {
     173             :     unsigned OpNum = MI.getOperandNo(&MO);
     174      267647 :     DstSubIdx = MI.getOperand(OpNum+1).getImm();
     175      267647 :     break;
     176             :   }
     177          10 :   case TargetOpcode::EXTRACT_SUBREG: {
     178          10 :     unsigned SubReg = MI.getOperand(2).getImm();
     179             :     SrcSubIdx = TRI.composeSubRegIndices(SubReg, SrcSubIdx);
     180             :   }
     181             :   }
     182             : 
     183             :   unsigned PreA, PreB; // Unused.
     184      433975 :   if (SrcSubIdx && DstSubIdx)
     185        4065 :     return !TRI.getCommonSuperRegClass(SrcRC, SrcSubIdx, DstRC, DstSubIdx, PreA,
     186        4065 :                                        PreB);
     187      429910 :   if (SrcSubIdx)
     188       96915 :     return !TRI.getMatchingSuperRegClass(SrcRC, DstRC, SrcSubIdx);
     189      332995 :   if (DstSubIdx)
     190      263904 :     return !TRI.getMatchingSuperRegClass(DstRC, SrcRC, DstSubIdx);
     191       69091 :   return !TRI.getCommonSubClass(SrcRC, DstRC);
     192             : }
     193             : 
     194      301241 : void DetectDeadLanes::addUsedLanesOnOperand(const MachineOperand &MO,
     195             :                                             LaneBitmask UsedLanes) {
     196             :   if (!MO.readsReg())
     197             :     return;
     198      301221 :   unsigned MOReg = MO.getReg();
     199      301221 :   if (!TargetRegisterInfo::isVirtualRegister(MOReg))
     200             :     return;
     201             : 
     202             :   unsigned MOSubReg = MO.getSubReg();
     203      301221 :   if (MOSubReg != 0)
     204       93920 :     UsedLanes = TRI->composeSubRegIndexLaneMask(MOSubReg, UsedLanes);
     205      301221 :   UsedLanes &= MRI->getMaxLaneMaskForVReg(MOReg);
     206             : 
     207             :   unsigned MORegIdx = TargetRegisterInfo::virtReg2Index(MOReg);
     208      301221 :   VRegInfo &MORegInfo = VRegInfos[MORegIdx];
     209      301221 :   LaneBitmask PrevUsedLanes = MORegInfo.UsedLanes;
     210             :   // Any change at all?
     211      301221 :   if ((UsedLanes & ~PrevUsedLanes).none())
     212             :     return;
     213             : 
     214             :   // Set UsedLanes and remember instruction for further propagation.
     215      189850 :   MORegInfo.UsedLanes = PrevUsedLanes | UsedLanes;
     216      189850 :   if (DefinedByCopy.test(MORegIdx))
     217       60853 :     PutInWorklist(MORegIdx);
     218             : }
     219             : 
     220      238428 : void DetectDeadLanes::transferUsedLanesStep(const MachineInstr &MI,
     221             :                                             LaneBitmask UsedLanes) {
     222      790823 :   for (const MachineOperand &MO : MI.uses()) {
     223      552395 :     if (!MO.isReg() || !TargetRegisterInfo::isVirtualRegister(MO.getReg()))
     224      251154 :       continue;
     225      301241 :     LaneBitmask UsedOnMO = transferUsedLanes(MI, UsedLanes, MO);
     226      301241 :     addUsedLanesOnOperand(MO, UsedOnMO);
     227             :   }
     228      238428 : }
     229             : 
     230           0 : LaneBitmask DetectDeadLanes::transferUsedLanes(const MachineInstr &MI,
     231             :                                                LaneBitmask UsedLanes,
     232             :                                                const MachineOperand &MO) const {
     233             :   unsigned OpNum = MI.getOperandNo(&MO);
     234             :   assert(lowersToCopies(MI) && DefinedByCopy[
     235             :            TargetRegisterInfo::virtReg2Index(MI.getOperand(0).getReg())]);
     236             : 
     237           0 :   switch (MI.getOpcode()) {
     238           0 :   case TargetOpcode::COPY:
     239             :   case TargetOpcode::PHI:
     240           0 :     return UsedLanes;
     241           0 :   case TargetOpcode::REG_SEQUENCE: {
     242             :     assert(OpNum % 2 == 1);
     243           0 :     unsigned SubIdx = MI.getOperand(OpNum + 1).getImm();
     244           0 :     return TRI->reverseComposeSubRegIndexLaneMask(SubIdx, UsedLanes);
     245             :   }
     246           0 :   case TargetOpcode::INSERT_SUBREG: {
     247           0 :     unsigned SubIdx = MI.getOperand(3).getImm();
     248             :     LaneBitmask MO2UsedLanes =
     249           0 :         TRI->reverseComposeSubRegIndexLaneMask(SubIdx, UsedLanes);
     250           0 :     if (OpNum == 2)
     251           0 :       return MO2UsedLanes;
     252             : 
     253           0 :     const MachineOperand &Def = MI.getOperand(0);
     254           0 :     unsigned DefReg = Def.getReg();
     255           0 :     const TargetRegisterClass *RC = MRI->getRegClass(DefReg);
     256             :     LaneBitmask MO1UsedLanes;
     257           0 :     if (RC->CoveredBySubRegs)
     258           0 :       MO1UsedLanes = UsedLanes & ~TRI->getSubRegIndexLaneMask(SubIdx);
     259             :     else
     260           0 :       MO1UsedLanes = RC->LaneMask;
     261             : 
     262             :     assert(OpNum == 1);
     263           0 :     return MO1UsedLanes;
     264             :   }
     265           0 :   case TargetOpcode::EXTRACT_SUBREG: {
     266             :     assert(OpNum == 1);
     267           0 :     unsigned SubIdx = MI.getOperand(2).getImm();
     268           0 :     return TRI->composeSubRegIndexLaneMask(SubIdx, UsedLanes);
     269             :   }
     270           0 :   default:
     271           0 :     llvm_unreachable("function must be called with COPY-like instruction");
     272             :   }
     273             : }
     274             : 
     275      288683 : void DetectDeadLanes::transferDefinedLanesStep(const MachineOperand &Use,
     276             :                                                LaneBitmask DefinedLanes) {
     277             :   if (!Use.readsReg())
     278             :     return;
     279             :   // Check whether the operand writes a vreg and is part of a COPY-like
     280             :   // instruction.
     281      288583 :   const MachineInstr &MI = *Use.getParent();
     282      288583 :   if (MI.getDesc().getNumDefs() != 1)
     283             :     return;
     284             :   // FIXME: PATCHPOINT instructions announce a Def that does not always exist,
     285             :   // they really need to be modeled differently!
     286      227389 :   if (MI.getOpcode() == TargetOpcode::PATCHPOINT)
     287             :     return;
     288             :   const MachineOperand &Def = *MI.defs().begin();
     289      227389 :   unsigned DefReg = Def.getReg();
     290      227389 :   if (!TargetRegisterInfo::isVirtualRegister(DefReg))
     291             :     return;
     292             :   unsigned DefRegIdx = TargetRegisterInfo::virtReg2Index(DefReg);
     293      218813 :   if (!DefinedByCopy.test(DefRegIdx))
     294             :     return;
     295             : 
     296             :   unsigned OpNum = MI.getOperandNo(&Use);
     297             :   DefinedLanes =
     298      130002 :       TRI->reverseComposeSubRegIndexLaneMask(Use.getSubReg(), DefinedLanes);
     299      130002 :   DefinedLanes = transferDefinedLanes(Def, OpNum, DefinedLanes);
     300             : 
     301      130002 :   VRegInfo &RegInfo = VRegInfos[DefRegIdx];
     302      130002 :   LaneBitmask PrevDefinedLanes = RegInfo.DefinedLanes;
     303             :   // Any change at all?
     304      130002 :   if ((DefinedLanes & ~PrevDefinedLanes).none())
     305             :     return;
     306             : 
     307       60699 :   RegInfo.DefinedLanes = PrevDefinedLanes | DefinedLanes;
     308       60699 :   PutInWorklist(DefRegIdx);
     309             : }
     310             : 
     311           0 : LaneBitmask DetectDeadLanes::transferDefinedLanes(const MachineOperand &Def,
     312             :     unsigned OpNum, LaneBitmask DefinedLanes) const {
     313           0 :   const MachineInstr &MI = *Def.getParent();
     314             :   // Translate DefinedLanes if necessary.
     315           0 :   switch (MI.getOpcode()) {
     316           0 :   case TargetOpcode::REG_SEQUENCE: {
     317           0 :     unsigned SubIdx = MI.getOperand(OpNum + 1).getImm();
     318           0 :     DefinedLanes = TRI->composeSubRegIndexLaneMask(SubIdx, DefinedLanes);
     319           0 :     DefinedLanes &= TRI->getSubRegIndexLaneMask(SubIdx);
     320           0 :     break;
     321             :   }
     322           0 :   case TargetOpcode::INSERT_SUBREG: {
     323           0 :     unsigned SubIdx = MI.getOperand(3).getImm();
     324           0 :     if (OpNum == 2) {
     325           0 :       DefinedLanes = TRI->composeSubRegIndexLaneMask(SubIdx, DefinedLanes);
     326           0 :       DefinedLanes &= TRI->getSubRegIndexLaneMask(SubIdx);
     327             :     } else {
     328             :       assert(OpNum == 1 && "INSERT_SUBREG must have two operands");
     329             :       // Ignore lanes defined by operand 2.
     330           0 :       DefinedLanes &= ~TRI->getSubRegIndexLaneMask(SubIdx);
     331             :     }
     332             :     break;
     333             :   }
     334           0 :   case TargetOpcode::EXTRACT_SUBREG: {
     335           0 :     unsigned SubIdx = MI.getOperand(2).getImm();
     336             :     assert(OpNum == 1 && "EXTRACT_SUBREG must have one register operand only");
     337           0 :     DefinedLanes = TRI->reverseComposeSubRegIndexLaneMask(SubIdx, DefinedLanes);
     338             :     break;
     339             :   }
     340             :   case TargetOpcode::COPY:
     341             :   case TargetOpcode::PHI:
     342             :     break;
     343           0 :   default:
     344           0 :     llvm_unreachable("function must be called with COPY-like instruction");
     345             :   }
     346             : 
     347             :   assert(Def.getSubReg() == 0 &&
     348             :          "Should not have subregister defs in machine SSA phase");
     349           0 :   DefinedLanes &= MRI->getMaxLaneMaskForVReg(Def.getReg());
     350           0 :   return DefinedLanes;
     351             : }
     352             : 
     353      798770 : LaneBitmask DetectDeadLanes::determineInitialDefinedLanes(unsigned Reg) {
     354             :   // Live-In or unused registers have no definition but are considered fully
     355             :   // defined.
     356      798770 :   if (!MRI->hasOneDef(Reg))
     357      360394 :     return LaneBitmask::getAll();
     358             : 
     359      438376 :   const MachineOperand &Def = *MRI->def_begin(Reg);
     360      438376 :   const MachineInstr &DefMI = *Def.getParent();
     361             :   if (lowersToCopies(DefMI)) {
     362             :     // Start optimisatically with no used or defined lanes for copy
     363             :     // instructions. The following dataflow analysis will add more bits.
     364             :     unsigned RegIdx = TargetRegisterInfo::virtReg2Index(Reg);
     365             :     DefinedByCopy.set(RegIdx);
     366      188427 :     PutInWorklist(RegIdx);
     367             : 
     368      188427 :     if (Def.isDead())
     369          22 :       return LaneBitmask::getNone();
     370             : 
     371             :     // COPY/PHI can copy across unrelated register classes (example: float/int)
     372             :     // with incompatible subregister structure. Do not include these in the
     373             :     // dataflow analysis since we cannot transfer lanemasks in a meaningful way.
     374      188405 :     const TargetRegisterClass *DefRC = MRI->getRegClass(Reg);
     375             : 
     376             :     // Determine initially DefinedLanes.
     377             :     LaneBitmask DefinedLanes;
     378      646281 :     for (const MachineOperand &MO : DefMI.uses()) {
     379      457876 :       if (!MO.isReg() || !MO.readsReg())
     380             :         continue;
     381      294101 :       unsigned MOReg = MO.getReg();
     382      294101 :       if (!MOReg)
     383             :         continue;
     384             : 
     385             :       LaneBitmask MODefinedLanes;
     386      294101 :       if (TargetRegisterInfo::isPhysicalRegister(MOReg)) {
     387             :         MODefinedLanes = LaneBitmask::getAll();
     388      247724 :       } else if (isCrossCopy(*MRI, DefMI, DefRC, MO)) {
     389             :         MODefinedLanes = LaneBitmask::getAll();
     390             :       } else {
     391             :         assert(TargetRegisterInfo::isVirtualRegister(MOReg));
     392      214560 :         if (MRI->hasOneDef(MOReg)) {
     393      214560 :           const MachineOperand &MODef = *MRI->def_begin(MOReg);
     394      214560 :           const MachineInstr &MODefMI = *MODef.getParent();
     395             :           // Bits from copy-like operations will be added later.
     396      149823 :           if (lowersToCopies(MODefMI) || MODefMI.isImplicitDef())
     397             :             continue;
     398             :         }
     399             :         unsigned MOSubReg = MO.getSubReg();
     400      145618 :         MODefinedLanes = MRI->getMaxLaneMaskForVReg(MOReg);
     401      145618 :         MODefinedLanes = TRI->reverseComposeSubRegIndexLaneMask(
     402             :             MOSubReg, MODefinedLanes);
     403             :       }
     404             : 
     405             :       unsigned OpNum = DefMI.getOperandNo(&MO);
     406      225159 :       DefinedLanes |= transferDefinedLanes(Def, OpNum, MODefinedLanes);
     407             :     }
     408      188405 :     return DefinedLanes;
     409             :   }
     410      249949 :   if (DefMI.isImplicitDef() || Def.isDead())
     411       12342 :     return LaneBitmask::getNone();
     412             : 
     413             :   assert(Def.getSubReg() == 0 &&
     414             :          "Should not have subregister defs in machine SSA phase");
     415      237607 :   return MRI->getMaxLaneMaskForVReg(Reg);
     416             : }
     417             : 
     418           0 : LaneBitmask DetectDeadLanes::determineInitialUsedLanes(unsigned Reg) {
     419             :   LaneBitmask UsedLanes = LaneBitmask::getNone();
     420           0 :   for (const MachineOperand &MO : MRI->use_nodbg_operands(Reg)) {
     421           0 :     if (!MO.readsReg())
     422           0 :       continue;
     423             : 
     424           0 :     const MachineInstr &UseMI = *MO.getParent();
     425           0 :     if (UseMI.isKill())
     426           0 :       continue;
     427             : 
     428             :     unsigned SubReg = MO.getSubReg();
     429             :     if (lowersToCopies(UseMI)) {
     430             :       assert(UseMI.getDesc().getNumDefs() == 1);
     431           0 :       const MachineOperand &Def = *UseMI.defs().begin();
     432           0 :       unsigned DefReg = Def.getReg();
     433             :       // The used lanes of COPY-like instruction operands are determined by the
     434             :       // following dataflow analysis.
     435           0 :       if (TargetRegisterInfo::isVirtualRegister(DefReg)) {
     436             :         // But ignore copies across incompatible register classes.
     437             :         bool CrossCopy = false;
     438             :         if (lowersToCopies(UseMI)) {
     439           0 :           const TargetRegisterClass *DstRC = MRI->getRegClass(DefReg);
     440           0 :           CrossCopy = isCrossCopy(*MRI, UseMI, DstRC, MO);
     441             :           if (CrossCopy)
     442             :             LLVM_DEBUG(dbgs() << "Copy across incompatible classes: " << UseMI);
     443             :         }
     444             : 
     445           0 :         if (!CrossCopy)
     446           0 :           continue;
     447             :       }
     448             :     }
     449             : 
     450             :     // Shortcut: All lanes are used.
     451           0 :     if (SubReg == 0)
     452           0 :       return MRI->getMaxLaneMaskForVReg(Reg);
     453             : 
     454           0 :     UsedLanes |= TRI->getSubRegIndexLaneMask(SubReg);
     455             :   }
     456           0 :   return UsedLanes;
     457             : }
     458             : 
     459           0 : bool DetectDeadLanes::isUndefRegAtInput(const MachineOperand &MO,
     460             :                                         const VRegInfo &RegInfo) const {
     461             :   unsigned SubReg = MO.getSubReg();
     462      613112 :   LaneBitmask Mask = TRI->getSubRegIndexLaneMask(SubReg);
     463      613112 :   return (RegInfo.DefinedLanes & RegInfo.UsedLanes & Mask).none();
     464             : }
     465             : 
     466      601955 : bool DetectDeadLanes::isUndefInput(const MachineOperand &MO,
     467             :                                    bool *CrossCopy) const {
     468      601955 :   if (!MO.isUse())
     469             :     return false;
     470      601955 :   const MachineInstr &MI = *MO.getParent();
     471             :   if (!lowersToCopies(MI))
     472             :     return false;
     473      250653 :   const MachineOperand &Def = MI.getOperand(0);
     474      250653 :   unsigned DefReg = Def.getReg();
     475      250653 :   if (!TargetRegisterInfo::isVirtualRegister(DefReg))
     476             :     return false;
     477             :   unsigned DefRegIdx = TargetRegisterInfo::virtReg2Index(DefReg);
     478      237886 :   if (!DefinedByCopy.test(DefRegIdx))
     479             :     return false;
     480             : 
     481      237886 :   const VRegInfo &DefRegInfo = VRegInfos[DefRegIdx];
     482      237886 :   LaneBitmask UsedLanes = transferUsedLanes(MI, DefRegInfo.UsedLanes, MO);
     483      237886 :   if (UsedLanes.any())
     484             :     return false;
     485             : 
     486         111 :   unsigned MOReg = MO.getReg();
     487         111 :   if (TargetRegisterInfo::isVirtualRegister(MOReg)) {
     488         111 :     const TargetRegisterClass *DstRC = MRI->getRegClass(DefReg);
     489         111 :     *CrossCopy = isCrossCopy(*MRI, MI, DstRC, MO);
     490             :   }
     491             :   return true;
     492             : }
     493             : 
     494       24856 : bool DetectDeadLanes::runOnce(MachineFunction &MF) {
     495             :   // First pass: Populate defs/uses of vregs with initial values
     496       24856 :   unsigned NumVirtRegs = MRI->getNumVirtRegs();
     497      823626 :   for (unsigned RegIdx = 0; RegIdx < NumVirtRegs; ++RegIdx) {
     498             :     unsigned Reg = TargetRegisterInfo::index2VirtReg(RegIdx);
     499             : 
     500             :     // Determine used/defined lanes and add copy instructions to worklist.
     501      798770 :     VRegInfo &Info = VRegInfos[RegIdx];
     502      798770 :     Info.DefinedLanes = determineInitialDefinedLanes(Reg);
     503      798770 :     Info.UsedLanes = determineInitialUsedLanes(Reg);
     504             :   }
     505             : 
     506             :   // Iterate as long as defined lanes/used lanes keep changing.
     507      263284 :   while (!Worklist.empty()) {
     508      238428 :     unsigned RegIdx = Worklist.front();
     509      238428 :     Worklist.pop_front();
     510             :     WorklistMembers.reset(RegIdx);
     511      238428 :     VRegInfo &Info = VRegInfos[RegIdx];
     512             :     unsigned Reg = TargetRegisterInfo::index2VirtReg(RegIdx);
     513             : 
     514             :     // Transfer UsedLanes to operands of DefMI (backwards dataflow).
     515      238428 :     MachineOperand &Def = *MRI->def_begin(Reg);
     516      238428 :     const MachineInstr &MI = *Def.getParent();
     517      238428 :     transferUsedLanesStep(MI, Info.UsedLanes);
     518             :     // Transfer DefinedLanes to users of Reg (forward dataflow).
     519      765539 :     for (const MachineOperand &MO : MRI->use_nodbg_operands(Reg))
     520      288683 :       transferDefinedLanesStep(MO, Info.DefinedLanes);
     521             :   }
     522             : 
     523             :   LLVM_DEBUG(dbgs() << "Defined/Used lanes:\n"; for (unsigned RegIdx = 0;
     524             :                                                      RegIdx < NumVirtRegs;
     525             :                                                      ++RegIdx) {
     526             :     unsigned Reg = TargetRegisterInfo::index2VirtReg(RegIdx);
     527             :     const VRegInfo &Info = VRegInfos[RegIdx];
     528             :     dbgs() << printReg(Reg, nullptr)
     529             :            << " Used: " << PrintLaneMask(Info.UsedLanes)
     530             :            << " Def: " << PrintLaneMask(Info.DefinedLanes) << '\n';
     531             :   } dbgs() << "\n";);
     532             : 
     533             :   bool Again = false;
     534             :   // Mark operands as dead/unused.
     535       54121 :   for (MachineBasicBlock &MBB : MF) {
     536      548922 :     for (MachineInstr &MI : MBB) {
     537     3218282 :       for (MachineOperand &MO : MI.operands()) {
     538     2698625 :         if (!MO.isReg())
     539             :           continue;
     540     1434454 :         unsigned Reg = MO.getReg();
     541     1434454 :         if (!TargetRegisterInfo::isVirtualRegister(Reg))
     542             :           continue;
     543             :         unsigned RegIdx = TargetRegisterInfo::virtReg2Index(Reg);
     544     1051599 :         const VRegInfo &RegInfo = VRegInfos[RegIdx];
     545     1051599 :         if (MO.isDef() && !MO.isDead() && RegInfo.UsedLanes.none()) {
     546             :           LLVM_DEBUG(dbgs()
     547             :                      << "Marking operand '" << MO << "' as dead in " << MI);
     548             :           MO.setIsDead();
     549             :         }
     550             :         if (MO.readsReg()) {
     551      613112 :           bool CrossCopy = false;
     552     1226224 :           if (isUndefRegAtInput(MO, RegInfo)) {
     553             :             LLVM_DEBUG(dbgs()
     554             :                        << "Marking operand '" << MO << "' as undef in " << MI);
     555             :             MO.setIsUndef();
     556      601955 :           } else if (isUndefInput(MO, &CrossCopy)) {
     557             :             LLVM_DEBUG(dbgs()
     558             :                        << "Marking operand '" << MO << "' as undef in " << MI);
     559             :             MO.setIsUndef();
     560         111 :             if (CrossCopy)
     561             :               Again = true;
     562             :           }
     563             :         }
     564             :       }
     565             :     }
     566             :   }
     567             : 
     568       24856 :   return Again;
     569             : }
     570             : 
     571      194419 : bool DetectDeadLanes::runOnMachineFunction(MachineFunction &MF) {
     572             :   // Don't bother if we won't track subregister liveness later.  This pass is
     573             :   // required for correctness if subregister liveness is enabled because the
     574             :   // register coalescer cannot deal with hidden dead defs. However without
     575             :   // subregister liveness enabled, the expected benefits of this pass are small
     576             :   // so we safe the compile time.
     577      194419 :   MRI = &MF.getRegInfo();
     578      194419 :   if (!MRI->subRegLivenessEnabled()) {
     579             :     LLVM_DEBUG(dbgs() << "Skipping Detect dead lanes pass\n");
     580             :     return false;
     581             :   }
     582             : 
     583       24854 :   TRI = MRI->getTargetRegisterInfo();
     584             : 
     585       24854 :   unsigned NumVirtRegs = MRI->getNumVirtRegs();
     586      823556 :   VRegInfos = new VRegInfo[NumVirtRegs];
     587       24854 :   WorklistMembers.resize(NumVirtRegs);
     588       24854 :   DefinedByCopy.resize(NumVirtRegs);
     589             : 
     590             :   bool Again;
     591       24856 :   do {
     592       24856 :     Again = runOnce(MF);
     593             :   } while(Again);
     594             : 
     595             :   DefinedByCopy.clear();
     596             :   WorklistMembers.clear();
     597       24854 :   delete[] VRegInfos;
     598             :   return true;
     599             : }

Generated by: LCOV version 1.13