40#define DEBUG_TYPE "detect-dead-lanes"
44 : MRI(MRI), TRI(TRI) {
45 unsigned NumVirtRegs = MRI->getNumVirtRegs();
46 VRegInfos = std::unique_ptr<VRegInfo[]>(
new VRegInfo[NumVirtRegs]);
47 WorklistMembers.resize(NumVirtRegs);
48 DefinedByCopy.resize(NumVirtRegs);
57 switch (
MI.getOpcode()) {
58 case TargetOpcode::COPY:
59 case TargetOpcode::PHI:
60 case TargetOpcode::INSERT_SUBREG:
61 case TargetOpcode::REG_SEQUENCE:
62 case TargetOpcode::EXTRACT_SUBREG:
81 unsigned DstSubIdx = 0;
82 switch (
MI.getOpcode()) {
83 case TargetOpcode::INSERT_SUBREG:
85 DstSubIdx =
MI.getOperand(3).getImm();
87 case TargetOpcode::REG_SEQUENCE: {
89 DstSubIdx =
MI.getOperand(OpNum+1).getImm();
92 case TargetOpcode::EXTRACT_SUBREG: {
93 unsigned SubReg =
MI.getOperand(2).getImm();
94 SrcSubIdx =
TRI.composeSubRegIndices(SubReg, SrcSubIdx);
98 return !
TRI.findCommonRegClass(SrcRC, SrcSubIdx, DstRC, DstSubIdx);
101void DeadLaneDetector::addUsedLanesOnOperand(
const MachineOperand &MO,
111 UsedLanes = TRI->composeSubRegIndexLaneMask(MOSubReg, UsedLanes);
112 UsedLanes &= MRI->getMaxLaneMaskForVReg(MOReg);
115 DeadLaneDetector::VRegInfo &MORegInfo = VRegInfos[MORegIdx];
116 LaneBitmask PrevUsedLanes = MORegInfo.
UsedLanes;
118 if ((UsedLanes & ~PrevUsedLanes).
none())
122 MORegInfo.
UsedLanes = PrevUsedLanes | UsedLanes;
123 if (DefinedByCopy.test(MORegIdx))
124 PutInWorklist(MORegIdx);
127void DeadLaneDetector::transferUsedLanesStep(
const MachineInstr &
MI,
129 for (
const MachineOperand &MO :
MI.uses()) {
133 addUsedLanesOnOperand(MO, UsedOnMO);
143 DefinedByCopy[
MI.getOperand(0).getReg().virtRegIndex()]);
145 switch (
MI.getOpcode()) {
146 case TargetOpcode::COPY:
147 case TargetOpcode::PHI:
149 case TargetOpcode::REG_SEQUENCE: {
151 unsigned SubIdx =
MI.getOperand(OpNum + 1).getImm();
152 return TRI->reverseComposeSubRegIndexLaneMask(SubIdx, UsedLanes);
154 case TargetOpcode::INSERT_SUBREG: {
155 unsigned SubIdx =
MI.getOperand(3).getImm();
157 TRI->reverseComposeSubRegIndexLaneMask(SubIdx, UsedLanes);
166 MO1UsedLanes = UsedLanes & ~TRI->getSubRegIndexLaneMask(SubIdx);
173 case TargetOpcode::EXTRACT_SUBREG: {
175 unsigned SubIdx =
MI.getOperand(2).getImm();
176 return TRI->composeSubRegIndexLaneMask(SubIdx, UsedLanes);
190 if (
MI.getDesc().getNumDefs() != 1)
194 if (
MI.getOpcode() == TargetOpcode::PATCHPOINT)
201 if (!DefinedByCopy.
test(DefRegIdx))
206 TRI->reverseComposeSubRegIndexLaneMask(
Use.getSubReg(), DefinedLanes);
209 VRegInfo &RegInfo = VRegInfos[DefRegIdx];
210 LaneBitmask PrevDefinedLanes = RegInfo.DefinedLanes;
212 if ((DefinedLanes & ~PrevDefinedLanes).
none())
215 RegInfo.DefinedLanes = PrevDefinedLanes | DefinedLanes;
216 PutInWorklist(DefRegIdx);
223 switch (
MI.getOpcode()) {
224 case TargetOpcode::REG_SEQUENCE: {
225 unsigned SubIdx =
MI.getOperand(OpNum + 1).getImm();
226 DefinedLanes = TRI->composeSubRegIndexLaneMask(SubIdx, DefinedLanes);
227 DefinedLanes &= TRI->getSubRegIndexLaneMask(SubIdx);
230 case TargetOpcode::INSERT_SUBREG: {
231 unsigned SubIdx =
MI.getOperand(3).getImm();
233 DefinedLanes = TRI->composeSubRegIndexLaneMask(SubIdx, DefinedLanes);
234 DefinedLanes &= TRI->getSubRegIndexLaneMask(SubIdx);
236 assert(OpNum == 1 &&
"INSERT_SUBREG must have two operands");
238 DefinedLanes &= ~TRI->getSubRegIndexLaneMask(SubIdx);
242 case TargetOpcode::EXTRACT_SUBREG: {
243 unsigned SubIdx =
MI.getOperand(2).getImm();
244 assert(OpNum == 1 &&
"EXTRACT_SUBREG must have one register operand only");
245 DefinedLanes = TRI->reverseComposeSubRegIndexLaneMask(SubIdx, DefinedLanes);
248 case TargetOpcode::COPY:
249 case TargetOpcode::PHI:
255 assert(Def.getSubReg() == 0 &&
256 "Should not have subregister defs in machine SSA phase");
257 DefinedLanes &= MRI->getMaxLaneMaskForVReg(Def.getReg());
272 unsigned RegIdx =
Register(Reg).virtRegIndex();
273 DefinedByCopy.
set(RegIdx);
274 PutInWorklist(RegIdx);
300 if (MRI->hasOneDef(MOReg)) {
301 const MachineOperand &MODef = *MRI->def_begin(MOReg);
302 const MachineInstr &MODefMI = *MODef.
getParent();
308 MODefinedLanes = MRI->getMaxLaneMaskForVReg(MOReg);
309 MODefinedLanes = TRI->reverseComposeSubRegIndexLaneMask(
310 MOSubReg, MODefinedLanes);
318 if (
DefMI.isImplicitDef() ||
Def.isDead())
322 "Should not have subregister defs in machine SSA phase");
323 return MRI->getMaxLaneMaskForVReg(
Reg);
328 for (
const MachineOperand &MO : MRI->use_nodbg_operands(
Reg)) {
339 const MachineOperand &
Def = *
UseMI.defs().begin();
345 bool CrossCopy =
false;
360 return MRI->getMaxLaneMaskForVReg(
Reg);
362 UsedLanes |= TRI->getSubRegIndexLaneMask(SubReg);
369class DetectDeadLanes {
371 bool run(MachineFunction &MF);
379 std::pair<bool, bool>
380 modifySubRegisterOperandStatus(
const DeadLaneDetector &DLD,
381 MachineFunction &MF);
383 bool isUndefRegAtInput(
const MachineOperand &MO,
384 const DeadLaneDetector::VRegInfo &RegInfo)
const;
386 bool isUndefInput(
const DeadLaneDetector &DLD,
const MachineOperand &MO,
387 bool *CrossCopy)
const;
389 const MachineRegisterInfo *MRI =
nullptr;
390 const TargetRegisterInfo *
TRI =
nullptr;
395 DetectDeadLanesLegacy() : MachineFunctionPass(
ID) {}
397 StringRef getPassName()
const override {
return "Detect Dead Lanes"; }
399 void getAnalysisUsage(AnalysisUsage &AU)
const override {
405 bool runOnMachineFunction(MachineFunction &MF)
override {
406 return DetectDeadLanes().run(MF);
412char DetectDeadLanesLegacy::ID = 0;
418bool DetectDeadLanes::isUndefRegAtInput(
420 unsigned SubReg = MO.getSubReg();
427 bool *CrossCopy)
const {
456 unsigned NumVirtRegs = MRI->getNumVirtRegs();
457 for (
unsigned RegIdx = 0; RegIdx < NumVirtRegs; ++RegIdx) {
462 Info.DefinedLanes = determineInitialDefinedLanes(
Reg);
463 Info.UsedLanes = determineInitialUsedLanes(
Reg);
467 while (!Worklist.empty()) {
468 unsigned RegIdx = Worklist.front();
469 Worklist.pop_front();
470 WorklistMembers.reset(RegIdx);
475 MachineOperand &
Def = *MRI->def_begin(
Reg);
476 const MachineInstr &
MI = *
Def.getParent();
477 transferUsedLanesStep(
MI,
Info.UsedLanes);
479 for (
const MachineOperand &MO : MRI->use_nodbg_operands(
Reg))
480 transferDefinedLanesStep(MO,
Info.DefinedLanes);
484 dbgs() <<
"Defined/Used lanes:\n";
485 for (
unsigned RegIdx = 0; RegIdx < NumVirtRegs; ++RegIdx) {
514 <<
"Marking operand '" << MO <<
"' as dead in " <<
MI);
519 bool CrossCopy =
false;
520 if (isUndefRegAtInput(MO, RegInfo)) {
522 <<
"Marking operand '" << MO <<
"' as undef in " <<
MI);
525 }
else if (isUndefInput(DLD, MO, &CrossCopy)) {
527 <<
"Marking operand '" << MO <<
"' as undef in " <<
MI);
538 return std::make_pair(
Changed, Again);
544 if (!DetectDeadLanes().
run(MF))
558 if (!MRI->subRegLivenessEnabled()) {
563 TRI = MRI->getTargetRegisterInfo();
572 std::tie(LocalChanged, Again) = modifySubRegisterOperandStatus(DLD, MF);
MachineInstrBuilder & UseMI
MachineInstrBuilder MachineInstrBuilder & DefMI
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
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)
AnalysisUsage & addPreserved()
Add the specified Pass class to the set of analyses preserved by this pass.
LLVM_ABI void setPreservesCFG()
This function should be called by the pass, iff they do not:
bool test(unsigned Idx) const
Returns true if bit Idx is set.
BitVector & set()
Set all bits in the bitvector.
Represents analyses that only rely on functions' control flow.
LLVM_ABI 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...
LLVM_ABI DeadLaneDetector(const MachineRegisterInfo *MRI, const TargetRegisterInfo *TRI)
bool isDefinedByCopy(unsigned RegIdx) const
LLVM_ABI LaneBitmask transferDefinedLanes(const MachineOperand &Def, unsigned OpNum, LaneBitmask DefinedLanes) const
Given a mask DefinedLanes of lanes defined at operand OpNum of COPY-like instruction,...
LLVM_ABI void computeSubRegisterLaneBitInfo()
Update the DefinedLanes and the UsedLanes for all virtual registers.
const VRegInfo & getVRegInfo(unsigned RegIdx) const
LLVM_ABI PreservedAnalyses run(MachineFunction &MF, MachineFunctionAnalysisManager &MFAM)
const bool CoveredBySubRegs
Whether a combination of subregisters can cover every register in the class.
const LaneBitmask LaneMask
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.
def_iterator def_begin(Register RegNo) const
bool hasOneDef(Register RegNo) const
Return true if there is exactly one operand defining the specified register.
const TargetRegisterInfo * getTargetRegisterInfo() const
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.
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.
DXILDebugInfoMap run(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.
MCRegisterClass TargetRegisterClass
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()