Skip to content

Commit

Permalink
R600: Use depth first scheduling algorithm
Browse files Browse the repository at this point in the history
It should increase PV substitution opportunities and lower gpr
usage (pending computations path are "flushed" sooner)

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@182128 91177308-0d34-0410-b5e6-96231b3b80d8
  • Loading branch information
Vincent Lejeune committed May 17, 2013
1 parent f63f85a commit 21ca0b3
Show file tree
Hide file tree
Showing 4 changed files with 33 additions and 81 deletions.
78 changes: 26 additions & 52 deletions lib/Target/R600/R600MachineScheduler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@
#include "llvm/Pass.h"
#include "llvm/PassManager.h"
#include "llvm/Support/raw_ostream.h"
#include <set>

using namespace llvm;

Expand All @@ -31,9 +30,6 @@ void R600SchedStrategy::initialize(ScheduleDAGMI *dag) {
TII = static_cast<const R600InstrInfo*>(DAG->TII);
TRI = static_cast<const R600RegisterInfo*>(DAG->TRI);
MRI = &DAG->MRI;
Available[IDAlu]->clear();
Available[IDFetch]->clear();
Available[IDOther]->clear();
CurInstKind = IDOther;
CurEmitted = 0;
OccupedSlotsMask = 15;
Expand All @@ -44,16 +40,11 @@ void R600SchedStrategy::initialize(ScheduleDAGMI *dag) {
InstKindLimit[IDFetch] = ST.getTexVTXClauseSize();
}

void R600SchedStrategy::MoveUnits(ReadyQueue *QSrc, ReadyQueue *QDst)
void R600SchedStrategy::MoveUnits(std::vector<SUnit *> &QSrc,
std::vector<SUnit *> &QDst)
{
if (QSrc->empty())
return;
for (ReadyQueue::iterator I = QSrc->begin(),
E = QSrc->end(); I != E; ++I) {
(*I)->NodeQueueId &= ~QSrc->getID();
QDst->push(*I);
}
QSrc->clear();
QDst.insert(QDst.end(), QSrc.begin(), QSrc.end());
QSrc.clear();
}

SUnit* R600SchedStrategy::pickNode(bool &IsTopNode) {
Expand All @@ -64,9 +55,9 @@ SUnit* R600SchedStrategy::pickNode(bool &IsTopNode) {
// check if we might want to switch current clause type
bool AllowSwitchToAlu = (CurInstKind == IDOther) ||
(CurEmitted >= InstKindLimit[CurInstKind]) ||
(Available[CurInstKind]->empty());
(Available[CurInstKind].empty());
bool AllowSwitchFromAlu = (CurEmitted >= InstKindLimit[CurInstKind]) &&
(!Available[IDFetch]->empty() || !Available[IDOther]->empty());
(!Available[IDFetch].empty() || !Available[IDOther].empty());

if ((AllowSwitchToAlu && CurInstKind != IDAlu) ||
(!AllowSwitchFromAlu && CurInstKind == IDAlu)) {
Expand Down Expand Up @@ -99,10 +90,6 @@ SUnit* R600SchedStrategy::pickNode(bool &IsTopNode) {
SU->dump(DAG);
} else {
dbgs() << "NO NODE ";
for (int i = 0; i < IDLast; ++i) {
Available[i]->dump();
Pending[i]->dump();
}
for (unsigned i = 0; i < DAG->SUnits.size(); i++) {
const SUnit &S = DAG->SUnits[i];
if (!S.isScheduled)
Expand Down Expand Up @@ -163,7 +150,7 @@ void R600SchedStrategy::releaseTopNode(SUnit *SU) {
DEBUG(dbgs() << IK << " <= ");
DEBUG(SU->dump(DAG));

Pending[IK]->push(SU);
Pending[IK].push_back(SU);
}

void R600SchedStrategy::releaseBottomNode(SUnit *SU) {
Expand Down Expand Up @@ -263,16 +250,16 @@ int R600SchedStrategy::getInstKind(SUnit* SU) {
}
}

SUnit *R600SchedStrategy::PopInst(std::multiset<SUnit *, CompareSUnit> &Q) {
SUnit *R600SchedStrategy::PopInst(std::vector<SUnit *> &Q) {
if (Q.empty())
return NULL;
for (std::set<SUnit *, CompareSUnit>::iterator It = Q.begin(), E = Q.end();
for (std::vector<SUnit *>::reverse_iterator It = Q.rbegin(), E = Q.rend();
It != E; ++It) {
SUnit *SU = *It;
InstructionsGroupCandidate.push_back(SU->getInstr());
if (TII->canBundle(InstructionsGroupCandidate)) {
InstructionsGroupCandidate.pop_back();
Q.erase(It);
Q.erase((It + 1).base());
return SU;
} else {
InstructionsGroupCandidate.pop_back();
Expand All @@ -282,14 +269,12 @@ SUnit *R600SchedStrategy::PopInst(std::multiset<SUnit *, CompareSUnit> &Q) {
}

void R600SchedStrategy::LoadAlu() {
ReadyQueue *QSrc = Pending[IDAlu];
for (ReadyQueue::iterator I = QSrc->begin(),
E = QSrc->end(); I != E; ++I) {
(*I)->NodeQueueId &= ~QSrc->getID();
AluKind AK = getAluKind(*I);
AvailableAlus[AK].insert(*I);
}
QSrc->clear();
std::vector<SUnit *> &QSrc = Pending[IDAlu];
for (unsigned i = 0, e = QSrc.size(); i < e; ++i) {
AluKind AK = getAluKind(QSrc[i]);
AvailableAlus[AK].push_back(QSrc[i]);
}
QSrc.clear();
}

void R600SchedStrategy::PrepareNextSlot() {
Expand Down Expand Up @@ -331,27 +316,16 @@ void R600SchedStrategy::AssignSlot(MachineInstr* MI, unsigned Slot) {
SUnit *R600SchedStrategy::AttemptFillSlot(unsigned Slot) {
static const AluKind IndexToID[] = {AluT_X, AluT_Y, AluT_Z, AluT_W};
SUnit *SlotedSU = PopInst(AvailableAlus[IndexToID[Slot]]);
SUnit *UnslotedSU = PopInst(AvailableAlus[AluAny]);
if (!UnslotedSU) {
if (SlotedSU)
return SlotedSU;
} else if (!SlotedSU) {
SUnit *UnslotedSU = PopInst(AvailableAlus[AluAny]);
if (UnslotedSU)
AssignSlot(UnslotedSU->getInstr(), Slot);
return UnslotedSU;
} else {
//Determine which one to pick (the lesser one)
if (CompareSUnit()(SlotedSU, UnslotedSU)) {
AvailableAlus[AluAny].insert(UnslotedSU);
return SlotedSU;
} else {
AvailableAlus[IndexToID[Slot]].insert(SlotedSU);
AssignSlot(UnslotedSU->getInstr(), Slot);
return UnslotedSU;
}
}
return UnslotedSU;
}

bool R600SchedStrategy::isAvailablesAluEmpty() const {
return Pending[IDAlu]->empty() && AvailableAlus[AluAny].empty() &&
return Pending[IDAlu].empty() && AvailableAlus[AluAny].empty() &&
AvailableAlus[AluT_XYZW].empty() && AvailableAlus[AluT_X].empty() &&
AvailableAlus[AluT_Y].empty() && AvailableAlus[AluT_Z].empty() &&
AvailableAlus[AluT_W].empty() && AvailableAlus[AluDiscarded].empty();
Expand Down Expand Up @@ -389,14 +363,14 @@ SUnit* R600SchedStrategy::pickAlu() {

SUnit* R600SchedStrategy::pickOther(int QID) {
SUnit *SU = 0;
ReadyQueue *AQ = Available[QID];
std::vector<SUnit *> &AQ = Available[QID];

if (AQ->empty()) {
if (AQ.empty()) {
MoveUnits(Pending[QID], AQ);
}
if (!AQ->empty()) {
SU = *AQ->begin();
AQ->remove(AQ->begin());
if (!AQ.empty()) {
SU = AQ.back();
AQ.resize(AQ.size() - 1);
}
return SU;
}
Expand Down
32 changes: 5 additions & 27 deletions lib/Target/R600/R600MachineScheduler.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,26 +24,13 @@ using namespace llvm;

namespace llvm {

class CompareSUnit {
public:
bool operator()(const SUnit *S1, const SUnit *S2) {
return S1->getDepth() > S2->getDepth();
}
};

class R600SchedStrategy : public MachineSchedStrategy {

const ScheduleDAGMI *DAG;
const R600InstrInfo *TII;
const R600RegisterInfo *TRI;
MachineRegisterInfo *MRI;

enum InstQueue {
QAlu = 1,
QFetch = 2,
QOther = 4
};

enum InstKind {
IDAlu,
IDFetch,
Expand All @@ -62,8 +49,9 @@ class R600SchedStrategy : public MachineSchedStrategy {
AluLast
};

ReadyQueue *Available[IDLast], *Pending[IDLast];
std::multiset<SUnit *, CompareSUnit> AvailableAlus[AluLast];
std::vector<SUnit *> Available[IDLast], Pending[IDLast];
std::vector<SUnit *> AvailableAlus[AluLast];
std::vector<SUnit *> FakeCopy;

InstKind CurInstKind;
int CurEmitted;
Expand All @@ -76,19 +64,9 @@ class R600SchedStrategy : public MachineSchedStrategy {
public:
R600SchedStrategy() :
DAG(0), TII(0), TRI(0), MRI(0) {
Available[IDAlu] = new ReadyQueue(QAlu, "AAlu");
Available[IDFetch] = new ReadyQueue(QFetch, "AFetch");
Available[IDOther] = new ReadyQueue(QOther, "AOther");
Pending[IDAlu] = new ReadyQueue(QAlu<<4, "PAlu");
Pending[IDFetch] = new ReadyQueue(QFetch<<4, "PFetch");
Pending[IDOther] = new ReadyQueue(QOther<<4, "POther");
}

virtual ~R600SchedStrategy() {
for (unsigned I = 0; I < IDLast; ++I) {
delete Available[I];
delete Pending[I];
}
}

virtual void initialize(ScheduleDAGMI *dag);
Expand All @@ -107,12 +85,12 @@ class R600SchedStrategy : public MachineSchedStrategy {
bool isAvailablesAluEmpty() const;
SUnit *AttemptFillSlot (unsigned Slot);
void PrepareNextSlot();
SUnit *PopInst(std::multiset<SUnit *, CompareSUnit> &Q);
SUnit *PopInst(std::vector<SUnit*> &Q);

void AssignSlot(MachineInstr *MI, unsigned Slot);
SUnit* pickAlu();
SUnit* pickOther(int QID);
void MoveUnits(ReadyQueue *QSrc, ReadyQueue *QDst);
void MoveUnits(std::vector<SUnit *> &QSrc, std::vector<SUnit *> &QDst);
};

} // namespace llvm
Expand Down
2 changes: 1 addition & 1 deletion test/CodeGen/R600/bfi_int.ll
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ entry:
; ((x & z) | (y & (x | z)))
; R600-CHECK: @bfi_sha256_ma
; R600-CHECK: XOR_INT * [[DST:T[0-9]+\.[XYZW]]], {{T[0-9]+\.[XYZW], T[0-9]+\.[XYZW]}}
; R600-CHECK: BFI_INT * {{T[0-9]+\.[XYZW]}}, {{[[DST]]|PV.x}}, {{T[0-9]+\.[XYZW], T[0-9]+\.[XYZW]}}
; R600-CHECK: BFI_INT * {{T[0-9]+\.[XYZW]}}, {{[[DST]]|PV\.[xyzw]}}, {{T[0-9]+\.[XYZW], T[0-9]+\.[XYZW]}}
; SI-CHECK: V_XOR_B32_e32 [[DST:VGPR[0-9]+]], {{VGPR[0-9]+, VGPR[0-9]+}}
; SI-CHECK: V_BFI_B32 {{VGPR[0-9]+}}, [[DST]], {{VGPR[0-9]+, VGPR[0-9]+}}

Expand Down
2 changes: 1 addition & 1 deletion test/CodeGen/R600/pv.ll
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
; RUN: llc < %s -march=r600 | FileCheck %s

;CHECK: DOT4 * T{{[0-9]\.W}} (MASKED)
;CHECK: CNDGE * T{{[0-9].[XYZW]}}, PV.x
;CHECK-NEXT: CNDGE T{{[0-9].[XYZW]}}, PV.x

define void @main() #0 {
main_body:
Expand Down

0 comments on commit 21ca0b3

Please sign in to comment.