39#define DEBUG_TYPE "detect-dead-lanes" 
   43    : MRI(MRI), TRI(TRI) {
 
   44  unsigned NumVirtRegs = MRI->getNumVirtRegs();
 
   45  VRegInfos = std::unique_ptr<VRegInfo[]>(
new VRegInfo[NumVirtRegs]);
 
   46  WorklistMembers.resize(NumVirtRegs);
 
   47  DefinedByCopy.resize(NumVirtRegs);
 
 
   56  switch (
MI.getOpcode()) {
 
   57  case TargetOpcode::COPY:
 
   58  case TargetOpcode::PHI:
 
   59  case TargetOpcode::INSERT_SUBREG:
 
   60  case TargetOpcode::REG_SEQUENCE:
 
   61  case TargetOpcode::EXTRACT_SUBREG:
 
 
   80  unsigned DstSubIdx = 0;
 
   81  switch (
MI.getOpcode()) {
 
   82  case TargetOpcode::INSERT_SUBREG:
 
   84      DstSubIdx = 
MI.getOperand(3).getImm();
 
   86  case TargetOpcode::REG_SEQUENCE: {
 
   88    DstSubIdx = 
MI.getOperand(OpNum+1).getImm();
 
   91  case TargetOpcode::EXTRACT_SUBREG: {
 
   92    unsigned SubReg = 
MI.getOperand(2).getImm();
 
   93    SrcSubIdx = 
TRI.composeSubRegIndices(
SubReg, SrcSubIdx);
 
   98  if (SrcSubIdx && DstSubIdx)
 
   99    return !
TRI.getCommonSuperRegClass(SrcRC, SrcSubIdx, DstRC, DstSubIdx, PreA,
 
  102    return !
TRI.getMatchingSuperRegClass(SrcRC, DstRC, SrcSubIdx);
 
  104    return !
TRI.getMatchingSuperRegClass(DstRC, SrcRC, DstSubIdx);
 
  105  return !
TRI.getCommonSubClass(SrcRC, DstRC);
 
 
  108void DeadLaneDetector::addUsedLanesOnOperand(
const MachineOperand &MO,
 
  118    UsedLanes = TRI->composeSubRegIndexLaneMask(MOSubReg, UsedLanes);
 
  119  UsedLanes &= MRI->getMaxLaneMaskForVReg(MOReg);
 
  122  DeadLaneDetector::VRegInfo &MORegInfo = VRegInfos[MORegIdx];
 
  123  LaneBitmask PrevUsedLanes = MORegInfo.
UsedLanes;
 
  125  if ((UsedLanes & ~PrevUsedLanes).
none())
 
  129  MORegInfo.
UsedLanes = PrevUsedLanes | UsedLanes;
 
  130  if (DefinedByCopy.test(MORegIdx))
 
  131    PutInWorklist(MORegIdx);
 
  134void DeadLaneDetector::transferUsedLanesStep(
const MachineInstr &
MI,
 
  136  for (
const MachineOperand &MO : 
MI.uses()) {
 
  140    addUsedLanesOnOperand(MO, UsedOnMO);
 
  150         DefinedByCopy[
MI.getOperand(0).getReg().virtRegIndex()]);
 
  152  switch (
MI.getOpcode()) {
 
  153  case TargetOpcode::COPY:
 
  154  case TargetOpcode::PHI:
 
  156  case TargetOpcode::REG_SEQUENCE: {
 
  158    unsigned SubIdx = 
MI.getOperand(OpNum + 1).getImm();
 
  159    return TRI->reverseComposeSubRegIndexLaneMask(SubIdx, UsedLanes);
 
  161  case TargetOpcode::INSERT_SUBREG: {
 
  162    unsigned SubIdx = 
MI.getOperand(3).getImm();
 
  164        TRI->reverseComposeSubRegIndexLaneMask(SubIdx, UsedLanes);
 
  173      MO1UsedLanes = UsedLanes & ~TRI->getSubRegIndexLaneMask(SubIdx);
 
  180  case TargetOpcode::EXTRACT_SUBREG: {
 
  182    unsigned SubIdx = 
MI.getOperand(2).getImm();
 
  183    return TRI->composeSubRegIndexLaneMask(SubIdx, UsedLanes);
 
 
  197  if (
MI.getDesc().getNumDefs() != 1)
 
  201  if (
MI.getOpcode() == TargetOpcode::PATCHPOINT)
 
  208  if (!DefinedByCopy.
test(DefRegIdx))
 
  213      TRI->reverseComposeSubRegIndexLaneMask(
Use.getSubReg(), DefinedLanes);
 
  216  VRegInfo &RegInfo = VRegInfos[DefRegIdx];
 
  217  LaneBitmask PrevDefinedLanes = RegInfo.DefinedLanes;
 
  219  if ((DefinedLanes & ~PrevDefinedLanes).
none())
 
  222  RegInfo.DefinedLanes = PrevDefinedLanes | DefinedLanes;
 
  223  PutInWorklist(DefRegIdx);
 
  230  switch (
MI.getOpcode()) {
 
  231  case TargetOpcode::REG_SEQUENCE: {
 
  232    unsigned SubIdx = 
MI.getOperand(OpNum + 1).getImm();
 
  233    DefinedLanes = TRI->composeSubRegIndexLaneMask(SubIdx, DefinedLanes);
 
  234    DefinedLanes &= TRI->getSubRegIndexLaneMask(SubIdx);
 
  237  case TargetOpcode::INSERT_SUBREG: {
 
  238    unsigned SubIdx = 
MI.getOperand(3).getImm();
 
  240      DefinedLanes = TRI->composeSubRegIndexLaneMask(SubIdx, DefinedLanes);
 
  241      DefinedLanes &= TRI->getSubRegIndexLaneMask(SubIdx);
 
  243      assert(OpNum == 1 && 
"INSERT_SUBREG must have two operands");
 
  245      DefinedLanes &= ~TRI->getSubRegIndexLaneMask(SubIdx);
 
  249  case TargetOpcode::EXTRACT_SUBREG: {
 
  250    unsigned SubIdx = 
MI.getOperand(2).getImm();
 
  251    assert(OpNum == 1 && 
"EXTRACT_SUBREG must have one register operand only");
 
  252    DefinedLanes = TRI->reverseComposeSubRegIndexLaneMask(SubIdx, DefinedLanes);
 
  255  case TargetOpcode::COPY:
 
  256  case TargetOpcode::PHI:
 
  262  assert(Def.getSubReg() == 0 &&
 
  263         "Should not have subregister defs in machine SSA phase");
 
  264  DefinedLanes &= MRI->getMaxLaneMaskForVReg(Def.getReg());
 
 
  271  if (!
MRI->hasOneDef(Reg))
 
  279    unsigned RegIdx = 
Register(Reg).virtRegIndex();
 
  280    DefinedByCopy.
set(RegIdx);
 
  281    PutInWorklist(RegIdx);
 
  307        if (MRI->hasOneDef(MOReg)) {
 
  308          const MachineOperand &MODef = *MRI->def_begin(MOReg);
 
  309          const MachineInstr &MODefMI = *MODef.
getParent();
 
  315        MODefinedLanes = MRI->getMaxLaneMaskForVReg(MOReg);
 
  316        MODefinedLanes = TRI->reverseComposeSubRegIndexLaneMask(
 
  317            MOSubReg, MODefinedLanes);
 
  325  if (
DefMI.isImplicitDef() || 
Def.isDead())
 
  329         "Should not have subregister defs in machine SSA phase");
 
  330  return MRI->getMaxLaneMaskForVReg(
Reg);
 
  335  for (
const MachineOperand &MO : MRI->use_nodbg_operands(
Reg)) {
 
  346      const MachineOperand &
Def = *
UseMI.defs().begin();
 
  352        bool CrossCopy = 
false;
 
  354          const TargetRegisterClass *DstRC = MRI->getRegClass(DefReg);
 
  367      return MRI->getMaxLaneMaskForVReg(
Reg);
 
  369    UsedLanes |= TRI->getSubRegIndexLaneMask(
SubReg);
 
  376class DetectDeadLanes {
 
  378  bool run(MachineFunction &MF);
 
  386  std::pair<bool, bool>
 
  387  modifySubRegisterOperandStatus(
const DeadLaneDetector &DLD,
 
  388                                 MachineFunction &MF);
 
  390  bool isUndefRegAtInput(
const MachineOperand &MO,
 
  391                         const DeadLaneDetector::VRegInfo &RegInfo) 
const;
 
  393  bool isUndefInput(
const DeadLaneDetector &DLD, 
const MachineOperand &MO,
 
  394                    bool *CrossCopy) 
const;
 
  396  const MachineRegisterInfo *
MRI = 
nullptr;
 
  397  const TargetRegisterInfo *
TRI = 
nullptr;
 
  402  DetectDeadLanesLegacy() : MachineFunctionPass(
ID) {}
 
  404  StringRef getPassName()
 const override { 
return "Detect Dead Lanes"; }
 
  406  void getAnalysisUsage(AnalysisUsage &AU)
 const override {
 
  411  bool runOnMachineFunction(MachineFunction &MF)
 override {
 
  412    return DetectDeadLanes().run(MF);
 
  418char DetectDeadLanesLegacy::ID = 0;
 
  424bool DetectDeadLanes::isUndefRegAtInput(
 
  426  unsigned SubReg = MO.getSubReg();
 
  433                                   bool *CrossCopy)
 const {
 
  462  unsigned NumVirtRegs = MRI->getNumVirtRegs();
 
  463  for (
unsigned RegIdx = 0; RegIdx < NumVirtRegs; ++RegIdx) {
 
  469    Info.UsedLanes = determineInitialUsedLanes(
Reg);
 
  473  while (!Worklist.empty()) {
 
  474    unsigned RegIdx = Worklist.front();
 
  475    Worklist.pop_front();
 
  476    WorklistMembers.reset(RegIdx);
 
  481    MachineOperand &
Def = *MRI->def_begin(
Reg);
 
  482    const MachineInstr &
MI = *
Def.getParent();
 
  483    transferUsedLanesStep(
MI, 
Info.UsedLanes);
 
  485    for (
const MachineOperand &MO : MRI->use_nodbg_operands(
Reg))
 
  486      transferDefinedLanesStep(MO, 
Info.DefinedLanes);
 
  490    dbgs() << 
"Defined/Used lanes:\n";
 
  491    for (
unsigned RegIdx = 0; RegIdx < NumVirtRegs; ++RegIdx) {
 
 
  520                     << 
"Marking operand '" << MO << 
"' as dead in " << 
MI);
 
  525          bool CrossCopy = 
false;
 
  526          if (isUndefRegAtInput(MO, RegInfo)) {
 
  528                       << 
"Marking operand '" << MO << 
"' as undef in " << 
MI);
 
  531          } 
else if (isUndefInput(DLD, MO, &CrossCopy)) {
 
  533                       << 
"Marking operand '" << MO << 
"' as undef in " << 
MI);
 
  544  return std::make_pair(
Changed, Again);
 
  550  if (!DetectDeadLanes().
run(MF))
 
 
  564  if (!
MRI->subRegLivenessEnabled()) {
 
  569  TRI = 
MRI->getTargetRegisterInfo();
 
  578    std::tie(LocalChanged, Again) = modifySubRegisterOperandStatus(DLD, MF);
 
unsigned const MachineRegisterInfo * MRI
MachineInstrBuilder & UseMI
MachineInstrBuilder MachineInstrBuilder & DefMI
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
Analysis containing CSE Info
static bool isCrossCopy(const MachineRegisterInfo &MRI, const MachineInstr &MI, const TargetRegisterClass *DstRC, const MachineOperand &MO)
static bool lowersToCopies(const MachineInstr &MI)
Returns true if MI will get lowered to a series of COPY instructions.
Analysis that tracks defined/used subregister lanes across COPY instructions and instructions that ge...
Register const TargetRegisterInfo * TRI
Promote Memory to Register
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
LLVM_ABI void setPreservesCFG()
This function should be called by the pass, iff they do not:
bool test(unsigned Idx) const
Represents analyses that only rely on functions' control flow.
LaneBitmask transferUsedLanes(const MachineInstr &MI, LaneBitmask UsedLanes, const MachineOperand &MO) const
Given a mask UsedLanes used from the output of instruction MI determine which lanes are used from ope...
void computeSubRegisterLaneBitInfo()
Update the DefinedLanes and the UsedLanes for all virtual registers.
DeadLaneDetector(const MachineRegisterInfo *MRI, const TargetRegisterInfo *TRI)
bool isDefinedByCopy(unsigned RegIdx) const
LaneBitmask transferDefinedLanes(const MachineOperand &Def, unsigned OpNum, LaneBitmask DefinedLanes) const
Given a mask DefinedLanes of lanes defined at operand OpNum of COPY-like instruction,...
const VRegInfo & getVRegInfo(unsigned RegIdx) const
PreservedAnalyses run(MachineFunction &MF, MachineFunctionAnalysisManager &MFAM)
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
Representation of each machine instruction.
bool isImplicitDef() const
MachineOperand class - Representation of each machine instruction operand.
unsigned getSubReg() const
LLVM_ABI unsigned getOperandNo() const
Returns the index of this operand in the instruction that it belongs to.
bool readsReg() const
readsReg - Returns true if this operand reads the previous value of its register.
bool isReg() const
isReg - Tests if this is a MO_Register operand.
void setIsDead(bool Val=true)
MachineInstr * getParent()
getParent - Return the instruction that this operand belongs to.
void setIsUndef(bool Val=true)
Register getReg() const
getReg - Returns the register number.
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
A set of analyses that are preserved following a run of a transformation pass.
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
Wrapper class representing virtual and physical registers.
static Register index2VirtReg(unsigned Index)
Convert a 0-based index to a virtual register number.
unsigned virtRegIndex() const
Convert a virtual register number to a 0-based index.
constexpr bool isVirtual() const
Return true if the specified register number is in the virtual register namespace.
constexpr bool isPhysical() const
Return true if the specified register number is in the physical register namespace.
const LaneBitmask LaneMask
const bool CoveredBySubRegs
Whether a combination of subregisters can cover every register in the class.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
A Use represents the edge between a Value definition and its users.
LLVM_ABI unsigned getOperandNo() const
Return the operand # of this use in its User.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
PointerTypeMap run(const Module &M)
Compute the PointerTypeMap for the module M.
NodeAddr< DefNode * > Def
This is an optimization pass for GlobalISel generic memory operations.
Printable PrintLaneMask(LaneBitmask LaneMask)
Create Printable object to print LaneBitmasks on a raw_ostream.
AnalysisManager< MachineFunction > MachineFunctionAnalysisManager
LLVM_ABI PreservedAnalyses getMachineFunctionPassPreservedAnalyses()
Returns the minimum set of Analyses that all machine function passes must preserve.
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
LLVM_ABI char & DetectDeadLanesID
This pass adds dead/undef flags after analyzing subregister lanes.
LLVM_ABI Printable printReg(Register Reg, const TargetRegisterInfo *TRI=nullptr, unsigned SubIdx=0, const MachineRegisterInfo *MRI=nullptr)
Prints virtual and physical registers with or without a TRI instance.
Contains a bitmask of which lanes of a given virtual register are defined and which ones are actually...
static constexpr LaneBitmask getAll()
constexpr bool none() const
constexpr bool any() const
static constexpr LaneBitmask getNone()