diff options
Diffstat (limited to 'lib/Target/AMDGPU/GCNRegPressure.h')
| -rw-r--r-- | lib/Target/AMDGPU/GCNRegPressure.h | 61 |
1 files changed, 55 insertions, 6 deletions
diff --git a/lib/Target/AMDGPU/GCNRegPressure.h b/lib/Target/AMDGPU/GCNRegPressure.h index 357d3b7b2334..e4894418b943 100644 --- a/lib/Target/AMDGPU/GCNRegPressure.h +++ b/lib/Target/AMDGPU/GCNRegPressure.h @@ -1,9 +1,8 @@ //===- GCNRegPressure.h -----------------------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// @@ -32,6 +31,8 @@ struct GCNRegPressure { SGPR_TUPLE, VGPR32, VGPR_TUPLE, + AGPR32, + AGPR_TUPLE, TOTAL_KINDS }; @@ -44,9 +45,10 @@ struct GCNRegPressure { void clear() { std::fill(&Value[0], &Value[TOTAL_KINDS], 0); } unsigned getSGPRNum() const { return Value[SGPR32]; } - unsigned getVGPRNum() const { return Value[VGPR32]; } + unsigned getVGPRNum() const { return std::max(Value[VGPR32], Value[AGPR32]); } - unsigned getVGPRTuplesWeight() const { return Value[VGPR_TUPLE]; } + unsigned getVGPRTuplesWeight() const { return std::max(Value[VGPR_TUPLE], + Value[AGPR_TUPLE]); } unsigned getSGPRTuplesWeight() const { return Value[SGPR_TUPLE]; } unsigned getOccupancy(const GCNSubtarget &ST) const { @@ -191,6 +193,50 @@ GCNRPTracker::LiveRegSet getLiveRegs(SlotIndex SI, const LiveIntervals &LIS, const MachineRegisterInfo &MRI); +/// creates a map MachineInstr -> LiveRegSet +/// R - range of iterators on instructions +/// After - upon entry or exit of every instruction +/// Note: there is no entry in the map for instructions with empty live reg set +/// Complexity = O(NumVirtRegs * averageLiveRangeSegmentsPerReg * lg(R)) +template <typename Range> +DenseMap<MachineInstr*, GCNRPTracker::LiveRegSet> +getLiveRegMap(Range &&R, bool After, LiveIntervals &LIS) { + std::vector<SlotIndex> Indexes; + Indexes.reserve(std::distance(R.begin(), R.end())); + auto &SII = *LIS.getSlotIndexes(); + for (MachineInstr *I : R) { + auto SI = SII.getInstructionIndex(*I); + Indexes.push_back(After ? SI.getDeadSlot() : SI.getBaseIndex()); + } + std::sort(Indexes.begin(), Indexes.end()); + + auto &MRI = (*R.begin())->getParent()->getParent()->getRegInfo(); + DenseMap<MachineInstr *, GCNRPTracker::LiveRegSet> LiveRegMap; + SmallVector<SlotIndex, 32> LiveIdxs, SRLiveIdxs; + for (unsigned I = 0, E = MRI.getNumVirtRegs(); I != E; ++I) { + auto Reg = TargetRegisterInfo::index2VirtReg(I); + if (!LIS.hasInterval(Reg)) + continue; + auto &LI = LIS.getInterval(Reg); + LiveIdxs.clear(); + if (!LI.findIndexesLiveAt(Indexes, std::back_inserter(LiveIdxs))) + continue; + if (!LI.hasSubRanges()) { + for (auto SI : LiveIdxs) + LiveRegMap[SII.getInstructionFromIndex(SI)][Reg] = + MRI.getMaxLaneMaskForVReg(Reg); + } else + for (const auto &S : LI.subranges()) { + // constrain search for subranges by indexes live at main range + SRLiveIdxs.clear(); + S.findIndexesLiveAt(LiveIdxs, std::back_inserter(SRLiveIdxs)); + for (auto SI : SRLiveIdxs) + LiveRegMap[SII.getInstructionFromIndex(SI)][Reg] |= S.LaneMask; + } + } + return LiveRegMap; +} + inline GCNRPTracker::LiveRegSet getLiveRegsAfter(const MachineInstr &MI, const LiveIntervals &LIS) { return getLiveRegs(LIS.getInstructionIndex(MI).getDeadSlot(), LIS, @@ -212,6 +258,9 @@ GCNRegPressure getRegPressure(const MachineRegisterInfo &MRI, return Res; } +bool isEqual(const GCNRPTracker::LiveRegSet &S1, + const GCNRPTracker::LiveRegSet &S2); + void printLivesAt(SlotIndex SI, const LiveIntervals &LIS, const MachineRegisterInfo &MRI); |
