diff options
author | Marek Olsak <marek.olsak@amd.com> | 2017-07-25 20:36:58 +0000 |
---|---|---|
committer | Marek Olsak <marek.olsak@amd.com> | 2017-07-25 20:36:58 +0000 |
commit | e6f74384b1fb963ea5e65cc7ee3e63a63ddf08f5 (patch) | |
tree | 629077e3c7d1c036acf36cb99da223bb4e1d9e80 /llvm/lib/Target/AMDGPU/SIMachineScheduler.cpp | |
parent | 09736e314c92d8ce73091b9883087299b6a68fe9 (diff) | |
download | bcm5719-llvm-e6f74384b1fb963ea5e65cc7ee3e63a63ddf08f5.tar.gz bcm5719-llvm-e6f74384b1fb963ea5e65cc7ee3e63a63ddf08f5.zip |
AMDGPU/SI: Force exports at the end for SI scheduler
Patch by: Axel Davy
Differential Revision: https://reviews.llvm.org/D34965
llvm-svn: 309027
Diffstat (limited to 'llvm/lib/Target/AMDGPU/SIMachineScheduler.cpp')
-rw-r--r-- | llvm/lib/Target/AMDGPU/SIMachineScheduler.cpp | 57 |
1 files changed, 57 insertions, 0 deletions
diff --git a/llvm/lib/Target/AMDGPU/SIMachineScheduler.cpp b/llvm/lib/Target/AMDGPU/SIMachineScheduler.cpp index 34886c48f46..de3ff627d97 100644 --- a/llvm/lib/Target/AMDGPU/SIMachineScheduler.cpp +++ b/llvm/lib/Target/AMDGPU/SIMachineScheduler.cpp @@ -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); |