89 #define DEBUG_TYPE "si-fix-wwm-liveness" 102 std::vector<MachineInstr *> WWMs;
103 std::vector<MachineOperand *> ThenDefs;
104 std::vector<std::pair<MachineOperand *, MachineLoop *>> LoopExitDefs;
105 std::vector<std::pair<MachineOperand *, MachineLoop *>> LoopPhiDefs;
116 StringRef getPassName()
const override {
return "SI Fix WWM Liveness"; }
141 "SI fix WWM liveness",
false,
false)
147 char SIFixWWMLiveness::
ID = 0;
152 return new SIFixWWMLiveness();
160 LIS = getAnalysisIfAvailable<LiveIntervals>();
164 TII = ST.getInstrInfo();
168 DomTree = &getAnalysis<MachineDominatorTree>();
169 LoopInfo = &getAnalysis<MachineLoopInfo>();
175 if (
MI.getOpcode() == AMDGPU::EXIT_WWM)
179 if (DefOpnd.isReg()) {
180 unsigned Reg = DefOpnd.getReg();
181 if (
TRI->isVGPR(*
MRI, Reg))
190 for (
auto ThenDef : ThenDefs)
191 Modified |= processThenDef(ThenDef);
192 for (
auto LoopExitDef : LoopExitDefs)
193 Modified |= processLoopExitDef(LoopExitDef.first, LoopExitDef.second);
194 for (
auto LoopPhiDef : LoopPhiDefs)
195 Modified |= processLoopPhiDef(LoopPhiDef.first, LoopPhiDef.second);
200 LoopExitDefs.clear();
215 for (
auto &
MI :
MRI->def_instructions(Reg)) {
227 for (
unsigned I = 1;
I != Defs.
size(); ++
I) {
228 if (!DomTree->dominates(Defs[0]->getParent(), Defs[
I]->getParent()))
237 if (Defs.
size() == 2) {
238 auto DomDefBlock = Defs[0]->getParent();
239 if (DomDefBlock->succ_size() == 2 &&
MRI->hasOneUse(Reg)) {
240 auto UseBlock =
MRI->use_begin(Reg)->getParent()->getParent();
241 for (
auto Succ : DomDefBlock->successors()) {
242 if (Succ == UseBlock) {
244 ThenDefs.push_back(&DefOpnd);
256 if (Defs.
size() == 1) {
260 bool IsLoopExit =
false;
261 for (
auto &
Use :
MRI->use_instructions(Reg)) {
262 auto UseBlock =
Use.getParent();
267 if (Parent->contains(UseBlock))
275 <<
" is a loop exit reg with loop header at " 277 LoopExitDefs.push_back(std::pair<MachineOperand *, MachineLoop *>(
289 if (!
MRI->hasOneUse(Reg))
291 auto UseBlock =
MRI->use_begin(Reg)->getParent()->getParent();
296 <<
" is multi-def but single use not in loop header\n");
299 for (
unsigned I = 1;
I != Defs.
size(); ++
I) {
304 <<
" is a loop phi reg with loop header at " 306 LoopPhiDefs.push_back(
307 std::pair<MachineOperand *, MachineLoop *>(&DefOpnd,
Loop));
323 auto UseBlock =
MRI->use_instr_begin(Reg)->getParent();
326 bool ContainsWWM =
false;
327 for (
auto WWM : WWMs) {
329 && !DomTree->dominates(UseBlock, WWM->getParent())) {
339 for (
auto &
MI :
MRI->def_instructions(Reg)) {
353 bool SIFixWWMLiveness::processLoopExitDef(
MachineOperand *DefOpnd,
357 bool ContainsWWM =
false;
358 for (
auto WWM : WWMs) {
359 if (Loop->
contains(WWM->getParent())) {
371 auto ImplicitDef =
BuildMI(*Pred, Pred->getFirstTerminator(),
DebugLoc(),
372 TII->get(TargetOpcode::IMPLICIT_DEF),
Reg);
392 bool ContainsWWM =
false;
393 for (
auto WWM : WWMs) {
394 if (Loop->
contains(WWM->getParent())) {
404 for (
auto &
Use :
MRI->use_operands(Reg))
405 Use.setIsKill(
false);
408 for (
auto &
Def :
MRI->def_instructions(Reg))
410 for (
auto Def : Defs) {
Interface definition for SIRegisterInfo.
AnalysisUsage & addPreserved()
Add the specified Pass class to the set of analyses preserved by this pass.
MachineInstr * getParent()
getParent - Return the instruction that this operand belongs to.
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
AMDGPU specific subclass of TargetSubtarget.
This class represents lattice values for constants.
void push_back(const T &Elt)
char & MachineDominatorsID
MachineDominators - This pass is a machine dominators analysis pass.
unsigned getReg() const
getReg - Returns the register number.
unsigned const TargetRegisterInfo * TRI
static MachineOperand CreateReg(unsigned Reg, bool isDef, bool isImp=false, bool isKill=false, bool isDead=false, bool isUndef=false, bool isEarlyClobber=false, unsigned SubReg=0, bool isDebug=false, bool isInternalRead=false, bool isRenamable=false)
#define INITIALIZE_PASS_DEPENDENCY(depName)
char & MachineLoopInfoID
MachineLoopInfo - This pass is a loop analysis pass.
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
LoopT * getLoopFor(const BlockT *BB) const
Return the inner most loop that BB lives in.
const HexagonInstrInfo * TII
Printable printReg(unsigned Reg, const TargetRegisterInfo *TRI=nullptr, unsigned SubIdx=0, const MachineRegisterInfo *MRI=nullptr)
Prints virtual and physical registers with or without a TRI instance.
A Use represents the edge between a Value definition and its users.
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
BlockT * getHeader() const
AnalysisUsage & addPreservedID(const void *ID)
StringRef getName() const
getName - Return the name of the corresponding LLVM function.
char & LiveVariablesID
LiveVariables pass - This pass computes the set of blocks in which each variable is life and sets mac...
MachineInstrBuilder BuildMI(MachineFunction &MF, const DebugLoc &DL, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
unsigned const MachineRegisterInfo * MRI
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
Represent the analysis usage information of a pass.
INITIALIZE_PASS_BEGIN(SIFixWWMLiveness, DEBUG_TYPE, "SI fix WWM liveness", false, false) INITIALIZE_PASS_END(SIFixWWMLiveness
FunctionPass class - This class is used to implement most global optimizations.
iterator_range< pred_iterator > predecessors()
INITIALIZE_PASS_END(RegBankSelect, DEBUG_TYPE, "Assign register bank of generic virtual registers", false, false) RegBankSelect
char & SIFixWWMLivenessID
FunctionPass * createSIFixWWMLivenessPass()
bool contains(const LoopT *L) const
Return true if the specified loop is contained within in this loop.
void addOperand(MachineFunction &MF, const MachineOperand &Op)
Add the specified operand to the instruction.
void initializeSIFixWWMLivenessPass(PassRegistry &)
AnalysisUsage & addRequiredID(const void *ID)
MachineOperand class - Representation of each machine instruction operand.
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small...
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.
const MachineBasicBlock * getParent() const
MachineRegisterInfo - Keep track of information for virtual and physical registers, including vreg register classes, use/def chains for registers, etc.
LoopT * getParentLoop() const
Provides AMDGPU specific target descriptions.
Representation of each machine instruction.
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
Interface definition for SIInstrInfo.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
Represents a single loop in the control flow graph.
static const Function * getParent(const Value *V)
StringRef - Represent a constant reference to a string, i.e.
DominatorTree Class - Concrete subclass of DominatorTreeBase that is used to compute a normal dominat...
const SIRegisterInfo * getRegisterInfo() const override