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"
26#include "llvm/Support/Debug.h"
27
28#define DEBUG_TYPE "localizer"
29
30using namespace llvm;
31
32namespace {
33
34class LocalizerImpl {
35 /// MRI contains all the register class/bank information that this
36 /// pass uses and updates.
37 MachineRegisterInfo *MRI = nullptr;
38 /// TTI used for getting remat costs for instructions.
39 TargetTransformInfo *TTI = nullptr;
40
41 /// Check if \p MOUse is used in the same basic block as \p Def.
42 /// If the use is in the same block, we say it is local.
43 /// When the use is not local, \p InsertMBB will contain the basic
44 /// block when to insert \p Def to have a local use.
45 static bool isLocalUse(MachineOperand &MOUse, const MachineInstr &Def,
46 MachineBasicBlock *&InsertMBB);
47
48 /// Initialize the field members using \p MF.
49 void init(MachineFunction &MF, function_ref<TargetTransformInfo *()> GetTTI);
50
51 typedef SmallSetVector<MachineInstr *, 32> LocalizedSetVecT;
52
53 /// If \p Op is a reg operand of a PHI, return the number of total
54 /// operands in the PHI that are the same as \p Op, including itself.
55 unsigned getNumPhiUses(MachineOperand &Op) const;
56
57 /// Do inter-block localization from the entry block.
58 bool localizeInterBlock(MachineFunction &MF,
59 LocalizedSetVecT &LocalizedInstrs);
60
61 /// Do intra-block localization of already localized instructions.
62 bool localizeIntraBlock(LocalizedSetVecT &LocalizedInstrs);
63
64public:
65 bool runOnMachineFunction(MachineFunction &MF,
67};
68
69} // namespace
70
71char LocalizerLegacy::ID = 0;
73 "Move/duplicate certain instructions close to their use",
74 false, false)
77 "Move/duplicate certain instructions close to their use",
79
81
82void LocalizerImpl::init(MachineFunction &MF,
84 MRI = &MF.getRegInfo();
85 TTI = GetTTI();
86}
87
94
95bool LocalizerImpl::isLocalUse(MachineOperand &MOUse, const MachineInstr &Def,
96 MachineBasicBlock *&InsertMBB) {
97 MachineInstr &MIUse = *MOUse.getParent();
98 InsertMBB = MIUse.getParent();
99 if (MIUse.isPHI())
100 InsertMBB = MIUse.getOperand(MOUse.getOperandNo() + 1).getMBB();
101 return InsertMBB == Def.getParent();
102}
103
104unsigned LocalizerImpl::getNumPhiUses(MachineOperand &Op) const {
105 auto *MI = dyn_cast<GPhi>(&*Op.getParent());
106 if (!MI)
107 return 0;
108
109 Register SrcReg = Op.getReg();
110 unsigned NumUses = 0;
111 for (unsigned I = 0, NumVals = MI->getNumIncomingValues(); I < NumVals; ++I) {
112 if (MI->getIncomingValue(I) == SrcReg)
113 ++NumUses;
114 }
115 return NumUses;
116}
117
118bool LocalizerImpl::localizeInterBlock(MachineFunction &MF,
119 LocalizedSetVecT &LocalizedInstrs) {
120 bool Changed = false;
121 DenseMap<std::pair<MachineBasicBlock *, Register>, Register> MBBWithLocalDef;
122
123 // Since the IRTranslator only emits constants into the entry block, and the
124 // rest of the GISel pipeline generally emits constants close to their users,
125 // we only localize instructions in the entry block here. This might change if
126 // we start doing CSE across blocks.
127 auto &MBB = MF.front();
128 auto &TL = *MF.getSubtarget().getTargetLowering();
129 for (MachineInstr &MI : llvm::reverse(MBB)) {
130 if (!TL.shouldLocalize(MI, TTI))
131 continue;
132 LLVM_DEBUG(dbgs() << "Should localize: " << MI);
133 assert(MI.getDesc().getNumDefs() == 1 &&
134 "More than one definition not supported yet");
135 Register Reg = MI.getOperand(0).getReg();
136 // Check if all the users of MI are local.
137 // We are going to invalidation the list of use operands, so we
138 // can't use range iterator.
139 for (MachineOperand &MOUse :
141 // Check if the use is already local.
142 MachineBasicBlock *InsertMBB;
143 LLVM_DEBUG(MachineInstr &MIUse = *MOUse.getParent();
144 dbgs() << "Checking use: " << MIUse
145 << " #Opd: " << MOUse.getOperandNo() << '\n');
146 if (isLocalUse(MOUse, MI, InsertMBB)) {
147 // Even if we're in the same block, if the block is very large we could
148 // still have many long live ranges. Try to do intra-block localization
149 // too.
150 LocalizedInstrs.insert(&MI);
151 continue;
152 }
153
154 // PHIs look like a single user but can use the same register in multiple
155 // edges, causing remat into each predecessor. Allow this to a certain
156 // extent.
157 unsigned NumPhiUses = getNumPhiUses(MOUse);
158 const unsigned PhiThreshold = 2; // FIXME: Tune this more.
159 if (NumPhiUses > PhiThreshold)
160 continue;
161
162 LLVM_DEBUG(dbgs() << "Fixing non-local use\n");
163 Changed = true;
164 auto MBBAndReg = std::make_pair(InsertMBB, Reg);
165 auto NewVRegIt = MBBWithLocalDef.find(MBBAndReg);
166 if (NewVRegIt == MBBWithLocalDef.end()) {
167 // Create the localized instruction.
168 MachineInstr *LocalizedMI = MF.CloneMachineInstr(&MI);
169 LocalizedInstrs.insert(LocalizedMI);
170 MachineInstr &UseMI = *MOUse.getParent();
171 if (MRI->hasOneUse(Reg) && !UseMI.isPHI())
172 InsertMBB->insert(UseMI, LocalizedMI);
173 else
174 InsertMBB->insert(InsertMBB->SkipPHIsAndLabels(InsertMBB->begin()),
175 LocalizedMI);
176
177 // Set a new register for the definition.
178 Register NewReg = MRI->cloneVirtualRegister(Reg);
179 LocalizedMI->getOperand(0).setReg(NewReg);
180 NewVRegIt =
181 MBBWithLocalDef.try_emplace(MBBAndReg, NewReg).first;
182 LLVM_DEBUG(dbgs() << "Inserted: " << *LocalizedMI);
183 }
184 LLVM_DEBUG(dbgs() << "Update use with: " << printReg(NewVRegIt->second)
185 << '\n');
186 // Update the user reg.
187 MOUse.setReg(NewVRegIt->second);
188 }
189 }
190 return Changed;
191}
192
193bool LocalizerImpl::localizeIntraBlock(LocalizedSetVecT &LocalizedInstrs) {
194 bool Changed = false;
195
196 // For each already-localized instruction which has multiple users, then we
197 // scan the block top down from the current position until we hit one of them.
198
199 // FIXME: Consider doing inst duplication if live ranges are very long due to
200 // many users, but this case may be better served by regalloc improvements.
201
202 for (MachineInstr *MI : LocalizedInstrs) {
203 Register Reg = MI->getOperand(0).getReg();
204 MachineBasicBlock &MBB = *MI->getParent();
205 // All of the user MIs of this reg.
206 SmallPtrSet<MachineInstr *, 32> Users;
207 for (MachineInstr &UseMI : MRI->use_nodbg_instructions(Reg)) {
208 if (!UseMI.isPHI())
209 Users.insert(&UseMI);
210 }
212 // If all the users were PHIs then they're not going to be in our block, we
213 // may still benefit from sinking, especially since the value might be live
214 // across a call.
215 if (Users.empty()) {
216 // Make sure we don't sink in between two terminator sequences by scanning
217 // forward, not backward.
219 LLVM_DEBUG(dbgs() << "Only phi users: moving inst to end: " << *MI);
220 } else {
221 ++II;
222 while (II != MBB.end() && !Users.count(&*II))
223 ++II;
224 assert(II != MBB.end() && "Didn't find the user in the MBB");
225 LLVM_DEBUG(dbgs() << "Intra-block: moving " << *MI << " before " << *II);
226 }
227
228 MI->removeFromParent();
229 MBB.insert(II, MI);
230 Changed = true;
231
232 // If the instruction (constant) being localized has single user, we can
233 // propagate debug location from user.
234 if (Users.size() == 1) {
235 const auto &DefDL = MI->getDebugLoc();
236 const auto &UserDL = (*Users.begin())->getDebugLoc();
237
238 if ((!DefDL || DefDL.getLine() == 0) && UserDL && UserDL.getLine() != 0) {
239 MI->setDebugLoc(UserDL);
240 }
241 }
242 }
243 return Changed;
244}
245
246bool LocalizerImpl::runOnMachineFunction(
247 MachineFunction &MF, function_ref<TargetTransformInfo *()> GetTTI) {
248 // If the ISel pipeline failed, do not bother running that pass.
249 if (MF.getProperties().hasFailedISel())
250 return false;
251
252 LLVM_DEBUG(dbgs() << "Localize instructions for: " << MF.getName() << '\n');
253
254 init(MF, GetTTI);
255
256 // Keep track of the instructions we localized. We'll do a second pass of
257 // intra-block localization to further reduce live ranges.
258 LocalizedSetVecT LocalizedInstrs;
259
260 bool Changed = localizeInterBlock(MF, LocalizedInstrs);
261 Changed |= localizeIntraBlock(LocalizedInstrs);
262 return Changed;
263}
264
266 LocalizerImpl Impl;
267 return Impl.runOnMachineFunction(MF, [&]() {
269 MF.getFunction());
270 });
271}
272
276 LocalizerImpl Impl;
277 bool Changed = Impl.runOnMachineFunction(MF, [&]() {
278 Function &F = MF.getFunction();
281 .getManager();
282 return &FAM.getResult<TargetIRAnalysis>(F);
283 });
287}
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:275
Represents analyses that only rely on functions' control flow.
Definition Analysis.h:73
iterator find(const_arg_type_t< KeyT > Val)
Definition DenseMap.h:223
std::pair< iterator, bool > try_emplace(KeyT &&Key, Ts &&...Args)
Definition DenseMap.h:299
iterator end()
Definition DenseMap.h:141
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:88
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
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,...
bool hasOneUse(Register RegNo) const
hasOneUse - Return true if there is exactly one instruction using the specified register.
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...
iterator_range< use_iterator > use_operands(Register Reg) const
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
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< 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:633
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:407
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
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.