35#define DEBUG_TYPE "gcn-vopd-utils"
40 namespace VOPD = AMDGPU::VOPD;
49 for (
auto &
Literal : UniqueLiterals) {
58 MII != FirstMI.
getParent()->instr_end(); ++MII) {
59 if (&*MII == &SecondMI)
63 }() &&
"Expected FirstMI to precede SecondMI");
65 for (
const auto &
Use : SecondMI.
uses())
69 auto getVRegIdx = [&](
unsigned OpcodeIdx,
unsigned OperandIdx) {
70 const MachineInstr &
MI = (OpcodeIdx == VOPD::X) ? FirstMI : SecondMI;
80 for (
auto CompIdx : VOPD::COMPONENTS) {
81 const MachineInstr &
MI = (CompIdx == VOPD::X) ? FirstMI : SecondMI;
90 if (!
TII.isInlineConstant(
MI, VOPD::Component::SRC0))
94 if (InstInfo[CompIdx].hasMandatoryLiteral()) {
95 auto CompOprIdx = InstInfo[CompIdx].getMandatoryLiteralCompOperandIndex();
96 addLiteral(
MI.getOperand(CompOprIdx));
98 if (
MI.getDesc().hasImplicitUseOfPhysReg(AMDGPU::VCC))
99 UniqueScalarRegs.
push_back(AMDGPU::VCC_LO);
102 if (UniqueLiterals.
size() > 1)
104 if ((UniqueLiterals.
size() + UniqueScalarRegs.
size()) > 2)
109 FirstMI.
getOpcode() == AMDGPU::V_MOV_B32_e32 &&
110 SecondMI.
getOpcode() == AMDGPU::V_MOV_B32_e32;
112 if (InstInfo.hasInvalidOperand(getVRegIdx, SkipSrc))
115 LLVM_DEBUG(
dbgs() <<
"VOPD Reg Constraints Passed\n\tX: " << FirstMI
116 <<
"\n\tY: " << SecondMI <<
"\n");
133 return SecondCanBeVOPD.Y;
138 if (!((FirstCanBeVOPD.X && SecondCanBeVOPD.Y) ||
139 (FirstCanBeVOPD.Y && SecondCanBeVOPD.X)))
161 LLVM_DEBUG(
dbgs() <<
"Target does not support VOPDPairingMutation\n");
165 std::vector<SUnit>::iterator ISUI, JSUI;
166 for (ISUI = DAG->
SUnits.begin(); ISUI != DAG->
SUnits.end(); ++ISUI) {
173 for (JSUI = ISUI + 1; JSUI != DAG->
SUnits.end(); ++JSUI) {
174 if (JSUI->isBoundaryNode())
unsigned const MachineRegisterInfo * MRI
static bool shouldScheduleAdjacent(const TargetInstrInfo &TII, const TargetSubtargetInfo &TSI, const MachineInstr *FirstMI, const MachineInstr &SecondMI)
Check if the instr pair, FirstMI and SecondMI, should be fused together.
Provides AMDGPU specific target descriptions.
Base class for AMDGPU specific classes of TargetSubtarget.
AMD GCN specific subclass of TargetSubtarget.
static bool shouldScheduleVOPDAdjacent(const TargetInstrInfo &TII, const TargetSubtargetInfo &TSI, const MachineInstr *FirstMI, const MachineInstr &SecondMI)
Check if the instr pair, FirstMI and SecondMI, should be scheduled together.
const HexagonInstrInfo * TII
unsigned const TargetRegisterInfo * TRI
Interface definition for SIInstrInfo.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file defines the SmallVector class.
This class represents an Operation in the Expression.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
Representation of each machine instruction.
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
const MachineBasicBlock * getParent() const
iterator_range< mop_iterator > uses()
Returns a range that includes all operands that are register uses.
bool modifiesRegister(Register Reg, const TargetRegisterInfo *TRI) const
Return true if the MachineInstr modifies (fully define or partially define) the specified register.
const MCInstrDesc & getDesc() const
Returns the target instruction descriptor of this MachineInstr.
const MachineFunction * getMF() const
Return the function that contains the basic block that this instruction belongs to.
MachineOperand class - Representation of each machine instruction operand.
bool isReg() const
isReg - Tests if this is a MO_Register operand.
Register getReg() const
getReg - Returns the register number.
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
Wrapper class representing virtual and physical registers.
A ScheduleDAG for scheduling lists of MachineInstr.
Mutate the DAG as a postpass after normal DAG building.
const TargetInstrInfo * TII
Target instruction information.
std::vector< SUnit > SUnits
The scheduling units.
MachineFunction & MF
Machine function.
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
TargetInstrInfo - Interface to description of machine instruction set.
TargetSubtargetInfo - Generic base class for all target subtargets.
A Use represents the edge between a Value definition and its users.
CanBeVOPD getCanBeVOPD(unsigned Opc)
VOPD::InstInfo getVOPDInstInfo(const MCInstrDesc &OpX, const MCInstrDesc &OpY)
bool hasVOPD(const MCSubtargetInfo &STI)
void apply(Opt *O, const Mod &M, const Mods &... Ms)
This is an optimization pass for GlobalISel generic memory operations.
std::unique_ptr< ScheduleDAGMutation > createVOPDPairingMutation()
bool fuseInstructionPair(ScheduleDAGInstrs &DAG, SUnit &FirstSU, SUnit &SecondSU)
Create an artificial edge between FirstSU and SecondSU.
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
bool(*)(const TargetInstrInfo &TII, const TargetSubtargetInfo &STI, const MachineInstr *FirstMI, const MachineInstr &SecondMI) MacroFusionPredTy
Check if the instr pair, FirstMI and SecondMI, should be fused together.
DWARFExpression::Operation Op
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.
bool hasLessThanNumFused(const SUnit &SU, unsigned FuseLimit)
Checks if the number of cluster edges between SU and its predecessors is less than FuseLimit.
bool checkVOPDRegConstraints(const SIInstrInfo &TII, const MachineInstr &FirstMI, const MachineInstr &SecondMI)