aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/libs/llvm14/lib/CodeGen/RegAllocBase.cpp
diff options
context:
space:
mode:
authorvitalyisaev <vitalyisaev@yandex-team.com>2023-06-29 10:00:50 +0300
committervitalyisaev <vitalyisaev@yandex-team.com>2023-06-29 10:00:50 +0300
commit6ffe9e53658409f212834330e13564e4952558f6 (patch)
tree85b1e00183517648b228aafa7c8fb07f5276f419 /contrib/libs/llvm14/lib/CodeGen/RegAllocBase.cpp
parent726057070f9c5a91fc10fde0d5024913d10f1ab9 (diff)
downloadydb-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.cpp195
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");
+ }
+}