1 //===-- FixupStatepointCallerSaved.cpp - Fixup caller saved registers  ----===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 ///
10 /// \file
11 /// Statepoint instruction in deopt parameters contains values which are
12 /// meaningful to the runtime and should be able to be read at the moment the
13 /// call returns. So we can say that we need to encode the fact that these
14 /// values are "late read" by runtime. If we could express this notion for
15 /// register allocator it would produce the right form for us.
16 /// The need to fixup (i.e this pass) is specifically handling the fact that
17 /// we cannot describe such a late read for the register allocator.
18 /// Register allocator may put the value on a register clobbered by the call.
19 /// This pass forces the spill of such registers and replaces corresponding
20 /// statepoint operands to added spill slots.
21 ///
22 //===----------------------------------------------------------------------===//
23 
24 #include "llvm/ADT/SmallSet.h"
25 #include "llvm/ADT/Statistic.h"
26 #include "llvm/CodeGen/MachineFrameInfo.h"
27 #include "llvm/CodeGen/MachineFunctionPass.h"
28 #include "llvm/CodeGen/MachineRegisterInfo.h"
29 #include "llvm/CodeGen/Passes.h"
30 #include "llvm/CodeGen/StackMaps.h"
31 #include "llvm/CodeGen/TargetFrameLowering.h"
32 #include "llvm/CodeGen/TargetInstrInfo.h"
33 #include "llvm/IR/Statepoint.h"
34 #include "llvm/InitializePasses.h"
35 #include "llvm/Support/Debug.h"
36 
37 using namespace llvm;
38 
39 #define DEBUG_TYPE "fixup-statepoint-caller-saved"
40 STATISTIC(NumSpilledRegisters, "Number of spilled register");
41 STATISTIC(NumSpillSlotsAllocated, "Number of spill slots allocated");
42 STATISTIC(NumSpillSlotsExtended, "Number of spill slots extended");
43 
44 static cl::opt<bool> FixupSCSExtendSlotSize(
45     "fixup-scs-extend-slot-size", cl::Hidden, cl::init(false),
46     cl::desc("Allow spill in spill slot of greater size than register size"),
47     cl::Hidden);
48 
49 namespace {
50 
51 class FixupStatepointCallerSaved : public MachineFunctionPass {
52 public:
53   static char ID;
54 
55   FixupStatepointCallerSaved() : MachineFunctionPass(ID) {
56     initializeFixupStatepointCallerSavedPass(*PassRegistry::getPassRegistry());
57   }
58 
59   void getAnalysisUsage(AnalysisUsage &AU) const override {
60     MachineFunctionPass::getAnalysisUsage(AU);
61   }
62 
63   StringRef getPassName() const override {
64     return "Fixup Statepoint Caller Saved";
65   }
66 
67   bool runOnMachineFunction(MachineFunction &MF) override;
68 };
69 } // End anonymous namespace.
70 
71 char FixupStatepointCallerSaved::ID = 0;
72 char &llvm::FixupStatepointCallerSavedID = FixupStatepointCallerSaved::ID;
73 
74 INITIALIZE_PASS_BEGIN(FixupStatepointCallerSaved, DEBUG_TYPE,
75                       "Fixup Statepoint Caller Saved", false, false)
76 INITIALIZE_PASS_END(FixupStatepointCallerSaved, DEBUG_TYPE,
77                     "Fixup Statepoint Caller Saved", false, false)
78 
79 // Utility function to get size of the register.
80 static unsigned getRegisterSize(const TargetRegisterInfo &TRI, Register Reg) {
81   const TargetRegisterClass *RC = TRI.getMinimalPhysRegClass(Reg);
82   return TRI.getSpillSize(*RC);
83 }
84 
85 namespace {
86 // Cache used frame indexes during statepoint re-write to re-use them in
87 // processing next statepoint instruction.
88 // Two strategies. One is to preserve the size of spill slot while another one
89 // extends the size of spill slots to reduce the number of them, causing
90 // the less total frame size. But unspill will have "implicit" any extend.
91 class FrameIndexesCache {
92 private:
93   struct FrameIndexesPerSize {
94     // List of used frame indexes during processing previous statepoints.
95     SmallVector<int, 8> Slots;
96     // Current index of un-used yet frame index.
97     unsigned Index = 0;
98   };
99   MachineFrameInfo &MFI;
100   const TargetRegisterInfo &TRI;
101   // Map size to list of frame indexes of this size. If the mode is
102   // FixupSCSExtendSlotSize then the key 0 is used to keep all frame indexes.
103   // If the size of required spill slot is greater than in a cache then the
104   // size will be increased.
105   DenseMap<unsigned, FrameIndexesPerSize> Cache;
106 
107 public:
108   FrameIndexesCache(MachineFrameInfo &MFI, const TargetRegisterInfo &TRI)
109       : MFI(MFI), TRI(TRI) {}
110   // Reset the current state of used frame indexes. After invocation of
111   // this function all frame indexes are available for allocation.
112   void reset() {
113     for (auto &It : Cache)
114       It.second.Index = 0;
115   }
116   // Get frame index to spill the register.
117   int getFrameIndex(Register Reg) {
118     unsigned Size = getRegisterSize(TRI, Reg);
119     // In FixupSCSExtendSlotSize mode the bucket with 0 index is used
120     // for all sizes.
121     unsigned Bucket = FixupSCSExtendSlotSize ? 0 : Size;
122     FrameIndexesPerSize &Line = Cache[Bucket];
123     if (Line.Index < Line.Slots.size()) {
124       int FI = Line.Slots[Line.Index++];
125       // If all sizes are kept together we probably need to extend the
126       // spill slot size.
127       if (MFI.getObjectSize(FI) < Size) {
128         MFI.setObjectSize(FI, Size);
129         MFI.setObjectAlignment(FI, Align(Size));
130         NumSpillSlotsExtended++;
131       }
132       return FI;
133     }
134     int FI = MFI.CreateSpillStackObject(Size, Size);
135     NumSpillSlotsAllocated++;
136     Line.Slots.push_back(FI);
137     ++Line.Index;
138     return FI;
139   }
140   // Sort all registers to spill in descendent order. In the
141   // FixupSCSExtendSlotSize mode it will minimize the total frame size.
142   // In non FixupSCSExtendSlotSize mode we can skip this step.
143   void sortRegisters(SmallVectorImpl<Register> &Regs) {
144     if (!FixupSCSExtendSlotSize)
145       return;
146     llvm::sort(Regs.begin(), Regs.end(), [&](Register &A, Register &B) {
147       return getRegisterSize(TRI, A) > getRegisterSize(TRI, B);
148     });
149   }
150 };
151 
152 // Describes the state of the current processing statepoint instruction.
153 class StatepointState {
154 private:
155   // statepoint instruction.
156   MachineInstr &MI;
157   MachineFunction &MF;
158   const TargetRegisterInfo &TRI;
159   const TargetInstrInfo &TII;
160   MachineFrameInfo &MFI;
161   // Mask with callee saved registers.
162   const uint32_t *Mask;
163   // Cache of frame indexes used on previous instruction processing.
164   FrameIndexesCache &CacheFI;
165   // Operands with physical registers requiring spilling.
166   SmallVector<unsigned, 8> OpsToSpill;
167   // Set of register to spill.
168   SmallVector<Register, 8> RegsToSpill;
169   // Map Register to Frame Slot index.
170   DenseMap<Register, int> RegToSlotIdx;
171 
172 public:
173   StatepointState(MachineInstr &MI, const uint32_t *Mask,
174                   FrameIndexesCache &CacheFI)
175       : MI(MI), MF(*MI.getMF()), TRI(*MF.getSubtarget().getRegisterInfo()),
176         TII(*MF.getSubtarget().getInstrInfo()), MFI(MF.getFrameInfo()),
177         Mask(Mask), CacheFI(CacheFI) {}
178   // Return true if register is callee saved.
179   bool isCalleeSaved(Register Reg) { return (Mask[Reg / 32] >> Reg % 32) & 1; }
180   // Iterates over statepoint meta args to find caller saver registers.
181   // Also cache the size of found registers.
182   // Returns true if caller save registers found.
183   bool findRegistersToSpill() {
184     SmallSet<Register, 8> VisitedRegs;
185     for (unsigned Idx = StatepointOpers(&MI).getVarIdx(),
186                   EndIdx = MI.getNumOperands();
187          Idx < EndIdx; ++Idx) {
188       MachineOperand &MO = MI.getOperand(Idx);
189       if (!MO.isReg() || MO.isImplicit())
190         continue;
191       Register Reg = MO.getReg();
192       assert(Reg.isPhysical() && "Only physical regs are expected");
193       if (isCalleeSaved(Reg))
194         continue;
195       if (VisitedRegs.insert(Reg).second)
196         RegsToSpill.push_back(Reg);
197       OpsToSpill.push_back(Idx);
198     }
199     CacheFI.sortRegisters(RegsToSpill);
200     return !RegsToSpill.empty();
201   }
202   // Spill all caller saved registers right before statepoint instruction.
203   // Remember frame index where register is spilled.
204   void spillRegisters() {
205     for (Register Reg : RegsToSpill) {
206       int FI = CacheFI.getFrameIndex(Reg);
207       const TargetRegisterClass *RC = TRI.getMinimalPhysRegClass(Reg);
208       TII.storeRegToStackSlot(*MI.getParent(), MI, Reg, true /*is_Kill*/, FI,
209                               RC, &TRI);
210       NumSpilledRegisters++;
211       RegToSlotIdx[Reg] = FI;
212     }
213   }
214   // Re-write statepoint machine instruction to replace caller saved operands
215   // with indirect memory location (frame index).
216   void rewriteStatepoint() {
217     MachineInstr *NewMI =
218         MF.CreateMachineInstr(TII.get(MI.getOpcode()), MI.getDebugLoc(), true);
219     MachineInstrBuilder MIB(MF, NewMI);
220 
221     // Add End marker.
222     OpsToSpill.push_back(MI.getNumOperands());
223     unsigned CurOpIdx = 0;
224 
225     for (unsigned I = 0; I < MI.getNumOperands(); ++I) {
226       MachineOperand &MO = MI.getOperand(I);
227       if (I == OpsToSpill[CurOpIdx]) {
228         int FI = RegToSlotIdx[MO.getReg()];
229         MIB.addImm(StackMaps::IndirectMemRefOp);
230         MIB.addImm(getRegisterSize(TRI, MO.getReg()));
231         assert(MO.isReg() && "Should be register");
232         assert(MO.getReg().isPhysical() && "Should be physical register");
233         MIB.addFrameIndex(FI);
234         MIB.addImm(0);
235         ++CurOpIdx;
236       } else
237         MIB.add(MO);
238     }
239     assert(CurOpIdx == (OpsToSpill.size() - 1) && "Not all operands processed");
240     // Add mem operands.
241     NewMI->setMemRefs(MF, MI.memoperands());
242     for (auto It : RegToSlotIdx) {
243       int FrameIndex = It.second;
244       auto PtrInfo = MachinePointerInfo::getFixedStack(MF, FrameIndex);
245       auto *MMO = MF.getMachineMemOperand(PtrInfo, MachineMemOperand::MOLoad,
246                                           getRegisterSize(TRI, It.first),
247                                           MFI.getObjectAlign(FrameIndex));
248       NewMI->addMemOperand(MF, MMO);
249     }
250     // Insert new statepoint and erase old one.
251     MI.getParent()->insert(MI, NewMI);
252     MI.eraseFromParent();
253   }
254 };
255 
256 class StatepointProcessor {
257 private:
258   MachineFunction &MF;
259   const TargetRegisterInfo &TRI;
260   FrameIndexesCache CacheFI;
261 
262 public:
263   StatepointProcessor(MachineFunction &MF)
264       : MF(MF), TRI(*MF.getSubtarget().getRegisterInfo()),
265         CacheFI(MF.getFrameInfo(), TRI) {}
266 
267   bool process(MachineInstr &MI) {
268     StatepointOpers SO(&MI);
269     uint64_t Flags = SO.getFlags();
270     // Do nothing for LiveIn, it supports all registers.
271     if (Flags & (uint64_t)StatepointFlags::DeoptLiveIn)
272       return false;
273     CallingConv::ID CC = SO.getCallingConv();
274     const uint32_t *Mask = TRI.getCallPreservedMask(MF, CC);
275     CacheFI.reset();
276     StatepointState SS(MI, Mask, CacheFI);
277 
278     if (!SS.findRegistersToSpill())
279       return false;
280 
281     SS.spillRegisters();
282     SS.rewriteStatepoint();
283     return true;
284   }
285 };
286 } // namespace
287 
288 bool FixupStatepointCallerSaved::runOnMachineFunction(MachineFunction &MF) {
289   if (skipFunction(MF.getFunction()))
290     return false;
291 
292   const Function &F = MF.getFunction();
293   if (!F.hasGC())
294     return false;
295 
296   SmallVector<MachineInstr *, 16> Statepoints;
297   for (MachineBasicBlock &BB : MF)
298     for (MachineInstr &I : BB)
299       if (I.getOpcode() == TargetOpcode::STATEPOINT)
300         Statepoints.push_back(&I);
301 
302   if (Statepoints.empty())
303     return false;
304 
305   bool Changed = false;
306   StatepointProcessor SPP(MF);
307   for (MachineInstr *I : Statepoints)
308     Changed |= SPP.process(*I);
309   return Changed;
310 }
311