100 using namespace llvm;
102 #define DEBUG_TYPE "si-fix-sgpr-copies" 105 "amdgpu-enable-merge-m0",
106 cl::desc(
"Merge and hoist M0 initializations"),
121 StringRef getPassName()
const override {
return "SI Fix SGPR copies"; }
134 "SI Fix SGPR copies",
false,
false)
139 char SIFixSGPRCopies::
ID = 0;
144 return new SIFixSGPRCopies();
160 static std::pair<const TargetRegisterClass *, const TargetRegisterClass *>
180 return std::make_pair(SrcRC, DstRC);
186 return SrcRC != &AMDGPU::VReg_1RegClass && TRI.
isSGPRClass(DstRC) &&
193 return DstRC != &AMDGPU::VReg_1RegClass && TRI.
isSGPRClass(SrcRC) &&
203 unsigned SrcReg = Src.getReg();
209 const auto *
UseMI = MO.getParent();
267 if (SubReg != AMDGPU::NoSubRegister)
288 "Expected SGPR REG_SEQUENCE to only have SGPR inputs");
323 if (Visited.
count(Reg))
332 case AMDGPU::SI_IF_BREAK:
346 if (
I->modifiesRegister(AMDGPU::EXEC, &TRI))
375 case AMDGPU::V_MOV_B32_e32:
376 SMovOp = AMDGPU::S_MOV_B32;
378 case AMDGPU::V_MOV_B64_PSEUDO:
379 SMovOp = AMDGPU::S_MOV_B64;
386 template <
class UnaryPredicate>
397 while (!Worklist.empty()) {
400 if (!Visited.
insert(MBB).second)
433 if (MBBFrom == MBBTo)
451 using InitListMap = std::map<unsigned, std::list<MachineInstr *>>;
455 bool Changed =
false;
459 for (
auto &MO:
MI.operands()) {
460 if ((MO.isReg() && ((MO.isDef() && MO.getReg() !=
Reg) || !MO.isDef())) ||
461 (!MO.isImm() && !MO.isReg()) || (MO.isImm() && Imm)) {
464 }
else if (MO.isImm())
468 Inits[Imm->
getImm()].push_front(&
MI);
473 for (
auto &
Init : Inits) {
474 auto &Defs =
Init.second;
476 for (
auto I1 = Defs.begin(),
E = Defs.end(); I1 !=
E; ) {
479 for (
auto I2 = std::next(I1); I2 !=
E; ) {
491 bool MayClobberFrom =
isReachable(Clobber, &*From, MBBTo, MDT);
492 bool MayClobberTo =
isReachable(Clobber, &*To, MBBTo, MDT);
493 if (!MayClobberFrom && !MayClobberTo)
495 if ((MayClobberFrom && !MayClobberTo) ||
496 (!MayClobberFrom && MayClobberTo))
502 return !((MBBFrom == MBBTo &&
510 return C.first !=
Init.first &&
516 if (!intereferes(MI2, MI1)) {
526 if (!intereferes(MI1, MI2)) {
544 if (!intereferes(MI1, I) && !intereferes(MI2, I)) {
548 <<
"and moving from " 551 I->getParent()->splice(I, MI2->
getParent(), MI2);
575 MDT = &getAnalysis<MachineDominatorTree>();
639 <<
"Not fixing PHI for uniform branch: " << MI <<
'\n');
684 case AMDGPU::REG_SEQUENCE:
695 case AMDGPU::INSERT_SUBREG: {
Interface definition for SIRegisterInfo.
static cl::opt< bool > EnableM0Merge("amdgpu-enable-merge-m0", cl::desc("Merge and hoist M0 initializations"), cl::init(false))
AnalysisUsage & addPreserved()
Add the specified Pass class to the set of analyses preserved by this pass.
AMDGPU specific subclass of TargetSubtarget.
MachineBasicBlock * getMBB() const
const TargetRegisterClass * getRegClass(unsigned Reg) const
Return the register class of the specified virtual register.
static bool isSafeToFoldImmIntoCopy(const MachineInstr *Copy, const MachineInstr *MoveImm, const SIInstrInfo *TII, unsigned &SMovOp, int64_t &Imm)
This class represents lattice values for constants.
bool isOperandLegal(const MachineInstr &MI, unsigned OpIdx, const MachineOperand *MO=nullptr) const
Check if MO is a legal operand if it was the OpIdx Operand for MI.
const TargetRegisterClass * getEquivalentVGPRClass(const TargetRegisterClass *SRC) const
Implements a dense probed hash-table based set.
void push_back(const T &Elt)
const DebugLoc & getDebugLoc() const
Returns the debug location id of this MachineInstr.
const TargetRegisterClass * getOpRegClass(const MachineInstr &MI, unsigned OpNo) const
Return the correct register class for OpNo.
iterator getFirstTerminator()
Returns an iterator to the first terminator instruction of this basic block.
unsigned getReg() const
getReg - Returns the register number.
unsigned getOperandNo(const_mop_iterator I) const
Returns the number of the operand iterator I points to.
static bool isVirtualRegister(unsigned Reg)
Return true if the specified register number is in the virtual register namespace.
iterator_range< reg_nodbg_iterator > reg_nodbg_operands(unsigned Reg) const
unsigned getSubReg() const
bool isRegSequence() const
const SIInstrInfo * getInstrInfo() const override
unsigned const TargetRegisterInfo * TRI
const TargetRegisterClass * getEquivalentSGPRClass(const TargetRegisterClass *VRC) const
static bool hasVGPROperands(const MachineInstr &MI, const SIRegisterInfo *TRI)
bool isImm() const
isImm - Tests if this is a MO_Immediate operand.
bool isMoveImmediate(QueryType Type=IgnoreBundle) const
Return true if this instruction is a move immediate (including conditional moves) instruction...
static bool foldVGPRCopyIntoRegSequence(MachineInstr &MI, const SIRegisterInfo *TRI, const SIInstrInfo *TII, MachineRegisterInfo &MRI)
static bool tryChangeVGPRtoSGPRinCopy(MachineInstr &MI, const SIRegisterInfo *TRI, const SIInstrInfo *TII)
AnalysisUsage & addRequired()
#define INITIALIZE_PASS_DEPENDENCY(depName)
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
const HexagonInstrInfo * TII
Printable printMBBReference(const MachineBasicBlock &MBB)
Prints a machine basic block reference.
unsigned getNumOperands() const
Retuns the total number of operands.
void eraseFromParent()
Unlink 'this' from the containing basic block and delete it.
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
bool isSGPRClass(const TargetRegisterClass *RC) const
static bool hoistAndMergeSGPRInits(unsigned Reg, const MachineRegisterInfo &MRI, MachineDominatorTree &MDT)
MachineInstr * getVRegDef(unsigned Reg) const
getVRegDef - Return the machine instr that defines the specified virtual register or null if none is ...
void clearKillFlags(unsigned Reg) const
clearKillFlags - Iterate over all the uses of the given register and clear the kill flag from the Mac...
INITIALIZE_PASS_BEGIN(SIFixSGPRCopies, DEBUG_TYPE, "SI Fix SGPR copies", false, false) INITIALIZE_PASS_END(SIFixSGPRCopies
LLVM_READONLY MachineOperand * getNamedOperand(MachineInstr &MI, unsigned OperandName) const
Returns the operand named Op.
MachineBasicBlock * findNearestCommonDominator(MachineBasicBlock *A, MachineBasicBlock *B)
findNearestCommonDominator - Find nearest common dominator basic block for basic block A and B...
static bool isSGPRToVGPRCopy(const TargetRegisterClass *SrcRC, const TargetRegisterClass *DstRC, const SIRegisterInfo &TRI)
void ChangeToImmediate(int64_t ImmVal)
ChangeToImmediate - Replace this operand with a new immediate operand of the specified value...
MachineInstrBuilder BuildMI(MachineFunction &MF, const DebugLoc &DL, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
initializer< Ty > init(const Ty &Val)
CodeGenOpt::Level getOptLevel() const
Returns the optimization level: None, Less, Default, or Aggressive.
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.
MachineInstrBuilder & UseMI
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
std::pair< iterator, bool > insert(const ValueT &V)
bool hasVGPRs(const TargetRegisterClass *RC) const
Represent the analysis usage information of a pass.
use_instr_iterator use_instr_begin(unsigned RegNo) const
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly...
FunctionPass class - This class is used to implement most global optimizations.
std::pair< NoneType, bool > insert(const T &V)
insert - Insert an element into the set if it isn't already there.
const TargetRegisterClass * getSubRegClass(const TargetRegisterClass *RC, unsigned SubIdx) const
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
pred_iterator pred_begin()
INITIALIZE_PASS_END(RegBankSelect, DEBUG_TYPE, "Assign register bank of generic virtual registers", false, false) RegBankSelect
unsigned getNumExplicitOperands() const
Returns the number of non-implicit operands.
static bool phiHasBreakDef(const MachineInstr &PHI, const MachineRegisterInfo &MRI, SmallSet< unsigned, 8 > &Visited)
Iterator for intrusive lists based on ilist_node.
static std::pair< const TargetRegisterClass *, const TargetRegisterClass * > getCopyRegClasses(const MachineInstr &Copy, const SIRegisterInfo &TRI, const MachineRegisterInfo &MRI)
void setDesc(const MCInstrDesc &tid)
Replace the instruction descriptor (thus opcode) of the current instruction with a new one...
BlockVerifier::State From
bool searchPredecessors(const MachineBasicBlock *MBB, const MachineBasicBlock *CutOff, UnaryPredicate Predicate)
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...
bool dominates(const MachineDomTreeNode *A, const MachineDomTreeNode *B) const
MachineInstrBuilder MachineInstrBuilder & DefMI
Predicate
Predicate - These are "(BI << 5) | BO" for various predicates.
bool properlyDominates(const MachineDomTreeNode *A, const MachineDomTreeNode *B) const
void setPreservesCFG()
This function should be called by the pass, iff they do not:
static bool hasTerminatorThatModifiesExec(const MachineBasicBlock &MBB, const TargetRegisterInfo &TRI)
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
void addImplicitDefUseOperands(MachineFunction &MF)
Add all implicit def and use operands to this instruction.
FunctionPass * createSIFixSGPRCopiesPass()
static bool phiHasVGPROperands(const MachineInstr &PHI, const MachineRegisterInfo &MRI, const SIRegisterInfo *TRI, const SIInstrInfo *TII)
static bool isVGPRToSGPRCopy(const TargetRegisterClass *SrcRC, const TargetRegisterClass *DstRC, const SIRegisterInfo &TRI)
const MachineBasicBlock * getParent() const
MachineRegisterInfo - Keep track of information for virtual and physical registers, including vreg register classes, use/def chains for registers, etc.
Provides AMDGPU specific target descriptions.
Representation of each machine instruction.
static bool isPhysicalRegister(unsigned Reg)
Return true if the specified register number is in the physical register namespace.
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
Interface definition for SIInstrInfo.
void moveToVALU(MachineInstr &MI, MachineDominatorTree *MDT=nullptr) const
Replace this instruction's opcode with the equivalent VALU opcode.
bool hasOneUse(unsigned RegNo) const
hasOneUse - Return true if there is exactly one instruction using the specified register.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
void setReg(unsigned Reg)
Change the register this operand corresponds to.
const LLVMTargetMachine & getTarget() const
getTarget - Return the target machine this machine code is compiled with
static bool predsHasDivergentTerminator(MachineBasicBlock *MBB, const TargetRegisterInfo *TRI)
bool isReg() const
isReg - Tests if this is a MO_Register operand.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
const TargetRegisterClass * getPhysRegClass(unsigned Reg) const
Return the 'base' register class for this register.
iterator_range< def_instr_iterator > def_instructions(unsigned Reg) const
void setRegClass(unsigned Reg, const TargetRegisterClass *RC)
setRegClass - Set the register class of the specified virtual register.
StringRef - Represent a constant reference to a string, i.e.
const MachineOperand & getOperand(unsigned i) const
DominatorTree Class - Concrete subclass of DominatorTreeBase that is used to compute a normal dominat...
static bool isReachable(const MachineInstr *From, const MachineInstr *To, const MachineBasicBlock *CutOff, MachineDominatorTree &MDT)
unsigned createVirtualRegister(const TargetRegisterClass *RegClass, StringRef Name="")
createVirtualRegister - Create and return a new virtual register in the function with the specified r...
size_type count(const T &V) const
count - Return 1 if the element is in the set, 0 otherwise.
const SIRegisterInfo * getRegisterInfo() const override