LLVM 23.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"
28#include "llvm/Pass.h"
29#include "llvm/Support/Debug.h"
31#include <iterator>
32#include <utility>
33
34using namespace llvm;
35
36#define DEBUG_TYPE "lrshrink"
37
38STATISTIC(NumInstrsHoistedToShrinkLiveRange,
39 "Number of insructions hoisted to shrink live range.");
40
41namespace {
42
43class LiveRangeShrink : public MachineFunctionPass {
44public:
45 static char ID;
46
47 LiveRangeShrink() : MachineFunctionPass(ID) {}
48
49 void getAnalysisUsage(AnalysisUsage &AU) const override {
50 AU.setPreservesCFG();
52 }
53
54 StringRef getPassName() const override { return "Live Range Shrink"; }
55
56 bool runOnMachineFunction(MachineFunction &MF) override;
57};
58
59} // end anonymous namespace
60
61char LiveRangeShrink::ID = 0;
62
63char &llvm::LiveRangeShrinkID = LiveRangeShrink::ID;
64
65INITIALIZE_PASS(LiveRangeShrink, "lrshrink", "Live Range Shrink Pass", false,
66 false)
67
68using InstOrderMap = DenseMap<MachineInstr *, unsigned>;
69
70/// Returns \p New if it's dominated by \p Old, otherwise return \p Old.
71/// \p M maintains a map from instruction to its dominating order that satisfies
72/// M[A] > M[B] guarantees that A is dominated by B.
73/// If \p New is not in \p M, return \p Old. Otherwise if \p Old is null, return
74/// \p New.
76 MachineInstr *Old,
77 const InstOrderMap &M) {
78 auto NewIter = M.find(&New);
79 if (NewIter == M.end())
80 return Old;
81 if (Old == nullptr)
82 return &New;
83 unsigned OrderOld = M.find(Old)->second;
84 unsigned OrderNew = NewIter->second;
85 if (OrderOld != OrderNew)
86 return OrderOld < OrderNew ? &New : Old;
87 // OrderOld == OrderNew, we need to iterate down from Old to see if it
88 // can reach New, if yes, New is dominated by Old.
89 for (MachineInstr *I = Old->getNextNode(); M.find(I)->second == OrderNew;
90 I = I->getNextNode())
91 if (I == &New)
92 return &New;
93 return Old;
94}
95
96/// Returns whether this instruction is considered a code motion barrier by this
97/// pass. We can be less conservative than hasUnmodeledSideEffects() when
98/// deciding whether an instruction is a barrier because it is known that pseudo
99/// probes are safe to move in this pass specifically (see commit 1cb47a063e2b).
101 return MI.hasUnmodeledSideEffects() && !MI.isPseudoProbe();
102}
103
104/// Builds Instruction to its dominating order number map \p M by traversing
105/// from instruction \p Start.
107 InstOrderMap &M) {
108 M.clear();
109 unsigned i = 0;
110 for (MachineInstr &I : make_range(Start, Start->getParent()->end())) {
112 break;
113 M[&I] = i++;
114 }
115}
116
117bool LiveRangeShrink::runOnMachineFunction(MachineFunction &MF) {
118 if (skipFunction(MF.getFunction()))
119 return false;
120
121 MachineRegisterInfo &MRI = MF.getRegInfo();
122 const TargetInstrInfo &TII = *MF.getSubtarget().getInstrInfo();
123
124 LLVM_DEBUG(dbgs() << "**** Analysing " << MF.getName() << '\n');
125
126 InstOrderMap IOM;
127 // Map from register to instruction order (value of IOM) where the
128 // register is used last. When moving instructions up, we need to
129 // make sure all its defs (including dead def) will not cross its
130 // last use when moving up.
131 DenseMap<Register, std::pair<unsigned, MachineInstr *>> UseMap;
132
133 for (MachineBasicBlock &MBB : MF) {
134 if (MBB.empty())
135 continue;
136
138 if (MBB.isEHPad()) {
139 // Do not track PHIs in IOM when handling EHPads.
140 // Otherwise their uses may be hoisted outside a landingpad range.
142 if (Next == MBB.end())
143 continue;
144 }
145
148 UseMap.clear();
149 bool SawStore = false;
150
151 while (Next != MBB.end()) {
152 MachineInstr &MI = *Next;
154
155 unsigned CurrentOrder = IOM[&MI];
156 unsigned Barrier = 0;
157 MachineInstr *BarrierMI = nullptr;
158 for (const MachineOperand &MO : MI.operands()) {
159 if (!MO.isReg() || MO.isDebug())
160 continue;
161 if (MO.isUse())
162 UseMap[MO.getReg()] = std::make_pair(CurrentOrder, &MI);
163 else if (MO.isDead()) {
164 // Barrier is the last instruction where MO get used. MI should not
165 // be moved above Barrier.
166 auto It = UseMap.find(MO.getReg());
167 if (It != UseMap.end() && Barrier < It->second.first)
168 std::tie(Barrier, BarrierMI) = It->second;
169 }
170 }
171
172 if (!MI.isSafeToMove(SawStore)) {
173 // If MI has side effects, it should become a barrier for code motion.
174 // IOM is rebuild from the next instruction to prevent later
175 // instructions from being moved before this MI.
176 if (isCodeMotionBarrier(MI) && Next != MBB.end()) {
178 SawStore = false;
179 }
180 continue;
181 }
182
183 const MachineOperand *DefMO = nullptr;
184 MachineInstr *Insert = nullptr;
185
186 // Number of live-ranges that will be shortened. We do not count
187 // live-ranges that are defined by a COPY as it could be coalesced later.
188 unsigned NumEligibleUse = 0;
189
190 for (const MachineOperand &MO : MI.operands()) {
191 if (!MO.isReg() || MO.isDead() || MO.isDebug())
192 continue;
193 Register Reg = MO.getReg();
194 // Do not move the instruction if it def/uses a physical register,
195 // unless it is a constant physical register or a noreg.
196 if (!Reg.isVirtual()) {
197 if (!Reg || MRI.isConstantPhysReg(Reg))
198 continue;
199 Insert = nullptr;
200 break;
201 }
202 if (MO.isDef()) {
203 // Do not move if there is more than one def.
204 if (DefMO) {
205 Insert = nullptr;
206 break;
207 }
208 DefMO = &MO;
209 } else if (MRI.hasOneNonDBGUse(Reg) && MRI.hasOneDef(Reg) && DefMO &&
210 MRI.getRegClass(DefMO->getReg()) ==
211 MRI.getRegClass(MO.getReg())) {
212 // The heuristic does not handle different register classes yet
213 // (registers of different sizes, looser/tighter constraints). This
214 // is because it needs more accurate model to handle register
215 // pressure correctly.
216 MachineInstr &DefInstr = *MRI.def_instr_begin(Reg);
217 if (!TII.isCopyInstr(DefInstr))
218 NumEligibleUse++;
219 Insert = FindDominatedInstruction(DefInstr, Insert, IOM);
220 } else {
221 Insert = nullptr;
222 break;
223 }
224 }
225
226 // If Barrier equals IOM[I], traverse forward to find if BarrierMI is
227 // after Insert, if yes, then we should not hoist.
228 for (MachineInstr *I = Insert; I && IOM[I] == Barrier;
229 I = I->getNextNode())
230 if (I == BarrierMI) {
231 Insert = nullptr;
232 break;
233 }
234 // Move the instruction when # of shrunk live range > 1.
235 if (DefMO && Insert && NumEligibleUse > 1 && Barrier <= IOM[Insert]) {
236 MachineBasicBlock::iterator I = std::next(Insert->getIterator());
237 // Skip all the PHI and debug instructions.
238 while (I != MBB.end() && (I->isPHI() || I->isDebugOrPseudoInstr()))
239 I = std::next(I);
240 if (I == MI.getIterator())
241 continue;
242
243 // Update the dominator order to be the same as the insertion point.
244 // We do this to maintain a non-decreasing order without need to update
245 // all instruction orders after the insertion point.
246 unsigned NewOrder = IOM[&*I];
247 IOM[&MI] = NewOrder;
248 NumInstrsHoistedToShrinkLiveRange++;
249
250 // Find MI's debug value following MI.
251 MachineBasicBlock::iterator EndIter = std::next(MI.getIterator());
252 if (MI.getOperand(0).isReg())
253 for (; EndIter != MBB.end() && EndIter->isDebugValue() &&
254 EndIter->hasDebugOperandForReg(MI.getOperand(0).getReg());
255 ++EndIter)
256 IOM[&*EndIter] = NewOrder;
257 MBB.splice(I, &MBB, MI.getIterator(), EndIter);
258 }
259 }
260 }
261 return false;
262}
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:114
LLVM_ABI void setPreservesCFG()
This function should be called by the pass, iff they do not:
Definition Pass.cpp:270
iterator find(const_arg_type_t< KeyT > Val)
Definition DenseMap.h:178
iterator end()
Definition DenseMap.h:81
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.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
Definition CallingConv.h:24
This is an optimization pass for GlobalISel generic memory operations.
Definition Types.h:26
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:207
FunctionAddr VTableAddr Next
Definition InstrProf.h:141