diff options
author | vitalyisaev <vitalyisaev@yandex-team.com> | 2023-06-29 10:00:50 +0300 |
---|---|---|
committer | vitalyisaev <vitalyisaev@yandex-team.com> | 2023-06-29 10:00:50 +0300 |
commit | 6ffe9e53658409f212834330e13564e4952558f6 (patch) | |
tree | 85b1e00183517648b228aafa7c8fb07f5276f419 /contrib/libs/llvm14/lib/CodeGen/RegAllocBase.cpp | |
parent | 726057070f9c5a91fc10fde0d5024913d10f1ab9 (diff) | |
download | ydb-6ffe9e53658409f212834330e13564e4952558f6.tar.gz |
YQ Connector: support managed ClickHouse
Со стороны dqrun можно обратиться к инстансу коннектора, который работает на streaming стенде, и извлечь данные из облачного CH.
Diffstat (limited to 'contrib/libs/llvm14/lib/CodeGen/RegAllocBase.cpp')
-rw-r--r-- | contrib/libs/llvm14/lib/CodeGen/RegAllocBase.cpp | 195 |
1 files changed, 195 insertions, 0 deletions
diff --git a/contrib/libs/llvm14/lib/CodeGen/RegAllocBase.cpp b/contrib/libs/llvm14/lib/CodeGen/RegAllocBase.cpp new file mode 100644 index 0000000000..d891d4c2ff --- /dev/null +++ b/contrib/libs/llvm14/lib/CodeGen/RegAllocBase.cpp @@ -0,0 +1,195 @@ +//===- RegAllocBase.cpp - Register Allocator Base Class -------------------===// +// +// 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 RegAllocBase class which provides common functionality +// for LiveIntervalUnion-based register allocators. +// +//===----------------------------------------------------------------------===// + +#include "RegAllocBase.h" +#include "llvm/ADT/SmallVector.h" +#include "llvm/ADT/Statistic.h" +#include "llvm/CodeGen/LiveInterval.h" +#include "llvm/CodeGen/LiveIntervals.h" +#include "llvm/CodeGen/LiveRegMatrix.h" +#include "llvm/CodeGen/MachineInstr.h" +#include "llvm/CodeGen/MachineModuleInfo.h" +#include "llvm/CodeGen/MachineRegisterInfo.h" +#include "llvm/CodeGen/Spiller.h" +#include "llvm/CodeGen/TargetRegisterInfo.h" +#include "llvm/CodeGen/VirtRegMap.h" +#include "llvm/Pass.h" +#include "llvm/Support/CommandLine.h" +#include "llvm/Support/Debug.h" +#include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/Timer.h" +#include "llvm/Support/raw_ostream.h" +#include <cassert> + +using namespace llvm; + +#define DEBUG_TYPE "regalloc" + +STATISTIC(NumNewQueued, "Number of new live ranges queued"); + +// Temporary verification option until we can put verification inside +// MachineVerifier. +static cl::opt<bool, true> + VerifyRegAlloc("verify-regalloc", cl::location(RegAllocBase::VerifyEnabled), + cl::Hidden, cl::desc("Verify during register allocation")); + +const char RegAllocBase::TimerGroupName[] = "regalloc"; +const char RegAllocBase::TimerGroupDescription[] = "Register Allocation"; +bool RegAllocBase::VerifyEnabled = false; + +//===----------------------------------------------------------------------===// +// RegAllocBase Implementation +//===----------------------------------------------------------------------===// + +// Pin the vtable to this file. +void RegAllocBase::anchor() {} + +void RegAllocBase::init(VirtRegMap &vrm, LiveIntervals &lis, + LiveRegMatrix &mat) { + TRI = &vrm.getTargetRegInfo(); + MRI = &vrm.getRegInfo(); + VRM = &vrm; + LIS = &lis; + Matrix = &mat; + MRI->freezeReservedRegs(vrm.getMachineFunction()); + RegClassInfo.runOnMachineFunction(vrm.getMachineFunction()); +} + +// Visit all the live registers. If they are already assigned to a physical +// register, unify them with the corresponding LiveIntervalUnion, otherwise push +// them on the priority queue for later assignment. +void RegAllocBase::seedLiveRegs() { + NamedRegionTimer T("seed", "Seed Live Regs", TimerGroupName, + TimerGroupDescription, TimePassesIsEnabled); + for (unsigned i = 0, e = MRI->getNumVirtRegs(); i != e; ++i) { + Register Reg = Register::index2VirtReg(i); + if (MRI->reg_nodbg_empty(Reg)) + continue; + enqueue(&LIS->getInterval(Reg)); + } +} + +// Top-level driver to manage the queue of unassigned VirtRegs and call the +// selectOrSplit implementation. +void RegAllocBase::allocatePhysRegs() { + seedLiveRegs(); + + // Continue assigning vregs one at a time to available physical registers. + while (LiveInterval *VirtReg = dequeue()) { + assert(!VRM->hasPhys(VirtReg->reg()) && "Register already assigned"); + + // Unused registers can appear when the spiller coalesces snippets. + if (MRI->reg_nodbg_empty(VirtReg->reg())) { + LLVM_DEBUG(dbgs() << "Dropping unused " << *VirtReg << '\n'); + aboutToRemoveInterval(*VirtReg); + LIS->removeInterval(VirtReg->reg()); + continue; + } + + // Invalidate all interference queries, live ranges could have changed. + Matrix->invalidateVirtRegs(); + + // selectOrSplit requests the allocator to return an available physical + // register if possible and populate a list of new live intervals that + // result from splitting. + LLVM_DEBUG(dbgs() << "\nselectOrSplit " + << TRI->getRegClassName(MRI->getRegClass(VirtReg->reg())) + << ':' << *VirtReg << " w=" << VirtReg->weight() << '\n'); + + using VirtRegVec = SmallVector<Register, 4>; + + VirtRegVec SplitVRegs; + MCRegister AvailablePhysReg = selectOrSplit(*VirtReg, SplitVRegs); + + if (AvailablePhysReg == ~0u) { + // selectOrSplit failed to find a register! + // Probably caused by an inline asm. + MachineInstr *MI = nullptr; + for (MachineRegisterInfo::reg_instr_iterator + I = MRI->reg_instr_begin(VirtReg->reg()), + E = MRI->reg_instr_end(); + I != E;) { + MI = &*(I++); + if (MI->isInlineAsm()) + break; + } + + const TargetRegisterClass *RC = MRI->getRegClass(VirtReg->reg()); + ArrayRef<MCPhysReg> AllocOrder = RegClassInfo.getOrder(RC); + if (AllocOrder.empty()) + report_fatal_error("no registers from class available to allocate"); + else if (MI && MI->isInlineAsm()) { + MI->emitError("inline assembly requires more registers than available"); + } else if (MI) { + LLVMContext &Context = + MI->getParent()->getParent()->getMMI().getModule()->getContext(); + Context.emitError("ran out of registers during register allocation"); + } else { + report_fatal_error("ran out of registers during register allocation"); + } + + // Keep going after reporting the error. + VRM->assignVirt2Phys(VirtReg->reg(), AllocOrder.front()); + continue; + } + + if (AvailablePhysReg) + Matrix->assign(*VirtReg, AvailablePhysReg); + + for (Register Reg : SplitVRegs) { + assert(LIS->hasInterval(Reg)); + + LiveInterval *SplitVirtReg = &LIS->getInterval(Reg); + assert(!VRM->hasPhys(SplitVirtReg->reg()) && "Register already assigned"); + if (MRI->reg_nodbg_empty(SplitVirtReg->reg())) { + assert(SplitVirtReg->empty() && "Non-empty but used interval"); + LLVM_DEBUG(dbgs() << "not queueing unused " << *SplitVirtReg << '\n'); + aboutToRemoveInterval(*SplitVirtReg); + LIS->removeInterval(SplitVirtReg->reg()); + continue; + } + LLVM_DEBUG(dbgs() << "queuing new interval: " << *SplitVirtReg << "\n"); + assert(Register::isVirtualRegister(SplitVirtReg->reg()) && + "expect split value in virtual register"); + enqueue(SplitVirtReg); + ++NumNewQueued; + } + } +} + +void RegAllocBase::postOptimization() { + spiller().postOptimization(); + for (auto DeadInst : DeadRemats) { + LIS->RemoveMachineInstrFromMaps(*DeadInst); + DeadInst->eraseFromParent(); + } + DeadRemats.clear(); +} + +void RegAllocBase::enqueue(LiveInterval *LI) { + const Register Reg = LI->reg(); + + assert(Reg.isVirtual() && "Can only enqueue virtual registers"); + + if (VRM->hasPhys(Reg)) + return; + + const TargetRegisterClass &RC = *MRI->getRegClass(Reg); + if (ShouldAllocateClass(*TRI, RC)) { + LLVM_DEBUG(dbgs() << "Enqueuing " << printReg(Reg, TRI) << '\n'); + enqueueImpl(LI); + } else { + LLVM_DEBUG(dbgs() << "Not enqueueing " << printReg(Reg, TRI) + << " in skipped register class\n"); + } +} |