Lines Matching +full:global +full:- +full:regs
1 //===- AArch64LowerHomogeneousPrologEpilog.cpp ----------------------------===//
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
11 //===----------------------------------------------------------------------===//
39 "frame-helper-size-threshold", cl::init(2), cl::Hidden,
101 "aarch64-lower-homogeneous-prolog-epilog",
119 MachineFunction *MF = MMI->getMachineFunction(F); in run()
132 static std::string getFrameHelperName(SmallVectorImpl<unsigned> &Regs, in getFrameHelperName() argument
150 for (auto Reg : Regs) { in getFrameHelperName()
164 LLVMContext &C = M->getContext(); in createFrameHelperMachineFunction()
165 Function *F = M->getFunction(Name); in createFrameHelperMachineFunction()
172 F->setLinkage(GlobalValue::LinkOnceODRLinkage); in createFrameHelperMachineFunction()
173 F->setUnnamedAddr(GlobalValue::UnnamedAddr::Global); in createFrameHelperMachineFunction()
175 // Set no-opt/minsize, so we don't insert padding between outlined in createFrameHelperMachineFunction()
177 F->addFnAttr(Attribute::OptimizeNone); in createFrameHelperMachineFunction()
178 F->addFnAttr(Attribute::NoInline); in createFrameHelperMachineFunction()
179 F->addFnAttr(Attribute::MinSize); in createFrameHelperMachineFunction()
180 F->addFnAttr(Attribute::Naked); in createFrameHelperMachineFunction()
182 MachineFunction &MF = MMI->getOrCreateMachineFunction(*F); in createFrameHelperMachineFunction()
201 /// Emit a store-pair instruction for frame-setup.
242 /// Emit a load-pair instruction for frame-destroy.
283 /// Return a unique function if a helper can be formed with the given Regs
286 /// stp x22, x21, [sp, #-32]! ; x29/x30 has been stored at the caller
291 /// stp x22, x21, [sp, #-32]! ; x29/x30 has been stored at the caller
310 /// @param Regs callee save regs that the helper will handle
314 SmallVectorImpl<unsigned> &Regs, in getOrCreateFrameHelper() argument
317 assert(Regs.size() >= 2); in getOrCreateFrameHelper()
318 auto Name = getFrameHelperName(Regs, Type, FpOffset); in getOrCreateFrameHelper()
319 auto *F = M->getFunction(Name); in getOrCreateFrameHelper()
328 int Size = (int)Regs.size(); in getOrCreateFrameHelper()
333 auto LRIdx = std::distance(Regs.begin(), llvm::find(Regs, AArch64::LR)); in getOrCreateFrameHelper()
337 if (LRIdx != Size - 2) { in getOrCreateFrameHelper()
338 assert(Regs[Size - 2] != AArch64::LR); in getOrCreateFrameHelper()
339 emitStore(MF, MBB, MBB.end(), TII, Regs[Size - 2], Regs[Size - 1], in getOrCreateFrameHelper()
340 LRIdx - Size + 2, true); in getOrCreateFrameHelper()
344 for (int I = Size - 3; I >= 0; I -= 2) { in getOrCreateFrameHelper()
345 // FP/LR has been stored at call-site. in getOrCreateFrameHelper()
346 if (Regs[I - 1] == AArch64::LR) in getOrCreateFrameHelper()
348 emitStore(MF, MBB, MBB.end(), TII, Regs[I - 1], Regs[I], Size - I - 1, in getOrCreateFrameHelper()
373 for (int I = 0; I < Size - 2; I += 2) in getOrCreateFrameHelper()
374 emitLoad(MF, MBB, MBB.end(), TII, Regs[I], Regs[I + 1], Size - I - 2, in getOrCreateFrameHelper()
376 // Restore the last CSR with post-increment of SP. in getOrCreateFrameHelper()
377 emitLoad(MF, MBB, MBB.end(), TII, Regs[Size - 2], Regs[Size - 1], Size, in getOrCreateFrameHelper()
385 return M->getFunction(Name); in getOrCreateFrameHelper()
392 /// @param Regs callee save registers that are saved or restored.
397 SmallVectorImpl<unsigned> &Regs, in shouldUseFrameHelper() argument
399 const auto *TRI = MBB.getParent()->getSubtarget().getRegisterInfo(); in shouldUseFrameHelper()
400 auto RegCount = Regs.size(); in shouldUseFrameHelper()
406 if (!llvm::is_contained(Regs, AArch64::LR)) in shouldUseFrameHelper()
412 InstCount--; in shouldUseFrameHelper()
419 // Bail-out if X16 is live across the epilog helper because it is used in in shouldUseFrameHelper()
422 if (NextMI->readsRegister(AArch64::W16, TRI)) in shouldUseFrameHelper()
427 if (SuccMBB->isLiveIn(AArch64::W16) || SuccMBB->isLiveIn(AArch64::X16)) in shouldUseFrameHelper()
436 if (NextMBBI->getOpcode() != AArch64::RET_ReallyLR) in shouldUseFrameHelper()
475 SmallVector<unsigned, 8> Regs; in lowerEpilog() local
485 Regs.push_back(MO.getReg()); in lowerEpilog()
488 int Size = (int)Regs.size(); in lowerEpilog()
496 if (shouldUseFrameHelper(MBB, NextMBBI, Regs, FrameHelperType::EpilogTail)) { in lowerEpilog()
497 // When MBB ends with a return, emit a tail-call to the epilog helper in lowerEpilog()
499 getOrCreateFrameHelper(M, MMI, Regs, FrameHelperType::EpilogTail); in lowerEpilog()
500 BuildMI(MBB, MBBI, DL, TII->get(AArch64::TCRETURNdi)) in lowerEpilog()
507 Return->removeFromParent(); in lowerEpilog()
508 } else if (shouldUseFrameHelper(MBB, NextMBBI, Regs, in lowerEpilog()
512 getOrCreateFrameHelper(M, MMI, Regs, FrameHelperType::Epilog); in lowerEpilog()
513 BuildMI(MBB, MBBI, DL, TII->get(AArch64::BL)) in lowerEpilog()
518 // Fall back to no-helper. in lowerEpilog()
519 for (int I = 0; I < Size - 2; I += 2) in lowerEpilog()
520 emitLoad(MF, MBB, MBBI, *TII, Regs[I], Regs[I + 1], Size - I - 2, false); in lowerEpilog()
521 // Restore the last CSR with post-increment of SP. in lowerEpilog()
522 emitLoad(MF, MBB, MBBI, *TII, Regs[Size - 2], Regs[Size - 1], Size, true); in lowerEpilog()
525 MBBI->removeFromParent(); in lowerEpilog()
533 /// 1. With a helper including frame-setup
536 /// stp x29, x30, [sp, #-16]!
542 /// stp x29, x30, [sp, #-16]!
548 /// stp x22, x21, [sp, #-48]!
558 SmallVector<unsigned, 8> Regs; in lowerProlog() local
566 LRIdx = Regs.size(); in lowerProlog()
573 Regs.push_back(MO.getReg()); in lowerProlog()
579 int Size = (int)Regs.size(); in lowerProlog()
587 shouldUseFrameHelper(MBB, NextMBBI, Regs, FrameHelperType::PrologFrame)) { in lowerProlog()
589 emitStore(MF, MBB, MBBI, *TII, AArch64::LR, AArch64::FP, -LRIdx - 2, true); in lowerProlog()
591 M, MMI, Regs, FrameHelperType::PrologFrame, *FpOffset); in lowerProlog()
592 BuildMI(MBB, MBBI, DL, TII->get(AArch64::BL)) in lowerProlog()
598 } else if (!FpOffset && shouldUseFrameHelper(MBB, NextMBBI, Regs, in lowerProlog()
601 emitStore(MF, MBB, MBBI, *TII, AArch64::LR, AArch64::FP, -LRIdx - 2, true); in lowerProlog()
603 getOrCreateFrameHelper(M, MMI, Regs, FrameHelperType::Prolog); in lowerProlog()
604 BuildMI(MBB, MBBI, DL, TII->get(AArch64::BL)) in lowerProlog()
609 // Fall back to no-helper. in lowerProlog()
610 emitStore(MF, MBB, MBBI, *TII, Regs[Size - 2], Regs[Size - 1], -Size, true); in lowerProlog()
611 for (int I = Size - 3; I >= 0; I -= 2) in lowerProlog()
612 emitStore(MF, MBB, MBBI, *TII, Regs[I - 1], Regs[I], Size - I - 1, false); in lowerProlog()
614 BuildMI(MBB, MBBI, DL, TII->get(AArch64::ADDXri)) in lowerProlog()
623 MBBI->removeFromParent(); in lowerProlog()