diff options
| author | Dimitry Andric <dim@FreeBSD.org> | 2019-12-20 19:53:05 +0000 |
|---|---|---|
| committer | Dimitry Andric <dim@FreeBSD.org> | 2019-12-20 19:53:05 +0000 |
| commit | 0b57cec536236d46e3dba9bd041533462f33dbb7 (patch) | |
| tree | 56229dbdbbf76d18580f72f789003db17246c8d9 /contrib/llvm/lib/CodeGen/LiveRegMatrix.cpp | |
| parent | 718ef55ec7785aae63f98f8ca05dc07ed399c16d (diff) | |
Notes
Diffstat (limited to 'contrib/llvm/lib/CodeGen/LiveRegMatrix.cpp')
| -rw-r--r-- | contrib/llvm/lib/CodeGen/LiveRegMatrix.cpp | 222 |
1 files changed, 0 insertions, 222 deletions
diff --git a/contrib/llvm/lib/CodeGen/LiveRegMatrix.cpp b/contrib/llvm/lib/CodeGen/LiveRegMatrix.cpp deleted file mode 100644 index ce99e5535c25..000000000000 --- a/contrib/llvm/lib/CodeGen/LiveRegMatrix.cpp +++ /dev/null @@ -1,222 +0,0 @@ -//===- LiveRegMatrix.cpp - Track register interference --------------------===// -// -// 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 -// -//===----------------------------------------------------------------------===// -// -// This file defines the LiveRegMatrix analysis pass. -// -//===----------------------------------------------------------------------===// - -#include "llvm/CodeGen/LiveRegMatrix.h" -#include "RegisterCoalescer.h" -#include "llvm/ADT/Statistic.h" -#include "llvm/CodeGen/LiveInterval.h" -#include "llvm/CodeGen/LiveIntervalUnion.h" -#include "llvm/CodeGen/LiveIntervals.h" -#include "llvm/CodeGen/MachineFunction.h" -#include "llvm/CodeGen/TargetRegisterInfo.h" -#include "llvm/CodeGen/TargetSubtargetInfo.h" -#include "llvm/CodeGen/VirtRegMap.h" -#include "llvm/MC/LaneBitmask.h" -#include "llvm/MC/MCRegisterInfo.h" -#include "llvm/Pass.h" -#include "llvm/Support/Debug.h" -#include "llvm/Support/raw_ostream.h" -#include <cassert> - -using namespace llvm; - -#define DEBUG_TYPE "regalloc" - -STATISTIC(NumAssigned , "Number of registers assigned"); -STATISTIC(NumUnassigned , "Number of registers unassigned"); - -char LiveRegMatrix::ID = 0; -INITIALIZE_PASS_BEGIN(LiveRegMatrix, "liveregmatrix", - "Live Register Matrix", false, false) -INITIALIZE_PASS_DEPENDENCY(LiveIntervals) -INITIALIZE_PASS_DEPENDENCY(VirtRegMap) -INITIALIZE_PASS_END(LiveRegMatrix, "liveregmatrix", - "Live Register Matrix", false, false) - -LiveRegMatrix::LiveRegMatrix() : MachineFunctionPass(ID) {} - -void LiveRegMatrix::getAnalysisUsage(AnalysisUsage &AU) const { - AU.setPreservesAll(); - AU.addRequiredTransitive<LiveIntervals>(); - AU.addRequiredTransitive<VirtRegMap>(); - MachineFunctionPass::getAnalysisUsage(AU); -} - -bool LiveRegMatrix::runOnMachineFunction(MachineFunction &MF) { - TRI = MF.getSubtarget().getRegisterInfo(); - LIS = &getAnalysis<LiveIntervals>(); - VRM = &getAnalysis<VirtRegMap>(); - - unsigned NumRegUnits = TRI->getNumRegUnits(); - if (NumRegUnits != Matrix.size()) - Queries.reset(new LiveIntervalUnion::Query[NumRegUnits]); - Matrix.init(LIUAlloc, NumRegUnits); - - // Make sure no stale queries get reused. - invalidateVirtRegs(); - return false; -} - -void LiveRegMatrix::releaseMemory() { - for (unsigned i = 0, e = Matrix.size(); i != e; ++i) { - Matrix[i].clear(); - // No need to clear Queries here, since LiveIntervalUnion::Query doesn't - // have anything important to clear and LiveRegMatrix's runOnFunction() - // does a std::unique_ptr::reset anyways. - } -} - -template <typename Callable> -static bool foreachUnit(const TargetRegisterInfo *TRI, - LiveInterval &VRegInterval, unsigned PhysReg, - Callable Func) { - if (VRegInterval.hasSubRanges()) { - for (MCRegUnitMaskIterator Units(PhysReg, TRI); Units.isValid(); ++Units) { - unsigned Unit = (*Units).first; - LaneBitmask Mask = (*Units).second; - for (LiveInterval::SubRange &S : VRegInterval.subranges()) { - if ((S.LaneMask & Mask).any()) { - if (Func(Unit, S)) - return true; - break; - } - } - } - } else { - for (MCRegUnitIterator Units(PhysReg, TRI); Units.isValid(); ++Units) { - if (Func(*Units, VRegInterval)) - return true; - } - } - return false; -} - -void LiveRegMatrix::assign(LiveInterval &VirtReg, unsigned PhysReg) { - LLVM_DEBUG(dbgs() << "assigning " << printReg(VirtReg.reg, TRI) << " to " - << printReg(PhysReg, TRI) << ':'); - assert(!VRM->hasPhys(VirtReg.reg) && "Duplicate VirtReg assignment"); - VRM->assignVirt2Phys(VirtReg.reg, PhysReg); - - foreachUnit( - TRI, VirtReg, PhysReg, [&](unsigned Unit, const LiveRange &Range) { - LLVM_DEBUG(dbgs() << ' ' << printRegUnit(Unit, TRI) << ' ' << Range); - Matrix[Unit].unify(VirtReg, Range); - return false; - }); - - ++NumAssigned; - LLVM_DEBUG(dbgs() << '\n'); -} - -void LiveRegMatrix::unassign(LiveInterval &VirtReg) { - unsigned PhysReg = VRM->getPhys(VirtReg.reg); - LLVM_DEBUG(dbgs() << "unassigning " << printReg(VirtReg.reg, TRI) << " from " - << printReg(PhysReg, TRI) << ':'); - VRM->clearVirt(VirtReg.reg); - - foreachUnit(TRI, VirtReg, PhysReg, - [&](unsigned Unit, const LiveRange &Range) { - LLVM_DEBUG(dbgs() << ' ' << printRegUnit(Unit, TRI)); - Matrix[Unit].extract(VirtReg, Range); - return false; - }); - - ++NumUnassigned; - LLVM_DEBUG(dbgs() << '\n'); -} - -bool LiveRegMatrix::isPhysRegUsed(unsigned PhysReg) const { - for (MCRegUnitIterator Unit(PhysReg, TRI); Unit.isValid(); ++Unit) { - if (!Matrix[*Unit].empty()) - return true; - } - return false; -} - -bool LiveRegMatrix::checkRegMaskInterference(LiveInterval &VirtReg, - unsigned PhysReg) { - // Check if the cached information is valid. - // The same BitVector can be reused for all PhysRegs. - // We could cache multiple VirtRegs if it becomes necessary. - if (RegMaskVirtReg != VirtReg.reg || RegMaskTag != UserTag) { - RegMaskVirtReg = VirtReg.reg; - RegMaskTag = UserTag; - RegMaskUsable.clear(); - LIS->checkRegMaskInterference(VirtReg, RegMaskUsable); - } - - // The BitVector is indexed by PhysReg, not register unit. - // Regmask interference is more fine grained than regunits. - // For example, a Win64 call can clobber %ymm8 yet preserve %xmm8. - return !RegMaskUsable.empty() && (!PhysReg || !RegMaskUsable.test(PhysReg)); -} - -bool LiveRegMatrix::checkRegUnitInterference(LiveInterval &VirtReg, - unsigned PhysReg) { - if (VirtReg.empty()) - return false; - CoalescerPair CP(VirtReg.reg, PhysReg, *TRI); - - bool Result = foreachUnit(TRI, VirtReg, PhysReg, [&](unsigned Unit, - const LiveRange &Range) { - const LiveRange &UnitRange = LIS->getRegUnit(Unit); - return Range.overlaps(UnitRange, CP, *LIS->getSlotIndexes()); - }); - return Result; -} - -LiveIntervalUnion::Query &LiveRegMatrix::query(const LiveRange &LR, - unsigned RegUnit) { - LiveIntervalUnion::Query &Q = Queries[RegUnit]; - Q.init(UserTag, LR, Matrix[RegUnit]); - return Q; -} - -LiveRegMatrix::InterferenceKind -LiveRegMatrix::checkInterference(LiveInterval &VirtReg, unsigned PhysReg) { - if (VirtReg.empty()) - return IK_Free; - - // Regmask interference is the fastest check. - if (checkRegMaskInterference(VirtReg, PhysReg)) - return IK_RegMask; - - // Check for fixed interference. - if (checkRegUnitInterference(VirtReg, PhysReg)) - return IK_RegUnit; - - // Check the matrix for virtual register interference. - bool Interference = foreachUnit(TRI, VirtReg, PhysReg, - [&](unsigned Unit, const LiveRange &LR) { - return query(LR, Unit).checkInterference(); - }); - if (Interference) - return IK_VirtReg; - - return IK_Free; -} - -bool LiveRegMatrix::checkInterference(SlotIndex Start, SlotIndex End, - unsigned PhysReg) { - // Construct artificial live range containing only one segment [Start, End). - VNInfo valno(0, Start); - LiveRange::Segment Seg(Start, End, &valno); - LiveRange LR; - LR.addSegment(Seg); - - // Check for interference with that segment - for (MCRegUnitIterator Units(PhysReg, TRI); Units.isValid(); ++Units) { - if (query(LR, *Units).checkInterference()) - return true; - } - return false; -} |
