LLVM 24.0.0git
LiveRangeShrink.cpp
Go to the documentation of this file.
1//===- LiveRangeShrink.cpp - Move instructions to shrink live range -------===//
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/// \file
10/// This pass moves instructions close to the definition of its operands to
11/// shrink live range of the def instruction. The code motion is limited within
12/// the basic block. The moved instruction should have 1 def, and more than one
13/// uses, all of which are the only use of the def.
14///
15///===---------------------------------------------------------------------===//
16
17#include "llvm/ADT/DenseMap.h"
18#include "llvm/ADT/Statistic.h"
29#include "llvm/Pass.h"
30#include "llvm/Support/Debug.h"
32#include <iterator>
33#include <utility>
34
35using namespace llvm;
36
37#define DEBUG_TYPE "lrshrink"
38
39STATISTIC(NumInstrsHoistedToShrinkLiveRange,
40 "Number of insructions hoisted to shrink live range.");
41
42namespace {
43
44class LiveRangeShrink : public MachineFunctionPass {
45public:
46 static char ID;
47
48 LiveRangeShrink() : MachineFunctionPass(ID) {}
49
50 void getAnalysisUsage(AnalysisUsage &AU) const override {
51 AU.setPreservesCFG();
53 }
54
55 StringRef getPassName() const override { return "Live Range Shrink"; }
56
57 bool runOnMachineFunction(MachineFunction &MF) override;
58};
59
60} // end anonymous namespace
61
62char LiveRangeShrink::ID = 0;
63
64char &llvm::LiveRangeShrinkID = LiveRangeShrink::ID;
65
66INITIALIZE_PASS(LiveRangeShrink, "lrshrink", "Live Range Shrink Pass", false,
67 false)
68
69using InstOrderMap = DenseMap<MachineInstr *, unsigned>;
70
71/// Returns \p New if it's dominated by \p Old, otherwise return \p Old.
72/// \p M maintains a map from instruction to its dominating order that satisfies
73/// M[A] > M[B] guarantees that A is dominated by B.
74/// If \p New is not in \p M, return \p Old. Otherwise if \p Old is null, return
75/// \p New.
77 MachineInstr *Old,
78 const InstOrderMap &M) {
79 auto NewIter = M.find(&New);
80 if (NewIter == M.end())
81 return Old;
82 if (Old == nullptr)
83 return &New;
84 unsigned OrderOld = M.find(Old)->second;
85 unsigned OrderNew = NewIter->second;
86 if (OrderOld != OrderNew)
87 return OrderOld < OrderNew ? &New : Old;
88 // OrderOld == OrderNew, we need to iterate down from Old to see if it
89 // can reach New, if yes, New is dominated by Old.
90 for (MachineInstr *I = Old->getNextNode(); M.find(I)->second == OrderNew;
91 I = I->getNextNode())
92 if (I == &New)
93 return &New;
94 return Old;
95}
96
97/// Returns whether this instruction is considered a code motion barrier by this
98/// pass. We can be less conservative than hasUnmodeledSideEffects() when
99/// deciding whether an instruction is a barrier because it is known that pseudo
100/// probes are safe to move in this pass specifically (see commit 1cb47a063e2b).
102 return MI.hasUnmodeledSideEffects() && !MI.isPseudoProbe();
103}
104
105/// Builds Instruction to its dominating order number map \p M by traversing
106/// from instruction \p Start.
108 InstOrderMap &M) {
109 M.clear();
110 unsigned i = 0;
111 for (MachineInstr &I : make_range(Start, Start->getParent()->end())) {
113 break;
114 M[&I] = i++;
115 }
116}
117
118bool LiveRangeShrink::runOnMachineFunction(MachineFunction &MF) {
119 if (skipFunction(MF.getFunction()))
120 return false;
121
122 MachineRegisterInfo &MRI = MF.getRegInfo();
123 const TargetInstrInfo &TII = *MF.getSubtarget().getInstrInfo();
124
125 LLVM_DEBUG(dbgs() << "**** Analysing " << MF.getName() << '\n');
126
127 InstOrderMap IOM;
128 // Map from register to instruction order (value of IOM) where the
129 // register is used last. When moving instructions up, we need to
130 // make sure all its defs (including dead def) will not cross its
131 // last use when moving up.
132 DenseMap<Register, std::pair<unsigned, MachineInstr *>> UseMap;
133
134 for (MachineBasicBlock &MBB : MF) {
135 if (MBB.empty())
136 continue;
137
139 if (MBB.isEHPad()) {
140 // Do not track PHIs in IOM when handling EHPads.
141 // Otherwise their uses may be hoisted outside a landingpad range.
143 if (Next == MBB.end())
144 continue;
145 }
146
149 UseMap.clear();
150 bool SawStore = false;
151
152 while (Next != MBB.end()) {
153 MachineInstr &MI = *Next;
155
156 unsigned CurrentOrder = IOM[&MI];
157 unsigned Barrier = 0;
158 MachineInstr *BarrierMI = nullptr;
159 for (const MachineOperand &MO : MI.operands()) {
160 if (!MO.isReg() || MO.isDebug())
161 continue;
162 if (MO.isUse())
163 UseMap[MO.getReg()] = std::make_pair(CurrentOrder, &MI);
164 else if (MO.isDead()) {
165 // Barrier is the last instruction where MO get used. MI should not
166 // be moved above Barrier.
167 auto It = UseMap.find(MO.getReg());
168 if (It != UseMap.end() && Barrier < It->second.first)
169 std::tie(Barrier, BarrierMI) = It->second;
170 }
171 }
172
173 if (!MI.isSafeToMove(SawStore)) {
174 // If MI has side effects, it should become a barrier for code motion.
175 // IOM is rebuild from the next instruction to prevent later
176 // instructions from being moved before this MI.
177 if (isCodeMotionBarrier(MI) && Next != MBB.end()) {
179 SawStore = false;
180 }
181 continue;
182 }
183
184 const MachineOperand *DefMO = nullptr;
185 MachineInstr *Insert = nullptr;
186
187 // Number of live-ranges that will be shortened. We do not count
188 // live-ranges that are defined by a COPY as it could be coalesced later.
189 unsigned NumEligibleUse = 0;
190
191 for (const MachineOperand &MO : MI.operands()) {
192 if (!MO.isReg() || MO.isDead() || MO.isDebug())
193 continue;
194 Register Reg = MO.getReg();
195 // Do not move the instruction if it def/uses a physical register,
196 // unless it is a constant physical register or a noreg.
197 if (!Reg.isVirtual()) {
198 if (!Reg || MRI.isConstantPhysReg(Reg))
199 continue;
200 Insert = nullptr;
201 break;
202 }
203 if (MO.isDef()) {
204 // Do not move if there is more than one def.
205 if (DefMO) {
206 Insert = nullptr;
207 break;
208 }
209 DefMO = &MO;
210 } else if (MRI.hasOneNonDBGUse(Reg) && MRI.hasOneDef(Reg) && DefMO &&
211 MRI.getRegClass(DefMO->getReg()) ==
212 MRI.getRegClass(MO.getReg())) {
213 // The heuristic does not handle different register classes yet
214 // (registers of different sizes, looser/tighter constraints). This
215 // is because it needs more accurate model to handle register
216 // pressure correctly.
217 MachineInstr &DefInstr = *MRI.def_instr_begin(Reg);
218 if (!TII.isCopyInstr(DefInstr))
219 NumEligibleUse++;
220 Insert = FindDominatedInstruction(DefInstr, Insert, IOM);
221 } else {
222 Insert = nullptr;
223 break;
224 }
225 }
226
227 // If Barrier equals IOM[I], traverse forward to find if BarrierMI is
228 // after Insert, if yes, then we should not hoist.
229 for (MachineInstr *I = Insert; I && IOM[I] == Barrier;
230 I = I->getNextNode())
231 if (I == BarrierMI) {
232 Insert = nullptr;
233 break;
234 }
235 // Move the instruction when # of shrunk live range > 1.
236 if (DefMO && Insert && NumEligibleUse > 1 && Barrier <= IOM[Insert]) {
237 MachineBasicBlock::iterator I = std::next(Insert->getIterator());
238 // Skip all the PHI and debug instructions.
239 while (I != MBB.end() && (I->isPHI() || I->isDebugOrPseudoInstr()))
240 I = std::next(I);
241 if (I == MI.getIterator())
242 continue;
243
244 // Update the dominator order to be the same as the insertion point.
245 // We do this to maintain a non-decreasing order without need to update
246 // all instruction orders after the insertion point.
247 unsigned NewOrder = IOM[&*I];
248 IOM[&MI] = NewOrder;
249 NumInstrsHoistedToShrinkLiveRange++;
250
251 // Find MI's debug value following MI.
252 MachineBasicBlock::iterator EndIter = std::next(MI.getIterator());
253 if (MI.getOperand(0).isReg())
254 for (; EndIter != MBB.end() && EndIter->isDebugValue() &&
255 EndIter->hasDebugOperandForReg(MI.getOperand(0).getReg());
256 ++EndIter)
257 IOM[&*EndIter] = NewOrder;
258 MBB.splice(I, &MBB, MI.getIterator(), EndIter);
259 }
260 }
261 }
262 return false;
263}
aarch64 promote const
MachineBasicBlock & MBB
This file defines the DenseMap class.
const HexagonInstrInfo * TII
IRTranslator LLVM IR MI
static bool isCodeMotionBarrier(MachineInstr &MI)
Returns whether this instruction is considered a code motion barrier by this pass.
static MachineInstr * FindDominatedInstruction(MachineInstr &New, MachineInstr *Old, const InstOrderMap &M)
Returns New if it's dominated by Old, otherwise return Old.
static void BuildInstOrderMap(MachineBasicBlock::iterator Start, InstOrderMap &M)
Builds Instruction to its dominating order number map M by traversing from instruction Start.
#define I(x, y, z)
Definition MD5.cpp:57
Register Reg
Promote Memory to Register
Definition Mem2Reg.cpp:110
if(PassOpts->AAPipeline)
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
Definition PassSupport.h:56
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
Definition Statistic.h:171
#define LLVM_DEBUG(...)
Definition Debug.h:119
LLVM_ABI void setPreservesCFG()
This function should be called by the pass, iff they do not:
Definition Pass.cpp:275
iterator find(const_arg_type_t< KeyT > Val)
Definition DenseMap.h:223
iterator end()
Definition DenseMap.h:141
bool isEHPad() const
Returns true if the block is a landing pad.
LLVM_ABI iterator SkipPHIsLabelsAndDebug(iterator I, Register Reg=Register(), bool SkipPseudoOp=true)
Return the first instruction in MBB after I that is not a PHI, label or debug.
void splice(iterator Where, MachineBasicBlock *Other, iterator From)
Take an instruction from MBB 'Other' at the position From, and insert it into this MBB right before '...
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.
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.
Representation of each machine instruction.
Register getReg() const
getReg - Returns the register number.
LLVM_ABI bool hasOneNonDBGUse(Register RegNo) const
hasOneNonDBGUse - Return true if there is exactly one non-Debug use of the specified register.
const TargetRegisterClass * getRegClass(Register Reg) const
Return the register class of the specified virtual register.
def_instr_iterator def_instr_begin(Register RegNo) const
bool hasOneDef(Register RegNo) const
Return true if there is exactly one operand defining the specified register.
LLVM_ABI bool isConstantPhysReg(MCRegister PhysReg) const
Returns true if PhysReg is unallocatable and constant throughout the function.
constexpr bool isVirtual() const
Return true if the specified register number is in the virtual register namespace.
Definition Register.h:79
virtual const TargetInstrInfo * getInstrInfo() const
This provides a very simple, boring adaptor for a begin and end iterator into a range type.
This is an optimization pass for GlobalISel generic memory operations.
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
LLVM_ABI char & LiveRangeShrinkID
LiveRangeShrink pass.
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition Debug.cpp:209
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Next
Definition InstrProf.h:147