Go to the documentation of this file.
36 #define DEBUG_TYPE "gcn-create-vopd"
37 STATISTIC(NumVOPDCreated,
"Number of VOPD Insts Created.");
57 return "GCN Create VOPD Instructions";
61 std::pair<MachineInstr *, MachineInstr *> &Pair) {
62 auto *FirstMI = Pair.first;
63 auto *SecondMI = Pair.second;
64 unsigned Opc1 = FirstMI->getOpcode();
65 unsigned Opc2 = SecondMI->getOpcode();
69 "Should have previously determined this as a possible VOPD\n");
71 auto VOPDInst =
BuildMI(*FirstMI->getParent(), FirstMI,
72 FirstMI->getDebugLoc(), SII->get(NewOpcode))
73 .
setMIFlags(FirstMI->getFlags() | SecondMI->getFlags());
75 namespace VOPD = AMDGPU::VOPD;
81 auto MCOprIdx = InstInfo[CompIdx].getIndexOfDstInMCOperands();
82 VOPDInst.add(
MI[CompIdx]->getOperand(MCOprIdx));
86 auto CompSrcOprNum = InstInfo[CompIdx].getCompSrcOperandsNum();
87 for (
unsigned CompSrcIdx = 0; CompSrcIdx < CompSrcOprNum; ++CompSrcIdx) {
88 auto MCOprIdx = InstInfo[CompIdx].getIndexOfSrcInMCOperands(CompSrcIdx);
89 VOPDInst.add(
MI[CompIdx]->getOperand(MCOprIdx));
94 VOPDInst.copyImplicitOps(*
MI[CompIdx]);
97 << *Pair.first <<
"\tY: " << *Pair.second <<
"\n");
100 MI[CompIdx]->eraseFromParent();
115 bool Changed =
false;
119 for (
auto &
MBB : MF) {
122 auto *FirstMI = &*MII;
126 if (FirstMI->isDebugInstr())
128 auto *SecondMI = &*MII;
129 unsigned Opc = FirstMI->getOpcode();
130 unsigned Opc2 = SecondMI->getOpcode();
133 std::pair<MachineInstr *, MachineInstr *> Pair;
135 if (FirstCanBeVOPD.
X && SecondCanBeVOPD.
Y)
136 Pair = {FirstMI, SecondMI};
137 else if (FirstCanBeVOPD.
Y && SecondCanBeVOPD.
X)
138 Pair = {SecondMI, FirstMI};
144 ReplaceCandidates.push_back(Pair);
149 for (
auto &Pair : ReplaceCandidates) {
150 Changed |= doReplace(SII, Pair);
IterT next_nodbg(IterT It, IterT End, bool SkipPseudoOp=true)
Increment It, then continue incrementing it while it points to a debug instruction.
This is an optimization pass for GlobalISel generic memory operations.
bool hasVOPD(const MCSubtargetInfo &STI)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
bool checkVOPDRegConstraints(const SIInstrInfo &TII, const MachineInstr &FirstMI, const MachineInstr &SecondMI)
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
int getVOPDFull(unsigned OpX, unsigned OpY)
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
Represent the analysis usage information of a pass.
VOPD::InstInfo getVOPDInstInfo(const MCInstrDesc &OpX, const MCInstrDesc &OpY)
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
Representation of each machine instruction.
STATISTIC(NumVOPDCreated, "Number of VOPD Insts Created.")
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
StringRef - Represent a constant reference to a string, i.e.
void setPreservesCFG()
This function should be called by the pass, iff they do not:
constexpr unsigned COMPONENTS[]
Function & getFunction()
Return the LLVM function that this machine code represents.
unsigned getVOPDOpcode(unsigned Opc)
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
const MachineInstrBuilder & setMIFlags(unsigned Flags) const
CanBeVOPD getCanBeVOPD(unsigned Opc)