39#define DEBUG_TYPE "detect-dead-lanes"
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,
125 if ((UsedLanes & ~PrevUsedLanes).
none())
129 MORegInfo.
UsedLanes = PrevUsedLanes | UsedLanes;
130 if (DefinedByCopy.
test(MORegIdx))
131 PutInWorklist(MORegIdx);
134void DeadLaneDetector::transferUsedLanesStep(
const MachineInstr &
MI,
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();
161 case TargetOpcode::INSERT_SUBREG: {
162 unsigned SubIdx =
MI.getOperand(3).getImm();
173 MO1UsedLanes = UsedLanes & ~TRI->getSubRegIndexLaneMask(SubIdx);
180 case TargetOpcode::EXTRACT_SUBREG: {
182 unsigned SubIdx =
MI.getOperand(2).getImm();
197 if (
MI.getDesc().getNumDefs() != 1)
201 if (
MI.getOpcode() == TargetOpcode::PATCHPOINT)
208 if (!DefinedByCopy.
test(DefRegIdx))
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();
237 case TargetOpcode::INSERT_SUBREG: {
238 unsigned SubIdx =
MI.getOperand(3).getImm();
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");
255 case TargetOpcode::COPY:
256 case TargetOpcode::PHI:
262 assert(Def.getSubReg() == 0 &&
263 "Should not have subregister defs in machine SSA phase");
280 DefinedByCopy.
set(RegIdx);
281 PutInWorklist(RegIdx);
317 MOSubReg, MODefinedLanes);
325 if (
DefMI.isImplicitDef() ||
Def.isDead())
329 "Should not have subregister defs in machine SSA phase");
352 bool CrossCopy =
false;
376class DetectDeadLanes {
386 std::pair<bool, bool>
394 bool *CrossCopy)
const;
404 StringRef getPassName()
const override {
return "Detect Dead Lanes"; }
412 return DetectDeadLanes().run(MF);
418char DetectDeadLanesLegacy::ID = 0;
424bool DetectDeadLanes::isUndefRegAtInput(
426 unsigned SubReg = MO.getSubReg();
433 bool *CrossCopy)
const {
463 for (
unsigned RegIdx = 0; RegIdx < NumVirtRegs; ++RegIdx) {
468 Info.DefinedLanes = determineInitialDefinedLanes(Reg);
469 Info.UsedLanes = determineInitialUsedLanes(Reg);
473 while (!Worklist.empty()) {
474 unsigned RegIdx = Worklist.front();
475 Worklist.pop_front();
476 WorklistMembers.
reset(RegIdx);
483 transferUsedLanesStep(
MI,
Info.UsedLanes);
486 transferDefinedLanesStep(MO,
Info.DefinedLanes);
490 dbgs() <<
"Defined/Used lanes:\n";
491 for (
unsigned RegIdx = 0; RegIdx < NumVirtRegs; ++RegIdx) {
505 bool Changed =
false;
514 if (!
Reg.isVirtual())
516 unsigned RegIdx =
Reg.virtRegIndex();
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();
573 bool Changed =
false;
578 std::tie(LocalChanged, Again) = modifySubRegisterOperandStatus(DLD, MF);
579 Changed |= LocalChanged;
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
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
A container for analyses that lazily runs them and caches their results.
Represent the analysis usage information of a pass.
LLVM_ABI void setPreservesCFG()
This function should be called by the pass, iff they do not:
bool test(unsigned Idx) const
void resize(unsigned N, bool t=false)
resize - Grow or shrink the bitvector.
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,...
const TargetRegisterClass * getRegClass(Register Reg) const
Return the register class of the specified virtual register.
iterator_range< use_nodbg_iterator > use_nodbg_operands(Register Reg) const
def_iterator def_begin(Register RegNo) const
bool hasOneDef(Register RegNo) const
Return true if there is exactly one operand defining the specified register.
LLVM_ABI LaneBitmask getMaxLaneMaskForVReg(Register Reg) const
Returns a mask covering all bits that can appear in lane masks of subregisters of the virtual registe...
unsigned getNumVirtRegs() const
getNumVirtRegs - Return the number of virtual registers created.
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.
StringRef - Represent a constant reference to a string, i.e.
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...
LaneBitmask reverseComposeSubRegIndexLaneMask(unsigned IdxA, LaneBitmask LaneMask) const
Transform a lanemask given for a virtual register to the corresponding lanemask before using subregis...
LaneBitmask getSubRegIndexLaneMask(unsigned SubIdx) const
Return a bitmask representing the parts of a register that are covered by SubIdx.
LaneBitmask composeSubRegIndexLaneMask(unsigned IdxA, LaneBitmask Mask) const
Transforms a LaneMask computed for one subregister to the lanemask that would have been computed when...
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.
Reg
All possible values of the reg field in the ModR/M byte.
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.
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 any() const
static constexpr LaneBitmask getNone()