summaryrefslogtreecommitdiff
path: root/lib/Target/AMDGPU/SIMachineScheduler.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Target/AMDGPU/SIMachineScheduler.cpp')
-rw-r--r--lib/Target/AMDGPU/SIMachineScheduler.cpp83
1 files changed, 70 insertions, 13 deletions
diff --git a/lib/Target/AMDGPU/SIMachineScheduler.cpp b/lib/Target/AMDGPU/SIMachineScheduler.cpp
index 34886c48f461..6b67b76652ed 100644
--- a/lib/Target/AMDGPU/SIMachineScheduler.cpp
+++ b/lib/Target/AMDGPU/SIMachineScheduler.cpp
@@ -19,16 +19,16 @@
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/CodeGen/LiveInterval.h"
-#include "llvm/CodeGen/LiveIntervalAnalysis.h"
+#include "llvm/CodeGen/LiveIntervals.h"
#include "llvm/CodeGen/MachineInstr.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/CodeGen/MachineScheduler.h"
#include "llvm/CodeGen/RegisterPressure.h"
#include "llvm/CodeGen/SlotIndexes.h"
+#include "llvm/CodeGen/TargetRegisterInfo.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/raw_ostream.h"
-#include "llvm/Target/TargetRegisterInfo.h"
#include <algorithm>
#include <cassert>
#include <map>
@@ -595,11 +595,11 @@ void SIScheduleBlock::printDebug(bool full) {
<< LiveOutPressure[DAG->getVGPRSetID()] << "\n\n";
dbgs() << "LiveIns:\n";
for (unsigned Reg : LiveInRegs)
- dbgs() << PrintVRegOrUnit(Reg, DAG->getTRI()) << ' ';
+ dbgs() << printVRegOrUnit(Reg, DAG->getTRI()) << ' ';
dbgs() << "\nLiveOuts:\n";
for (unsigned Reg : LiveOutRegs)
- dbgs() << PrintVRegOrUnit(Reg, DAG->getTRI()) << ' ';
+ dbgs() << printVRegOrUnit(Reg, DAG->getTRI()) << ' ';
}
dbgs() << "\nInstructions:\n";
@@ -1130,6 +1130,62 @@ void SIScheduleBlockCreator::regroupNoUserInstructions() {
}
}
+void SIScheduleBlockCreator::colorExports() {
+ unsigned ExportColor = NextNonReservedID++;
+ SmallVector<unsigned, 8> ExpGroup;
+
+ // Put all exports together in a block.
+ // The block will naturally end up being scheduled last,
+ // thus putting exports at the end of the schedule, which
+ // is better for performance.
+ // However we must ensure, for safety, the exports can be put
+ // together in the same block without any other instruction.
+ // This could happen, for example, when scheduling after regalloc
+ // if reloading a spilled register from memory using the same
+ // register than used in a previous export.
+ // If that happens, do not regroup the exports.
+ for (unsigned SUNum : DAG->TopDownIndex2SU) {
+ const SUnit &SU = DAG->SUnits[SUNum];
+ if (SIInstrInfo::isEXP(*SU.getInstr())) {
+ // Check the EXP can be added to the group safely,
+ // ie without needing any other instruction.
+ // The EXP is allowed to depend on other EXP
+ // (they will be in the same group).
+ for (unsigned j : ExpGroup) {
+ bool HasSubGraph;
+ std::vector<int> SubGraph;
+ // By construction (topological order), if SU and
+ // DAG->SUnits[j] are linked, DAG->SUnits[j] is neccessary
+ // in the parent graph of SU.
+#ifndef NDEBUG
+ SubGraph = DAG->GetTopo()->GetSubGraph(SU, DAG->SUnits[j],
+ HasSubGraph);
+ assert(!HasSubGraph);
+#endif
+ SubGraph = DAG->GetTopo()->GetSubGraph(DAG->SUnits[j], SU,
+ HasSubGraph);
+ if (!HasSubGraph)
+ continue; // No dependencies between each other
+
+ // SubGraph contains all the instructions required
+ // between EXP SUnits[j] and EXP SU.
+ for (unsigned k : SubGraph) {
+ if (!SIInstrInfo::isEXP(*DAG->SUnits[k].getInstr()))
+ // Other instructions than EXP would be required in the group.
+ // Abort the groupping.
+ return;
+ }
+ }
+
+ ExpGroup.push_back(SUNum);
+ }
+ }
+
+ // The group can be formed. Give the color.
+ for (unsigned j : ExpGroup)
+ CurrentColoring[j] = ExportColor;
+}
+
void SIScheduleBlockCreator::createBlocksForVariant(SISchedulerBlockCreatorVariant BlockVariant) {
unsigned DAGSize = DAG->SUnits.size();
std::map<unsigned,unsigned> RealID;
@@ -1159,6 +1215,7 @@ void SIScheduleBlockCreator::createBlocksForVariant(SISchedulerBlockCreatorVaria
regroupNoUserInstructions();
colorMergeConstantLoadsNextGroup();
colorMergeIfPossibleNextGroupOnlyForReserved();
+ colorExports();
// Put SUs of same color into same block
Node2CurrentBlock.resize(DAGSize, -1);
@@ -1365,8 +1422,8 @@ void SIScheduleBlockCreator::fillStats() {
else {
unsigned Depth = 0;
for (SIScheduleBlock *Pred : Block->getPreds()) {
- if (Depth < Pred->Depth + 1)
- Depth = Pred->Depth + 1;
+ if (Depth < Pred->Depth + Pred->getCost())
+ Depth = Pred->Depth + Pred->getCost();
}
Block->Depth = Depth;
}
@@ -1380,7 +1437,7 @@ void SIScheduleBlockCreator::fillStats() {
else {
unsigned Height = 0;
for (const auto &Succ : Block->getSuccs())
- Height = std::min(Height, Succ.first->Height + 1);
+ Height = std::max(Height, Succ.first->Height + Succ.first->getCost());
Block->Height = Height;
}
}
@@ -1578,7 +1635,7 @@ SIScheduleBlock *SIScheduleBlockScheduler::pickBlock() {
dbgs() << Block->getID() << ' ';
dbgs() << "\nCurrent Live:\n";
for (unsigned Reg : LiveRegs)
- dbgs() << PrintVRegOrUnit(Reg, DAG->getTRI()) << ' ';
+ dbgs() << printVRegOrUnit(Reg, DAG->getTRI()) << ' ';
dbgs() << '\n';
dbgs() << "Current VGPRs: " << VregCurrentUsage << '\n';
dbgs() << "Current SGPRs: " << SregCurrentUsage << '\n';
@@ -1993,9 +2050,9 @@ void SIScheduleDAGMI::schedule()
placeDebugValues();
DEBUG({
- unsigned BBNum = begin()->getParent()->getNumber();
- dbgs() << "*** Final schedule for BB#" << BBNum << " ***\n";
- dumpSchedule();
- dbgs() << '\n';
- });
+ dbgs() << "*** Final schedule for "
+ << printMBBReference(*begin()->getParent()) << " ***\n";
+ dumpSchedule();
+ dbgs() << '\n';
+ });
}