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