LLVM 24.0.0git
Localizer.cpp
Go to the documentation of this file.
1//===- Localizer.cpp ---------------------- Localize some instrs -*- C++ -*-==//
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/// \file
9/// This file implements the Localizer class.
10//===----------------------------------------------------------------------===//
11
13#include "llvm/ADT/DenseMap.h"
14#include "llvm/ADT/STLExtras.h"
15#include "llvm/ADT/SetVector.h"
24#include "llvm/IR/Analysis.h"
27#include "llvm/Support/Debug.h"
28
29#define DEBUG_TYPE "localizer"
30
31using namespace llvm;
32
33namespace {
34
35class LocalizerImpl {
36 /// MRI contains all the register class/bank information that this
37 /// pass uses and updates.
38 MachineRegisterInfo *MRI = nullptr;
39 /// TTI used for getting remat costs for instructions.
40 TargetTransformInfo *TTI = nullptr;
41
42 /// Check if \p MOUse is used in the same basic block as \p Def.
43 /// If the use is in the same block, we say it is local.
44 /// When the use is not local, \p InsertMBB will contain the basic
45 /// block when to insert \p Def to have a local use.
46 static bool isLocalUse(MachineOperand &MOUse, const MachineInstr &Def,
47 MachineBasicBlock *&InsertMBB);
48
49 /// Initialize the field members using \p MF.
50 void init(MachineFunction &MF, function_ref<TargetTransformInfo *()> GetTTI);
51
52 typedef SmallSetVector<MachineInstr *, 32> LocalizedSetVecT;
53
54 /// If \p Op is a reg operand of a PHI, return the number of total
55 /// operands in the PHI that are the same as \p Op, including itself.
56 unsigned getNumPhiUses(MachineOperand &Op) const;
57
58 /// Do inter-block localization from the entry block.
59 bool localizeInterBlock(MachineFunction &MF,
60 LocalizedSetVecT &LocalizedInstrs);
61
62 /// Do intra-block localization of already localized instructions.
63 bool localizeIntraBlock(LocalizedSetVecT &LocalizedInstrs);
64
65public:
66 bool runOnMachineFunction(MachineFunction &MF,
68};
69
70} // namespace
71
72char LocalizerLegacy::ID = 0;
74 "Move/duplicate certain instructions close to their use",
75 false, false)
78 "Move/duplicate certain instructions close to their use",
80
82
83void LocalizerImpl::init(MachineFunction &MF,
85 MRI = &MF.getRegInfo();
86 TTI = GetTTI();
87}
88
95
96bool LocalizerImpl::isLocalUse(MachineOperand &MOUse, const MachineInstr &Def,
97 MachineBasicBlock *&InsertMBB) {
98 MachineInstr &MIUse = *MOUse.getParent();
99 InsertMBB = MIUse.getParent();
100 if (MIUse.isPHI())
101 InsertMBB = MIUse.getOperand(MOUse.getOperandNo() + 1).getMBB();
102 return InsertMBB == Def.getParent();
103}
104
105unsigned LocalizerImpl::getNumPhiUses(MachineOperand &Op) const {
106 auto *MI = dyn_cast<GPhi>(&*Op.getParent());
107 if (!MI)
108 return 0;
109
110 Register SrcReg = Op.getReg();
111 unsigned NumUses = 0;
112 for (unsigned I = 0, NumVals = MI->getNumIncomingValues(); I < NumVals; ++I) {
113 if (MI->getIncomingValue(I) == SrcReg)
114 ++NumUses;
115 }
116 return NumUses;
117}
118
119bool LocalizerImpl::localizeInterBlock(MachineFunction &MF,
120 LocalizedSetVecT &LocalizedInstrs) {
121 bool Changed = false;
122 DenseMap<std::pair<MachineBasicBlock *, Register>, Register> MBBWithLocalDef;
123
124 // Since the IRTranslator only emits constants into the entry block, and the
125 // rest of the GISel pipeline generally emits constants close to their users,
126 // we only localize instructions in the entry block here. This might change if
127 // we start doing CSE across blocks.
128 auto &MBB = MF.front();
129 auto &TL = *MF.getSubtarget().getTargetLowering();
130 for (MachineInstr &MI : llvm::reverse(MBB)) {
131 if (!TL.shouldLocalize(MI, TTI))
132 continue;
133 LLVM_DEBUG(dbgs() << "Should localize: " << MI);
134 assert(MI.getDesc().getNumDefs() == 1 &&
135 "More than one definition not supported yet");
136 Register Reg = MI.getOperand(0).getReg();
137 // Check if all the users of MI are local. We are going to invalidate the
138 // list of use operands, so we can't use a range iterator. Debug users stay
139 // with the original definition.
140 for (MachineOperand &MOUse :
142 // Check if the use is already local.
143 MachineBasicBlock *InsertMBB;
144 LLVM_DEBUG(MachineInstr &MIUse = *MOUse.getParent();
145 dbgs() << "Checking use: " << MIUse
146 << " #Opd: " << MOUse.getOperandNo() << '\n');
147 if (isLocalUse(MOUse, MI, InsertMBB)) {
148 // Even if we're in the same block, if the block is very large we could
149 // still have many long live ranges. Try to do intra-block localization
150 // too.
151 LocalizedInstrs.insert(&MI);
152 continue;
153 }
154
155 // PHIs look like a single user but can use the same register in multiple
156 // edges, causing remat into each predecessor. Allow this to a certain
157 // extent.
158 unsigned NumPhiUses = getNumPhiUses(MOUse);
159 const unsigned PhiThreshold = 2; // FIXME: Tune this more.
160 if (NumPhiUses > PhiThreshold)
161 continue;
162
163 LLVM_DEBUG(dbgs() << "Fixing non-local use\n");
164 Changed = true;
165 auto MBBAndReg = std::make_pair(InsertMBB, Reg);
166 auto NewVRegIt = MBBWithLocalDef.find(MBBAndReg);
167 if (NewVRegIt == MBBWithLocalDef.end()) {
168 // Create the localized instruction.
169 MachineInstr *LocalizedMI = MF.CloneMachineInstr(&MI);
170 LocalizedInstrs.insert(LocalizedMI);
171 MachineInstr &UseMI = *MOUse.getParent();
172 if (MRI->hasOneNonDBGUse(Reg) && !UseMI.isPHI())
173 InsertMBB->insert(UseMI, LocalizedMI);
174 else
175 InsertMBB->insert(InsertMBB->SkipPHIsAndLabels(InsertMBB->begin()),
176 LocalizedMI);
177
178 // Set a new register for the definition.
179 Register NewReg = MRI->cloneVirtualRegister(Reg);
180 LocalizedMI->getOperand(0).setReg(NewReg);
181 NewVRegIt =
182 MBBWithLocalDef.try_emplace(MBBAndReg, NewReg).first;
183 LLVM_DEBUG(dbgs() << "Inserted: " << *LocalizedMI);
184 }
185 LLVM_DEBUG(dbgs() << "Update use with: " << printReg(NewVRegIt->second)
186 << '\n');
187 // Update the user reg.
188 MOUse.setReg(NewVRegIt->second);
189 }
190 }
191 return Changed;
192}
193
194bool LocalizerImpl::localizeIntraBlock(LocalizedSetVecT &LocalizedInstrs) {
195 bool Changed = false;
196
197 // For each already-localized instruction which has multiple users, then we
198 // scan the block top down from the current position until we hit one of them.
199
200 // FIXME: Consider doing inst duplication if live ranges are very long due to
201 // many users, but this case may be better served by regalloc improvements.
202
203 for (MachineInstr *MI : LocalizedInstrs) {
204 Register Reg = MI->getOperand(0).getReg();
205 MachineBasicBlock &MBB = *MI->getParent();
206 // All of the user MIs of this reg.
207 SmallPtrSet<MachineInstr *, 32> Users;
208 for (MachineInstr &UseMI : MRI->use_nodbg_instructions(Reg)) {
209 if (!UseMI.isPHI())
210 Users.insert(&UseMI);
211 }
213 // If all the users were PHIs then they're not going to be in our block, we
214 // may still benefit from sinking, especially since the value might be live
215 // across a call.
216 if (Users.empty()) {
217 // Make sure we don't sink in between two terminator sequences by scanning
218 // forward, not backward.
220 LLVM_DEBUG(dbgs() << "Only phi users: moving inst to end: " << *MI);
221 } else {
222 ++II;
223 while (II != MBB.end() && !Users.count(&*II))
224 ++II;
225 assert(II != MBB.end() && "Didn't find the user in the MBB");
226 LLVM_DEBUG(dbgs() << "Intra-block: moving " << *MI << " before " << *II);
227 }
228
229 // Leave each DBG_VALUE above MI that uses one of its results behind as
230 // undef, so that it still ends any earlier location of the variable, and
231 // put a copy right after MI, like MachineSink does. No copy is needed if a
232 // later DBG_VALUE of the same variable replaces it before that.
233 SmallVector<MachineInstr *, 4> DbgUsers;
234 SmallVector<MachineInstr *, 4> DbgUsersToCopy;
235 for (MachineInstr &DbgMI :
237 if (!DbgMI.isDebugValue())
238 continue;
239 erase_if(DbgUsersToCopy, [&](const MachineInstr *Earlier) {
240 return Earlier->getDebugVariable() == DbgMI.getDebugVariable() &&
241 Earlier->getDebugLoc().getInlinedAt() ==
242 DbgMI.getDebugLoc().getInlinedAt() &&
244 DbgMI.getDebugExpression());
245 });
246 if (DbgMI.hasDebugOperandForReg(Reg)) {
247 DbgUsers.push_back(&DbgMI);
248 DbgUsersToCopy.push_back(&DbgMI);
249 }
250 }
251
252 MI->removeFromParent();
253 MBB.insert(II, MI);
254 Changed = true;
255
256 for (MachineInstr *DbgMI : DbgUsersToCopy)
257 MBB.insert(II, MBB.getParent()->CloneMachineInstr(DbgMI));
258 for (MachineInstr *DbgMI : DbgUsers)
259 DbgMI->setDebugValueUndef();
260
261 // If the instruction (constant) being localized has single user, we can
262 // propagate debug location from user.
263 if (Users.size() == 1) {
264 const auto &DefDL = MI->getDebugLoc();
265 const auto &UserDL = (*Users.begin())->getDebugLoc();
266
267 if ((!DefDL || DefDL.getLine() == 0) && UserDL && UserDL.getLine() != 0) {
268 MI->setDebugLoc(UserDL);
269 }
270 }
271 }
272 return Changed;
273}
274
275bool LocalizerImpl::runOnMachineFunction(
276 MachineFunction &MF, function_ref<TargetTransformInfo *()> GetTTI) {
277 // If the ISel pipeline failed, do not bother running that pass.
278 if (MF.getProperties().hasFailedISel())
279 return false;
280
281 LLVM_DEBUG(dbgs() << "Localize instructions for: " << MF.getName() << '\n');
282
283 init(MF, GetTTI);
284
285 // Keep track of the instructions we localized. We'll do a second pass of
286 // intra-block localization to further reduce live ranges.
287 LocalizedSetVecT LocalizedInstrs;
288
289 bool Changed = localizeInterBlock(MF, LocalizedInstrs);
290 Changed |= localizeIntraBlock(LocalizedInstrs);
291 return Changed;
292}
293
295 LocalizerImpl Impl;
296 return Impl.runOnMachineFunction(MF, [&]() {
298 MF.getFunction());
299 });
300}
301
305 LocalizerImpl Impl;
306 bool Changed = Impl.runOnMachineFunction(MF, [&]() {
307 Function &F = MF.getFunction();
310 .getManager();
311 return &FAM.getResult<TargetIRAnalysis>(F);
312 });
316}
MachineInstrBuilder & UseMI
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
MachineBasicBlock & MBB
This file defines the DenseMap class.
#define DEBUG_TYPE
Declares convenience wrapper classes for interpreting MachineInstr instances as specific generic oper...
#define _
IRTranslator LLVM IR MI
iv Induction Variable Users
Definition IVUsers.cpp:48
#define F(x, y, z)
Definition MD5.cpp:54
#define I(x, y, z)
Definition MD5.cpp:57
Register Reg
Promote Memory to Register
Definition Mem2Reg.cpp:110
uint64_t IntrinsicInst * II
FunctionAnalysisManager FAM
#define INITIALIZE_PASS_DEPENDENCY(depName)
Definition PassSupport.h:42
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
Definition PassSupport.h:44
#define INITIALIZE_PASS_BEGIN(passName, arg, name, cfg, analysis)
Definition PassSupport.h:39
This file contains some templates that are useful if you are working with the STL at all.
This file implements a set that has insertion order iteration characteristics.
#define LLVM_DEBUG(...)
Definition Debug.h:119
This file describes how to lower LLVM code to machine code.
This pass exposes codegen information to IR-level passes.
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
Represent the analysis usage information of a pass.
AnalysisUsage & addRequired()
LLVM_ABI void setPreservesCFG()
This function should be called by the pass, iff they do not:
Definition Pass.cpp:280
Represents analyses that only rely on functions' control flow.
Definition Analysis.h:73
static bool fragmentsOverlap(const FragmentInfo &A, const FragmentInfo &B)
Check if fragments overlap between a pair of FragmentInfos.
LLVM_ABI DILocation * getInlinedAt() const
Definition DebugLoc.cpp:58
iterator find(const_arg_type_t< KeyT > Val)
Definition DenseMap.h:766
iterator end()
Definition DenseMap.h:686
std::pair< iterator, bool > try_emplace(KeyT &&Key, Ts &&...Args)
Definition DenseMap.h:856
This pass implements the localization mechanism described at the top of this file.
Definition Localizer.h:40
bool runOnMachineFunction(MachineFunction &MF) override
runOnMachineFunction - This method must be overloaded to perform the desired machine code transformat...
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - This function should be overriden by passes that need analysis information to do t...
Definition Localizer.cpp:89
LLVM_ABI PreservedAnalyses run(MachineFunction &MF, MachineFunctionAnalysisManager &MFAM)
An RAII based helper class to modify MachineFunctionProperties when running pass.
LLVM_ABI iterator getFirstTerminatorForward()
Finds the first terminator in a block by scanning forward.
LLVM_ABI instr_iterator insert(instr_iterator I, MachineInstr *M)
Insert MI into the instruction list before I, possibly inside a bundle.
LLVM_ABI iterator SkipPHIsAndLabels(iterator I)
Return the first instruction in MBB after I that is not a PHI or a label.
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
MachineInstrBundleIterator< MachineInstr > iterator
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.
StringRef getName() const
getName - Return the name of the corresponding LLVM function.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
Function & getFunction()
Return the LLVM function that this machine code represents.
const MachineFunctionProperties & getProperties() const
Get the function properties.
const MachineBasicBlock & front() const
void insert(iterator MBBI, MachineBasicBlock *MBB)
Representation of each machine instruction.
const MachineBasicBlock * getParent() const
LLVM_ABI const DILocalVariable * getDebugVariable() const
Return the debug variable referenced by this DBG_VALUE instruction.
LLVM_ABI const DIExpression * getDebugExpression() const
Return the complex address expression referenced by this DBG_VALUE instruction.
const DebugLoc & getDebugLoc() const
Returns the debug location id of this MachineInstr.
const MachineOperand & getOperand(unsigned i) const
MachineOperand class - Representation of each machine instruction operand.
LLVM_ABI unsigned getOperandNo() const
Returns the index of this operand in the instruction that it belongs to.
MachineBasicBlock * getMBB() const
LLVM_ABI void setReg(Register Reg)
Change the register this operand corresponds to.
MachineInstr * getParent()
getParent - Return the instruction that this operand belongs to.
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
LLVM_ABI bool hasOneNonDBGUse(Register RegNo) const
hasOneNonDBGUse - Return true if there is exactly one non-Debug use of the specified register.
iterator_range< use_nodbg_iterator > use_nodbg_operands(Register Reg) const
iterator_range< use_instr_nodbg_iterator > use_nodbg_instructions(Register Reg) const
LLVM_ABI Register cloneVirtualRegister(Register VReg, StringRef Name="")
Create and return a new virtual register in the function with the same attributes as the given regist...
AnalysisType & getAnalysis() const
getAnalysis<AnalysisType>() - This function is used by subclasses to get to the analysis information ...
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
Wrapper class representing virtual and physical registers.
Definition Register.h:20
A SetVector that performs no allocations if smaller than a certain size.
Definition SetVector.h:345
void push_back(const T &Elt)
Analysis pass providing the TargetTransformInfo.
virtual const TargetLowering * getTargetLowering() const
Wrapper pass for TargetTransformInfo.
This pass provides access to the codegen interfaces that are needed for IR-level transformations.
An efficient, type-erasing, non-owning reference to a callable.
Changed
Pass manager infrastructure for declaring and invalidating analyses.
initializer< Ty > init(const Ty &Val)
This is an optimization pass for GlobalISel generic memory operations.
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:643
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
iterator_range< early_inc_iterator_impl< detail::IterOfRange< RangeT > > > make_early_inc_range(RangeT &&Range)
Make a range that does early increment to allow mutation of the underlying range without disrupting i...
Definition STLExtras.h:649
AnalysisManager< MachineFunction > MachineFunctionAnalysisManager
LLVM_ABI PreservedAnalyses getMachineFunctionPassPreservedAnalyses()
Returns the minimum set of Analyses that all machine function passes must preserve.
auto reverse(ContainerTy &&C)
Definition STLExtras.h:408
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition Debug.cpp:209
TargetTransformInfo TTI
LLVM_ABI void getSelectionDAGFallbackAnalysisUsage(AnalysisUsage &AU)
Modify analysis usage so it preserves passes required for the SelectionDAG fallback.
Definition Utils.cpp:1137
DWARFExpression::Operation Op
void erase_if(Container &C, UnaryPredicate P)
Provide a container algorithm similar to C++ Library Fundamentals v2's erase_if which is equivalent t...
Definition STLExtras.h:2208
AnalysisManager< Function > FunctionAnalysisManager
Convenience typedef for the Function analysis manager.
LLVM_ABI Printable printReg(Register Reg, const TargetRegisterInfo *TRI=nullptr, unsigned SubIdx=0, const MachineRegisterInfo *MRI=nullptr)
Prints virtual and physical registers with or without a TRI instance.