aboutsummaryrefslogtreecommitdiffstats
path: root/lib/Target/R600/R600Packetizer.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Target/R600/R600Packetizer.cpp')
-rw-r--r--lib/Target/R600/R600Packetizer.cpp246
1 files changed, 64 insertions, 182 deletions
diff --git a/lib/Target/R600/R600Packetizer.cpp b/lib/Target/R600/R600Packetizer.cpp
index 05e96f1..da614c7 100644
--- a/lib/Target/R600/R600Packetizer.cpp
+++ b/lib/Target/R600/R600Packetizer.cpp
@@ -14,22 +14,21 @@
//
//===----------------------------------------------------------------------===//
-#ifndef R600PACKETIZER_CPP
-#define R600PACKETIZER_CPP
-
#define DEBUG_TYPE "packets"
#include "llvm/Support/Debug.h"
-#include "llvm/Support/raw_ostream.h"
+#include "AMDGPU.h"
+#include "R600InstrInfo.h"
#include "llvm/CodeGen/DFAPacketizer.h"
-#include "llvm/CodeGen/Passes.h"
-#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/CodeGen/MachineDominators.h"
+#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/CodeGen/MachineLoopInfo.h"
+#include "llvm/CodeGen/Passes.h"
#include "llvm/CodeGen/ScheduleDAG.h"
-#include "AMDGPU.h"
-#include "R600InstrInfo.h"
+#include "llvm/Support/raw_ostream.h"
+
+using namespace llvm;
-namespace llvm {
+namespace {
class R600Packetizer : public MachineFunctionPass {
@@ -60,37 +59,59 @@ private:
const R600InstrInfo *TII;
const R600RegisterInfo &TRI;
- enum BankSwizzle {
- ALU_VEC_012 = 0,
- ALU_VEC_021,
- ALU_VEC_120,
- ALU_VEC_102,
- ALU_VEC_201,
- ALU_VEC_210
- };
-
unsigned getSlot(const MachineInstr *MI) const {
return TRI.getHWRegChan(MI->getOperand(0).getReg());
}
- std::vector<unsigned> getPreviousVector(MachineBasicBlock::iterator I) const {
- std::vector<unsigned> Result;
+ /// \returns register to PV chan mapping for bundle/single instructions that
+ /// immediatly precedes I.
+ DenseMap<unsigned, unsigned> getPreviousVector(MachineBasicBlock::iterator I)
+ const {
+ DenseMap<unsigned, unsigned> Result;
I--;
if (!TII->isALUInstr(I->getOpcode()) && !I->isBundle())
return Result;
MachineBasicBlock::instr_iterator BI = I.getInstrIterator();
if (I->isBundle())
BI++;
- while (BI->isBundledWithPred() && !TII->isPredicated(BI)) {
+ do {
+ if (TII->isPredicated(BI))
+ continue;
+ if (TII->isTransOnly(BI))
+ continue;
int OperandIdx = TII->getOperandIdx(BI->getOpcode(), R600Operands::WRITE);
- if (OperandIdx > -1 && BI->getOperand(OperandIdx).getImm())
- Result.push_back(BI->getOperand(0).getReg());
- BI++;
- }
+ if (OperandIdx > -1 && BI->getOperand(OperandIdx).getImm() == 0)
+ continue;
+ unsigned Dst = BI->getOperand(0).getReg();
+ if (BI->getOpcode() == AMDGPU::DOT4_r600 ||
+ BI->getOpcode() == AMDGPU::DOT4_eg) {
+ Result[Dst] = AMDGPU::PV_X;
+ continue;
+ }
+ unsigned PVReg = 0;
+ switch (TRI.getHWRegChan(Dst)) {
+ case 0:
+ PVReg = AMDGPU::PV_X;
+ break;
+ case 1:
+ PVReg = AMDGPU::PV_Y;
+ break;
+ case 2:
+ PVReg = AMDGPU::PV_Z;
+ break;
+ case 3:
+ PVReg = AMDGPU::PV_W;
+ break;
+ default:
+ llvm_unreachable("Invalid Chan");
+ }
+ Result[Dst] = PVReg;
+ } while ((++BI)->isBundledWithPred());
return Result;
}
- void substitutePV(MachineInstr *MI, const std::vector<unsigned> &PV) const {
+ void substitutePV(MachineInstr *MI, const DenseMap<unsigned, unsigned> &PVs)
+ const {
R600Operands::Ops Ops[] = {
R600Operands::SRC0,
R600Operands::SRC1,
@@ -101,30 +122,9 @@ private:
if (OperandIdx < 0)
continue;
unsigned Src = MI->getOperand(OperandIdx).getReg();
- for (unsigned j = 0, e = PV.size(); j < e; j++) {
- if (Src == PV[j]) {
- unsigned Chan = TRI.getHWRegChan(Src);
- unsigned PVReg;
- switch (Chan) {
- case 0:
- PVReg = AMDGPU::PV_X;
- break;
- case 1:
- PVReg = AMDGPU::PV_Y;
- break;
- case 2:
- PVReg = AMDGPU::PV_Z;
- break;
- case 3:
- PVReg = AMDGPU::PV_W;
- break;
- default:
- llvm_unreachable("Invalid Chan");
- }
- MI->getOperand(OperandIdx).setReg(PVReg);
- break;
- }
- }
+ const DenseMap<unsigned, unsigned>::const_iterator It = PVs.find(Src);
+ if (It != PVs.end())
+ MI->getOperand(OperandIdx).setReg(It->second);
}
}
public:
@@ -209,8 +209,11 @@ public:
}
dbgs() << "because of Consts read limitations\n";
});
- const std::vector<unsigned> &PV = getPreviousVector(MI);
- bool FitsReadPortLimits = fitsReadPortLimitation(CurrentPacketMIs, PV);
+ const DenseMap<unsigned, unsigned> &PV =
+ getPreviousVector(CurrentPacketMIs.front());
+ std::vector<R600InstrInfo::BankSwizzle> BS;
+ bool FitsReadPortLimits =
+ TII->fitsReadPortLimitations(CurrentPacketMIs, PV, BS);
DEBUG(
if (!FitsReadPortLimits) {
dbgs() << "Couldn't pack :\n";
@@ -223,6 +226,14 @@ public:
dbgs() << "because of Read port limitations\n";
});
bool isBundlable = FitsConstLimits && FitsReadPortLimits;
+ if (isBundlable) {
+ for (unsigned i = 0, e = CurrentPacketMIs.size(); i < e; i++) {
+ MachineInstr *MI = CurrentPacketMIs[i];
+ unsigned Op = TII->getOperandIdx(MI->getOpcode(),
+ R600Operands::BANK_SWIZZLE);
+ MI->getOperand(Op).setImm(BS[i]);
+ }
+ }
CurrentPacketMIs.pop_back();
if (!isBundlable) {
endPacket(MI->getParent(), MI);
@@ -234,133 +245,6 @@ public:
substitutePV(MI, PV);
return VLIWPacketizerList::addToPacket(MI);
}
-private:
- std::vector<std::pair<int, unsigned> >
- ExtractSrcs(const MachineInstr *MI, const std::vector<unsigned> &PV) const {
- R600Operands::Ops Ops[] = {
- R600Operands::SRC0,
- R600Operands::SRC1,
- R600Operands::SRC2
- };
- std::vector<std::pair<int, unsigned> > Result;
- for (unsigned i = 0; i < 3; i++) {
- int OperandIdx = TII->getOperandIdx(MI->getOpcode(), Ops[i]);
- if (OperandIdx < 0){
- Result.push_back(std::pair<int, unsigned>(-1,0));
- continue;
- }
- unsigned Src = MI->getOperand(OperandIdx).getReg();
- if (std::find(PV.begin(), PV.end(), Src) != PV.end()) {
- Result.push_back(std::pair<int, unsigned>(-1,0));
- continue;
- }
- unsigned Reg = TRI.getEncodingValue(Src) & 0xff;
- if (Reg > 127) {
- Result.push_back(std::pair<int, unsigned>(-1,0));
- continue;
- }
- unsigned Chan = TRI.getHWRegChan(Src);
- Result.push_back(std::pair<int, unsigned>(Reg, Chan));
- }
- return Result;
- }
-
- std::vector<std::pair<int, unsigned> >
- Swizzle(std::vector<std::pair<int, unsigned> > Src,
- BankSwizzle Swz) const {
- switch (Swz) {
- case ALU_VEC_012:
- break;
- case ALU_VEC_021:
- std::swap(Src[1], Src[2]);
- break;
- case ALU_VEC_102:
- std::swap(Src[0], Src[1]);
- break;
- case ALU_VEC_120:
- std::swap(Src[0], Src[1]);
- std::swap(Src[0], Src[2]);
- break;
- case ALU_VEC_201:
- std::swap(Src[0], Src[2]);
- std::swap(Src[0], Src[1]);
- break;
- case ALU_VEC_210:
- std::swap(Src[0], Src[2]);
- break;
- }
- return Src;
- }
-
- bool isLegal(const std::vector<MachineInstr *> &IG,
- const std::vector<BankSwizzle> &Swz,
- const std::vector<unsigned> &PV) const {
- assert (Swz.size() == IG.size());
- int Vector[4][3];
- memset(Vector, -1, sizeof(Vector));
- for (unsigned i = 0, e = IG.size(); i < e; i++) {
- const std::vector<std::pair<int, unsigned> > &Srcs =
- Swizzle(ExtractSrcs(IG[i], PV), Swz[i]);
- for (unsigned j = 0; j < 3; j++) {
- const std::pair<int, unsigned> &Src = Srcs[j];
- if (Src.first < 0)
- continue;
- if (Vector[Src.second][j] < 0)
- Vector[Src.second][j] = Src.first;
- if (Vector[Src.second][j] != Src.first)
- return false;
- }
- }
- return true;
- }
-
- bool recursiveFitsFPLimitation(
- std::vector<MachineInstr *> IG,
- const std::vector<unsigned> &PV,
- std::vector<BankSwizzle> &SwzCandidate,
- std::vector<MachineInstr *> CurrentlyChecked)
- const {
- if (!isLegal(CurrentlyChecked, SwzCandidate, PV))
- return false;
- if (IG.size() == CurrentlyChecked.size()) {
- return true;
- }
- BankSwizzle AvailableSwizzle[] = {
- ALU_VEC_012,
- ALU_VEC_021,
- ALU_VEC_120,
- ALU_VEC_102,
- ALU_VEC_201,
- ALU_VEC_210
- };
- CurrentlyChecked.push_back(IG[CurrentlyChecked.size()]);
- for (unsigned i = 0; i < 6; i++) {
- SwzCandidate.push_back(AvailableSwizzle[i]);
- if (recursiveFitsFPLimitation(IG, PV, SwzCandidate, CurrentlyChecked))
- return true;
- SwzCandidate.pop_back();
- }
- return false;
- }
-
- bool fitsReadPortLimitation(
- std::vector<MachineInstr *> IG,
- const std::vector<unsigned> &PV)
- const {
- //Todo : support shared src0 - src1 operand
- std::vector<BankSwizzle> SwzCandidate;
- bool Result = recursiveFitsFPLimitation(IG, PV, SwzCandidate,
- std::vector<MachineInstr *>());
- if (!Result)
- return false;
- for (unsigned i = 0, e = IG.size(); i < e; i++) {
- MachineInstr *MI = IG[i];
- unsigned Op = TII->getOperandIdx(MI->getOpcode(),
- R600Operands::BANK_SWIZZLE);
- MI->getOperand(Op).setImm(SwzCandidate[i]);
- }
- return true;
- }
};
bool R600Packetizer::runOnMachineFunction(MachineFunction &Fn) {
@@ -437,10 +321,8 @@ bool R600Packetizer::runOnMachineFunction(MachineFunction &Fn) {
}
-}
+} // end anonymous namespace
llvm::FunctionPass *llvm::createR600Packetizer(TargetMachine &tm) {
return new R600Packetizer(tm);
}
-
-#endif // R600PACKETIZER_CPP