LLVM: lib/CodeGen/GlobalISel/Localizer.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
22
23#define DEBUG_TYPE "localizer"
24
25using namespace llvm;
26
29 "Move/duplicate certain instructions close to their use",
30 false, false)
33 "Move/duplicate certain instructions close to their use",
35
38
41
45}
46
52
57 if (MIUse.isPHI())
59 return InsertMBB == Def.getParent();
60}
61
64 if ()
65 return 0;
66
68 unsigned NumUses = 0;
69 for (unsigned I = 0, NumVals = MI->getNumIncomingValues(); I < NumVals; ++I) {
70 if (MI->getIncomingValue(I) == SrcReg)
71 ++NumUses;
72 }
73 return NumUses;
74}
75
77 LocalizedSetVecT &LocalizedInstrs) {
79 DenseMap<std::pair<MachineBasicBlock *, Register>, Register> MBBWithLocalDef;
80
81
82
83
84
88 if (!TL.shouldLocalize(MI, TTI))
89 continue;
91 assert(MI.getDesc().getNumDefs() == 1 &&
92 "More than one definition not supported yet");
94
95
96
97 for (MachineOperand &MOUse :
99
100 MachineBasicBlock *InsertMBB;
102 dbgs() << "Checking use: " << MIUse
103 << " #Opd: " << MOUse.getOperandNo() << '\n');
104 if (isLocalUse(MOUse, MI, InsertMBB)) {
105
106
107
108 LocalizedInstrs.insert(&MI);
109 continue;
110 }
111
112
113
114
115 unsigned NumPhiUses = getNumPhiUses(MOUse);
116 const unsigned PhiThreshold = 2;
117 if (NumPhiUses > PhiThreshold)
118 continue;
119
122 auto MBBAndReg = std::make_pair(InsertMBB, Reg);
123 auto NewVRegIt = MBBWithLocalDef.find(MBBAndReg);
124 if (NewVRegIt == MBBWithLocalDef.end()) {
125
126 MachineInstr *LocalizedMI = MF.CloneMachineInstr(&MI);
127 LocalizedInstrs.insert(LocalizedMI);
129 if (MRI->hasOneUse(Reg) && .isPHI())
131 else
133 LocalizedMI);
134
135
136 Register NewReg = MRI->cloneVirtualRegister(Reg);
138 NewVRegIt =
139 MBBWithLocalDef.try_emplace(MBBAndReg, NewReg).first;
141 }
143 << '\n');
144
145 MOUse.setReg(NewVRegIt->second);
146 }
147 }
149}
150
151bool Localizer::localizeIntraBlock(LocalizedSetVecT &LocalizedInstrs) {
153
154
155
156
157
158
159
160 for (MachineInstr *MI : LocalizedInstrs) {
162 MachineBasicBlock &MBB = *MI->getParent();
163
164 SmallPtrSet<MachineInstr *, 32> Users;
165 for (MachineInstr &UseMI : MRI->use_nodbg_instructions(Reg)) {
166 if (.isPHI())
168 }
170
171
172
173 if (Users.empty()) {
174
175
177 LLVM_DEBUG(dbgs() << "Only phi users: moving inst to end: " << *MI);
178 } else {
179 ++II;
181 ++II;
182 assert(II != MBB.end() && "Didn't find the user in the MBB");
183 LLVM_DEBUG(dbgs() << "Intra-block: moving " << *MI << " before " << *II);
184 }
185
186 MI->removeFromParent();
189
190
191
192 if (Users.size() == 1) {
193 const auto &DefDL = MI->getDebugLoc();
194 const auto &UserDL = (*Users.begin())->getDebugLoc();
195
196 if ((!DefDL || DefDL.getLine() == 0) && UserDL && UserDL.getLine() != 0) {
197 MI->setDebugLoc(UserDL);
198 }
199 }
200 }
202}
203
205
207 return false;
208
209
210 if (DoNotRunPass(MF))
211 return false;
212
214
215 init(MF);
216
217
218
219 LocalizedSetVecT LocalizedInstrs;
220
221 bool Changed = localizeInterBlock(MF, LocalizedInstrs);
222 Changed |= localizeIntraBlock(LocalizedInstrs);
224}
unsigned const MachineRegisterInfo * MRI
MachineInstrBuilder & UseMI
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
This file defines the DenseMap class.
Declares convenience wrapper classes for interpreting MachineInstr instances as specific generic oper...
iv Induction Variable Users
Promote Memory to Register
uint64_t IntrinsicInst * II
#define INITIALIZE_PASS_DEPENDENCY(depName)
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
#define INITIALIZE_PASS_BEGIN(passName, arg, name, cfg, analysis)
dot regions Print regions of function to dot true view regions View regions of function(with no function bodies)"
This file describes how to lower LLVM code to machine code.
This pass exposes codegen information to IR-level passes.
Represent the analysis usage information of a pass.
AnalysisUsage & addRequired()
iterator find(const_arg_type_t< KeyT > Val)
std::pair< iterator, bool > try_emplace(KeyT &&Key, Ts &&...Args)
This pass implements the localization mechanism described at the top of this file.
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - This function should be overriden by passes that need analysis information to do t...
Definition Localizer.cpp:47
Localizer()
Definition Localizer.cpp:39
bool runOnMachineFunction(MachineFunction &MF) override
runOnMachineFunction - This method must be overloaded to perform the desired machine code transformat...
Definition Localizer.cpp:204
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.
MachineInstrBundleIterator< MachineInstr > iterator
MachineFunctionPass(char &ID)
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.
AnalysisType & getAnalysis() const
getAnalysis() - This function is used by subclasses to get to the analysis information ...
Wrapper class representing virtual and physical registers.
virtual const TargetLowering * getTargetLowering() const
Wrapper pass for TargetTransformInfo.
This is an optimization pass for GlobalISel generic memory operations.
decltype(auto) dyn_cast(const From &Val)
dyn_cast - Return the argument parameter cast to the specified type.
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...
auto reverse(ContainerTy &&C)
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
LLVM_ABI void getSelectionDAGFallbackAnalysisUsage(AnalysisUsage &AU)
Modify analysis usage so it preserves passes required for the SelectionDAG fallback.
DWARFExpression::Operation Op
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.
Implement std::hash so that hash_code can be used in STL containers.