aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/libs/llvm16/lib/CodeGen/RegUsageInfoPropagate.cpp
diff options
context:
space:
mode:
authorvvvv <vvvv@ydb.tech>2024-02-06 20:01:22 +0300
committerAlexander Smirnov <alex@ydb.tech>2024-02-09 19:18:27 +0300
commitee2b7fbda052aa09b6fdb83b8c6f0305fef3e193 (patch)
tree102765416c3866bde98a82facc7752d329ee0226 /contrib/libs/llvm16/lib/CodeGen/RegUsageInfoPropagate.cpp
parent7494ca32d3a5aca00b7ac527b5f127989335102c (diff)
downloadydb-ee2b7fbda052aa09b6fdb83b8c6f0305fef3e193.tar.gz
llvm16 targets
Diffstat (limited to 'contrib/libs/llvm16/lib/CodeGen/RegUsageInfoPropagate.cpp')
-rw-r--r--contrib/libs/llvm16/lib/CodeGen/RegUsageInfoPropagate.cpp154
1 files changed, 154 insertions, 0 deletions
diff --git a/contrib/libs/llvm16/lib/CodeGen/RegUsageInfoPropagate.cpp b/contrib/libs/llvm16/lib/CodeGen/RegUsageInfoPropagate.cpp
new file mode 100644
index 00000000000..d356962e0d7
--- /dev/null
+++ b/contrib/libs/llvm16/lib/CodeGen/RegUsageInfoPropagate.cpp
@@ -0,0 +1,154 @@
+//=--- RegUsageInfoPropagate.cpp - Register Usage Informartion Propagation --=//
+//
+// 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 pass is required to take advantage of the interprocedural register
+/// allocation infrastructure.
+///
+/// This pass iterates through MachineInstrs in a given MachineFunction and at
+/// each callsite queries RegisterUsageInfo for RegMask (calculated based on
+/// actual register allocation) of the callee function, if the RegMask detail
+/// is available then this pass will update the RegMask of the call instruction.
+/// This updated RegMask will be used by the register allocator while allocating
+/// the current MachineFunction.
+///
+//===----------------------------------------------------------------------===//
+
+#include "llvm/CodeGen/MachineBasicBlock.h"
+#include "llvm/CodeGen/MachineFrameInfo.h"
+#include "llvm/CodeGen/MachineFunctionPass.h"
+#include "llvm/CodeGen/MachineInstr.h"
+#include "llvm/CodeGen/MachineRegisterInfo.h"
+#include "llvm/CodeGen/Passes.h"
+#include "llvm/CodeGen/RegisterUsageInfo.h"
+#include "llvm/IR/Module.h"
+#include "llvm/Pass.h"
+#include "llvm/Support/Debug.h"
+#include "llvm/Support/raw_ostream.h"
+
+using namespace llvm;
+
+#define DEBUG_TYPE "ip-regalloc"
+
+#define RUIP_NAME "Register Usage Information Propagation"
+
+namespace {
+
+class RegUsageInfoPropagation : public MachineFunctionPass {
+public:
+ RegUsageInfoPropagation() : MachineFunctionPass(ID) {
+ PassRegistry &Registry = *PassRegistry::getPassRegistry();
+ initializeRegUsageInfoPropagationPass(Registry);
+ }
+
+ StringRef getPassName() const override { return RUIP_NAME; }
+
+ bool runOnMachineFunction(MachineFunction &MF) override;
+
+ void getAnalysisUsage(AnalysisUsage &AU) const override {
+ AU.addRequired<PhysicalRegisterUsageInfo>();
+ AU.setPreservesAll();
+ MachineFunctionPass::getAnalysisUsage(AU);
+ }
+
+ static char ID;
+
+private:
+ static void setRegMask(MachineInstr &MI, ArrayRef<uint32_t> RegMask) {
+ assert(RegMask.size() ==
+ MachineOperand::getRegMaskSize(MI.getParent()->getParent()
+ ->getRegInfo().getTargetRegisterInfo()
+ ->getNumRegs())
+ && "expected register mask size");
+ for (MachineOperand &MO : MI.operands()) {
+ if (MO.isRegMask())
+ MO.setRegMask(RegMask.data());
+ }
+ }
+};
+
+} // end of anonymous namespace
+
+INITIALIZE_PASS_BEGIN(RegUsageInfoPropagation, "reg-usage-propagation",
+ RUIP_NAME, false, false)
+INITIALIZE_PASS_DEPENDENCY(PhysicalRegisterUsageInfo)
+INITIALIZE_PASS_END(RegUsageInfoPropagation, "reg-usage-propagation",
+ RUIP_NAME, false, false)
+
+char RegUsageInfoPropagation::ID = 0;
+
+// Assumes call instructions have a single reference to a function.
+static const Function *findCalledFunction(const Module &M,
+ const MachineInstr &MI) {
+ for (const MachineOperand &MO : MI.operands()) {
+ if (MO.isGlobal())
+ return dyn_cast<const Function>(MO.getGlobal());
+
+ if (MO.isSymbol())
+ return M.getFunction(MO.getSymbolName());
+ }
+
+ return nullptr;
+}
+
+bool RegUsageInfoPropagation::runOnMachineFunction(MachineFunction &MF) {
+ const Module &M = *MF.getFunction().getParent();
+ PhysicalRegisterUsageInfo *PRUI = &getAnalysis<PhysicalRegisterUsageInfo>();
+
+ LLVM_DEBUG(dbgs() << " ++++++++++++++++++++ " << getPassName()
+ << " ++++++++++++++++++++ \n");
+ LLVM_DEBUG(dbgs() << "MachineFunction : " << MF.getName() << "\n");
+
+ const MachineFrameInfo &MFI = MF.getFrameInfo();
+ if (!MFI.hasCalls() && !MFI.hasTailCall())
+ return false;
+
+ bool Changed = false;
+
+ for (MachineBasicBlock &MBB : MF) {
+ for (MachineInstr &MI : MBB) {
+ if (!MI.isCall())
+ continue;
+ LLVM_DEBUG(
+ dbgs()
+ << "Call Instruction Before Register Usage Info Propagation : \n"
+ << MI << "\n");
+
+ auto UpdateRegMask = [&](const Function &F) {
+ const ArrayRef<uint32_t> RegMask = PRUI->getRegUsageInfo(F);
+ if (RegMask.empty())
+ return;
+ setRegMask(MI, RegMask);
+ Changed = true;
+ };
+
+ if (const Function *F = findCalledFunction(M, MI)) {
+ if (F->isDefinitionExact()) {
+ UpdateRegMask(*F);
+ } else {
+ LLVM_DEBUG(dbgs() << "Function definition is not exact\n");
+ }
+ } else {
+ LLVM_DEBUG(dbgs() << "Failed to find call target function\n");
+ }
+
+ LLVM_DEBUG(
+ dbgs()
+ << "Call Instruction After Register Usage Info Propagation : \n"
+ << MI << '\n');
+ }
+ }
+
+ LLVM_DEBUG(
+ dbgs() << " +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"
+ "++++++ \n");
+ return Changed;
+}
+
+FunctionPass *llvm::createRegUsageInfoPropPass() {
+ return new RegUsageInfoPropagation();
+}