1 //===-- FixupStatepointCallerSaved.cpp - Fixup caller saved registers ----===//
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
7 //===----------------------------------------------------------------------===//
10 /// Statepoint instruction in deopt parameters contains values which are
11 /// meaningful to the runtime and should be able to be read at the moment the
12 /// call returns. So we can say that we need to encode the fact that these
13 /// values are "late read" by runtime. If we could express this notion for
14 /// register allocator it would produce the right form for us.
15 /// The need to fixup (i.e this pass) is specifically handling the fact that
16 /// we cannot describe such a late read for the register allocator.
17 /// Register allocator may put the value on a register clobbered by the call.
18 /// This pass forces the spill of such registers and replaces corresponding
19 /// statepoint operands to added spill slots.
21 //===----------------------------------------------------------------------===//
23 #include "llvm/ADT/SmallSet.h"
24 #include "llvm/ADT/Statistic.h"
25 #include "llvm/CodeGen/MachineFrameInfo.h"
26 #include "llvm/CodeGen/MachineFunctionPass.h"
27 #include "llvm/CodeGen/MachineRegisterInfo.h"
28 #include "llvm/CodeGen/Passes.h"
29 #include "llvm/CodeGen/StackMaps.h"
30 #include "llvm/CodeGen/TargetFrameLowering.h"
31 #include "llvm/CodeGen/TargetInstrInfo.h"
32 #include "llvm/IR/Statepoint.h"
33 #include "llvm/InitializePasses.h"
34 #include "llvm/Support/Debug.h"
38 #define DEBUG_TYPE "fixup-statepoint-caller-saved"
39 STATISTIC(NumSpilledRegisters
, "Number of spilled register");
40 STATISTIC(NumSpillSlotsAllocated
, "Number of spill slots allocated");
41 STATISTIC(NumSpillSlotsExtended
, "Number of spill slots extended");
43 static cl::opt
<bool> FixupSCSExtendSlotSize(
44 "fixup-scs-extend-slot-size", cl::Hidden
, cl::init(false),
45 cl::desc("Allow spill in spill slot of greater size than register size"),
48 static cl::opt
<bool> PassGCPtrInCSR(
49 "fixup-allow-gcptr-in-csr", cl::Hidden
, cl::init(false),
50 cl::desc("Allow passing GC Pointer arguments in callee saved registers"));
52 static cl::opt
<bool> EnableCopyProp(
53 "fixup-scs-enable-copy-propagation", cl::Hidden
, cl::init(true),
54 cl::desc("Enable simple copy propagation during register reloading"));
56 // This is purely debugging option.
57 // It may be handy for investigating statepoint spilling issues.
58 static cl::opt
<unsigned> MaxStatepointsWithRegs(
59 "fixup-max-csr-statepoints", cl::Hidden
,
60 cl::desc("Max number of statepoints allowed to pass GC Ptrs in registers"));
64 class FixupStatepointCallerSaved
: public MachineFunctionPass
{
68 FixupStatepointCallerSaved() : MachineFunctionPass(ID
) {
69 initializeFixupStatepointCallerSavedPass(*PassRegistry::getPassRegistry());
72 void getAnalysisUsage(AnalysisUsage
&AU
) const override
{
74 MachineFunctionPass::getAnalysisUsage(AU
);
77 StringRef
getPassName() const override
{
78 return "Fixup Statepoint Caller Saved";
81 bool runOnMachineFunction(MachineFunction
&MF
) override
;
84 } // End anonymous namespace.
86 char FixupStatepointCallerSaved::ID
= 0;
87 char &llvm::FixupStatepointCallerSavedID
= FixupStatepointCallerSaved::ID
;
89 INITIALIZE_PASS_BEGIN(FixupStatepointCallerSaved
, DEBUG_TYPE
,
90 "Fixup Statepoint Caller Saved", false, false)
91 INITIALIZE_PASS_END(FixupStatepointCallerSaved
, DEBUG_TYPE
,
92 "Fixup Statepoint Caller Saved", false, false)
94 // Utility function to get size of the register.
95 static unsigned getRegisterSize(const TargetRegisterInfo
&TRI
, Register Reg
) {
96 const TargetRegisterClass
*RC
= TRI
.getMinimalPhysRegClass(Reg
);
97 return TRI
.getSpillSize(*RC
);
100 // Try to eliminate redundant copy to register which we're going to
101 // spill, i.e. try to change:
106 // If there are no uses of X between copy and STATEPOINT, that COPY
107 // may be eliminated.
108 // Reg - register we're about to spill
109 // RI - On entry points to statepoint.
110 // On successful copy propagation set to new spill point.
111 // IsKill - set to true if COPY is Kill (there are no uses of Y)
112 // Returns either found source copy register or original one.
113 static Register
performCopyPropagation(Register Reg
,
114 MachineBasicBlock::iterator
&RI
,
115 bool &IsKill
, const TargetInstrInfo
&TII
,
116 const TargetRegisterInfo
&TRI
) {
117 // First check if statepoint itself uses Reg in non-meta operands.
118 int Idx
= RI
->findRegisterUseOperandIdx(Reg
, false, &TRI
);
119 if (Idx
>= 0 && (unsigned)Idx
< StatepointOpers(&*RI
).getNumDeoptArgsIdx()) {
127 MachineBasicBlock
*MBB
= RI
->getParent();
128 MachineBasicBlock::reverse_iterator E
= MBB
->rend();
129 MachineInstr
*Def
= nullptr, *Use
= nullptr;
130 for (auto It
= ++(RI
.getReverse()); It
!= E
; ++It
) {
131 if (It
->readsRegister(Reg
, &TRI
) && !Use
)
133 if (It
->modifiesRegister(Reg
, &TRI
)) {
142 auto DestSrc
= TII
.isCopyInstr(*Def
);
143 if (!DestSrc
|| DestSrc
->Destination
->getReg() != Reg
)
146 Register SrcReg
= DestSrc
->Source
->getReg();
148 if (getRegisterSize(TRI
, Reg
) != getRegisterSize(TRI
, SrcReg
))
151 LLVM_DEBUG(dbgs() << "spillRegisters: perform copy propagation "
152 << printReg(Reg
, &TRI
) << " -> " << printReg(SrcReg
, &TRI
)
155 // Insert spill immediately after Def
156 RI
= ++MachineBasicBlock::iterator(Def
);
157 IsKill
= DestSrc
->Source
->isKill();
159 // There are no uses of original register between COPY and STATEPOINT.
160 // There can't be any after STATEPOINT, so we can eliminate Def.
162 LLVM_DEBUG(dbgs() << "spillRegisters: removing dead copy " << *Def
);
163 Def
->eraseFromParent();
169 // Pair {Register, FrameIndex}
170 using RegSlotPair
= std::pair
<Register
, int>;
172 // Keeps track of what reloads were inserted in MBB.
173 class RegReloadCache
{
174 using ReloadSet
= SmallSet
<RegSlotPair
, 8>;
175 DenseMap
<const MachineBasicBlock
*, ReloadSet
> Reloads
;
178 RegReloadCache() = default;
180 // Record reload of Reg from FI in block MBB
181 void recordReload(Register Reg
, int FI
, const MachineBasicBlock
*MBB
) {
182 RegSlotPair
RSP(Reg
, FI
);
183 auto Res
= Reloads
[MBB
].insert(RSP
);
185 assert(Res
.second
&& "reload already exists");
188 // Does basic block MBB contains reload of Reg from FI?
189 bool hasReload(Register Reg
, int FI
, const MachineBasicBlock
*MBB
) {
190 RegSlotPair
RSP(Reg
, FI
);
191 return Reloads
.count(MBB
) && Reloads
[MBB
].count(RSP
);
195 // Cache used frame indexes during statepoint re-write to re-use them in
196 // processing next statepoint instruction.
197 // Two strategies. One is to preserve the size of spill slot while another one
198 // extends the size of spill slots to reduce the number of them, causing
199 // the less total frame size. But unspill will have "implicit" any extend.
200 class FrameIndexesCache
{
202 struct FrameIndexesPerSize
{
203 // List of used frame indexes during processing previous statepoints.
204 SmallVector
<int, 8> Slots
;
205 // Current index of un-used yet frame index.
208 MachineFrameInfo
&MFI
;
209 const TargetRegisterInfo
&TRI
;
210 // Map size to list of frame indexes of this size. If the mode is
211 // FixupSCSExtendSlotSize then the key 0 is used to keep all frame indexes.
212 // If the size of required spill slot is greater than in a cache then the
213 // size will be increased.
214 DenseMap
<unsigned, FrameIndexesPerSize
> Cache
;
216 // Keeps track of slots reserved for the shared landing pad processing.
217 // Initialized from GlobalIndices for the current EHPad.
218 SmallSet
<int, 8> ReservedSlots
;
220 // Landing pad can be destination of several statepoints. Every register
221 // defined by such statepoints must be spilled to the same stack slot.
222 // This map keeps that information.
223 DenseMap
<const MachineBasicBlock
*, SmallVector
<RegSlotPair
, 8>>
226 FrameIndexesPerSize
&getCacheBucket(unsigned Size
) {
227 // In FixupSCSExtendSlotSize mode the bucket with 0 index is used
229 return Cache
[FixupSCSExtendSlotSize
? 0 : Size
];
233 FrameIndexesCache(MachineFrameInfo
&MFI
, const TargetRegisterInfo
&TRI
)
234 : MFI(MFI
), TRI(TRI
) {}
235 // Reset the current state of used frame indexes. After invocation of
236 // this function all frame indexes are available for allocation with
237 // the exception of slots reserved for landing pad processing (if any).
238 void reset(const MachineBasicBlock
*EHPad
) {
239 for (auto &It
: Cache
)
242 ReservedSlots
.clear();
243 if (EHPad
&& GlobalIndices
.count(EHPad
))
244 for (auto &RSP
: GlobalIndices
[EHPad
])
245 ReservedSlots
.insert(RSP
.second
);
248 // Get frame index to spill the register.
249 int getFrameIndex(Register Reg
, MachineBasicBlock
*EHPad
) {
250 // Check if slot for Reg is already reserved at EHPad.
251 auto It
= GlobalIndices
.find(EHPad
);
252 if (It
!= GlobalIndices
.end()) {
253 auto &Vec
= It
->second
;
254 auto Idx
= llvm::find_if(
255 Vec
, [Reg
](RegSlotPair
&RSP
) { return Reg
== RSP
.first
; });
256 if (Idx
!= Vec
.end()) {
257 int FI
= Idx
->second
;
258 LLVM_DEBUG(dbgs() << "Found global FI " << FI
<< " for register "
259 << printReg(Reg
, &TRI
) << " at "
260 << printMBBReference(*EHPad
) << "\n");
261 assert(ReservedSlots
.count(FI
) && "using unreserved slot");
266 unsigned Size
= getRegisterSize(TRI
, Reg
);
267 FrameIndexesPerSize
&Line
= getCacheBucket(Size
);
268 while (Line
.Index
< Line
.Slots
.size()) {
269 int FI
= Line
.Slots
[Line
.Index
++];
270 if (ReservedSlots
.count(FI
))
272 // If all sizes are kept together we probably need to extend the
274 if (MFI
.getObjectSize(FI
) < Size
) {
275 MFI
.setObjectSize(FI
, Size
);
276 MFI
.setObjectAlignment(FI
, Align(Size
));
277 NumSpillSlotsExtended
++;
281 int FI
= MFI
.CreateSpillStackObject(Size
, Align(Size
));
282 NumSpillSlotsAllocated
++;
283 Line
.Slots
.push_back(FI
);
286 // Remember assignment {Reg, FI} for EHPad
288 GlobalIndices
[EHPad
].push_back(std::make_pair(Reg
, FI
));
289 LLVM_DEBUG(dbgs() << "Reserved FI " << FI
<< " for spilling reg "
290 << printReg(Reg
, &TRI
) << " at landing pad "
291 << printMBBReference(*EHPad
) << "\n");
297 // Sort all registers to spill in descendent order. In the
298 // FixupSCSExtendSlotSize mode it will minimize the total frame size.
299 // In non FixupSCSExtendSlotSize mode we can skip this step.
300 void sortRegisters(SmallVectorImpl
<Register
> &Regs
) {
301 if (!FixupSCSExtendSlotSize
)
303 llvm::sort(Regs
, [&](Register
&A
, Register
&B
) {
304 return getRegisterSize(TRI
, A
) > getRegisterSize(TRI
, B
);
309 // Describes the state of the current processing statepoint instruction.
310 class StatepointState
{
312 // statepoint instruction.
315 // If non-null then statepoint is invoke, and this points to the landing pad.
316 MachineBasicBlock
*EHPad
;
317 const TargetRegisterInfo
&TRI
;
318 const TargetInstrInfo
&TII
;
319 MachineFrameInfo
&MFI
;
320 // Mask with callee saved registers.
321 const uint32_t *Mask
;
322 // Cache of frame indexes used on previous instruction processing.
323 FrameIndexesCache
&CacheFI
;
324 bool AllowGCPtrInCSR
;
325 // Operands with physical registers requiring spilling.
326 SmallVector
<unsigned, 8> OpsToSpill
;
327 // Set of register to spill.
328 SmallVector
<Register
, 8> RegsToSpill
;
329 // Set of registers to reload after statepoint.
330 SmallVector
<Register
, 8> RegsToReload
;
331 // Map Register to Frame Slot index.
332 DenseMap
<Register
, int> RegToSlotIdx
;
335 StatepointState(MachineInstr
&MI
, const uint32_t *Mask
,
336 FrameIndexesCache
&CacheFI
, bool AllowGCPtrInCSR
)
337 : MI(MI
), MF(*MI
.getMF()), TRI(*MF
.getSubtarget().getRegisterInfo()),
338 TII(*MF
.getSubtarget().getInstrInfo()), MFI(MF
.getFrameInfo()),
339 Mask(Mask
), CacheFI(CacheFI
), AllowGCPtrInCSR(AllowGCPtrInCSR
) {
341 // Find statepoint's landing pad, if any.
343 MachineBasicBlock
*MBB
= MI
.getParent();
344 // Invoke statepoint must be last one in block.
345 bool Last
= std::none_of(++MI
.getIterator(), MBB
->end().getInstrIterator(),
346 [](MachineInstr
&I
) {
347 return I
.getOpcode() == TargetOpcode::STATEPOINT
;
353 auto IsEHPad
= [](MachineBasicBlock
*B
) { return B
->isEHPad(); };
355 assert(llvm::count_if(MBB
->successors(), IsEHPad
) < 2 && "multiple EHPads");
357 auto It
= llvm::find_if(MBB
->successors(), IsEHPad
);
358 if (It
!= MBB
->succ_end())
362 MachineBasicBlock
*getEHPad() const { return EHPad
; }
364 // Return true if register is callee saved.
365 bool isCalleeSaved(Register Reg
) { return (Mask
[Reg
/ 32] >> Reg
% 32) & 1; }
367 // Iterates over statepoint meta args to find caller saver registers.
368 // Also cache the size of found registers.
369 // Returns true if caller save registers found.
370 bool findRegistersToSpill() {
371 SmallSet
<Register
, 8> GCRegs
;
372 // All GC pointer operands assigned to registers produce new value.
373 // Since they're tied to their defs, it is enough to collect def registers.
374 for (const auto &Def
: MI
.defs())
375 GCRegs
.insert(Def
.getReg());
377 SmallSet
<Register
, 8> VisitedRegs
;
378 for (unsigned Idx
= StatepointOpers(&MI
).getVarIdx(),
379 EndIdx
= MI
.getNumOperands();
380 Idx
< EndIdx
; ++Idx
) {
381 MachineOperand
&MO
= MI
.getOperand(Idx
);
382 // Leave `undef` operands as is, StackMaps will rewrite them
384 if (!MO
.isReg() || MO
.isImplicit() || MO
.isUndef())
386 Register Reg
= MO
.getReg();
387 assert(Reg
.isPhysical() && "Only physical regs are expected");
389 if (isCalleeSaved(Reg
) && (AllowGCPtrInCSR
|| !is_contained(GCRegs
, Reg
)))
392 LLVM_DEBUG(dbgs() << "Will spill " << printReg(Reg
, &TRI
) << " at index "
395 if (VisitedRegs
.insert(Reg
).second
)
396 RegsToSpill
.push_back(Reg
);
397 OpsToSpill
.push_back(Idx
);
399 CacheFI
.sortRegisters(RegsToSpill
);
400 return !RegsToSpill
.empty();
403 // Spill all caller saved registers right before statepoint instruction.
404 // Remember frame index where register is spilled.
405 void spillRegisters() {
406 for (Register Reg
: RegsToSpill
) {
407 int FI
= CacheFI
.getFrameIndex(Reg
, EHPad
);
408 const TargetRegisterClass
*RC
= TRI
.getMinimalPhysRegClass(Reg
);
410 NumSpilledRegisters
++;
411 RegToSlotIdx
[Reg
] = FI
;
413 LLVM_DEBUG(dbgs() << "Spilling " << printReg(Reg
, &TRI
) << " to FI " << FI
416 // Perform trivial copy propagation
418 MachineBasicBlock::iterator
InsertBefore(MI
);
419 Reg
= performCopyPropagation(Reg
, InsertBefore
, IsKill
, TII
, TRI
);
421 LLVM_DEBUG(dbgs() << "Insert spill before " << *InsertBefore
);
422 TII
.storeRegToStackSlot(*MI
.getParent(), InsertBefore
, Reg
, IsKill
, FI
,
427 void insertReloadBefore(unsigned Reg
, MachineBasicBlock::iterator It
,
428 MachineBasicBlock
*MBB
) {
429 const TargetRegisterClass
*RC
= TRI
.getMinimalPhysRegClass(Reg
);
430 int FI
= RegToSlotIdx
[Reg
];
431 if (It
!= MBB
->end()) {
432 TII
.loadRegFromStackSlot(*MBB
, It
, Reg
, FI
, RC
, &TRI
);
436 // To insert reload at the end of MBB, insert it before last instruction
437 // and then swap them.
438 assert(!MBB
->empty() && "Empty block");
440 TII
.loadRegFromStackSlot(*MBB
, It
, Reg
, FI
, RC
, &TRI
);
441 MachineInstr
*Reload
= It
->getPrevNode();
444 assert(TII
.isLoadFromStackSlot(*Reload
, Dummy
) == Reg
);
447 MBB
->insertAfter(It
, Reload
);
450 // Insert reloads of (relocated) registers spilled in statepoint.
451 void insertReloads(MachineInstr
*NewStatepoint
, RegReloadCache
&RC
) {
452 MachineBasicBlock
*MBB
= NewStatepoint
->getParent();
453 auto InsertPoint
= std::next(NewStatepoint
->getIterator());
455 for (auto Reg
: RegsToReload
) {
456 insertReloadBefore(Reg
, InsertPoint
, MBB
);
457 LLVM_DEBUG(dbgs() << "Reloading " << printReg(Reg
, &TRI
) << " from FI "
458 << RegToSlotIdx
[Reg
] << " after statepoint\n");
460 if (EHPad
&& !RC
.hasReload(Reg
, RegToSlotIdx
[Reg
], EHPad
)) {
461 RC
.recordReload(Reg
, RegToSlotIdx
[Reg
], EHPad
);
462 auto EHPadInsertPoint
= EHPad
->SkipPHIsLabelsAndDebug(EHPad
->begin());
463 insertReloadBefore(Reg
, EHPadInsertPoint
, EHPad
);
464 LLVM_DEBUG(dbgs() << "...also reload at EHPad "
465 << printMBBReference(*EHPad
) << "\n");
470 // Re-write statepoint machine instruction to replace caller saved operands
471 // with indirect memory location (frame index).
472 MachineInstr
*rewriteStatepoint() {
473 MachineInstr
*NewMI
=
474 MF
.CreateMachineInstr(TII
.get(MI
.getOpcode()), MI
.getDebugLoc(), true);
475 MachineInstrBuilder
MIB(MF
, NewMI
);
477 unsigned NumOps
= MI
.getNumOperands();
479 // New indices for the remaining defs.
480 SmallVector
<unsigned, 8> NewIndices
;
481 unsigned NumDefs
= MI
.getNumDefs();
482 for (unsigned I
= 0; I
< NumDefs
; ++I
) {
483 MachineOperand
&DefMO
= MI
.getOperand(I
);
484 assert(DefMO
.isReg() && DefMO
.isDef() && "Expected Reg Def operand");
485 Register Reg
= DefMO
.getReg();
486 assert(DefMO
.isTied() && "Def is expected to be tied");
487 // We skipped undef uses and did not spill them, so we should not
488 // proceed with defs here.
489 if (MI
.getOperand(MI
.findTiedOperandIdx(I
)).isUndef()) {
490 if (AllowGCPtrInCSR
) {
491 NewIndices
.push_back(NewMI
->getNumOperands());
492 MIB
.addReg(Reg
, RegState::Define
);
496 if (!AllowGCPtrInCSR
) {
497 assert(is_contained(RegsToSpill
, Reg
));
498 RegsToReload
.push_back(Reg
);
500 if (isCalleeSaved(Reg
)) {
501 NewIndices
.push_back(NewMI
->getNumOperands());
502 MIB
.addReg(Reg
, RegState::Define
);
504 NewIndices
.push_back(NumOps
);
505 RegsToReload
.push_back(Reg
);
511 OpsToSpill
.push_back(MI
.getNumOperands());
512 unsigned CurOpIdx
= 0;
514 for (unsigned I
= NumDefs
; I
< MI
.getNumOperands(); ++I
) {
515 MachineOperand
&MO
= MI
.getOperand(I
);
516 if (I
== OpsToSpill
[CurOpIdx
]) {
517 int FI
= RegToSlotIdx
[MO
.getReg()];
518 MIB
.addImm(StackMaps::IndirectMemRefOp
);
519 MIB
.addImm(getRegisterSize(TRI
, MO
.getReg()));
520 assert(MO
.isReg() && "Should be register");
521 assert(MO
.getReg().isPhysical() && "Should be physical register");
522 MIB
.addFrameIndex(FI
);
528 if (AllowGCPtrInCSR
&& MI
.isRegTiedToDefOperand(I
, &OldDef
)) {
529 assert(OldDef
< NumDefs
);
530 assert(NewIndices
[OldDef
] < NumOps
);
531 MIB
->tieOperands(NewIndices
[OldDef
], MIB
->getNumOperands() - 1);
535 assert(CurOpIdx
== (OpsToSpill
.size() - 1) && "Not all operands processed");
537 NewMI
->setMemRefs(MF
, MI
.memoperands());
538 for (auto It
: RegToSlotIdx
) {
539 Register R
= It
.first
;
540 int FrameIndex
= It
.second
;
541 auto PtrInfo
= MachinePointerInfo::getFixedStack(MF
, FrameIndex
);
542 MachineMemOperand::Flags Flags
= MachineMemOperand::MOLoad
;
543 if (is_contained(RegsToReload
, R
))
544 Flags
|= MachineMemOperand::MOStore
;
546 MF
.getMachineMemOperand(PtrInfo
, Flags
, getRegisterSize(TRI
, R
),
547 MFI
.getObjectAlign(FrameIndex
));
548 NewMI
->addMemOperand(MF
, MMO
);
551 // Insert new statepoint and erase old one.
552 MI
.getParent()->insert(MI
, NewMI
);
554 LLVM_DEBUG(dbgs() << "rewritten statepoint to : " << *NewMI
<< "\n");
555 MI
.eraseFromParent();
560 class StatepointProcessor
{
563 const TargetRegisterInfo
&TRI
;
564 FrameIndexesCache CacheFI
;
565 RegReloadCache ReloadCache
;
568 StatepointProcessor(MachineFunction
&MF
)
569 : MF(MF
), TRI(*MF
.getSubtarget().getRegisterInfo()),
570 CacheFI(MF
.getFrameInfo(), TRI
) {}
572 bool process(MachineInstr
&MI
, bool AllowGCPtrInCSR
) {
573 StatepointOpers
SO(&MI
);
574 uint64_t Flags
= SO
.getFlags();
575 // Do nothing for LiveIn, it supports all registers.
576 if (Flags
& (uint64_t)StatepointFlags::DeoptLiveIn
)
578 LLVM_DEBUG(dbgs() << "\nMBB " << MI
.getParent()->getNumber() << " "
579 << MI
.getParent()->getName() << " : process statepoint "
581 CallingConv::ID CC
= SO
.getCallingConv();
582 const uint32_t *Mask
= TRI
.getCallPreservedMask(MF
, CC
);
583 StatepointState
SS(MI
, Mask
, CacheFI
, AllowGCPtrInCSR
);
584 CacheFI
.reset(SS
.getEHPad());
586 if (!SS
.findRegistersToSpill())
590 auto *NewStatepoint
= SS
.rewriteStatepoint();
591 SS
.insertReloads(NewStatepoint
, ReloadCache
);
597 bool FixupStatepointCallerSaved::runOnMachineFunction(MachineFunction
&MF
) {
598 if (skipFunction(MF
.getFunction()))
601 const Function
&F
= MF
.getFunction();
605 SmallVector
<MachineInstr
*, 16> Statepoints
;
606 for (MachineBasicBlock
&BB
: MF
)
607 for (MachineInstr
&I
: BB
)
608 if (I
.getOpcode() == TargetOpcode::STATEPOINT
)
609 Statepoints
.push_back(&I
);
611 if (Statepoints
.empty())
614 bool Changed
= false;
615 StatepointProcessor
SPP(MF
);
616 unsigned NumStatepoints
= 0;
617 bool AllowGCPtrInCSR
= PassGCPtrInCSR
;
618 for (MachineInstr
*I
: Statepoints
) {
620 if (MaxStatepointsWithRegs
.getNumOccurrences() &&
621 NumStatepoints
>= MaxStatepointsWithRegs
)
622 AllowGCPtrInCSR
= false;
623 Changed
|= SPP
.process(*I
, AllowGCPtrInCSR
);