47 #define DEBUG_TYPE "detect-dead-lanes" 65 StringRef getPassName()
const override {
return "Detect Dead Lanes"; }
103 LaneBitmask determineInitialUsedLanes(
unsigned Reg);
108 bool isUndefInput(
const MachineOperand &MO,
bool *CrossCopy)
const;
113 void PutInWorklist(
unsigned RegIdx) {
114 if (WorklistMembers.test(RegIdx))
116 WorklistMembers.set(RegIdx);
117 Worklist.push_back(RegIdx);
122 std::deque<unsigned> Worklist;
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:
158 unsigned SrcReg = MO.
getReg();
166 unsigned DstSubIdx = 0;
168 case TargetOpcode::INSERT_SUBREG:
172 case TargetOpcode::REG_SEQUENCE: {
177 case TargetOpcode::EXTRACT_SUBREG: {
184 if (SrcSubIdx && DstSubIdx)
194 void DetectDeadLanes::addUsedLanesOnOperand(
const MachineOperand &MO,
198 unsigned MOReg = MO.
getReg();
204 UsedLanes =
TRI->composeSubRegIndexLaneMask(MOSubReg, UsedLanes);
205 UsedLanes &=
MRI->getMaxLaneMaskForVReg(MOReg);
208 VRegInfo &MORegInfo = VRegInfos[MORegIdx];
211 if ((UsedLanes & ~PrevUsedLanes).none())
215 MORegInfo.UsedLanes = PrevUsedLanes | UsedLanes;
216 if (DefinedByCopy.test(MORegIdx))
217 PutInWorklist(MORegIdx);
220 void DetectDeadLanes::transferUsedLanesStep(
const MachineInstr &
MI,
225 LaneBitmask UsedOnMO = transferUsedLanes(MI, UsedLanes, MO);
226 addUsedLanesOnOperand(MO, UsedOnMO);
238 case TargetOpcode::COPY:
239 case TargetOpcode::PHI:
241 case TargetOpcode::REG_SEQUENCE: {
244 return TRI->reverseComposeSubRegIndexLaneMask(SubIdx, UsedLanes);
246 case TargetOpcode::INSERT_SUBREG: {
249 TRI->reverseComposeSubRegIndexLaneMask(SubIdx, UsedLanes);
254 unsigned DefReg = Def.
getReg();
258 MO1UsedLanes = UsedLanes & ~
TRI->getSubRegIndexLaneMask(SubIdx);
265 case TargetOpcode::EXTRACT_SUBREG: {
268 return TRI->composeSubRegIndexLaneMask(SubIdx, UsedLanes);
286 if (MI.
getOpcode() == TargetOpcode::PATCHPOINT)
289 unsigned DefReg = Def.
getReg();
293 if (!DefinedByCopy.test(DefRegIdx))
298 TRI->reverseComposeSubRegIndexLaneMask(Use.
getSubReg(), DefinedLanes);
299 DefinedLanes = transferDefinedLanes(Def, OpNum, DefinedLanes);
301 VRegInfo &RegInfo = VRegInfos[DefRegIdx];
302 LaneBitmask PrevDefinedLanes = RegInfo.DefinedLanes;
304 if ((DefinedLanes & ~PrevDefinedLanes).none())
307 RegInfo.DefinedLanes = PrevDefinedLanes | DefinedLanes;
308 PutInWorklist(DefRegIdx);
316 case TargetOpcode::REG_SEQUENCE: {
318 DefinedLanes =
TRI->composeSubRegIndexLaneMask(SubIdx, DefinedLanes);
319 DefinedLanes &=
TRI->getSubRegIndexLaneMask(SubIdx);
322 case TargetOpcode::INSERT_SUBREG: {
325 DefinedLanes =
TRI->composeSubRegIndexLaneMask(SubIdx, DefinedLanes);
326 DefinedLanes &=
TRI->getSubRegIndexLaneMask(SubIdx);
328 assert(OpNum == 1 &&
"INSERT_SUBREG must have two operands");
330 DefinedLanes &= ~
TRI->getSubRegIndexLaneMask(SubIdx);
334 case TargetOpcode::EXTRACT_SUBREG: {
336 assert(OpNum == 1 &&
"EXTRACT_SUBREG must have one register operand only");
337 DefinedLanes =
TRI->reverseComposeSubRegIndexLaneMask(SubIdx, DefinedLanes);
340 case TargetOpcode::COPY:
341 case TargetOpcode::PHI:
348 "Should not have subregister defs in machine SSA phase");
349 DefinedLanes &=
MRI->getMaxLaneMaskForVReg(Def.
getReg());
353 LaneBitmask DetectDeadLanes::determineInitialDefinedLanes(
unsigned Reg) {
356 if (!
MRI->hasOneDef(Reg))
365 DefinedByCopy.set(RegIdx);
366 PutInWorklist(RegIdx);
381 unsigned MOReg = MO.
getReg();
392 if (
MRI->hasOneDef(MOReg)) {
400 MODefinedLanes =
MRI->getMaxLaneMaskForVReg(MOReg);
401 MODefinedLanes =
TRI->reverseComposeSubRegIndexLaneMask(
402 MOSubReg, MODefinedLanes);
406 DefinedLanes |= transferDefinedLanes(Def, OpNum, MODefinedLanes);
414 "Should not have subregister defs in machine SSA phase");
415 return MRI->getMaxLaneMaskForVReg(Reg);
418 LaneBitmask DetectDeadLanes::determineInitialUsedLanes(
unsigned Reg) {
432 unsigned DefReg = Def.getReg();
437 bool CrossCopy =
false;
442 LLVM_DEBUG(
dbgs() <<
"Copy across incompatible classes: " << UseMI);
452 return MRI->getMaxLaneMaskForVReg(Reg);
454 UsedLanes |=
TRI->getSubRegIndexLaneMask(SubReg);
463 return (RegInfo.DefinedLanes & RegInfo.UsedLanes & Mask).none();
467 bool *CrossCopy)
const {
474 unsigned DefReg = Def.
getReg();
478 if (!DefinedByCopy.test(DefRegIdx))
481 const VRegInfo &DefRegInfo = VRegInfos[DefRegIdx];
482 LaneBitmask UsedLanes = transferUsedLanes(MI, DefRegInfo.UsedLanes, MO);
486 unsigned MOReg = MO.
getReg();
496 unsigned NumVirtRegs =
MRI->getNumVirtRegs();
497 for (
unsigned RegIdx = 0; RegIdx < NumVirtRegs; ++RegIdx) {
502 Info.DefinedLanes = determineInitialDefinedLanes(Reg);
503 Info.UsedLanes = determineInitialUsedLanes(Reg);
507 while (!Worklist.empty()) {
508 unsigned RegIdx = Worklist.front();
509 Worklist.pop_front();
510 WorklistMembers.reset(RegIdx);
517 transferUsedLanesStep(MI, Info.UsedLanes);
520 transferDefinedLanesStep(MO, Info.DefinedLanes);
523 LLVM_DEBUG(
dbgs() <<
"Defined/Used lanes:\n";
for (
unsigned RegIdx = 0;
524 RegIdx < NumVirtRegs;
540 unsigned Reg = MO.
getReg();
544 const VRegInfo &RegInfo = VRegInfos[RegIdx];
545 if (MO.
isDef() && !MO.
isDead() && RegInfo.UsedLanes.none()) {
547 <<
"Marking operand '" << MO <<
"' as dead in " << MI);
551 bool CrossCopy =
false;
552 if (isUndefRegAtInput(MO, RegInfo)) {
554 <<
"Marking operand '" << MO <<
"' as undef in " << MI);
556 }
else if (isUndefInput(MO, &CrossCopy)) {
558 <<
"Marking operand '" << MO <<
"' as undef in " << MI);
578 if (!
MRI->subRegLivenessEnabled()) {
583 TRI =
MRI->getTargetRegisterInfo();
585 unsigned NumVirtRegs =
MRI->getNumVirtRegs();
586 VRegInfos =
new VRegInfo[NumVirtRegs];
587 WorklistMembers.resize(NumVirtRegs);
588 DefinedByCopy.resize(NumVirtRegs);
595 DefinedByCopy.clear();
596 WorklistMembers.clear();
const TargetRegisterClass * getCommonSubClass(const TargetRegisterClass *A, const TargetRegisterClass *B, const MVT::SimpleValueType SVT=MVT::SimpleValueType::Any) const
Find the largest common subclass of A and B.
MachineInstr * getParent()
getParent - Return the instruction that this operand belongs to.
const TargetRegisterClass * getRegClass(unsigned Reg) const
Return the register class of the specified virtual register.
static unsigned virtReg2Index(unsigned Reg)
Convert a virtual register number to a 0-based index.
This class represents lattice values for constants.
iterator_range< mop_iterator > uses()
Returns a range that includes all operands that are register uses.
static unsigned index2VirtReg(unsigned Index)
Convert a 0-based index to a virtual register number.
unsigned getReg() const
getReg - Returns the register number.
unsigned getOperandNo(const_mop_iterator I) const
Returns the number of the operand iterator I points to.
void setIsUndef(bool Val=true)
static bool isVirtualRegister(unsigned Reg)
Return true if the specified register number is in the virtual register namespace.
unsigned getSubReg() const
unsigned const TargetRegisterInfo * TRI
void setIsDead(bool Val=true)
Printable PrintLaneMask(LaneBitmask LaneMask)
Create Printable object to print LaneBitmasks on a raw_ostream.
const TargetRegisterClass * RC
iterator_range< mop_iterator > operands()
char & DetectDeadLanesID
This pass adds dead/undef flags after analyzing subregister lanes.
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
Printable printReg(unsigned Reg, const TargetRegisterInfo *TRI=nullptr, unsigned SubIdx=0, const MachineRegisterInfo *MRI=nullptr)
Prints virtual and physical registers with or without a TRI instance.
A Use represents the edge between a Value definition and its users.
static constexpr LaneBitmask getAll()
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
static constexpr LaneBitmask getNone()
const TargetRegisterClass * getCommonSuperRegClass(const TargetRegisterClass *RCA, unsigned SubA, const TargetRegisterClass *RCB, unsigned SubB, unsigned &PreA, unsigned &PreB) const
Find a common super-register class if it exists.
bool readsReg() const
readsReg - Returns true if this operand reads the previous value of its register. ...
const MCInstrDesc & getDesc() const
Returns the target instruction descriptor of this MachineInstr.
Analysis containing CSE Info
const TargetRegisterInfo * getTargetRegisterInfo() const
unsigned const MachineRegisterInfo * MRI
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
MachineInstrBuilder & UseMI
unsigned composeSubRegIndices(unsigned a, unsigned b) const
Return the subregister index you get from composing two subregister indices.
static bool lowersToCopies(const MachineInstr &MI)
Returns true if MI will get lowered to a series of COPY instructions.
Represent the analysis usage information of a pass.
iterator_range< mop_iterator > defs()
Returns a range over all explicit operands that are register definitions.
virtual const TargetRegisterClass * getMatchingSuperRegClass(const TargetRegisterClass *A, const TargetRegisterClass *B, unsigned Idx) const
Return a subclass of the specified register class A so that each register in it has a sub-register of...
bool isImplicitDef() const
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
static bool isCrossCopy(const MachineRegisterInfo &MRI, const MachineInstr &MI, const TargetRegisterClass *DstRC, const MachineOperand &MO)
MachineOperand class - Representation of each machine instruction operand.
MachineInstrBuilder MachineInstrBuilder & DefMI
unsigned getNumDefs() const
Return the number of MachineOperands that are register definitions.
void setPreservesCFG()
This function should be called by the pass, iff they do not:
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
MachineRegisterInfo - Keep track of information for virtual and physical registers, including vreg register classes, use/def chains for registers, etc.
Representation of each machine instruction.
static bool isPhysicalRegister(unsigned Reg)
Return true if the specified register number is in the physical register namespace.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
constexpr bool any() const
const LaneBitmask LaneMask
const bool CoveredBySubRegs
Whether a combination of subregisters can cover every register in the class.
bool isReg() const
isReg - Tests if this is a MO_Register operand.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
std::underlying_type< E >::type Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
StringRef - Represent a constant reference to a string, i.e.
const MachineOperand & getOperand(unsigned i) const