Go to the documentation of this file.
40 #define DEBUG_TYPE "detect-dead-lanes"
58 StringRef getPassName()
const override {
return "Detect Dead Lanes"; }
101 bool isUndefInput(
const MachineOperand &MO,
bool *CrossCopy)
const;
106 void PutInWorklist(
unsigned RegIdx) {
107 if (WorklistMembers.test(RegIdx))
109 WorklistMembers.set(RegIdx);
110 Worklist.push_back(RegIdx);
115 std::deque<unsigned> Worklist;
135 switch (
MI.getOpcode()) {
136 case TargetOpcode::COPY:
137 case TargetOpcode::PHI:
138 case TargetOpcode::INSERT_SUBREG:
139 case TargetOpcode::REG_SEQUENCE:
140 case TargetOpcode::EXTRACT_SUBREG:
159 unsigned DstSubIdx = 0;
160 switch (
MI.getOpcode()) {
161 case TargetOpcode::INSERT_SUBREG:
162 if (
MI.getOperandNo(&MO) == 2)
163 DstSubIdx =
MI.getOperand(3).getImm();
165 case TargetOpcode::REG_SEQUENCE: {
166 unsigned OpNum =
MI.getOperandNo(&MO);
167 DstSubIdx =
MI.getOperand(OpNum+1).getImm();
170 case TargetOpcode::EXTRACT_SUBREG: {
171 unsigned SubReg =
MI.getOperand(2).getImm();
177 if (SrcSubIdx && DstSubIdx)
187 void DetectDeadLanes::addUsedLanesOnOperand(
const MachineOperand &MO,
201 VRegInfo &MORegInfo = VRegInfos[MORegIdx];
204 if ((UsedLanes & ~PrevUsedLanes).none())
208 MORegInfo.UsedLanes = PrevUsedLanes | UsedLanes;
209 if (DefinedByCopy.test(MORegIdx))
210 PutInWorklist(MORegIdx);
213 void DetectDeadLanes::transferUsedLanesStep(
const MachineInstr &
MI,
219 addUsedLanesOnOperand(MO, UsedOnMO);
226 unsigned OpNum =
MI.getOperandNo(&MO);
230 switch (
MI.getOpcode()) {
231 case TargetOpcode::COPY:
232 case TargetOpcode::PHI:
234 case TargetOpcode::REG_SEQUENCE: {
236 unsigned SubIdx =
MI.getOperand(OpNum + 1).getImm();
239 case TargetOpcode::INSERT_SUBREG: {
240 unsigned SubIdx =
MI.getOperand(3).getImm();
258 case TargetOpcode::EXTRACT_SUBREG: {
260 unsigned SubIdx =
MI.getOperand(2).getImm();
275 if (
MI.getDesc().getNumDefs() != 1)
279 if (
MI.getOpcode() == TargetOpcode::PATCHPOINT)
286 if (!DefinedByCopy.test(DefRegIdx))
289 unsigned OpNum =
MI.getOperandNo(&
Use);
292 DefinedLanes = transferDefinedLanes(
Def, OpNum, DefinedLanes);
294 VRegInfo &RegInfo = VRegInfos[DefRegIdx];
295 LaneBitmask PrevDefinedLanes = RegInfo.DefinedLanes;
297 if ((DefinedLanes & ~PrevDefinedLanes).none())
300 RegInfo.DefinedLanes = PrevDefinedLanes | DefinedLanes;
301 PutInWorklist(DefRegIdx);
308 switch (
MI.getOpcode()) {
309 case TargetOpcode::REG_SEQUENCE: {
310 unsigned SubIdx =
MI.getOperand(OpNum + 1).getImm();
315 case TargetOpcode::INSERT_SUBREG: {
316 unsigned SubIdx =
MI.getOperand(3).getImm();
321 assert(OpNum == 1 &&
"INSERT_SUBREG must have two operands");
327 case TargetOpcode::EXTRACT_SUBREG: {
328 unsigned SubIdx =
MI.getOperand(2).getImm();
329 assert(OpNum == 1 &&
"EXTRACT_SUBREG must have one register operand only");
333 case TargetOpcode::COPY:
334 case TargetOpcode::PHI:
341 "Should not have subregister defs in machine SSA phase");
346 LaneBitmask DetectDeadLanes::determineInitialDefinedLanes(
unsigned Reg) {
358 DefinedByCopy.set(RegIdx);
359 PutInWorklist(RegIdx);
395 MOSubReg, MODefinedLanes);
398 unsigned OpNum =
DefMI.getOperandNo(&MO);
399 DefinedLanes |= transferDefinedLanes(
Def, OpNum, MODefinedLanes);
403 if (
DefMI.isImplicitDef() ||
Def.isDead())
407 "Should not have subregister defs in machine SSA phase");
411 LaneBitmask DetectDeadLanes::determineInitialUsedLanes(
unsigned Reg) {
430 bool CrossCopy =
false;
456 return (RegInfo.DefinedLanes & RegInfo.UsedLanes &
Mask).
none();
460 bool *CrossCopy)
const {
471 if (!DefinedByCopy.test(DefRegIdx))
474 const VRegInfo &DefRegInfo = VRegInfos[DefRegIdx];
475 LaneBitmask UsedLanes = transferUsedLanes(
MI, DefRegInfo.UsedLanes, MO);
490 for (
unsigned RegIdx = 0; RegIdx < NumVirtRegs; ++RegIdx) {
495 Info.DefinedLanes = determineInitialDefinedLanes(
Reg);
496 Info.UsedLanes = determineInitialUsedLanes(
Reg);
500 while (!Worklist.empty()) {
501 unsigned RegIdx = Worklist.front();
502 Worklist.pop_front();
503 WorklistMembers.reset(RegIdx);
510 transferUsedLanesStep(
MI,
Info.UsedLanes);
513 transferDefinedLanesStep(MO,
Info.DefinedLanes);
517 dbgs() <<
"Defined/Used lanes:\n";
518 for (
unsigned RegIdx = 0; RegIdx < NumVirtRegs; ++RegIdx) {
528 bool Changed =
false;
540 const VRegInfo &RegInfo = VRegInfos[RegIdx];
541 if (MO.
isDef() && !MO.
isDead() && RegInfo.UsedLanes.none()) {
543 <<
"Marking operand '" << MO <<
"' as dead in " <<
MI);
548 bool CrossCopy =
false;
549 if (isUndefRegAtInput(MO, RegInfo)) {
551 <<
"Marking operand '" << MO <<
"' as undef in " <<
MI);
554 }
else if (isUndefInput(MO, &CrossCopy)) {
556 <<
"Marking operand '" << MO <<
"' as undef in " <<
MI);
567 return std::make_pair(Changed, Again);
585 VRegInfos =
new VRegInfo[NumVirtRegs];
586 WorklistMembers.resize(NumVirtRegs);
587 DefinedByCopy.resize(NumVirtRegs);
589 bool Changed =
false;
593 std::tie(LocalChanged, Again) = runOnce(MF);
594 Changed |= LocalChanged;
597 DefinedByCopy.clear();
598 WorklistMembers.clear();
def_iterator def_begin(Register RegNo) const
This is an optimization pass for GlobalISel generic memory operations.
bool isImplicitDef() const
bool subRegLivenessEnabled() const
MachineInstrBuilder & UseMI
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
Reg
All possible values of the reg field in the ModR/M byte.
const TargetRegisterInfo * getTargetRegisterInfo() const
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
unsigned getNumVirtRegs() const
getNumVirtRegs - Return the number of virtual registers created.
static Register index2VirtReg(unsigned Index)
Convert a 0-based index to a virtual register number.
unsigned const TargetRegisterInfo * TRI
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
static bool isCrossCopy(const MachineRegisterInfo &MRI, const MachineInstr &MI, const TargetRegisterClass *DstRC, const MachineOperand &MO)
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
constexpr std::underlying_type_t< E > Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
iterator_range< use_nodbg_iterator > use_nodbg_operands(Register Reg) const
LaneBitmask getSubRegIndexLaneMask(unsigned SubIdx) const
Return a bitmask representing the parts of a register that are covered by SubIdx.
const bool CoveredBySubRegs
Whether a combination of subregisters can cover every register in the class.
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
static bool isPhysicalRegister(unsigned Reg)
Return true if the specified register number is in the physical register namespace.
static constexpr LaneBitmask getNone()
Represent the analysis usage information of a pass.
MachineOperand class - Representation of each machine instruction operand.
Printable PrintLaneMask(LaneBitmask LaneMask)
Create Printable object to print LaneBitmasks on a raw_ostream.
Analysis containing CSE Info
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...
MachineInstr * getParent()
getParent - Return the instruction that this operand belongs to.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
const TargetRegisterClass * getRegClass(Register Reg) const
Return the register class of the specified virtual register.
void setIsDead(bool Val=true)
const LaneBitmask LaneMask
bool isReg() const
isReg - Tests if this is a MO_Register operand.
Representation of each machine instruction.
char & DetectDeadLanesID
This pass adds dead/undef flags after analyzing subregister lanes.
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.
constexpr bool any() const
static bool isVirtualRegister(unsigned Reg)
Return true if the specified register number is in the virtual register namespace.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
const TargetRegisterClass * getCommonSubClass(const TargetRegisterClass *A, const TargetRegisterClass *B) const
Find the largest common subclass of A and B.
Register getReg() const
getReg - Returns the register number.
bool hasOneDef(Register RegNo) const
Return true if there is exactly one operand defining the specified register.
void setPreservesCFG()
This function should be called by the pass, iff they do not:
StringRef - Represent a constant reference to a string, i.e.
constexpr bool none() const
unsigned composeSubRegIndices(unsigned a, unsigned b) const
Return the subregister index you get from composing two subregister indices.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
void setIsUndef(bool Val=true)
unsigned const MachineRegisterInfo * MRI
Wrapper class representing virtual and physical registers.
unsigned getSubReg() const
LaneBitmask getMaxLaneMaskForVReg(Register Reg) const
Returns a mask covering all bits that can appear in lane masks of subregisters of the virtual registe...
bool readsReg() const
readsReg - Returns true if this operand reads the previous value of its register.
LaneBitmask composeSubRegIndexLaneMask(unsigned IdxA, LaneBitmask Mask) const
Transforms a LaneMask computed for one subregister to the lanemask that would have been computed when...
static bool lowersToCopies(const MachineInstr &MI)
Returns true if MI will get lowered to a series of COPY instructions.
MachineInstrBuilder MachineInstrBuilder & DefMI
static unsigned virtReg2Index(Register Reg)
Convert a virtual register number to a 0-based index.
LaneBitmask reverseComposeSubRegIndexLaneMask(unsigned IdxA, LaneBitmask LaneMask) const
Transform a lanemask given for a virtual register to the corresponding lanemask before using subregis...
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.
static constexpr LaneBitmask getAll()
A Use represents the edge between a Value definition and its users.