32 #define DEBUG_TYPE "packets" 51 StringRef getPassName()
const override {
return "R600 Packetizer"; }
61 bool ConsideredInstUsesAlreadyWrittenVectorElement;
73 if (!TII->
isALUInstr(I->getOpcode()) && !I->isBundle())
81 int BISlot = getSlot(*BI);
82 if (LastDstChan >= BISlot)
88 if (OperandIdx > -1 && BI->getOperand(OperandIdx).getImm() == 0)
90 int DstIdx = TII->
getOperandIdx(BI->getOpcode(), R600::OpName::dst);
94 unsigned Dst = BI->getOperand(DstIdx).getReg();
96 Result[Dst] = R600::PS;
99 if (BI->getOpcode() == R600::DOT4_r600 ||
100 BI->getOpcode() == R600::DOT4_eg) {
101 Result[Dst] = R600::PV_X;
104 if (Dst == R600::OQAP) {
125 }
while ((++BI)->isBundledWithPred());
136 for (
unsigned i = 0; i < 3; i++) {
157 void initPacketizerState()
override {
158 ConsideredInstUsesAlreadyWrittenVectorElement =
false;
169 bool isSoloInstruction(
const MachineInstr &MI)
override {
174 if (MI.
getOpcode() == R600::GROUP_BARRIER)
183 bool isLegalToPacketizeTogether(
SUnit *SUI,
SUnit *SUJ)
override {
185 if (getSlot(*MII) == getSlot(*MIJ))
186 ConsideredInstUsesAlreadyWrittenVectorElement =
true;
189 OpJ = TII->
getOperandIdx(MIJ->getOpcode(), R600::OpName::pred_sel);
191 PredJ = (OpJ > -1)?MIJ->getOperand(OpJ).getReg():0;
195 for (
unsigned i = 0, e = SUJ->
Succs.size(); i < e; ++i) {
213 return !ARDef || !ARUse;
218 bool isLegalToPruneDependencies(
SUnit *SUI,
SUnit *SUJ)
override {
229 std::vector<R600InstrInfo::BankSwizzle> &BS,
232 assert (!isTransSlot || VLIW5);
235 if (!isTransSlot && !CurrentPacketMIs.empty()) {
236 if (getSlot(MI) <= getSlot(*CurrentPacketMIs.back())) {
237 if (ConsideredInstUsesAlreadyWrittenVectorElement &&
241 dbgs() <<
"Considering as Trans Inst :";
251 CurrentPacketMIs.push_back(&MI);
254 dbgs() <<
"Couldn't pack :\n";
256 dbgs() <<
"with the following packets :\n";
257 for (
unsigned i = 0, e = CurrentPacketMIs.size() - 1; i < e; i++) {
258 CurrentPacketMIs[i]->dump();
261 dbgs() <<
"because of Consts read limitations\n";
263 CurrentPacketMIs.pop_back();
269 PV, BS, isTransSlot)) {
271 dbgs() <<
"Couldn't pack :\n";
273 dbgs() <<
"with the following packets :\n";
274 for (
unsigned i = 0, e = CurrentPacketMIs.size() - 1; i < e; i++) {
275 CurrentPacketMIs[i]->dump();
278 dbgs() <<
"because of Read port limitations\n";
280 CurrentPacketMIs.pop_back();
288 CurrentPacketMIs.pop_back();
294 CurrentPacketMIs.empty() ? &
MI : CurrentPacketMIs.front();
296 getPreviousVector(FirstInBundle);
297 std::vector<R600InstrInfo::BankSwizzle> BS;
300 if (isBundlableWithCurrentPMI(MI, PV, BS, isTransSlot)) {
301 for (
unsigned i = 0, e = CurrentPacketMIs.size(); i < e; i++) {
304 R600::OpName::bank_swizzle);
310 if (!CurrentPacketMIs.empty())
311 setIsLastBit(CurrentPacketMIs.back(), 0);
312 substitutePV(MI, PV);
315 endPacket(std::next(It)->
getParent(), std::next(It));
336 assert(Packetizer.getResourceTracker() &&
"Empty DFA table!");
337 assert(Packetizer.getResourceTracker()->getInstrItins());
339 if (Packetizer.getResourceTracker()->getInstrItins()->isEmpty())
353 MBB != MBBe; ++MBB) {
357 if (MI->isKill() || MI->getOpcode() == R600::IMPLICIT_DEF ||
358 (MI->getOpcode() == R600::CF_ALU && !MI->getOperand(8).getImm())) {
361 MBB->erase(DeleteMI);
371 MBB != MBBe; ++MBB) {
373 unsigned RemainingCount = MBB->size();
375 RegionEnd != MBB->begin();) {
379 for(;I != MBB->begin(); --
I, --RemainingCount) {
380 if (TII->isSchedulingBoundary(*std::prev(I), &*MBB, Fn))
386 if (I == RegionEnd) {
387 RegionEnd = std::prev(RegionEnd);
392 if (I == std::prev(RegionEnd)) {
393 RegionEnd = std::prev(RegionEnd);
397 Packetizer.PacketizeMIs(&*MBB, &*I, RegionEnd);
409 "R600 Packetizer",
false,
false)
413 char R600Packetizer::
ID = 0;
418 return new R600Packetizer();
bool usesAddressRegister(MachineInstr &MI) const
AnalysisUsage & addPreserved()
Add the specified Pass class to the set of analyses preserved by this pass.
AMDGPU specific subclass of TargetSubtarget.
This class represents lattice values for constants.
Interface definition for R600InstrInfo.
unsigned getReg() const
getReg - Returns the register number.
bool isPredicated(const MachineInstr &MI) const override
unsigned const TargetRegisterInfo * TRI
A register anti-dependence (aka WAR).
AnalysisUsage & addRequired()
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
const HexagonInstrInfo * TII
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
A register output-dependence (aka WAW).
virtual MachineBasicBlock::iterator addToPacket(MachineInstr &MI)
instr_iterator getInstrIterator() const
iterator find(const_arg_type_t< KeyT > Val)
MachineInstr * getInstr() const
Returns the representative MachineInstr for this SUnit.
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.
const R600InstrInfo * getInstrInfo() const override
bool isLDSInstr(unsigned Opcode) const
void setImm(int64_t immVal)
FunctionPass class - This class is used to implement most global optimizations.
int getOperandIdx(const MachineInstr &MI, unsigned Op) const
Get the index of Op in the MachineInstr.
const R600RegisterInfo & getRegisterInfo() const
bool isVectorOnly(unsigned Opcode) const
static void write(bool isBE, void *P, T V)
INITIALIZE_PASS_END(RegBankSelect, DEBUG_TYPE, "Assign register bank of generic virtual registers", false, false) RegBankSelect
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
bool fitsConstReadLimitations(const std::vector< MachineInstr *> &) const
An instruction group can only access 2 channel pair (either [XY] or [ZW]) from KCache bank on R700+...
bool isTransOnly(unsigned Opcode) const
INITIALIZE_PASS_BEGIN(R600Packetizer, DEBUG_TYPE, "R600 Packetizer", false, false) INITIALIZE_PASS_END(R600Packetizer
bool isVector(const MachineInstr &MI) const
Vector instructions are instructions that must fill all instruction slots within an instruction group...
Iterator for intrusive lists based on ilist_node.
bool hasCaymanISA() const
void setPreservesCFG()
This function should be called by the pass, iff they do not:
unsigned getHWRegChan(unsigned reg) const
get the HW encoding for a register's channel.
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
bool isALUInstr(unsigned Opcode) const
bool readsLDSSrcReg(const MachineInstr &MI) const
FunctionPass * createR600Packetizer()
const MachineBasicBlock * getParent() const
Provides AMDGPU specific target descriptions.
Representation of each machine instruction.
bool fitsReadPortLimitations(const std::vector< MachineInstr *> &MIs, const DenseMap< unsigned, unsigned > &PV, std::vector< BankSwizzle > &BS, bool isLastAluTrans) const
Given the order VEC_012 < VEC_021 < VEC_120 < VEC_102 < VEC_201 < VEC_210 returns true and the first ...
void setReg(unsigned Reg)
Change the register this operand corresponds to.
Kind getKind() const
Returns an enum value representing the kind of the dependence.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
SmallVector< SDep, 4 > Succs
All sunit successors.
static const Function * getParent(const Value *V)
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...
bool isSucc(const SUnit *N) const
Tests if node N is a successor of this node.
bool definesAddressRegister(MachineInstr &MI) const
Scheduling unit. This is a node in the scheduling DAG.