LCOV - code coverage report
Current view: top level - lib/CodeGen - DetectDeadLanes.cpp (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 181 186 97.3 %
Date: 2018-02-17 17:14:17 Functions: 19 19 100.0 %
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       51204 : class DetectDeadLanes : public MachineFunctionPass {
      59             : public:
      60             :   bool runOnMachineFunction(MachineFunction &MF) override;
      61             : 
      62             :   static char ID;
      63       34322 :   DetectDeadLanes() : MachineFunctionPass(ID) {}
      64             : 
      65       17072 :   StringRef getPassName() const override { return "Detect Dead Lanes"; }
      66             : 
      67       17056 :   void getAnalysisUsage(AnalysisUsage &AU) const override {
      68       17056 :     AU.setPreservesCFG();
      69       17056 :     MachineFunctionPass::getAnalysisUsage(AU);
      70       17056 :   }
      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      235318 :   void PutInWorklist(unsigned RegIdx) {
     114      470636 :     if (WorklistMembers.test(RegIdx))
     115             :       return;
     116             :     WorklistMembers.set(RegIdx);
     117      178007 :     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      134278 : 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             :   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      399814 : static bool isCrossCopy(const MachineRegisterInfo &MRI,
     154             :                         const MachineInstr &MI,
     155             :                         const TargetRegisterClass *DstRC,
     156             :                         const MachineOperand &MO) {
     157             :   assert(lowersToCopies(MI));
     158             :   unsigned SrcReg = MO.getReg();
     159             :   const TargetRegisterClass *SrcRC = MRI.getRegClass(SrcReg);
     160      399814 :   if (DstRC == SrcRC)
     161             :     return false;
     162             : 
     163             :   unsigned SrcSubIdx = MO.getSubReg();
     164             : 
     165             :   const TargetRegisterInfo &TRI = *MRI.getTargetRegisterInfo();
     166             :   unsigned DstSubIdx = 0;
     167      368154 :   switch (MI.getOpcode()) {
     168             :   case TargetOpcode::INSERT_SUBREG:
     169         385 :     if (MI.getOperandNo(&MO) == 2)
     170         351 :       DstSubIdx = MI.getOperand(3).getImm();
     171             :     break;
     172             :   case TargetOpcode::REG_SEQUENCE: {
     173             :     unsigned OpNum = MI.getOperandNo(&MO);
     174      470668 :     DstSubIdx = MI.getOperand(OpNum+1).getImm();
     175      235334 :     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      368154 :   if (SrcSubIdx && DstSubIdx)
     185          53 :     return !TRI.getCommonSuperRegClass(SrcRC, SrcSubIdx, DstRC, DstSubIdx, PreA,
     186          53 :                                        PreB);
     187      368101 :   if (SrcSubIdx)
     188       82156 :     return !TRI.getMatchingSuperRegClass(SrcRC, DstRC, SrcSubIdx);
     189      285945 :   if (DstSubIdx)
     190      235632 :     return !TRI.getMatchingSuperRegClass(DstRC, SrcRC, DstSubIdx);
     191       50313 :   return !TRI.getCommonSubClass(SrcRC, DstRC);
     192             : }
     193             : 
     194      247642 : void DetectDeadLanes::addUsedLanesOnOperand(const MachineOperand &MO,
     195             :                                             LaneBitmask UsedLanes) {
     196             :   if (!MO.readsReg())
     197             :     return;
     198             :   unsigned MOReg = MO.getReg();
     199      247526 :   if (!TargetRegisterInfo::isVirtualRegister(MOReg))
     200             :     return;
     201             : 
     202             :   unsigned MOSubReg = MO.getSubReg();
     203      247526 :   if (MOSubReg != 0)
     204       74826 :     UsedLanes = TRI->composeSubRegIndexLaneMask(MOSubReg, UsedLanes);
     205      247526 :   UsedLanes &= MRI->getMaxLaneMaskForVReg(MOReg);
     206             : 
     207             :   unsigned MORegIdx = TargetRegisterInfo::virtReg2Index(MOReg);
     208      247526 :   VRegInfo &MORegInfo = VRegInfos[MORegIdx];
     209      247526 :   LaneBitmask PrevUsedLanes = MORegInfo.UsedLanes;
     210             :   // Any change at all?
     211      247526 :   if ((UsedLanes & ~PrevUsedLanes).none())
     212             :     return;
     213             : 
     214             :   // Set UsedLanes and remember instruction for further propagation.
     215      151563 :   MORegInfo.UsedLanes = PrevUsedLanes | UsedLanes;
     216      151563 :   if (DefinedByCopy.test(MORegIdx))
     217       46715 :     PutInWorklist(MORegIdx);
     218             : }
     219             : 
     220      178007 : void DetectDeadLanes::transferUsedLanesStep(const MachineInstr &MI,
     221             :                                             LaneBitmask UsedLanes) {
     222     1044923 :   for (const MachineOperand &MO : MI.uses()) {
     223      712807 :     if (!MO.isReg() || !TargetRegisterInfo::isVirtualRegister(MO.getReg()))
     224      185816 :       continue;
     225      247642 :     LaneBitmask UsedOnMO = transferUsedLanes(MI, UsedLanes, MO);
     226      247642 :     addUsedLanesOnOperand(MO, UsedOnMO);
     227             :   }
     228      178007 : }
     229             : 
     230      440380 : 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      440380 :   switch (MI.getOpcode()) {
     238      174529 :   case TargetOpcode::COPY:
     239             :   case TargetOpcode::PHI:
     240      174529 :     return UsedLanes;
     241      265146 :   case TargetOpcode::REG_SEQUENCE: {
     242             :     assert(OpNum % 2 == 1);
     243      530292 :     unsigned SubIdx = MI.getOperand(OpNum + 1).getImm();
     244      265146 :     return TRI->reverseComposeSubRegIndexLaneMask(SubIdx, UsedLanes);
     245             :   }
     246         695 :   case TargetOpcode::INSERT_SUBREG: {
     247         695 :     unsigned SubIdx = MI.getOperand(3).getImm();
     248             :     LaneBitmask MO2UsedLanes =
     249         695 :         TRI->reverseComposeSubRegIndexLaneMask(SubIdx, UsedLanes);
     250         695 :     if (OpNum == 2)
     251         399 :       return MO2UsedLanes;
     252             : 
     253             :     const MachineOperand &Def = MI.getOperand(0);
     254             :     unsigned DefReg = Def.getReg();
     255         296 :     const TargetRegisterClass *RC = MRI->getRegClass(DefReg);
     256             :     LaneBitmask MO1UsedLanes;
     257         296 :     if (RC->CoveredBySubRegs)
     258         113 :       MO1UsedLanes = UsedLanes & ~TRI->getSubRegIndexLaneMask(SubIdx);
     259             :     else
     260         183 :       MO1UsedLanes = RC->LaneMask;
     261             : 
     262             :     assert(OpNum == 1);
     263         296 :     return MO1UsedLanes;
     264             :   }
     265          10 :   case TargetOpcode::EXTRACT_SUBREG: {
     266             :     assert(OpNum == 1);
     267          10 :     unsigned SubIdx = MI.getOperand(2).getImm();
     268          10 :     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      236254 : 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             :   const MachineInstr &MI = *Use.getParent();
     282      236138 :   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      184052 :   if (MI.getOpcode() == TargetOpcode::PATCHPOINT)
     287             :     return;
     288             :   const MachineOperand &Def = *MI.defs().begin();
     289             :   unsigned DefReg = Def.getReg();
     290      184052 :   if (!TargetRegisterInfo::isVirtualRegister(DefReg))
     291             :     return;
     292             :   unsigned DefRegIdx = TargetRegisterInfo::virtReg2Index(DefReg);
     293      180019 :   if (!DefinedByCopy.test(DefRegIdx))
     294             :     return;
     295             : 
     296             :   unsigned OpNum = MI.getOperandNo(&Use);
     297             :   DefinedLanes =
     298       98387 :       TRI->reverseComposeSubRegIndexLaneMask(Use.getSubReg(), DefinedLanes);
     299       98387 :   DefinedLanes = transferDefinedLanes(Def, OpNum, DefinedLanes);
     300             : 
     301       98387 :   VRegInfo &RegInfo = VRegInfos[DefRegIdx];
     302       98387 :   LaneBitmask PrevDefinedLanes = RegInfo.DefinedLanes;
     303             :   // Any change at all?
     304       98387 :   if ((DefinedLanes & ~PrevDefinedLanes).none())
     305             :     return;
     306             : 
     307       47184 :   RegInfo.DefinedLanes = PrevDefinedLanes | DefinedLanes;
     308       47184 :   PutInWorklist(DefRegIdx);
     309             : }
     310             : 
     311      274107 : LaneBitmask DetectDeadLanes::transferDefinedLanes(const MachineOperand &Def,
     312             :     unsigned OpNum, LaneBitmask DefinedLanes) const {
     313             :   const MachineInstr &MI = *Def.getParent();
     314             :   // Translate DefinedLanes if necessary.
     315      274107 :   switch (MI.getOpcode()) {
     316      158654 :   case TargetOpcode::REG_SEQUENCE: {
     317      317308 :     unsigned SubIdx = MI.getOperand(OpNum + 1).getImm();
     318      158654 :     DefinedLanes = TRI->composeSubRegIndexLaneMask(SubIdx, DefinedLanes);
     319      158654 :     DefinedLanes &= TRI->getSubRegIndexLaneMask(SubIdx);
     320             :     break;
     321             :   }
     322         302 :   case TargetOpcode::INSERT_SUBREG: {
     323         302 :     unsigned SubIdx = MI.getOperand(3).getImm();
     324         302 :     if (OpNum == 2) {
     325         178 :       DefinedLanes = TRI->composeSubRegIndexLaneMask(SubIdx, DefinedLanes);
     326         178 :       DefinedLanes &= TRI->getSubRegIndexLaneMask(SubIdx);
     327             :     } else {
     328             :       assert(OpNum == 1 && "INSERT_SUBREG must have two operands");
     329             :       // Ignore lanes defined by operand 2.
     330         124 :       DefinedLanes &= ~TRI->getSubRegIndexLaneMask(SubIdx);
     331             :     }
     332             :     break;
     333             :   }
     334           6 :   case TargetOpcode::EXTRACT_SUBREG: {
     335           6 :     unsigned SubIdx = MI.getOperand(2).getImm();
     336             :     assert(OpNum == 1 && "EXTRACT_SUBREG must have one register operand only");
     337           6 :     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      274107 :   DefinedLanes &= MRI->getMaxLaneMaskForVReg(Def.getReg());
     350      274107 :   return DefinedLanes;
     351             : }
     352             : 
     353      665744 : LaneBitmask DetectDeadLanes::determineInitialDefinedLanes(unsigned Reg) {
     354             :   // Live-In or unused registers have no definition but are considered fully
     355             :   // defined.
     356      665744 :   if (!MRI->hasOneDef(Reg))
     357      292826 :     return LaneBitmask::getAll();
     358             : 
     359      745836 :   const MachineOperand &Def = *MRI->def_begin(Reg);
     360             :   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      141419 :     PutInWorklist(RegIdx);
     367             : 
     368      141419 :     if (Def.isDead())
     369          38 :       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      141381 :     const TargetRegisterClass *DefRC = MRI->getRegClass(Reg);
     375             : 
     376             :     // Determine initially DefinedLanes.
     377             :     LaneBitmask DefinedLanes;
     378      871073 :     for (const MachineOperand &MO : DefMI.uses()) {
     379      499768 :       if (!MO.isReg() || !MO.readsReg())
     380      134922 :         continue;
     381             :       unsigned MOReg = MO.getReg();
     382      229924 :       if (!MOReg)
     383           0 :         continue;
     384             : 
     385             :       LaneBitmask MODefinedLanes;
     386      229924 :       if (TargetRegisterInfo::isPhysicalRegister(MOReg)) {
     387             :         MODefinedLanes = LaneBitmask::getAll();
     388      201097 :       } else if (isCrossCopy(*MRI, DefMI, DefRC, MO)) {
     389             :         MODefinedLanes = LaneBitmask::getAll();
     390             :       } else {
     391             :         assert(TargetRegisterInfo::isVirtualRegister(MOReg));
     392      176059 :         if (MRI->hasOneDef(MOReg)) {
     393      352118 :           const MachineOperand &MODef = *MRI->def_begin(MOReg);
     394             :           const MachineInstr &MODefMI = *MODef.getParent();
     395             :           // Bits from copy-like operations will be added later.
     396      125427 :           if (lowersToCopies(MODefMI) || MODefMI.isImplicitDef())
     397       54204 :             continue;
     398             :         }
     399             :         unsigned MOSubReg = MO.getSubReg();
     400      121855 :         MODefinedLanes = MRI->getMaxLaneMaskForVReg(MOReg);
     401      121855 :         MODefinedLanes = TRI->reverseComposeSubRegIndexLaneMask(
     402             :             MOSubReg, MODefinedLanes);
     403             :       }
     404             : 
     405             :       unsigned OpNum = DefMI.getOperandNo(&MO);
     406      175720 :       DefinedLanes |= transferDefinedLanes(Def, OpNum, MODefinedLanes);
     407             :     }
     408      141381 :     return DefinedLanes;
     409             :   }
     410      457398 :   if (DefMI.isImplicitDef() || Def.isDead())
     411       10694 :     return LaneBitmask::getNone();
     412             : 
     413             :   assert(Def.getSubReg() == 0 &&
     414             :          "Should not have subregister defs in machine SSA phase");
     415      220805 :   return MRI->getMaxLaneMaskForVReg(Reg);
     416             : }
     417             : 
     418      665744 : LaneBitmask DetectDeadLanes::determineInitialUsedLanes(unsigned Reg) {
     419             :   LaneBitmask UsedLanes = LaneBitmask::getNone();
     420     1534829 :   for (const MachineOperand &MO : MRI->use_nodbg_operands(Reg)) {
     421         161 :     if (!MO.readsReg())
     422             :       continue;
     423             : 
     424             :     const MachineInstr &UseMI = *MO.getParent();
     425      434283 :     if (UseMI.isKill())
     426             :       continue;
     427             : 
     428             :     unsigned SubReg = MO.getSubReg();
     429             :     if (lowersToCopies(UseMI)) {
     430             :       assert(UseMI.getDesc().getNumDefs() == 1);
     431             :       const MachineOperand &Def = *UseMI.defs().begin();
     432             :       unsigned DefReg = Def.getReg();
     433             :       // The used lanes of COPY-like instruction operands are determined by the
     434             :       // following dataflow analysis.
     435      204945 :       if (TargetRegisterInfo::isVirtualRegister(DefReg)) {
     436             :         // But ignore copies across incompatible register classes.
     437             :         bool CrossCopy = false;
     438             :         if (lowersToCopies(UseMI)) {
     439      198584 :           const TargetRegisterClass *DstRC = MRI->getRegClass(DefReg);
     440      198584 :           CrossCopy = isCrossCopy(*MRI, UseMI, DstRC, MO);
     441             :           if (CrossCopy)
     442             :             DEBUG(dbgs() << "Copy across incompatible classes: " << UseMI);
     443             :         }
     444             : 
     445      198584 :         if (!CrossCopy)
     446             :           continue;
     447             :       }
     448             :     }
     449             : 
     450             :     // Shortcut: All lanes are used.
     451      260543 :     if (SubReg == 0)
     452      231103 :       return MRI->getMaxLaneMaskForVReg(Reg);
     453             : 
     454       29440 :     UsedLanes |= TRI->getSubRegIndexLaneMask(SubReg);
     455             :   }
     456      434641 :   return UsedLanes;
     457             : }
     458             : 
     459             : bool DetectDeadLanes::isUndefRegAtInput(const MachineOperand &MO,
     460             :                                         const VRegInfo &RegInfo) const {
     461             :   unsigned SubReg = MO.getSubReg();
     462             :   LaneBitmask Mask = TRI->getSubRegIndexLaneMask(SubReg);
     463             :   return (RegInfo.DefinedLanes & RegInfo.UsedLanes & Mask).none();
     464             : }
     465             : 
     466      515633 : bool DetectDeadLanes::isUndefInput(const MachineOperand &MO,
     467             :                                    bool *CrossCopy) const {
     468      515633 :   if (!MO.isUse())
     469             :     return false;
     470             :   const MachineInstr &MI = *MO.getParent();
     471             :   if (!lowersToCopies(MI))
     472             :     return false;
     473             :   const MachineOperand &Def = MI.getOperand(0);
     474             :   unsigned DefReg = Def.getReg();
     475      198977 :   if (!TargetRegisterInfo::isVirtualRegister(DefReg))
     476             :     return false;
     477             :   unsigned DefRegIdx = TargetRegisterInfo::virtReg2Index(DefReg);
     478      192738 :   if (!DefinedByCopy.test(DefRegIdx))
     479             :     return false;
     480             : 
     481      192738 :   const VRegInfo &DefRegInfo = VRegInfos[DefRegIdx];
     482      192738 :   LaneBitmask UsedLanes = transferUsedLanes(MI, DefRegInfo.UsedLanes, MO);
     483      192738 :   if (UsedLanes.any())
     484             :     return false;
     485             : 
     486             :   unsigned MOReg = MO.getReg();
     487         133 :   if (TargetRegisterInfo::isVirtualRegister(MOReg)) {
     488         133 :     const TargetRegisterClass *DstRC = MRI->getRegClass(DefReg);
     489         133 :     *CrossCopy = isCrossCopy(*MRI, MI, DstRC, MO);
     490             :   }
     491             :   return true;
     492             : }
     493             : 
     494       20514 : bool DetectDeadLanes::runOnce(MachineFunction &MF) {
     495             :   // First pass: Populate defs/uses of vregs with initial values
     496       20514 :   unsigned NumVirtRegs = MRI->getNumVirtRegs();
     497     1352002 :   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      665744 :     VRegInfo &Info = VRegInfos[RegIdx];
     502      665744 :     Info.DefinedLanes = determineInitialDefinedLanes(Reg);
     503      665744 :     Info.UsedLanes = determineInitialUsedLanes(Reg);
     504             :   }
     505             : 
     506             :   // Iterate as long as defined lanes/used lanes keep changing.
     507      198521 :   while (!Worklist.empty()) {
     508      178007 :     unsigned RegIdx = Worklist.front();
     509      178007 :     Worklist.pop_front();
     510             :     WorklistMembers.reset(RegIdx);
     511      178007 :     VRegInfo &Info = VRegInfos[RegIdx];
     512             :     unsigned Reg = TargetRegisterInfo::index2VirtReg(RegIdx);
     513             : 
     514             :     // Transfer UsedLanes to operands of DefMI (backwards dataflow).
     515      356014 :     MachineOperand &Def = *MRI->def_begin(Reg);
     516             :     const MachineInstr &MI = *Def.getParent();
     517      178007 :     transferUsedLanesStep(MI, Info.UsedLanes);
     518             :     // Transfer DefinedLanes to users of Reg (forward dataflow).
     519      592268 :     for (const MachineOperand &MO : MRI->use_nodbg_operands(Reg))
     520      236254 :       transferDefinedLanesStep(MO, Info.DefinedLanes);
     521             :   }
     522             : 
     523             :   DEBUG(
     524             :     dbgs() << "Defined/Used lanes:\n";
     525             :     for (unsigned RegIdx = 0; RegIdx < NumVirtRegs; ++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             :     }
     532             :     dbgs() << "\n";
     533             :   );
     534             : 
     535             :   bool Again = false;
     536             :   // Mark operands as dead/unused.
     537       44409 :   for (MachineBasicBlock &MBB : MF) {
     538      485012 :     for (MachineInstr &MI : MBB) {
     539     5260938 :       for (MachineOperand &MO : MI.operands()) {
     540     2411858 :         if (!MO.isReg())
     541     1195459 :           continue;
     542             :         unsigned Reg = MO.getReg();
     543     1216399 :         if (!TargetRegisterInfo::isVirtualRegister(Reg))
     544      317538 :           continue;
     545             :         unsigned RegIdx = TargetRegisterInfo::virtReg2Index(Reg);
     546      898861 :         const VRegInfo &RegInfo = VRegInfos[RegIdx];
     547     1639557 :         if (MO.isDef() && !MO.isDead() && RegInfo.UsedLanes.none()) {
     548             :           DEBUG(dbgs() << "Marking operand '" << MO << "' as dead in " << MI);
     549             :           MO.setIsDead();
     550             :         }
     551             :         if (MO.readsReg()) {
     552      525778 :           bool CrossCopy = false;
     553      525778 :           if (isUndefRegAtInput(MO, RegInfo)) {
     554             :             DEBUG(dbgs() << "Marking operand '" << MO << "' as undef in "
     555             :                   << MI);
     556             :             MO.setIsUndef();
     557      515633 :           } else if (isUndefInput(MO, &CrossCopy)) {
     558             :             DEBUG(dbgs() << "Marking operand '" << MO << "' as undef in "
     559             :                   << MI);
     560             :             MO.setIsUndef();
     561         133 :             if (CrossCopy)
     562             :               Again = true;
     563             :           }
     564             :         }
     565             :       }
     566             :     }
     567             :   }
     568             : 
     569       20514 :   return Again;
     570             : }
     571             : 
     572      158624 : bool DetectDeadLanes::runOnMachineFunction(MachineFunction &MF) {
     573             :   // Don't bother if we won't track subregister liveness later.  This pass is
     574             :   // required for correctness if subregister liveness is enabled because the
     575             :   // register coalescer cannot deal with hidden dead defs. However without
     576             :   // subregister liveness enabled, the expected benefits of this pass are small
     577             :   // so we safe the compile time.
     578      158624 :   MRI = &MF.getRegInfo();
     579      158624 :   if (!MRI->subRegLivenessEnabled()) {
     580             :     DEBUG(dbgs() << "Skipping Detect dead lanes pass\n");
     581             :     return false;
     582             :   }
     583             : 
     584       20500 :   TRI = MRI->getTargetRegisterInfo();
     585             : 
     586       20500 :   unsigned NumVirtRegs = MRI->getNumVirtRegs();
     587      685386 :   VRegInfos = new VRegInfo[NumVirtRegs];
     588       20500 :   WorklistMembers.resize(NumVirtRegs);
     589       20500 :   DefinedByCopy.resize(NumVirtRegs);
     590             : 
     591             :   bool Again;
     592       20514 :   do {
     593       20514 :     Again = runOnce(MF);
     594             :   } while(Again);
     595             : 
     596             :   DefinedByCopy.clear();
     597             :   WorklistMembers.clear();
     598       20500 :   delete[] VRegInfos;
     599             :   return true;
     600             : }

Generated by: LCOV version 1.13