LLVM 24.0.0git
NVPTXPeephole.cpp
Go to the documentation of this file.
1//===-- NVPTXPeephole.cpp - NVPTX Peephole Optimiztions -------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// In NVPTX, NVPTXFrameLowering will emit following instruction at the beginning
10// of a MachineFunction.
11//
12// mov %SPL, %depot
13// cvta.local %SP, %SPL
14//
15// Because Frame Index is a generic address and alloca can only return generic
16// pointer, without this pass the instructions producing alloca'ed address will
17// be based on %SP. NVPTXLowerAlloca tends to help replace store and load on
18// this address with their .local versions, but this may introduce a lot of
19// cvta.to.local instructions. Performance can be improved if we avoid casting
20// address back and forth and directly calculate local address based on %SPL.
21// This peephole pass optimizes these cases, for example
22//
23// It will transform the following pattern
24// %0 = LEA_ADDRi64 %VRFrame64, 4
25// %1 = cvta_to_local_64 %0
26//
27// into
28// %1 = LEA_ADDRi64 %VRFrameLocal64, 4
29//
30// %VRFrameLocal64 is the virtual register name of %SPL
31//
32//===----------------------------------------------------------------------===//
33
34#include "NVPTX.h"
35#include "NVPTXRegisterInfo.h"
36#include "NVPTXSubtarget.h"
42
43using namespace llvm;
44
45#define DEBUG_TYPE "nvptx-peephole"
46
48 auto &MBB = *Root.getParent();
49 auto &MF = *MBB.getParent();
50 // Check current instruction is cvta.to.local
51 if (Root.getOpcode() != NVPTX::cvta_to_local_64 &&
52 Root.getOpcode() != NVPTX::cvta_to_local_32)
53 return false;
54
55 auto &Op = Root.getOperand(1);
56 const auto &MRI = MF.getRegInfo();
57 MachineInstr *GenericAddrDef = nullptr;
58 if (Op.isReg() && Op.getReg().isVirtual()) {
59 GenericAddrDef = MRI.getUniqueVRegDef(Op.getReg());
60 }
61
62 // Check the register operand is uniquely defined by LEA_ADDRi instruction
63 if (!GenericAddrDef || GenericAddrDef->getParent() != &MBB ||
64 (GenericAddrDef->getOpcode() != NVPTX::LEA_ADDRi64 &&
65 GenericAddrDef->getOpcode() != NVPTX::LEA_ADDRi)) {
66 return false;
67 }
68
69 const NVPTXRegisterInfo *NRI =
70 MF.getSubtarget<NVPTXSubtarget>().getRegisterInfo();
71
72 // LEA and %SPL must have the same width.
73 if ((GenericAddrDef->getOpcode() == NVPTX::LEA_ADDRi64) !=
74 (NRI->getFrameLocalRegister(MF) == NVPTX::VRFrameLocal64))
75 return false;
76
77 // Check the LEA_ADDRi operand is Frame index
78 auto &BaseAddrOp = GenericAddrDef->getOperand(1);
79 if (BaseAddrOp.isReg() && BaseAddrOp.getReg() == NRI->getFrameRegister(MF)) {
80 return true;
81 }
82
83 return false;
84}
85
86static void CombineCVTAToLocal(MachineInstr &Root) {
87 auto &MBB = *Root.getParent();
88 auto &MF = *MBB.getParent();
89 const auto &MRI = MF.getRegInfo();
90 const TargetInstrInfo *TII = MF.getSubtarget().getInstrInfo();
91 auto &Prev = *MRI.getUniqueVRegDef(Root.getOperand(1).getReg());
92
93 const NVPTXRegisterInfo *NRI =
94 MF.getSubtarget<NVPTXSubtarget>().getRegisterInfo();
95
97 BuildMI(MF, Root.getDebugLoc(), TII->get(Prev.getOpcode()),
98 Root.getOperand(0).getReg())
100 .add(Prev.getOperand(2));
101
102 MBB.insert((MachineBasicBlock::iterator)&Root, MIB);
103
104 // Check if MRI has only one non dbg use, which is Root
105 if (MRI.hasOneNonDBGUse(Prev.getOperand(0).getReg())) {
106 Prev.eraseFromParent();
107 }
108 Root.eraseFromParent();
109}
110
112 bool Changed = false;
113 // Loop over all of the basic blocks.
114 for (auto &MBB : MF) {
115 // Traverse the basic block.
116 auto BlockIter = MBB.begin();
117
118 while (BlockIter != MBB.end()) {
119 auto &MI = *BlockIter++;
122 Changed = true;
123 }
124 } // Instruction
125 } // Basic Block
126
127 const NVPTXRegisterInfo *NRI =
128 MF.getSubtarget<NVPTXSubtarget>().getRegisterInfo();
129
130 // Remove unnecessary %VRFrame = cvta.local %VRFrameLocal
131 const auto &MRI = MF.getRegInfo();
132 if (MRI.use_empty(NRI->getFrameRegister(MF))) {
133 if (auto MI = MRI.getUniqueVRegDef(NRI->getFrameRegister(MF))) {
134 MI->eraseFromParent();
135 Changed = true;
136 }
137 }
138
139 return Changed;
140}
141
142namespace {
143struct NVPTXPeepholeLegacyPass : public MachineFunctionPass {
144public:
145 static char ID;
146 NVPTXPeepholeLegacyPass() : MachineFunctionPass(ID) {}
147
148 bool runOnMachineFunction(MachineFunction &MF) override {
149 if (skipFunction(MF.getFunction()))
150 return false;
151 return runNVPTXPeephole(MF);
152 }
153
154 StringRef getPassName() const override {
155 return "NVPTX optimize redundant cvta.to.local instruction";
156 }
157
158 void getAnalysisUsage(AnalysisUsage &AU) const override {
159 AU.setPreservesCFG();
161 }
162};
163} // namespace
164
165char NVPTXPeepholeLegacyPass::ID = 0;
166
167INITIALIZE_PASS(NVPTXPeepholeLegacyPass, "nvptx-peephole", "NVPTX Peephole",
168 false, false)
169
171 return new NVPTXPeepholeLegacyPass();
172}
173
MachineBasicBlock & MBB
const HexagonInstrInfo * TII
IRTranslator LLVM IR MI
static bool runNVPTXPeephole(MachineFunction &MF)
static bool isCVTAToLocalCombinationCandidate(MachineInstr &Root)
static void CombineCVTAToLocal(MachineInstr &Root)
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
Definition PassSupport.h:56
LLVM_ABI void setPreservesCFG()
This function should be called by the pass, iff they do not:
Definition Pass.cpp:275
Represents analyses that only rely on functions' control flow.
Definition Analysis.h:73
MachineInstrBundleIterator< MachineInstr > iterator
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
Function & getFunction()
Return the LLVM function that this machine code represents.
const MachineInstrBuilder & addReg(Register RegNo, RegState Flags={}, unsigned SubReg=0) const
Add a new virtual register operand.
const MachineInstrBuilder & add(const MachineOperand &MO) const
Representation of each machine instruction.
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
const MachineBasicBlock * getParent() const
const DebugLoc & getDebugLoc() const
Returns the debug location id of this MachineInstr.
const MachineOperand & getOperand(unsigned i) const
LLVM_ABI MachineInstrBundleIterator< MachineInstr > eraseFromParent()
Unlink 'this' from the containing basic block and delete it.
Register getReg() const
getReg - Returns the register number.
PreservedAnalyses run(MachineFunction &MF, MachineFunctionAnalysisManager &MFAM)
Register getFrameLocalRegister(const MachineFunction &MF) const
Register getFrameRegister(const MachineFunction &MF) const override
A set of analyses that are preserved following a run of a transformation pass.
Definition Analysis.h:112
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
Definition Analysis.h:118
PreservedAnalyses & preserveSet()
Mark an analysis set as preserved.
Definition Analysis.h:151
TargetInstrInfo - Interface to description of machine instruction set.
Changed
This is an optimization pass for GlobalISel generic memory operations.
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
AnalysisManager< MachineFunction > MachineFunctionAnalysisManager
LLVM_ABI PreservedAnalyses getMachineFunctionPassPreservedAnalyses()
Returns the minimum set of Analyses that all machine function passes must preserve.
MachineFunctionPass * createNVPTXPeepholeLegacyPass()
DWARFExpression::Operation Op