39#define DEBUG_TYPE "detect-dead-lanes"
43 : MRI(MRI), TRI(TRI) {
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);
97 return !
TRI.findCommonRegClass(SrcRC, SrcSubIdx, DstRC, DstSubIdx);
100void DeadLaneDetector::addUsedLanesOnOperand(
const MachineOperand &MO,
110 UsedLanes = TRI->composeSubRegIndexLaneMask(MOSubReg, UsedLanes);
111 UsedLanes &= MRI->getMaxLaneMaskForVReg(MOReg);
114 DeadLaneDetector::VRegInfo &MORegInfo = VRegInfos[MORegIdx];
115 LaneBitmask PrevUsedLanes = MORegInfo.
UsedLanes;
117 if ((UsedLanes & ~PrevUsedLanes).
none())
121 MORegInfo.
UsedLanes = PrevUsedLanes | UsedLanes;
122 if (DefinedByCopy.test(MORegIdx))
123 PutInWorklist(MORegIdx);
126void DeadLaneDetector::transferUsedLanesStep(
const MachineInstr &
MI,
128 for (
const MachineOperand &MO :
MI.uses()) {
132 addUsedLanesOnOperand(MO, UsedOnMO);
142 DefinedByCopy[
MI.getOperand(0).getReg().virtRegIndex()]);
144 switch (
MI.getOpcode()) {
145 case TargetOpcode::COPY:
146 case TargetOpcode::PHI:
148 case TargetOpcode::REG_SEQUENCE: {
150 unsigned SubIdx =
MI.getOperand(OpNum + 1).getImm();
151 return TRI->reverseComposeSubRegIndexLaneMask(SubIdx, UsedLanes);
153 case TargetOpcode::INSERT_SUBREG: {
154 unsigned SubIdx =
MI.getOperand(3).getImm();
156 TRI->reverseComposeSubRegIndexLaneMask(SubIdx, UsedLanes);
165 MO1UsedLanes = UsedLanes & ~TRI->getSubRegIndexLaneMask(SubIdx);
172 case TargetOpcode::EXTRACT_SUBREG: {
174 unsigned SubIdx =
MI.getOperand(2).getImm();
175 return TRI->composeSubRegIndexLaneMask(SubIdx, UsedLanes);
189 if (
MI.getDesc().getNumDefs() != 1)
193 if (
MI.getOpcode() == TargetOpcode::PATCHPOINT)
200 if (!DefinedByCopy.
test(DefRegIdx))
205 TRI->reverseComposeSubRegIndexLaneMask(
Use.getSubReg(), DefinedLanes);
208 VRegInfo &RegInfo = VRegInfos[DefRegIdx];
209 LaneBitmask PrevDefinedLanes = RegInfo.DefinedLanes;
211 if ((DefinedLanes & ~PrevDefinedLanes).
none())
214 RegInfo.DefinedLanes = PrevDefinedLanes | DefinedLanes;
215 PutInWorklist(DefRegIdx);
222 switch (
MI.getOpcode()) {
223 case TargetOpcode::REG_SEQUENCE: {
224 unsigned SubIdx =
MI.getOperand(OpNum + 1).getImm();
225 DefinedLanes = TRI->composeSubRegIndexLaneMask(SubIdx, DefinedLanes);
226 DefinedLanes &= TRI->getSubRegIndexLaneMask(SubIdx);
229 case TargetOpcode::INSERT_SUBREG: {
230 unsigned SubIdx =
MI.getOperand(3).getImm();
232 DefinedLanes = TRI->composeSubRegIndexLaneMask(SubIdx, DefinedLanes);
233 DefinedLanes &= TRI->getSubRegIndexLaneMask(SubIdx);
235 assert(OpNum == 1 &&
"INSERT_SUBREG must have two operands");
237 DefinedLanes &= ~TRI->getSubRegIndexLaneMask(SubIdx);
241 case TargetOpcode::EXTRACT_SUBREG: {
242 unsigned SubIdx =
MI.getOperand(2).getImm();
243 assert(OpNum == 1 &&
"EXTRACT_SUBREG must have one register operand only");
244 DefinedLanes = TRI->reverseComposeSubRegIndexLaneMask(SubIdx, DefinedLanes);
247 case TargetOpcode::COPY:
248 case TargetOpcode::PHI:
254 assert(Def.getSubReg() == 0 &&
255 "Should not have subregister defs in machine SSA phase");
256 DefinedLanes &= MRI->getMaxLaneMaskForVReg(Def.getReg());
263 if (!
MRI->hasOneDef(Reg))
271 unsigned RegIdx =
Register(Reg).virtRegIndex();
272 DefinedByCopy.
set(RegIdx);
273 PutInWorklist(RegIdx);
299 if (MRI->hasOneDef(MOReg)) {
300 const MachineOperand &MODef = *MRI->def_begin(MOReg);
301 const MachineInstr &MODefMI = *MODef.
getParent();
307 MODefinedLanes = MRI->getMaxLaneMaskForVReg(MOReg);
308 MODefinedLanes = TRI->reverseComposeSubRegIndexLaneMask(
309 MOSubReg, MODefinedLanes);
317 if (
DefMI.isImplicitDef() ||
Def.isDead())
321 "Should not have subregister defs in machine SSA phase");
322 return MRI->getMaxLaneMaskForVReg(
Reg);
327 for (
const MachineOperand &MO : MRI->use_nodbg_operands(
Reg)) {
338 const MachineOperand &
Def = *
UseMI.defs().begin();
344 bool CrossCopy =
false;
346 const TargetRegisterClass *DstRC = MRI->getRegClass(DefReg);
359 return MRI->getMaxLaneMaskForVReg(
Reg);
361 UsedLanes |= TRI->getSubRegIndexLaneMask(
SubReg);
368class DetectDeadLanes {
370 bool run(MachineFunction &MF);
378 std::pair<bool, bool>
379 modifySubRegisterOperandStatus(
const DeadLaneDetector &DLD,
380 MachineFunction &MF);
382 bool isUndefRegAtInput(
const MachineOperand &MO,
383 const DeadLaneDetector::VRegInfo &RegInfo)
const;
385 bool isUndefInput(
const DeadLaneDetector &DLD,
const MachineOperand &MO,
386 bool *CrossCopy)
const;
388 const MachineRegisterInfo *
MRI =
nullptr;
389 const TargetRegisterInfo *
TRI =
nullptr;
394 DetectDeadLanesLegacy() : MachineFunctionPass(
ID) {}
396 StringRef getPassName()
const override {
return "Detect Dead Lanes"; }
398 void getAnalysisUsage(AnalysisUsage &AU)
const override {
403 bool runOnMachineFunction(MachineFunction &MF)
override {
404 return DetectDeadLanes().run(MF);
410char DetectDeadLanesLegacy::ID = 0;
416bool DetectDeadLanes::isUndefRegAtInput(
418 unsigned SubReg = MO.getSubReg();
425 bool *CrossCopy)
const {
454 unsigned NumVirtRegs = MRI->getNumVirtRegs();
455 for (
unsigned RegIdx = 0; RegIdx < NumVirtRegs; ++RegIdx) {
460 Info.DefinedLanes = determineInitialDefinedLanes(
Reg);
461 Info.UsedLanes = determineInitialUsedLanes(
Reg);
465 while (!Worklist.empty()) {
466 unsigned RegIdx = Worklist.front();
467 Worklist.pop_front();
468 WorklistMembers.reset(RegIdx);
473 MachineOperand &
Def = *MRI->def_begin(
Reg);
474 const MachineInstr &
MI = *
Def.getParent();
475 transferUsedLanesStep(
MI,
Info.UsedLanes);
477 for (
const MachineOperand &MO : MRI->use_nodbg_operands(
Reg))
478 transferDefinedLanesStep(MO,
Info.DefinedLanes);
482 dbgs() <<
"Defined/Used lanes:\n";
483 for (
unsigned RegIdx = 0; RegIdx < NumVirtRegs; ++RegIdx) {
512 <<
"Marking operand '" << MO <<
"' as dead in " <<
MI);
517 bool CrossCopy =
false;
518 if (isUndefRegAtInput(MO, RegInfo)) {
520 <<
"Marking operand '" << MO <<
"' as undef in " <<
MI);
523 }
else if (isUndefInput(DLD, MO, &CrossCopy)) {
525 <<
"Marking operand '" << MO <<
"' as undef in " <<
MI);
536 return std::make_pair(
Changed, Again);
542 if (!DetectDeadLanes().
run(MF))
556 if (!
MRI->subRegLivenessEnabled()) {
561 TRI =
MRI->getTargetRegisterInfo();
570 std::tie(LocalChanged, Again) = modifySubRegisterOperandStatus(DLD, MF);
unsigned const MachineRegisterInfo * MRI
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)
LLVM_ABI void setPreservesCFG()
This function should be called by the pass, iff they do not:
bool test(unsigned Idx) const
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,...
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.
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...
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.
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.
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.
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()