[llvm] [llvm][NVPTX] Fix quadratic runtime in ProxyRegErasure (PR #105730)
Jeff Niu via llvm-commits
llvm-commits at lists.llvm.org
Thu Aug 22 14:03:30 PDT 2024
https://github.com/Mogball updated https://github.com/llvm/llvm-project/pull/105730
>From ed37b13939a8f2efc7c1bf0ffd6aebefb6d8410f Mon Sep 17 00:00:00 2001
From: Mogball <jeff at modular.com>
Date: Thu, 22 Aug 2024 16:41:28 -0400
Subject: [PATCH 1/2] [llvm][NVPTX] Fix quadratic runtime in ProxyRegErasure
This pass performs RAUW by walking the machine function for each RAUW
operation. For large functions, this runtime in this pass starts to blow
up. Linearize the pass by batching the RAUW ops at once.
---
.../lib/Target/NVPTX/NVPTXProxyRegErasure.cpp | 60 +++++++++----------
1 file changed, 28 insertions(+), 32 deletions(-)
diff --git a/llvm/lib/Target/NVPTX/NVPTXProxyRegErasure.cpp b/llvm/lib/Target/NVPTX/NVPTXProxyRegErasure.cpp
index 258ae97a20d582..7fe6993fd33e4c 100644
--- a/llvm/lib/Target/NVPTX/NVPTXProxyRegErasure.cpp
+++ b/llvm/lib/Target/NVPTX/NVPTXProxyRegErasure.cpp
@@ -34,7 +34,6 @@ void initializeNVPTXProxyRegErasurePass(PassRegistry &);
namespace {
struct NVPTXProxyRegErasure : public MachineFunctionPass {
-public:
static char ID;
NVPTXProxyRegErasure() : MachineFunctionPass(ID) {
initializeNVPTXProxyRegErasurePass(*PassRegistry::getPassRegistry());
@@ -49,23 +48,22 @@ struct NVPTXProxyRegErasure : public MachineFunctionPass {
void getAnalysisUsage(AnalysisUsage &AU) const override {
MachineFunctionPass::getAnalysisUsage(AU);
}
-
-private:
- void replaceMachineInstructionUsage(MachineFunction &MF, MachineInstr &MI);
-
- void replaceRegisterUsage(MachineInstr &Instr, MachineOperand &From,
- MachineOperand &To);
};
} // namespace
char NVPTXProxyRegErasure::ID = 0;
-INITIALIZE_PASS(NVPTXProxyRegErasure, "nvptx-proxyreg-erasure", "NVPTX ProxyReg Erasure", false, false)
+INITIALIZE_PASS(NVPTXProxyRegErasure, "nvptx-proxyreg-erasure",
+ "NVPTX ProxyReg Erasure", false, false)
bool NVPTXProxyRegErasure::runOnMachineFunction(MachineFunction &MF) {
SmallVector<MachineInstr *, 16> RemoveList;
+ // ProxyReg instructions forward a register as another: `%dst = mov.iN %src`.
+ // Bulk RAUW the `%dst` registers in two passes over the machine function.
+ DenseMap<Register, Register> RAUWBatch;
+
for (auto &BB : MF) {
for (auto &MI : BB) {
switch (MI.getOpcode()) {
@@ -74,44 +72,42 @@ bool NVPTXProxyRegErasure::runOnMachineFunction(MachineFunction &MF) {
case NVPTX::ProxyRegI32:
case NVPTX::ProxyRegI64:
case NVPTX::ProxyRegF32:
- case NVPTX::ProxyRegF64:
- replaceMachineInstructionUsage(MF, MI);
+ case NVPTX::ProxyRegF64: {
+ auto &InOp = *MI.uses().begin();
+ auto &OutOp = *MI.defs().begin();
+ assert(InOp.isReg() && "ProxyReg input should be a register.");
+ assert(OutOp.isReg() && "ProxyReg output should be a register.");
RemoveList.push_back(&MI);
+ RAUWBatch.try_emplace(OutOp.getReg(), InOp.getReg());
break;
}
+ }
}
}
+ // If there were no proxy instructions, exit early.
+ if (RemoveList.empty())
+ return false;
+
+ // Erase the proxy instructions first.
for (auto *MI : RemoveList) {
MI->eraseFromParent();
}
- return !RemoveList.empty();
-}
-
-void NVPTXProxyRegErasure::replaceMachineInstructionUsage(MachineFunction &MF,
- MachineInstr &MI) {
- auto &InOp = *MI.uses().begin();
- auto &OutOp = *MI.defs().begin();
-
- assert(InOp.isReg() && "ProxyReg input operand should be a register.");
- assert(OutOp.isReg() && "ProxyReg output operand should be a register.");
-
+ // Now go replace the registers.
for (auto &BB : MF) {
- for (auto &I : BB) {
- replaceRegisterUsage(I, OutOp, InOp);
+ for (auto &MI : BB) {
+ for (auto &Op : MI.uses()) {
+ if (Op.isReg()) {
+ auto it = RAUWBatch.find(Op.getReg());
+ if (it != RAUWBatch.end())
+ Op.setReg(it->second);
+ }
+ }
}
}
-}
-void NVPTXProxyRegErasure::replaceRegisterUsage(MachineInstr &Instr,
- MachineOperand &From,
- MachineOperand &To) {
- for (auto &Op : Instr.uses()) {
- if (Op.isReg() && Op.getReg() == From.getReg()) {
- Op.setReg(To.getReg());
- }
- }
+ return true;
}
MachineFunctionPass *llvm::createNVPTXProxyRegErasurePass() {
>From 2213e57dcb878d1bdc27d6692cb12b2ecc323812 Mon Sep 17 00:00:00 2001
From: Mogball <jeff at modular.com>
Date: Thu, 22 Aug 2024 17:03:18 -0400
Subject: [PATCH 2/2] early exit loop
---
llvm/lib/Target/NVPTX/NVPTXProxyRegErasure.cpp | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/llvm/lib/Target/NVPTX/NVPTXProxyRegErasure.cpp b/llvm/lib/Target/NVPTX/NVPTXProxyRegErasure.cpp
index 7fe6993fd33e4c..f3a3362addb0ea 100644
--- a/llvm/lib/Target/NVPTX/NVPTXProxyRegErasure.cpp
+++ b/llvm/lib/Target/NVPTX/NVPTXProxyRegErasure.cpp
@@ -98,11 +98,11 @@ bool NVPTXProxyRegErasure::runOnMachineFunction(MachineFunction &MF) {
for (auto &BB : MF) {
for (auto &MI : BB) {
for (auto &Op : MI.uses()) {
- if (Op.isReg()) {
- auto it = RAUWBatch.find(Op.getReg());
- if (it != RAUWBatch.end())
- Op.setReg(it->second);
- }
+ if (!Op.isReg())
+ continue;
+ auto it = RAUWBatch.find(Op.getReg());
+ if (it != RAUWBatch.end())
+ Op.setReg(it->second);
}
}
}
More information about the llvm-commits
mailing list