[AMDGPU] SISched: Detect dependency types between blocks

Patch by Axel Davy (axel.davy@normalesup.org)

Differential revision: https://reviews.llvm.org/D30153

llvm-svn: 298872
This commit is contained in:
Valery Pykhtin 2017-03-27 18:22:39 +00:00
parent 1856ceed82
commit fb9905545c
2 changed files with 39 additions and 26 deletions

View File

@ -539,21 +539,30 @@ void SIScheduleBlock::addPred(SIScheduleBlock *Pred) {
Preds.push_back(Pred); Preds.push_back(Pred);
assert(none_of(Succs, assert(none_of(Succs,
[=](SIScheduleBlock *S) { return PredID == S->getID(); }) && [=](std::pair<SIScheduleBlock*,
SIScheduleBlockLinkKind> S) {
return PredID == S.first->getID();
}) &&
"Loop in the Block Graph!"); "Loop in the Block Graph!");
} }
void SIScheduleBlock::addSucc(SIScheduleBlock *Succ) { void SIScheduleBlock::addSucc(SIScheduleBlock *Succ,
SIScheduleBlockLinkKind Kind) {
unsigned SuccID = Succ->getID(); unsigned SuccID = Succ->getID();
// Check if not already predecessor. // Check if not already predecessor.
for (SIScheduleBlock* S : Succs) { for (std::pair<SIScheduleBlock*, SIScheduleBlockLinkKind> &S : Succs) {
if (SuccID == S->getID()) if (SuccID == S.first->getID()) {
if (S.second == SIScheduleBlockLinkKind::NoData &&
Kind == SIScheduleBlockLinkKind::Data)
S.second = Kind;
return; return;
}
} }
if (Succ->isHighLatencyBlock()) if (Succ->isHighLatencyBlock())
++NumHighLatencySuccessors; ++NumHighLatencySuccessors;
Succs.push_back(Succ); Succs.push_back(std::make_pair(Succ, Kind));
assert(none_of(Preds, assert(none_of(Preds,
[=](SIScheduleBlock *P) { return SuccID == P->getID(); }) && [=](SIScheduleBlock *P) { return SuccID == P->getID(); }) &&
"Loop in the Block Graph!"); "Loop in the Block Graph!");
@ -573,8 +582,10 @@ void SIScheduleBlock::printDebug(bool full) {
} }
dbgs() << "\nSuccessors:\n"; dbgs() << "\nSuccessors:\n";
for (SIScheduleBlock* S : Succs) { for (std::pair<SIScheduleBlock*, SIScheduleBlockLinkKind> S : Succs) {
S->printDebug(false); if (S.second == SIScheduleBlockLinkKind::Data)
dbgs() << "(Data Dep) ";
S.first->printDebug(false);
} }
if (Scheduled) { if (Scheduled) {
@ -1096,7 +1107,8 @@ void SIScheduleBlockCreator::createBlocksForVariant(SISchedulerBlockCreatorVaria
if (SuccDep.isWeak() || Succ->NodeNum >= DAGSize) if (SuccDep.isWeak() || Succ->NodeNum >= DAGSize)
continue; continue;
if (Node2CurrentBlock[Succ->NodeNum] != SUID) if (Node2CurrentBlock[Succ->NodeNum] != SUID)
CurrentBlocks[SUID]->addSucc(CurrentBlocks[Node2CurrentBlock[Succ->NodeNum]]); CurrentBlocks[SUID]->addSucc(CurrentBlocks[Node2CurrentBlock[Succ->NodeNum]],
SuccDep.isCtrl() ? NoData : Data);
} }
for (SDep& PredDep : SU->Preds) { for (SDep& PredDep : SU->Preds) {
SUnit *Pred = PredDep.getSUnit(); SUnit *Pred = PredDep.getSUnit();
@ -1290,10 +1302,8 @@ void SIScheduleBlockCreator::fillStats() {
Block->Height = 0; Block->Height = 0;
else { else {
unsigned Height = 0; unsigned Height = 0;
for (SIScheduleBlock *Succ : Block->getSuccs()) { for (const auto &Succ : Block->getSuccs())
if (Height < Succ->Height + 1) Height = std::min(Height, Succ.first->Height + 1);
Height = Succ->Height + 1;
}
Block->Height = Height; Block->Height = Height;
} }
} }
@ -1574,17 +1584,13 @@ void SIScheduleBlockScheduler::decreaseLiveRegs(SIScheduleBlock *Block,
} }
void SIScheduleBlockScheduler::releaseBlockSuccs(SIScheduleBlock *Parent) { void SIScheduleBlockScheduler::releaseBlockSuccs(SIScheduleBlock *Parent) {
for (SIScheduleBlock* Block : Parent->getSuccs()) { for (const auto &Block : Parent->getSuccs()) {
--BlockNumPredsLeft[Block->getID()]; if (--BlockNumPredsLeft[Block.first->getID()] == 0)
if (BlockNumPredsLeft[Block->getID()] == 0) { ReadyBlocks.push_back(Block.first);
ReadyBlocks.push_back(Block);
} if (Parent->isHighLatencyBlock() &&
// TODO: Improve check. When the dependency between the high latency Block.second == SIScheduleBlockLinkKind::Data)
// instructions and the instructions of the other blocks are WAR or WAW LastPosHighLatencyParentScheduled[Block.first->getID()] = NumBlockScheduled;
// there will be no wait triggered. We would like these cases to not
// update LastPosHighLatencyParentScheduled.
if (Parent->isHighLatencyBlock())
LastPosHighLatencyParentScheduled[Block->getID()] = NumBlockScheduled;
} }
} }

View File

@ -54,6 +54,11 @@ struct SISchedulerCandidate {
class SIScheduleDAGMI; class SIScheduleDAGMI;
class SIScheduleBlockCreator; class SIScheduleBlockCreator;
enum SIScheduleBlockLinkKind {
NoData,
Data
};
class SIScheduleBlock { class SIScheduleBlock {
SIScheduleDAGMI *DAG; SIScheduleDAGMI *DAG;
SIScheduleBlockCreator *BC; SIScheduleBlockCreator *BC;
@ -92,7 +97,8 @@ class SIScheduleBlock {
unsigned ID; unsigned ID;
std::vector<SIScheduleBlock*> Preds; // All blocks predecessors. std::vector<SIScheduleBlock*> Preds; // All blocks predecessors.
std::vector<SIScheduleBlock*> Succs; // All blocks successors. // All blocks successors, and the kind of link
std::vector<std::pair<SIScheduleBlock*, SIScheduleBlockLinkKind>> Succs;
unsigned NumHighLatencySuccessors = 0; unsigned NumHighLatencySuccessors = 0;
public: public:
@ -112,10 +118,11 @@ public:
// Add block pred, which has instruction predecessor of SU. // Add block pred, which has instruction predecessor of SU.
void addPred(SIScheduleBlock *Pred); void addPred(SIScheduleBlock *Pred);
void addSucc(SIScheduleBlock *Succ); void addSucc(SIScheduleBlock *Succ, SIScheduleBlockLinkKind Kind);
const std::vector<SIScheduleBlock*>& getPreds() const { return Preds; } const std::vector<SIScheduleBlock*>& getPreds() const { return Preds; }
const std::vector<SIScheduleBlock*>& getSuccs() const { return Succs; } ArrayRef<std::pair<SIScheduleBlock*, SIScheduleBlockLinkKind>>
getSuccs() const { return Succs; }
unsigned Height; // Maximum topdown path length to block without outputs unsigned Height; // Maximum topdown path length to block without outputs
unsigned Depth; // Maximum bottomup path length to block without inputs unsigned Depth; // Maximum bottomup path length to block without inputs