48 #define DEBUG_TYPE "detect-dead-lanes"
66 StringRef getPassName()
const override {
return "Detect Dead Lanes"; }
104 LaneBitmask determineInitialUsedLanes(
unsigned Reg);
109 bool isUndefInput(
const MachineOperand &MO,
bool *CrossCopy)
const;
114 void PutInWorklist(
unsigned RegIdx) {
115 if (WorklistMembers.test(RegIdx))
117 WorklistMembers.set(RegIdx);
118 Worklist.push_back(RegIdx);
123 std::deque<unsigned> Worklist;
144 switch (MI.getOpcode()) {
145 case TargetOpcode::COPY:
146 case TargetOpcode::PHI:
147 case TargetOpcode::INSERT_SUBREG:
148 case TargetOpcode::REG_SEQUENCE:
149 case TargetOpcode::EXTRACT_SUBREG:
159 assert(lowersToCopies(MI));
160 unsigned SrcReg = MO.
getReg();
168 unsigned DstSubIdx = 0;
170 case TargetOpcode::INSERT_SUBREG:
174 case TargetOpcode::REG_SEQUENCE: {
179 case TargetOpcode::EXTRACT_SUBREG: {
186 if (SrcSubIdx && DstSubIdx)
196 void DetectDeadLanes::addUsedLanesOnOperand(
const MachineOperand &MO,
200 unsigned MOReg = MO.
getReg();
206 UsedLanes = TRI->composeSubRegIndexLaneMask(MOSubReg, UsedLanes);
207 UsedLanes &=
MRI->getMaxLaneMaskForVReg(MOReg);
210 VRegInfo &MORegInfo = VRegInfos[MORegIdx];
213 if ((UsedLanes & ~PrevUsedLanes).none())
217 MORegInfo.UsedLanes = PrevUsedLanes | UsedLanes;
218 if (DefinedByCopy.test(MORegIdx))
219 PutInWorklist(MORegIdx);
222 void DetectDeadLanes::transferUsedLanesStep(
const MachineInstr &
MI,
227 LaneBitmask UsedOnMO = transferUsedLanes(MI, UsedLanes, MO);
228 addUsedLanesOnOperand(MO, UsedOnMO);
236 assert(lowersToCopies(MI) && DefinedByCopy[
240 case TargetOpcode::COPY:
241 case TargetOpcode::PHI:
243 case TargetOpcode::REG_SEQUENCE: {
246 return TRI->reverseComposeSubRegIndexLaneMask(SubIdx, UsedLanes);
248 case TargetOpcode::INSERT_SUBREG: {
251 TRI->reverseComposeSubRegIndexLaneMask(SubIdx, UsedLanes);
256 unsigned DefReg = Def.
getReg();
260 MO1UsedLanes = UsedLanes & ~TRI->getSubRegIndexLaneMask(SubIdx);
267 case TargetOpcode::EXTRACT_SUBREG: {
270 return TRI->composeSubRegIndexLaneMask(SubIdx, UsedLanes);
288 if (MI.
getOpcode() == TargetOpcode::PATCHPOINT)
291 unsigned DefReg = Def.
getReg();
295 if (!DefinedByCopy.test(DefRegIdx))
300 TRI->reverseComposeSubRegIndexLaneMask(Use.
getSubReg(), DefinedLanes);
301 DefinedLanes = transferDefinedLanes(Def, OpNum, DefinedLanes);
303 VRegInfo &RegInfo = VRegInfos[DefRegIdx];
304 LaneBitmask PrevDefinedLanes = RegInfo.DefinedLanes;
306 if ((DefinedLanes & ~PrevDefinedLanes).none())
309 RegInfo.DefinedLanes = PrevDefinedLanes | DefinedLanes;
310 PutInWorklist(DefRegIdx);
318 case TargetOpcode::REG_SEQUENCE: {
320 DefinedLanes = TRI->composeSubRegIndexLaneMask(SubIdx, DefinedLanes);
321 DefinedLanes &= TRI->getSubRegIndexLaneMask(SubIdx);
324 case TargetOpcode::INSERT_SUBREG: {
327 DefinedLanes = TRI->composeSubRegIndexLaneMask(SubIdx, DefinedLanes);
328 DefinedLanes &= TRI->getSubRegIndexLaneMask(SubIdx);
330 assert(OpNum == 1 &&
"INSERT_SUBREG must have two operands");
332 DefinedLanes &= ~TRI->getSubRegIndexLaneMask(SubIdx);
336 case TargetOpcode::EXTRACT_SUBREG: {
338 assert(OpNum == 1 &&
"EXTRACT_SUBREG must have one register operand only");
339 DefinedLanes = TRI->reverseComposeSubRegIndexLaneMask(SubIdx, DefinedLanes);
342 case TargetOpcode::COPY:
343 case TargetOpcode::PHI:
350 "Should not have subregister defs in machine SSA phase");
351 DefinedLanes &=
MRI->getMaxLaneMaskForVReg(Def.
getReg());
355 LaneBitmask DetectDeadLanes::determineInitialDefinedLanes(
unsigned Reg) {
358 if (!
MRI->hasOneDef(Reg))
363 if (lowersToCopies(DefMI)) {
367 DefinedByCopy.set(RegIdx);
368 PutInWorklist(RegIdx);
383 unsigned MOReg = MO.
getReg();
394 if (
MRI->hasOneDef(MOReg)) {
402 MODefinedLanes =
MRI->getMaxLaneMaskForVReg(MOReg);
403 MODefinedLanes = TRI->reverseComposeSubRegIndexLaneMask(
404 MOSubReg, MODefinedLanes);
408 DefinedLanes |= transferDefinedLanes(Def, OpNum, MODefinedLanes);
416 "Should not have subregister defs in machine SSA phase");
417 return MRI->getMaxLaneMaskForVReg(Reg);
420 LaneBitmask DetectDeadLanes::determineInitialUsedLanes(
unsigned Reg) {
431 if (lowersToCopies(UseMI)) {
434 unsigned DefReg = Def.getReg();
439 bool CrossCopy =
false;
440 if (lowersToCopies(UseMI)) {
444 DEBUG(
dbgs() <<
"Copy accross incompatible classes: " << UseMI);
454 return MRI->getMaxLaneMaskForVReg(Reg);
456 UsedLanes |= TRI->getSubRegIndexLaneMask(SubReg);
465 return (RegInfo.DefinedLanes & RegInfo.UsedLanes & Mask).none();
469 bool *CrossCopy)
const {
473 if (!lowersToCopies(MI))
476 unsigned DefReg = Def.
getReg();
480 if (!DefinedByCopy.test(DefRegIdx))
483 const VRegInfo &DefRegInfo = VRegInfos[DefRegIdx];
484 LaneBitmask UsedLanes = transferUsedLanes(MI, DefRegInfo.UsedLanes, MO);
488 unsigned MOReg = MO.
getReg();
498 unsigned NumVirtRegs =
MRI->getNumVirtRegs();
499 for (
unsigned RegIdx = 0; RegIdx < NumVirtRegs; ++RegIdx) {
504 Info.DefinedLanes = determineInitialDefinedLanes(Reg);
505 Info.UsedLanes = determineInitialUsedLanes(Reg);
509 while (!Worklist.empty()) {
510 unsigned RegIdx = Worklist.front();
511 Worklist.pop_front();
512 WorklistMembers.reset(RegIdx);
519 transferUsedLanesStep(MI, Info.UsedLanes);
522 transferDefinedLanesStep(MO, Info.DefinedLanes);
526 dbgs() <<
"Defined/Used lanes:\n";
527 for (
unsigned RegIdx = 0; RegIdx < NumVirtRegs; ++RegIdx) {
529 const VRegInfo &Info = VRegInfos[RegIdx];
544 unsigned Reg = MO.
getReg();
548 const VRegInfo &RegInfo = VRegInfos[RegIdx];
549 if (MO.
isDef() && !MO.
isDead() && RegInfo.UsedLanes.none()) {
550 DEBUG(
dbgs() <<
"Marking operand '" << MO <<
"' as dead in " << MI);
554 bool CrossCopy =
false;
555 if (isUndefRegAtInput(MO, RegInfo)) {
556 DEBUG(
dbgs() <<
"Marking operand '" << MO <<
"' as undef in "
559 }
else if (isUndefInput(MO, &CrossCopy)) {
560 DEBUG(
dbgs() <<
"Marking operand '" << MO <<
"' as undef in "
581 if (!
MRI->subRegLivenessEnabled()) {
582 DEBUG(
dbgs() <<
"Skipping Detect dead lanes pass\n");
586 TRI =
MRI->getTargetRegisterInfo();
588 unsigned NumVirtRegs =
MRI->getNumVirtRegs();
589 VRegInfos =
new VRegInfo[NumVirtRegs];
590 WorklistMembers.resize(NumVirtRegs);
591 DefinedByCopy.resize(NumVirtRegs);
598 DefinedByCopy.clear();
599 WorklistMembers.clear();
MachineInstr * getParent()
getParent - Return the instruction that this operand belongs to.
static unsigned virtReg2Index(unsigned Reg)
Convert a virtual register number to a 0-based index.
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 getNumDefs() const
Return the number of MachineOperands that are register definitions.
static LaneBitmask getAll()
void setIsUndef(bool Val=true)
static bool isVirtualRegister(unsigned Reg)
Return true if the specified register number is in the virtual register namespace.
unsigned getOperandNo(const_mop_iterator I) const
Returns the number of the operand iterator I points to.
INITIALIZE_PASS(DetectDeadLanes,"detect-dead-lanes","Detect Dead Lanes", false, false) static bool lowersToCopies(const MachineInstr &MI)
Returns true if MI will get lowered to a series of COPY instructions.
const MCInstrDesc & getDesc() const
Returns the target instruction descriptor of this MachineInstr.
void setIsDead(bool Val=true)
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...
const TargetRegisterInfo * getTargetRegisterInfo() const
A Use represents the edge between a Value definition and its users.
bool isReg() const
isReg - Tests if this is a MO_Register operand.
const TargetRegisterClass * getRegClass(unsigned Reg) const
Return the register class of the specified virtual register.
Reg
All possible values of the reg field in the ModR/M byte.
constexpr bool any() const
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...
Printable PrintReg(unsigned Reg, const TargetRegisterInfo *TRI=nullptr, unsigned SubRegIdx=0)
Prints virtual and physical registers with or without a TRI instance.
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
bool isImplicitDef() const
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.
unsigned const MachineRegisterInfo * MRI
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
MachineInstrBuilder & UseMI
const MachineOperand & getOperand(unsigned i) const
Represent the analysis usage information of a pass.
iterator_range< mop_iterator > defs()
Returns a range over all explicit operands that are register definitions.
unsigned getSubReg() 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.
static bool isCrossCopy(const MachineRegisterInfo &MRI, const MachineInstr &MI, const TargetRegisterClass *DstRC, const MachineOperand &MO)
MachineOperand class - Representation of each machine instruction operand.
static LaneBitmask getNone()
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.
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.
const LaneBitmask LaneMask
const bool CoveredBySubRegs
Whether a combination of subregisters can cover every register in the class.
unsigned getReg() const
getReg - Returns the register number.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
static LLVM_ATTRIBUTE_UNUSED Printable PrintLaneMask(LaneBitmask LaneMask)
Create Printable object to print LaneBitmasks on a raw_ostream.
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.
unsigned composeSubRegIndices(unsigned a, unsigned b) const
Return the subregister index you get from composing two subregister indices.
bool readsReg() const
readsReg - Returns true if this operand reads the previous value of its register. ...