LLVM 24.0.0git
HexagonFrameLowering.cpp
Go to the documentation of this file.
1//===- HexagonFrameLowering.cpp - Define frame lowering -------------------===//
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
11#include "HexagonBlockRanges.h"
12#include "HexagonISelLowering.h"
13#include "HexagonInstrInfo.h"
15#include "HexagonRegisterInfo.h"
16#include "HexagonSubtarget.h"
19#include "llvm/ADT/BitVector.h"
20#include "llvm/ADT/DenseMap.h"
22#include "llvm/ADT/SetVector.h"
23#include "llvm/ADT/SmallSet.h"
43#include "llvm/IR/Attributes.h"
44#include "llvm/IR/DebugLoc.h"
45#include "llvm/IR/Function.h"
46#include "llvm/MC/MCDwarf.h"
48#include "llvm/Pass.h"
52#include "llvm/Support/Debug.h"
58#include <algorithm>
59#include <cassert>
60#include <cstdint>
61#include <iterator>
62#include <limits>
63#include <map>
64#include <optional>
65#include <utility>
66#include <vector>
67
68#define DEBUG_TYPE "hexagon-pei"
69
70// Hexagon stack frame layout as defined by the ABI:
71//
72// Incoming arguments
73// passed via stack
74// |
75// |
76// SP during function's FP during function's |
77// +-- runtime (top of stack) runtime (bottom) --+ |
78// | | |
79// --++---------------------+------------------+-----------------++-+-------
80// | parameter area for | variable-size | fixed-size |LR| arg
81// | called functions | local objects | local objects |FP|
82// --+----------------------+------------------+-----------------+--+-------
83// <- size known -> <- size unknown -> <- size known ->
84//
85// Low address High address
86//
87// <--- stack growth
88//
89//
90// - In any circumstances, the outgoing function arguments are always accessi-
91// ble using the SP, and the incoming arguments are accessible using the FP.
92// - If the local objects are not aligned, they can always be accessed using
93// the FP.
94// - If there are no variable-sized objects, the local objects can always be
95// accessed using the SP, regardless whether they are aligned or not. (The
96// alignment padding will be at the bottom of the stack (highest address),
97// and so the offset with respect to the SP will be known at the compile-
98// -time.)
99//
100// The only complication occurs if there are both, local aligned objects, and
101// dynamically allocated (variable-sized) objects. The alignment pad will be
102// placed between the FP and the local objects, thus preventing the use of the
103// FP to access the local objects. At the same time, the variable-sized objects
104// will be between the SP and the local objects, thus introducing an unknown
105// distance from the SP to the locals.
106//
107// To avoid this problem, a new register is created that holds the aligned
108// address of the bottom of the stack, referred in the sources as AP (aligned
109// pointer). The AP will be equal to "FP-p", where "p" is the smallest pad
110// that aligns AP to the required boundary (a maximum of the alignments of
111// all stack objects, fixed- and variable-sized). All local objects[1] will
112// then use AP as the base pointer.
113// [1] The exception is with "fixed" stack objects. "Fixed" stack objects get
114// their name from being allocated at fixed locations on the stack, relative
115// to the FP. In the presence of dynamic allocation and local alignment, such
116// objects can only be accessed through the FP.
117//
118// Illustration of the AP:
119// FP --+
120// |
121// ---------------+---------------------+-----+-----------------------++-+--
122// Rest of the | Local stack objects | Pad | Fixed stack objects |LR|
123// stack frame | (aligned) | | (CSR, spills, etc.) |FP|
124// ---------------+---------------------+-----+-----------------+-----+--+--
125// |<-- Multiple of the -->|
126// stack alignment +-- AP
127//
128// The AP is set up at the beginning of the function. Since it is not a dedi-
129// cated (reserved) register, it needs to be kept live throughout the function
130// to be available as the base register for local object accesses.
131// Normally, an address of a stack objects is obtained by a pseudo-instruction
132// PS_fi. To access local objects with the AP register present, a different
133// pseudo-instruction needs to be used: PS_fia. The PS_fia takes one extra
134// argument compared to PS_fi: the first input register is the AP register.
135// This keeps the register live between its definition and its uses.
136
137// The AP register is originally set up using pseudo-instruction PS_aligna:
138// AP = PS_aligna A
139// where
140// A - required stack alignment
141// The alignment value must be the maximum of all alignments required by
142// any stack object.
143
144// The dynamic allocation uses a pseudo-instruction PS_alloca:
145// Rd = PS_alloca Rs, A
146// where
147// Rd - address of the allocated space
148// Rs - minimum size (the actual allocated can be larger to accommodate
149// alignment)
150// A - required alignment
151
152using namespace llvm;
153
156 const DebugLoc &DL) {
157 if (!MF.getFunction().hasFnAttribute(Attribute::ShadowCallStack))
158 return;
159
160 const auto &HST = MF.getSubtarget<HexagonSubtarget>();
161 // Hexagon saves LR (R31) via allocframe. If there is no frame, LR is
162 // not on the regular stack and does not need shadow-stack protection.
163 if (!HST.getFrameLowering()->hasFP(MF))
164 return;
165
166 // The shadow call stack pointer has to survive arbitrary calls, so it is
167 // always one of the callee-saved registers R16-R27 (Hexagon ABI, "Register
168 // usage across calls"). It must also be reserved: besides keeping the
169 // register allocator away from it, reserving it keeps it out of the
170 // callee-saved set, so it is never spilled and restored as an ordinary
171 // callee-saved register - which would leave the epilogue below reading the
172 // *caller's* shadow-stack slot. The spill stubs are handled separately in
173 // useSpillFunction()/useRestoreFunction().
174 Register SCSPReg = HST.getSCSPReg();
175 const auto &HRI = *HST.getRegisterInfo();
176 if (!HST.isRegisterReservedByUser(SCSPReg))
177 // Lower-cased to match the spelling of the -ffixed-<reg> flag the user
178 // needs to pass; TRI names the register "R18".
179 report_fatal_error(Twine("Must reserve ") +
180 StringRef(HRI.getName(SCSPReg)).lower() +
181 " to use shadow call stack on Hexagon");
182
183 const auto &HII = *HST.getInstrInfo();
184
185 // SCSPReg = add(SCSPReg, #4)
186 BuildMI(MBB, MI, DL, HII.get(Hexagon::A2_addi), SCSPReg)
187 .addReg(SCSPReg)
188 .addImm(4)
190 // memw(SCSPReg + #-4) = r31
191 BuildMI(MBB, MI, DL, HII.get(Hexagon::S2_storeri_io))
192 .addReg(SCSPReg)
193 .addImm(-4)
194 .addReg(Hexagon::R31)
196
197 MBB.addLiveIn(SCSPReg);
198
199 if (!MF.needsFrameMoves())
200 return;
201
202 // CFI: DW_CFA_val_expression for the SCS register, DW_OP_bregN -4
203 // Tells the unwinder that the SCS register at entry = current value - 4.
204 unsigned DwarfSCSReg = HRI.getDwarfRegNum(SCSPReg, /*IsEH=*/true);
205 // DW_OP_breg0..DW_OP_breg31 (0x70..0x8f) are 32 opcodes indexed by
206 // register number, so the register number must fit in [0, 31].
207 assert(DwarfSCSReg < 32 && "SCS register should be < 32");
208 const char CFIInst[] = {
209 (char)dwarf::DW_CFA_val_expression,
210 (char)DwarfSCSReg,
211 2, // expression length
212 (char)(unsigned)(dwarf::DW_OP_breg0 + DwarfSCSReg),
213 (char)(-4 & 0x7f), // SLEB128 -4
214 };
216 .buildEscape(StringRef(CFIInst, sizeof(CFIInst)));
217}
218
221 const DebugLoc &DL) {
222 if (!MF.getFunction().hasFnAttribute(Attribute::ShadowCallStack))
223 return;
224
225 // hasFP() is true at both call sites: the non-vararg path in
226 // insertEpilogueInBlock returns early when !hasFP(), and the vararg+musl
227 // path is inside the hasFP() branch. Check defensively.
229 report_fatal_error("SCS epilogue requires a frame");
230
231 const auto &HST = MF.getSubtarget<HexagonSubtarget>();
232 Register SCSPReg = HST.getSCSPReg();
233 const auto &HII = *HST.getInstrInfo();
234
235 // r31 = memw(SCSPReg + #-4)
236 BuildMI(MBB, MI, DL, HII.get(Hexagon::L2_loadri_io), Hexagon::R31)
237 .addReg(SCSPReg)
238 .addImm(-4)
240 // SCSPReg = add(SCSPReg, #-4)
241 BuildMI(MBB, MI, DL, HII.get(Hexagon::A2_addi), SCSPReg)
242 .addReg(SCSPReg)
243 .addImm(-4)
245
246 if (MF.needsFrameMoves())
248}
249
250static cl::opt<bool> DisableDeallocRet("disable-hexagon-dealloc-ret",
251 cl::Hidden, cl::desc("Disable Dealloc Return for Hexagon target"));
252
254 NumberScavengerSlots("number-scavenger-slots", cl::Hidden,
255 cl::desc("Set the number of scavenger slots"),
256 cl::init(2));
257
258static cl::opt<int>
259 SpillFuncThreshold("spill-func-threshold", cl::Hidden,
260 cl::desc("Specify O2(not Os) spill func threshold"),
261 cl::init(6));
262
263static cl::opt<int>
264 SpillFuncThresholdOs("spill-func-threshold-Os", cl::Hidden,
265 cl::desc("Specify Os spill func threshold"),
266 cl::init(1));
267
269 "enable-stackovf-sanitizer", cl::Hidden,
270 cl::desc("Enable runtime checks for stack overflow."), cl::init(false));
271
272static cl::opt<bool>
273 EnableShrinkWrapping("hexagon-shrink-frame", cl::init(true), cl::Hidden,
274 cl::desc("Enable stack frame shrink wrapping"));
275
277 ShrinkLimit("shrink-frame-limit",
278 cl::init(std::numeric_limits<unsigned>::max()), cl::Hidden,
279 cl::desc("Max count of stack frame shrink-wraps"));
280
281static cl::opt<bool>
282 EnableSaveRestoreLong("enable-save-restore-long", cl::Hidden,
283 cl::desc("Enable long calls for save-restore stubs."),
284 cl::init(false));
285
286static cl::opt<bool> EliminateFramePointer("hexagon-fp-elim", cl::init(true),
287 cl::Hidden, cl::desc("Refrain from using FP whenever possible"));
288
289static cl::opt<bool> OptimizeSpillSlots("hexagon-opt-spill", cl::Hidden,
290 cl::init(true), cl::desc("Optimize spill slots"));
291
292#ifndef NDEBUG
294 cl::init(std::numeric_limits<unsigned>::max()));
295static unsigned SpillOptCount = 0;
296#endif
297
298namespace {
299
300 class HexagonCallFrameInformation : public MachineFunctionPass {
301 public:
302 static char ID;
303
304 HexagonCallFrameInformation() : MachineFunctionPass(ID) {}
305
306 bool runOnMachineFunction(MachineFunction &MF) override;
307
308 MachineFunctionProperties getRequiredProperties() const override {
309 return MachineFunctionProperties().setNoVRegs();
310 }
311 };
312
313 char HexagonCallFrameInformation::ID = 0;
314
315} // end anonymous namespace
316
317bool HexagonCallFrameInformation::runOnMachineFunction(MachineFunction &MF) {
318 auto &HFI = *MF.getSubtarget<HexagonSubtarget>().getFrameLowering();
319 bool NeedCFI = MF.needsFrameMoves();
320
321 if (!NeedCFI)
322 return false;
323 HFI.insertCFIInstructions(MF);
324 return true;
325}
326
327INITIALIZE_PASS(HexagonCallFrameInformation, "hexagon-cfi",
328 "Hexagon call frame information", false, false)
329
331 return new HexagonCallFrameInformation();
332}
333
334/// Map a register pair Reg to the subregister that has the greater "number",
335/// i.e. D3 (aka R7:6) will be mapped to R7, etc.
337 const TargetRegisterInfo &TRI,
338 bool hireg = true) {
339 if (Reg < Hexagon::D0 || Reg > Hexagon::D15)
340 return Reg;
341
342 Register RegNo = 0;
343 for (MCPhysReg SubReg : TRI.subregs(Reg)) {
344 if (hireg) {
345 if (SubReg > RegNo)
346 RegNo = SubReg;
347 } else {
348 if (!RegNo || SubReg < RegNo)
349 RegNo = SubReg;
350 }
351 }
352 return RegNo;
353}
354
355/// Returns the callee saved register with the largest id in the vector.
357 const TargetRegisterInfo &TRI) {
358 static_assert(Hexagon::R1 > 0,
359 "Assume physical registers are encoded as positive integers");
360 if (CSI.empty())
361 return 0;
362
363 Register Max = getMax32BitSubRegister(CSI[0].getReg(), TRI);
364 for (unsigned I = 1, E = CSI.size(); I < E; ++I) {
366 if (Reg > Max)
367 Max = Reg;
368 }
369 return Max;
370}
371
372/// Checks if the basic block contains any instruction that needs a stack
373/// frame to be already in place.
374static bool needsStackFrame(const MachineBasicBlock &MBB, const BitVector &CSR,
375 const HexagonRegisterInfo &HRI) {
376 for (const MachineInstr &MI : MBB) {
377 if (MI.isCall())
378 return true;
379 unsigned Opc = MI.getOpcode();
380 switch (Opc) {
381 case Hexagon::PS_alloca:
382 case Hexagon::PS_aligna:
383 return true;
384 default:
385 break;
386 }
387 // Check individual operands.
388 for (const MachineOperand &MO : MI.operands()) {
389 // While the presence of a frame index does not prove that a stack
390 // frame will be required, all frame indexes should be within alloc-
391 // frame/deallocframe. Otherwise, the code that translates a frame
392 // index into an offset would have to be aware of the placement of
393 // the frame creation/destruction instructions.
394 if (MO.isFI())
395 return true;
396 if (MO.isReg()) {
397 Register R = MO.getReg();
398 // Debug instructions may refer to $noreg.
399 if (!R)
400 continue;
401 // Virtual registers will need scavenging, which then may require
402 // a stack slot.
403 if (R.isVirtual())
404 return true;
405 for (MCPhysReg S : HRI.subregs_inclusive(R))
406 if (CSR[S])
407 return true;
408 continue;
409 }
410 if (MO.isRegMask()) {
411 // A regmask would normally have all callee-saved registers marked
412 // as preserved, so this check would not be needed, but in case of
413 // ever having other regmasks (for other calling conventions),
414 // make sure they would be processed correctly.
415 const uint32_t *BM = MO.getRegMask();
416 for (int x = CSR.find_first(); x >= 0; x = CSR.find_next(x)) {
417 unsigned R = x;
418 // If this regmask does not preserve a CSR, a frame will be needed.
419 if (!(BM[R/32] & (1u << (R%32))))
420 return true;
421 }
422 }
423 }
424 }
425 return false;
426}
427
428 /// Returns true if MBB has a machine instructions that indicates a tail call
429 /// in the block.
430static bool hasTailCall(const MachineBasicBlock &MBB) {
431 MachineBasicBlock::const_iterator I = MBB.getLastNonDebugInstr();
432 if (I == MBB.end())
433 return false;
434 unsigned RetOpc = I->getOpcode();
435 return RetOpc == Hexagon::PS_tailcall_i || RetOpc == Hexagon::PS_tailcall_r;
436}
437
438/// Returns true if MBB contains an instruction that returns.
439static bool hasReturn(const MachineBasicBlock &MBB) {
440 for (const MachineInstr &MI : MBB.terminators())
441 if (MI.isReturn())
442 return true;
443 return false;
444}
445
446/// Returns the "return" instruction from this block, or nullptr if there
447/// isn't any.
449 for (auto &I : MBB)
450 if (I.isReturn())
451 return &I;
452 return nullptr;
453}
454
455static bool isRestoreCall(unsigned Opc) {
456 switch (Opc) {
457 case Hexagon::RESTORE_DEALLOC_RET_JMP_V4:
458 case Hexagon::RESTORE_DEALLOC_RET_JMP_V4_PIC:
459 case Hexagon::RESTORE_DEALLOC_RET_JMP_V4_EXT:
460 case Hexagon::RESTORE_DEALLOC_RET_JMP_V4_EXT_PIC:
461 case Hexagon::RESTORE_DEALLOC_BEFORE_TAILCALL_V4_EXT:
462 case Hexagon::RESTORE_DEALLOC_BEFORE_TAILCALL_V4_EXT_PIC:
463 case Hexagon::RESTORE_DEALLOC_BEFORE_TAILCALL_V4:
464 case Hexagon::RESTORE_DEALLOC_BEFORE_TAILCALL_V4_PIC:
465 return true;
466 }
467 return false;
468}
469
470static inline bool isOptNone(const MachineFunction &MF) {
471 return MF.getFunction().hasOptNone() ||
473}
474
475static inline bool isOptSize(const MachineFunction &MF) {
476 const Function &F = MF.getFunction();
477 return F.hasOptSize() && !F.hasMinSize();
478}
479
480static inline bool isMinSize(const MachineFunction &MF) {
481 return MF.getFunction().hasMinSize();
482}
483
484/// Implements shrink-wrapping of the stack frame. By default, stack frame
485/// is created in the function entry block, and is cleaned up in every block
486/// that returns. This function finds alternate blocks: one for the frame
487/// setup (prolog) and one for the cleanup (epilog).
488void HexagonFrameLowering::findShrunkPrologEpilog(MachineFunction &MF,
489 MachineBasicBlock *&PrologB, MachineBasicBlock *&EpilogB) const {
490 static unsigned ShrinkCounter = 0;
491
492 if (MF.getSubtarget<HexagonSubtarget>().isEnvironmentMusl() &&
493 MF.getFunction().isVarArg())
494 return;
495 if (ShrinkLimit.getPosition()) {
496 if (ShrinkCounter >= ShrinkLimit)
497 return;
498 ShrinkCounter++;
499 }
500
501 auto &HRI = *MF.getSubtarget<HexagonSubtarget>().getRegisterInfo();
502
503 MachineDominatorTree MDT;
504 MDT.recalculate(MF);
505 MachinePostDominatorTree MPT;
506 MPT.recalculate(MF);
507
508 using UnsignedMap = DenseMap<unsigned, unsigned>;
509 using RPOTType = ReversePostOrderTraversal<const MachineFunction *>;
510
511 UnsignedMap RPO;
512 RPOTType RPOT(&MF);
513 unsigned RPON = 0;
514 for (auto &I : RPOT)
515 RPO[I->getNumber()] = RPON++;
516
517 // Don't process functions that have loops, at least for now. Placement
518 // of prolog and epilog must take loop structure into account. For simpli-
519 // city don't do it right now.
520 for (auto &I : MF) {
521 unsigned BN = RPO[I.getNumber()];
522 for (MachineBasicBlock *Succ : I.successors())
523 // If found a back-edge, return.
524 if (RPO[Succ->getNumber()] <= BN)
525 return;
526 }
527
528 // Collect the set of blocks that need a stack frame to execute. Scan
529 // each block for uses/defs of callee-saved registers, calls, etc.
531 BitVector CSR(Hexagon::NUM_TARGET_REGS);
532 for (const MCPhysReg *P = HRI.getCalleeSavedRegs(&MF); *P; ++P)
533 for (MCPhysReg S : HRI.subregs_inclusive(*P))
534 CSR[S] = true;
535
536 for (auto &I : MF)
537 if (needsStackFrame(I, CSR, HRI))
538 SFBlocks.push_back(&I);
539
540 LLVM_DEBUG({
541 dbgs() << "Blocks needing SF: {";
542 for (auto &B : SFBlocks)
543 dbgs() << " " << printMBBReference(*B);
544 dbgs() << " }\n";
545 });
546 // No frame needed?
547 if (SFBlocks.empty())
548 return;
549
550 // Pick a common dominator and a common post-dominator.
551 MachineBasicBlock *DomB = SFBlocks[0];
552 for (unsigned i = 1, n = SFBlocks.size(); i < n; ++i) {
553 DomB = MDT.findNearestCommonDominator(DomB, SFBlocks[i]);
554 if (!DomB)
555 break;
556 }
557 MachineBasicBlock *PDomB = SFBlocks[0];
558 for (unsigned i = 1, n = SFBlocks.size(); i < n; ++i) {
559 PDomB = MPT.findNearestCommonDominator(PDomB, SFBlocks[i]);
560 if (!PDomB)
561 break;
562 }
563 LLVM_DEBUG({
564 dbgs() << "Computed dom block: ";
565 if (DomB)
566 dbgs() << printMBBReference(*DomB);
567 else
568 dbgs() << "<null>";
569 dbgs() << ", computed pdom block: ";
570 if (PDomB)
571 dbgs() << printMBBReference(*PDomB);
572 else
573 dbgs() << "<null>";
574 dbgs() << "\n";
575 });
576 if (!DomB || !PDomB)
577 return;
578
579 // Make sure that DomB dominates PDomB and PDomB post-dominates DomB.
580 if (!MDT.dominates(DomB, PDomB)) {
581 LLVM_DEBUG(dbgs() << "Dom block does not dominate pdom block\n");
582 return;
583 }
584 if (!MPT.dominates(PDomB, DomB)) {
585 LLVM_DEBUG(dbgs() << "PDom block does not post-dominate dom block\n");
586 return;
587 }
588
589 // Finally, everything seems right.
590 PrologB = DomB;
591 EpilogB = PDomB;
592}
593
594/// Perform most of the PEI work here:
595/// - saving/restoring of the callee-saved registers,
596/// - stack frame creation and destruction.
597/// Normally, this work is distributed among various functions, but doing it
598/// in one place allows shrink-wrapping of the stack frame.
600 MachineBasicBlock &MBB) const {
601 auto &HRI = *MF.getSubtarget<HexagonSubtarget>().getRegisterInfo();
602
603 MachineFrameInfo &MFI = MF.getFrameInfo();
604 const std::vector<CalleeSavedInfo> &CSI = MFI.getCalleeSavedInfo();
605
606 MachineBasicBlock *PrologB = &MF.front(), *EpilogB = nullptr;
608 findShrunkPrologEpilog(MF, PrologB, EpilogB);
609
610 bool PrologueStubs = false;
611 insertCSRSpillsInBlock(*PrologB, CSI, HRI, PrologueStubs);
612 insertPrologueInBlock(*PrologB, PrologueStubs);
613 // Insert the SCS prologue after all FrameSetup instructions so that it
614 // follows allocframe and any CSR spills in the instruction stream. The
615 // packetizer may still fuse the SCS store with the first call in the
616 // function, but because Hexagon packets use old-value reads the original
617 // R31 is always what is stored.
618 {
619 MachineBasicBlock::iterator AfterProlog = PrologB->begin();
620 while (AfterProlog != PrologB->end() &&
621 AfterProlog->getFlag(MachineInstr::FrameSetup))
622 ++AfterProlog;
623 DebugLoc PrologDL = PrologB->findDebugLoc(AfterProlog);
624 emitSCSPrologue(MF, *PrologB, AfterProlog, PrologDL);
625 }
626 updateEntryPaths(MF, *PrologB);
627
628 if (EpilogB) {
629 insertCSRRestoresInBlock(*EpilogB, CSI, HRI);
630 insertEpilogueInBlock(*EpilogB);
631 } else {
632 for (auto &B : MF)
633 if (B.isReturnBlock())
634 insertCSRRestoresInBlock(B, CSI, HRI);
635
636 for (auto &B : MF)
637 if (B.isReturnBlock())
638 insertEpilogueInBlock(B);
639
640 for (auto &B : MF) {
641 if (B.empty())
642 continue;
643 MachineInstr *RetI = getReturn(B);
644 if (!RetI || isRestoreCall(RetI->getOpcode()))
645 continue;
646 for (auto &R : CSI)
647 RetI->addOperand(MachineOperand::CreateReg(R.getReg(), false, true));
648 }
649 }
650
651 if (EpilogB) {
652 // If there is an epilog block, it may not have a return instruction.
653 // In such case, we need to add the callee-saved registers as live-ins
654 // in all blocks on all paths from the epilog to any return block.
655 unsigned MaxBN = MF.getNumBlockIDs();
656 BitVector DoneT(MaxBN+1), DoneF(MaxBN+1), Path(MaxBN+1);
657 updateExitPaths(*EpilogB, *EpilogB, DoneT, DoneF, Path);
658 }
659}
660
661/// Returns true if the target can safely skip saving callee-saved registers
662/// for noreturn nounwind functions.
664 const MachineFunction &MF) const {
665 const auto &F = MF.getFunction();
666 assert(F.hasFnAttribute(Attribute::NoReturn) &&
667 F.getFunction().hasFnAttribute(Attribute::NoUnwind) &&
668 !F.getFunction().hasFnAttribute(Attribute::UWTable));
669 (void)F;
670
671 // No need to save callee saved registers if the function does not return.
672 return MF.getSubtarget<HexagonSubtarget>().noreturnStackElim();
673}
674
675// Helper function used to determine when to eliminate the stack frame for
676// functions marked as noreturn and when the noreturn-stack-elim options are
677// specified. When both these conditions are true, then a FP may not be needed
678// if the function makes a call. It is very similar to enableCalleeSaveSkip,
679// but it used to check if the allocframe can be eliminated as well.
680static bool enableAllocFrameElim(const MachineFunction &MF) {
681 const auto &F = MF.getFunction();
682 const auto &MFI = MF.getFrameInfo();
683 const auto &HST = MF.getSubtarget<HexagonSubtarget>();
684 assert(!MFI.hasVarSizedObjects() &&
685 !HST.getRegisterInfo()->hasStackRealignment(MF));
686 return F.hasFnAttribute(Attribute::NoReturn) &&
687 F.hasFnAttribute(Attribute::NoUnwind) &&
688 !F.hasFnAttribute(Attribute::UWTable) && HST.noreturnStackElim() &&
689 MFI.getStackSize() == 0;
690}
691
692void HexagonFrameLowering::insertPrologueInBlock(MachineBasicBlock &MBB,
693 bool PrologueStubs) const {
694 MachineFunction &MF = *MBB.getParent();
695 MachineFrameInfo &MFI = MF.getFrameInfo();
696 auto &HST = MF.getSubtarget<HexagonSubtarget>();
697 auto &HII = *HST.getInstrInfo();
698 auto &HRI = *HST.getRegisterInfo();
699
700 Align MaxAlign = std::max(MFI.getMaxAlign(), getStackAlign());
701
702 // Calculate the total stack frame size.
703 // Get the number of bytes to allocate from the FrameInfo.
704 unsigned FrameSize = MFI.getStackSize();
705 // Round up the max call frame size to the max alignment on the stack.
706 unsigned MaxCFA = alignTo(MFI.getMaxCallFrameSize(), MaxAlign);
707 MFI.setMaxCallFrameSize(MaxCFA);
708
709 FrameSize = MaxCFA + alignTo(FrameSize, MaxAlign);
710 MFI.setStackSize(FrameSize);
711
712 bool AlignStack = (MaxAlign > getStackAlign());
713
714 // Get the number of bytes to allocate from the FrameInfo.
715 unsigned NumBytes = MFI.getStackSize();
716 Register SP = HRI.getStackRegister();
717 unsigned MaxCF = MFI.getMaxCallFrameSize();
719
720 SmallVector<MachineInstr *, 4> AdjustRegs;
721 for (auto &MBB : MF)
722 for (auto &MI : MBB)
723 if (MI.getOpcode() == Hexagon::PS_alloca)
724 AdjustRegs.push_back(&MI);
725
726 for (auto *MI : AdjustRegs) {
727 assert((MI->getOpcode() == Hexagon::PS_alloca) && "Expected alloca");
728 expandAlloca(MI, MF, HII, SP, MaxCF);
729 MI->eraseFromParent();
730 }
731
732 DebugLoc dl = MBB.findDebugLoc(InsertPt);
733
734 if (MF.getFunction().isVarArg() &&
735 MF.getSubtarget<HexagonSubtarget>().isEnvironmentMusl()) {
736 // Calculate the size of register saved area.
737 int NumVarArgRegs = 6 - FirstVarArgSavedReg;
738 int RegisterSavedAreaSizePlusPadding = (NumVarArgRegs % 2 == 0)
739 ? NumVarArgRegs * 4
740 : NumVarArgRegs * 4 + 4;
741 if (RegisterSavedAreaSizePlusPadding > 0) {
742 // Decrement the stack pointer by size of register saved area plus
743 // padding if any.
744 BuildMI(MBB, InsertPt, dl, HII.get(Hexagon::A2_addi), SP)
745 .addReg(SP)
746 .addImm(-RegisterSavedAreaSizePlusPadding)
748
749 int NumBytes = 0;
750 // Copy all the named arguments below register saved area.
751 auto &HMFI = *MF.getInfo<HexagonMachineFunctionInfo>();
752 for (int i = HMFI.getFirstNamedArgFrameIndex(),
753 e = HMFI.getLastNamedArgFrameIndex(); i >= e; --i) {
754 uint64_t ObjSize = MFI.getObjectSize(i);
755 Align ObjAlign = MFI.getObjectAlign(i);
756
757 // Determine the kind of load/store that should be used.
758 unsigned LDOpc, STOpc;
759 uint64_t OpcodeChecker = ObjAlign.value();
760
761 // Handle cases where alignment of an object is > its size.
762 if (ObjAlign > ObjSize) {
763 if (ObjSize <= 1)
764 OpcodeChecker = 1;
765 else if (ObjSize <= 2)
766 OpcodeChecker = 2;
767 else if (ObjSize <= 4)
768 OpcodeChecker = 4;
769 else if (ObjSize > 4)
770 OpcodeChecker = 8;
771 }
772
773 switch (OpcodeChecker) {
774 case 1:
775 LDOpc = Hexagon::L2_loadrb_io;
776 STOpc = Hexagon::S2_storerb_io;
777 break;
778 case 2:
779 LDOpc = Hexagon::L2_loadrh_io;
780 STOpc = Hexagon::S2_storerh_io;
781 break;
782 case 4:
783 LDOpc = Hexagon::L2_loadri_io;
784 STOpc = Hexagon::S2_storeri_io;
785 break;
786 case 8:
787 default:
788 LDOpc = Hexagon::L2_loadrd_io;
789 STOpc = Hexagon::S2_storerd_io;
790 break;
791 }
792
793 Register RegUsed = LDOpc == Hexagon::L2_loadrd_io ? Hexagon::D3
794 : Hexagon::R6;
795 int LoadStoreCount = ObjSize / OpcodeChecker;
796
797 if (ObjSize % OpcodeChecker)
798 ++LoadStoreCount;
799
800 // Get the start location of the load. NumBytes is basically the
801 // offset from the stack pointer of previous function, which would be
802 // the caller in this case, as this function has variable argument
803 // list.
804 if (NumBytes != 0)
805 NumBytes = alignTo(NumBytes, ObjAlign);
806
807 int Count = 0;
808 while (Count < LoadStoreCount) {
809 // Load the value of the named argument on stack.
810 BuildMI(MBB, InsertPt, dl, HII.get(LDOpc), RegUsed)
811 .addReg(SP)
812 .addImm(RegisterSavedAreaSizePlusPadding +
813 ObjAlign.value() * Count + NumBytes)
815
816 // Store it below the register saved area plus padding.
817 BuildMI(MBB, InsertPt, dl, HII.get(STOpc))
818 .addReg(SP)
819 .addImm(ObjAlign.value() * Count + NumBytes)
820 .addReg(RegUsed)
822
823 Count++;
824 }
825 NumBytes += MFI.getObjectSize(i);
826 }
827
828 // Make NumBytes 8 byte aligned
829 NumBytes = alignTo(NumBytes, 8);
830
831 // If the number of registers having variable arguments is odd,
832 // leave 4 bytes of padding to get to the location where first
833 // variable argument which was passed through register was copied.
834 NumBytes = (NumVarArgRegs % 2 == 0) ? NumBytes : NumBytes + 4;
835
836 for (int j = FirstVarArgSavedReg, i = 0; j < 6; ++j, ++i) {
837 BuildMI(MBB, InsertPt, dl, HII.get(Hexagon::S2_storeri_io))
838 .addReg(SP)
839 .addImm(NumBytes + 4 * i)
840 .addReg(Hexagon::R0 + j)
842 }
843 }
844 }
845
846 if (hasFP(MF)) {
847 insertAllocframe(MBB, InsertPt, NumBytes);
848 if (AlignStack) {
849 BuildMI(MBB, InsertPt, dl, HII.get(Hexagon::A2_andir), SP)
850 .addReg(SP)
851 .addImm(-int64_t(MaxAlign.value()));
852 }
853 // If the stack-checking is enabled, and we spilled the callee-saved
854 // registers inline (i.e. did not use a spill function), then call
855 // the stack checker directly.
856 if (EnableStackOVFSanitizer && !PrologueStubs)
857 BuildMI(MBB, InsertPt, dl, HII.get(Hexagon::PS_call_stk))
858 .addExternalSymbol("__runtime_stack_check");
859 } else if (NumBytes > 0) {
860 assert(alignTo(NumBytes, 8) == NumBytes);
861 auto *TLI = HST.getTargetLowering();
862 bool NeedsProbing = TLI->hasInlineStackProbe(MF);
863 unsigned ProbeSize = 0;
864 if (NeedsProbing) {
865 Align StackAlign = getStackAlign();
866 ProbeSize = TLI->getStackProbeSize(MF, StackAlign);
867 }
868 if (NeedsProbing && NumBytes > ProbeSize) {
869 // Compute target SP in R28 (caller-saved scratch).
870 BuildMI(MBB, InsertPt, dl, HII.get(Hexagon::A2_addi), Hexagon::R28)
871 .addReg(SP)
872 .addImm(-int(NumBytes))
874 // Emit pseudo to be expanded by inlineStackProbe().
875 BuildMI(MBB, InsertPt, dl, HII.get(Hexagon::PS_probed_stackalloc))
876 .addReg(Hexagon::R28)
878 } else {
879 BuildMI(MBB, InsertPt, dl, HII.get(Hexagon::A2_addi), SP)
880 .addReg(SP)
881 .addImm(-int(NumBytes))
883 }
884 }
885}
886
887void HexagonFrameLowering::insertEpilogueInBlock(MachineBasicBlock &MBB) const {
888 MachineFunction &MF = *MBB.getParent();
889 auto &HST = MF.getSubtarget<HexagonSubtarget>();
890 auto &HII = *HST.getInstrInfo();
891 auto &HRI = *HST.getRegisterInfo();
892 Register SP = HRI.getStackRegister();
893
895 DebugLoc dl = MBB.findDebugLoc(InsertPt);
896
897 if (!hasFP(MF)) {
898 MachineFrameInfo &MFI = MF.getFrameInfo();
899 unsigned NumBytes = MFI.getStackSize();
900 if (MF.getFunction().isVarArg() &&
901 MF.getSubtarget<HexagonSubtarget>().isEnvironmentMusl()) {
902 // On Hexagon Linux, deallocate the stack for the register saved area.
903 int NumVarArgRegs = 6 - FirstVarArgSavedReg;
904 int RegisterSavedAreaSizePlusPadding = (NumVarArgRegs % 2 == 0) ?
905 (NumVarArgRegs * 4) : (NumVarArgRegs * 4 + 4);
906 NumBytes += RegisterSavedAreaSizePlusPadding;
907 }
908 if (NumBytes) {
909 BuildMI(MBB, InsertPt, dl, HII.get(Hexagon::A2_addi), SP)
910 .addReg(SP)
911 .addImm(NumBytes);
912 }
913 return;
914 }
915
916 MachineInstr *RetI = getReturn(MBB);
917 unsigned RetOpc = RetI ? RetI->getOpcode() : 0;
918
919 // Handle EH_RETURN.
920 if (RetOpc == Hexagon::EH_RETURN_JMPR) {
921 // EH paths overwrite R31 with a handler address; the shadow stack is
922 // not read on this path, so no SCS epilogue is needed.
923 BuildMI(MBB, InsertPt, dl, HII.get(Hexagon::L2_deallocframe))
924 .addDef(Hexagon::D15)
925 .addReg(Hexagon::R30);
926 BuildMI(MBB, InsertPt, dl, HII.get(Hexagon::A2_add), SP)
927 .addReg(SP)
928 .addReg(Hexagon::R28);
929 return;
930 }
931
932 // Check for RESTORE_DEALLOC_RET* tail call. Don't emit an extra dealloc-
933 // frame instruction if we encounter it.
934 // These are restore stubs, which useRestoreFunction() never selects when SCS
935 // is active (they do deallocframe+jumpr, bypassing the SCS epilogue), so no
936 // SCS epilogue is needed here.
937 if (RetOpc == Hexagon::RESTORE_DEALLOC_RET_JMP_V4 ||
938 RetOpc == Hexagon::RESTORE_DEALLOC_RET_JMP_V4_PIC ||
939 RetOpc == Hexagon::RESTORE_DEALLOC_RET_JMP_V4_EXT ||
940 RetOpc == Hexagon::RESTORE_DEALLOC_RET_JMP_V4_EXT_PIC) {
942 ++It;
943 // Delete all instructions after the RESTORE (except labels).
944 while (It != MBB.end()) {
945 if (!It->isLabel())
946 It = MBB.erase(It);
947 else
948 ++It;
949 }
950 return;
951 }
952
953 // It is possible that the restoring code is a call to a library function.
954 // All of the restore* functions include "deallocframe", so we need to make
955 // sure that we don't add an extra one.
956 bool NeedsSCS = MF.getFunction().hasFnAttribute(Attribute::ShadowCallStack);
957 bool NeedsDeallocframe = true;
958 unsigned PrevOpc = 0;
959 if (!MBB.empty() && InsertPt != MBB.begin()) {
960 MachineBasicBlock::iterator PrevIt = std::prev(InsertPt);
961 PrevOpc = PrevIt->getOpcode();
962 if (PrevOpc == Hexagon::RESTORE_DEALLOC_BEFORE_TAILCALL_V4 ||
963 PrevOpc == Hexagon::RESTORE_DEALLOC_BEFORE_TAILCALL_V4_PIC ||
964 PrevOpc == Hexagon::RESTORE_DEALLOC_BEFORE_TAILCALL_V4_EXT ||
965 PrevOpc == Hexagon::RESTORE_DEALLOC_BEFORE_TAILCALL_V4_EXT_PIC ||
966 PrevOpc == Hexagon::PS_call_nr || PrevOpc == Hexagon::PS_callr_nr)
967 NeedsDeallocframe = false;
968 }
969
970 if (!MF.getSubtarget<HexagonSubtarget>().isEnvironmentMusl() ||
971 !MF.getFunction().isVarArg()) {
972 if (!NeedsDeallocframe) {
973 // RESTORE_DEALLOC_BEFORE_TAILCALL is a restore stub, which
974 // useRestoreFunction() never selects when SCS is active.
975 // PS_call_nr/PS_callr_nr are noreturn calls so the shadow stack entry
976 // is never read - no SCS epilogue is needed on either path.
977 if (NeedsSCS && PrevOpc != Hexagon::PS_call_nr &&
978 PrevOpc != Hexagon::PS_callr_nr)
979 report_fatal_error("SCS with RESTORE_DEALLOC stub: "
980 "useRestoreFunction() should have prevented this");
981 return;
982 }
983 // If the returning instruction is PS_jmpret, replace it with
984 // dealloc_return, otherwise just add deallocframe. The function
985 // could be returning via a tail call.
986 if (RetOpc != Hexagon::PS_jmpret || DisableDeallocRet || NeedsSCS) {
987 BuildMI(MBB, InsertPt, dl, HII.get(Hexagon::L2_deallocframe))
988 .addDef(Hexagon::D15)
989 .addReg(Hexagon::R30);
990 // When shadow call stack is active, overwrite R31 restored by
991 // deallocframe with the shadow-stack copy, then retract the pointer.
992 if (NeedsSCS)
993 emitSCSEpilogue(MF, MBB, InsertPt, dl);
994 return;
995 }
996 unsigned NewOpc = Hexagon::L4_return;
997 MachineInstr *NewI = BuildMI(MBB, RetI, dl, HII.get(NewOpc))
998 .addDef(Hexagon::D15)
999 .addReg(Hexagon::R30);
1000 // Transfer the function live-out registers.
1001 NewI->copyImplicitOps(MF, *RetI);
1002 MBB.erase(RetI);
1003 } else {
1004 // L2_deallocframe instruction after it.
1005 // Calculate the size of register saved area.
1006 int NumVarArgRegs = 6 - FirstVarArgSavedReg;
1007 int RegisterSavedAreaSizePlusPadding = (NumVarArgRegs % 2 == 0) ?
1008 (NumVarArgRegs * 4) : (NumVarArgRegs * 4 + 4);
1009
1012 : std::prev(Term);
1013 bool HasRestoreStub =
1014 I != MBB.end() &&
1015 (I->getOpcode() == Hexagon::RESTORE_DEALLOC_BEFORE_TAILCALL_V4_EXT ||
1016 I->getOpcode() ==
1017 Hexagon::RESTORE_DEALLOC_BEFORE_TAILCALL_V4_EXT_PIC ||
1018 I->getOpcode() == Hexagon::RESTORE_DEALLOC_BEFORE_TAILCALL_V4 ||
1019 I->getOpcode() == Hexagon::RESTORE_DEALLOC_BEFORE_TAILCALL_V4_PIC);
1020 if (!HasRestoreStub)
1021 BuildMI(MBB, InsertPt, dl, HII.get(Hexagon::L2_deallocframe))
1022 .addDef(Hexagon::D15)
1023 .addReg(Hexagon::R30);
1024 if (RegisterSavedAreaSizePlusPadding != 0)
1025 BuildMI(MBB, InsertPt, dl, HII.get(Hexagon::A2_addi), SP)
1026 .addReg(SP)
1027 .addImm(RegisterSavedAreaSizePlusPadding);
1028 // RESTORE_DEALLOC stubs are never selected when SCS is active (see
1029 // useRestoreFunction()), so only emit the SCS epilogue when we emitted
1030 // our own deallocframe above.
1031 if (NeedsSCS && !HasRestoreStub)
1032 emitSCSEpilogue(MF, MBB, InsertPt, dl);
1033 }
1034}
1035
1036void HexagonFrameLowering::insertAllocframe(MachineBasicBlock &MBB,
1037 MachineBasicBlock::iterator InsertPt, unsigned NumBytes) const {
1038 MachineFunction &MF = *MBB.getParent();
1039 auto &HST = MF.getSubtarget<HexagonSubtarget>();
1040 auto &HII = *HST.getInstrInfo();
1041 auto &HRI = *HST.getRegisterInfo();
1042
1043 // Check for overflow.
1044 // Hexagon_TODO: Ugh! hardcoding. Is there an API that can be used?
1045 const unsigned int ALLOCFRAME_MAX = 16384;
1046
1047 // Create a dummy memory operand to avoid allocframe from being treated as
1048 // a volatile memory reference.
1051
1052 DebugLoc dl = MBB.findDebugLoc(InsertPt);
1053 Register SP = HRI.getStackRegister();
1054
1055 auto *TLI = HST.getTargetLowering();
1056 bool NeedsProbing = TLI->hasInlineStackProbe(MF) && NumBytes > 0;
1057 unsigned ProbeSize = 0;
1058 if (NeedsProbing) {
1059 Align StackAlign = getStackAlign();
1060 ProbeSize = TLI->getStackProbeSize(MF, StackAlign);
1061 }
1062
1063 if (NeedsProbing && NumBytes > ProbeSize) {
1064 // Emit allocframe(#0) to save FP/LR only.
1065 BuildMI(MBB, InsertPt, dl, HII.get(Hexagon::S2_allocframe))
1066 .addDef(SP)
1067 .addReg(SP)
1068 .addImm(0)
1069 .addMemOperand(MMO)
1071
1072 // Compute target SP in R28 (caller-saved scratch).
1073 BuildMI(MBB, InsertPt, dl, HII.get(Hexagon::A2_addi), Hexagon::R28)
1074 .addReg(SP)
1075 .addImm(-int(NumBytes))
1077
1078 // Emit pseudo to be expanded by inlineStackProbe().
1079 BuildMI(MBB, InsertPt, dl, HII.get(Hexagon::PS_probed_stackalloc))
1080 .addReg(Hexagon::R28)
1082 } else if (NumBytes >= ALLOCFRAME_MAX) {
1083 // Emit allocframe(#0).
1084 BuildMI(MBB, InsertPt, dl, HII.get(Hexagon::S2_allocframe))
1085 .addDef(SP)
1086 .addReg(SP)
1087 .addImm(0)
1088 .addMemOperand(MMO)
1090
1091 // Subtract the size from the stack pointer.
1092 Register SP = HRI.getStackRegister();
1093 BuildMI(MBB, InsertPt, dl, HII.get(Hexagon::A2_addi), SP)
1094 .addReg(SP)
1095 .addImm(-int(NumBytes))
1097 } else {
1098 BuildMI(MBB, InsertPt, dl, HII.get(Hexagon::S2_allocframe))
1099 .addDef(SP)
1100 .addReg(SP)
1101 .addImm(NumBytes)
1102 .addMemOperand(MMO)
1104 }
1105}
1106
1108 MachineFunction &MF, MachineBasicBlock &PrologueMBB) const {
1109 // Collect PS_probed_stackalloc pseudos to expand. Collecting first avoids
1110 // issues with modifying the block while iterating.
1112 for (MachineInstr &MI : PrologueMBB)
1113 if (MI.getOpcode() == Hexagon::PS_probed_stackalloc)
1114 ToReplace.push_back(&MI);
1115
1116 auto &HST = MF.getSubtarget<HexagonSubtarget>();
1117 auto &HII = *HST.getInstrInfo();
1118 auto *TLI = HST.getTargetLowering();
1119 Align StackAlign = getStackAlign();
1120 unsigned ProbeSize = TLI->getStackProbeSize(MF, StackAlign);
1122
1123 for (MachineInstr *MI : ToReplace) {
1124 MachineBasicBlock::iterator MBBI = MI->getIterator();
1125 DebugLoc DL = PrologueMBB.findDebugLoc(MBBI);
1126 Register TargetReg = MI->getOperand(0).getReg();
1127
1128 // Split the block: everything after the pseudo goes into ExitMBB.
1129 MachineBasicBlock *MBB = MI->getParent();
1130 MachineFunction::iterator InsertPt = std::next(MBB->getIterator());
1131 MachineBasicBlock *LoopMBB =
1132 MF.CreateMachineBasicBlock(MBB->getBasicBlock());
1133 MF.insert(InsertPt, LoopMBB);
1134 MachineBasicBlock *ExitMBB =
1135 MF.CreateMachineBasicBlock(MBB->getBasicBlock());
1136 MF.insert(InsertPt, ExitMBB);
1137
1138 // Move everything after the pseudo into ExitMBB.
1139 ExitMBB->splice(ExitMBB->end(), MBB, std::next(MBBI), MBB->end());
1141
1142 // LoopMBB: probe each page by decrementing SP and storing zero.
1143 // When NumBytes is not an exact multiple of ProbeSize the loop
1144 // will overshoot by up to ProbeSize-1 bytes; the final r29 = r28
1145 // in ExitMBB corrects SP to the true target.
1146 //
1147 // The store is placed before the compare+branch so that the
1148 // packetizer can bundle them into a single VLIW packet. All
1149 // non-predicated instructions in a packet commit unconditionally,
1150 // so the probe store executes on every iteration including the
1151 // last (when the branch falls through).
1152 //
1153 // r29 = add(r29, #-ProbeSize)
1154 // memw(r29+#0) = #0
1155 // p0 = cmp.gtu(r29, r28)
1156 // if (p0) jump LoopMBB
1157 BuildMI(*LoopMBB, LoopMBB->end(), DL, HII.get(Hexagon::A2_addi),
1158 Hexagon::R29)
1159 .addReg(Hexagon::R29)
1160 .addImm(-int(ProbeSize))
1161 .setMIFlags(Flags);
1162
1163 BuildMI(*LoopMBB, LoopMBB->end(), DL, HII.get(Hexagon::S4_storeiri_io))
1164 .addReg(Hexagon::R29)
1165 .addImm(0)
1166 .addImm(0)
1167 .setMIFlags(Flags);
1168
1169 BuildMI(*LoopMBB, LoopMBB->end(), DL, HII.get(Hexagon::C2_cmpgtu),
1170 Hexagon::P0)
1171 .addReg(Hexagon::R29)
1172 .addReg(TargetReg)
1173 .setMIFlags(Flags);
1174
1175 BuildMI(*LoopMBB, LoopMBB->end(), DL, HII.get(Hexagon::J2_jumpt))
1176 .addReg(Hexagon::P0)
1177 .addMBB(LoopMBB)
1178 .setMIFlags(Flags);
1179
1180 // ExitMBB: set final SP.
1181 BuildMI(*ExitMBB, ExitMBB->begin(), DL, HII.get(Hexagon::A2_tfr),
1182 Hexagon::R29)
1183 .addReg(TargetReg)
1184 .setMIFlags(Flags);
1185
1186 // Set up CFG edges.
1187 MBB->addSuccessor(LoopMBB);
1188 LoopMBB->addSuccessor(LoopMBB);
1189 LoopMBB->addSuccessor(ExitMBB);
1190
1191 // Remove the pseudo.
1192 MI->eraseFromParent();
1193
1194 // Recompute live-ins for the new blocks.
1195 fullyRecomputeLiveIns({ExitMBB, LoopMBB});
1196 }
1197}
1198
1199void HexagonFrameLowering::updateEntryPaths(MachineFunction &MF,
1200 MachineBasicBlock &SaveB) const {
1201 SetVector<unsigned> Worklist;
1202
1203 MachineBasicBlock &EntryB = MF.front();
1204 Worklist.insert(EntryB.getNumber());
1205
1206 unsigned SaveN = SaveB.getNumber();
1207 auto &CSI = MF.getFrameInfo().getCalleeSavedInfo();
1208
1209 for (unsigned i = 0; i < Worklist.size(); ++i) {
1210 unsigned BN = Worklist[i];
1212 for (auto &R : CSI)
1213 if (!MBB.isLiveIn(R.getReg()))
1214 MBB.addLiveIn(R.getReg());
1215 if (BN != SaveN)
1216 for (auto &SB : MBB.successors())
1217 Worklist.insert(SB->getNumber());
1218 }
1219}
1220
1221bool HexagonFrameLowering::updateExitPaths(MachineBasicBlock &MBB,
1222 MachineBasicBlock &RestoreB, BitVector &DoneT, BitVector &DoneF,
1223 BitVector &Path) const {
1224 assert(MBB.getNumber() >= 0);
1225 unsigned BN = MBB.getNumber();
1226 if (Path[BN] || DoneF[BN])
1227 return false;
1228 if (DoneT[BN])
1229 return true;
1230
1231 auto &CSI = MBB.getParent()->getFrameInfo().getCalleeSavedInfo();
1232
1233 Path[BN] = true;
1234 bool ReachedExit = false;
1235 for (auto &SB : MBB.successors())
1236 ReachedExit |= updateExitPaths(*SB, RestoreB, DoneT, DoneF, Path);
1237
1238 if (!MBB.empty() && MBB.back().isReturn()) {
1239 // Add implicit uses of all callee-saved registers to the reached
1240 // return instructions. This is to prevent the anti-dependency breaker
1241 // from renaming these registers.
1242 MachineInstr &RetI = MBB.back();
1243 if (!isRestoreCall(RetI.getOpcode()))
1244 for (auto &R : CSI)
1245 RetI.addOperand(MachineOperand::CreateReg(R.getReg(), false, true));
1246 ReachedExit = true;
1247 }
1248
1249 // We don't want to add unnecessary live-ins to the restore block: since
1250 // the callee-saved registers are being defined in it, the entry of the
1251 // restore block cannot be on the path from the definitions to any exit.
1252 if (ReachedExit && &MBB != &RestoreB) {
1253 for (auto &R : CSI)
1254 if (!MBB.isLiveIn(R.getReg()))
1255 MBB.addLiveIn(R.getReg());
1256 DoneT[BN] = true;
1257 }
1258 if (!ReachedExit)
1259 DoneF[BN] = true;
1260
1261 Path[BN] = false;
1262 return ReachedExit;
1263}
1264
1265static std::optional<MachineBasicBlock::iterator>
1267 // The CFI instructions need to be inserted right after allocframe.
1268 // An exception to this is a situation where allocframe is bundled
1269 // with a call: then the CFI instructions need to be inserted before
1270 // the packet with the allocframe+call (in case the call throws an
1271 // exception).
1272 auto End = B.instr_end();
1273
1274 for (MachineInstr &I : B) {
1275 MachineBasicBlock::iterator It = I.getIterator();
1276 if (!I.isBundle()) {
1277 if (I.getOpcode() == Hexagon::S2_allocframe)
1278 return std::next(It);
1279 continue;
1280 }
1281 // I is a bundle.
1282 bool HasCall = false, HasAllocFrame = false;
1283 auto T = It.getInstrIterator();
1284 while (++T != End && T->isBundled()) {
1285 if (T->getOpcode() == Hexagon::S2_allocframe)
1286 HasAllocFrame = true;
1287 else if (T->isCall())
1288 HasCall = true;
1289 }
1290 if (HasAllocFrame)
1291 return HasCall ? It : std::next(It);
1292 }
1293 return std::nullopt;
1294}
1295
1297 for (auto &B : MF)
1298 if (auto At = findCFILocation(B))
1299 insertCFIInstructionsAt(B, *At);
1300}
1301
1302void HexagonFrameLowering::insertCFIInstructionsAt(MachineBasicBlock &MBB,
1303 MachineBasicBlock::iterator At) const {
1304 MachineFunction &MF = *MBB.getParent();
1305 MachineFrameInfo &MFI = MF.getFrameInfo();
1306 auto &HST = MF.getSubtarget<HexagonSubtarget>();
1307 auto &HII = *HST.getInstrInfo();
1308 auto &HRI = *HST.getRegisterInfo();
1309
1310 // If CFI instructions have debug information attached, something goes
1311 // wrong with the final assembly generation: the prolog_end is placed
1312 // in a wrong location.
1313 DebugLoc DL;
1314 const MCInstrDesc &CFID = HII.get(TargetOpcode::CFI_INSTRUCTION);
1315
1316 MCSymbol *FrameLabel = MF.getContext().createTempSymbol();
1317 bool HasFP = hasFP(MF);
1318
1319 if (HasFP) {
1320 unsigned DwFPReg = HRI.getDwarfRegNum(HRI.getFrameRegister(), true);
1321 unsigned DwRAReg = HRI.getDwarfRegNum(HRI.getRARegister(), true);
1322
1323 // Define CFA via an offset from the value of FP.
1324 //
1325 // -8 -4 0 (SP)
1326 // --+----+----+---------------------
1327 // | FP | LR | increasing addresses -->
1328 // --+----+----+---------------------
1329 // | +-- Old SP (before allocframe)
1330 // +-- New FP (after allocframe)
1331 //
1332 // MCCFIInstruction::cfiDefCfa adds the offset from the register.
1333 // MCCFIInstruction::createOffset takes the offset without sign change.
1334 auto DefCfa = MCCFIInstruction::cfiDefCfa(FrameLabel, DwFPReg, 8);
1335 BuildMI(MBB, At, DL, CFID)
1336 .addCFIIndex(MF.addFrameInst(DefCfa));
1337 // R31 (return addr) = CFA - 4
1338 auto OffR31 = MCCFIInstruction::createOffset(FrameLabel, DwRAReg, -4);
1339 BuildMI(MBB, At, DL, CFID)
1340 .addCFIIndex(MF.addFrameInst(OffR31));
1341 // R30 (frame ptr) = CFA - 8
1342 auto OffR30 = MCCFIInstruction::createOffset(FrameLabel, DwFPReg, -8);
1343 BuildMI(MBB, At, DL, CFID)
1344 .addCFIIndex(MF.addFrameInst(OffR30));
1345 }
1346
1347 static const MCPhysReg RegsToMove[] = {
1348 Hexagon::R1, Hexagon::R0, Hexagon::R3, Hexagon::R2,
1349 Hexagon::R17, Hexagon::R16, Hexagon::R19, Hexagon::R18,
1350 Hexagon::R21, Hexagon::R20, Hexagon::R23, Hexagon::R22,
1351 Hexagon::R25, Hexagon::R24, Hexagon::R27, Hexagon::R26,
1352 Hexagon::D0, Hexagon::D1, Hexagon::D8, Hexagon::D9,
1353 Hexagon::D10, Hexagon::D11, Hexagon::D12, Hexagon::D13
1354 };
1355
1356 const std::vector<CalleeSavedInfo> &CSI = MFI.getCalleeSavedInfo();
1357
1358 for (MCPhysReg Reg : RegsToMove) {
1359 auto IfR = [Reg] (const CalleeSavedInfo &C) -> bool {
1360 return C.getReg() == Reg;
1361 };
1362 auto F = find_if(CSI, IfR);
1363 if (F == CSI.end())
1364 continue;
1365
1366 int64_t Offset;
1367 if (HasFP) {
1368 // If the function has a frame pointer (i.e. has an allocframe),
1369 // then the CFA has been defined in terms of FP. Any offsets in
1370 // the following CFI instructions have to be defined relative
1371 // to FP, which points to the bottom of the stack frame.
1372 // The function getFrameIndexReference can still choose to use SP
1373 // for the offset calculation, so we cannot simply call it here.
1374 // Instead, get the offset (relative to the FP) directly.
1375 Offset = MFI.getObjectOffset(F->getFrameIdx());
1376 } else {
1377 Register FrameReg;
1378 Offset =
1379 getFrameIndexReference(MF, F->getFrameIdx(), FrameReg).getFixed();
1380 }
1381 // Subtract 8 to make room for R30 and R31, which are added above.
1382 Offset -= 8;
1383
1384 if (Reg < Hexagon::D0 || Reg > Hexagon::D15) {
1385 unsigned DwarfReg = HRI.getDwarfRegNum(Reg, true);
1386 auto OffReg = MCCFIInstruction::createOffset(FrameLabel, DwarfReg,
1387 Offset);
1388 BuildMI(MBB, At, DL, CFID)
1389 .addCFIIndex(MF.addFrameInst(OffReg));
1390 } else {
1391 // Split the double regs into subregs, and generate appropriate
1392 // cfi_offsets.
1393 // The only reason, we are split double regs is, llvm-mc does not
1394 // understand paired registers for cfi_offset.
1395 // Eg .cfi_offset r1:0, -64
1396
1397 Register HiReg = HRI.getSubReg(Reg, Hexagon::isub_hi);
1398 Register LoReg = HRI.getSubReg(Reg, Hexagon::isub_lo);
1399 unsigned HiDwarfReg = HRI.getDwarfRegNum(HiReg, true);
1400 unsigned LoDwarfReg = HRI.getDwarfRegNum(LoReg, true);
1401 auto OffHi = MCCFIInstruction::createOffset(FrameLabel, HiDwarfReg,
1402 Offset+4);
1403 BuildMI(MBB, At, DL, CFID)
1404 .addCFIIndex(MF.addFrameInst(OffHi));
1405 auto OffLo = MCCFIInstruction::createOffset(FrameLabel, LoDwarfReg,
1406 Offset);
1407 BuildMI(MBB, At, DL, CFID)
1408 .addCFIIndex(MF.addFrameInst(OffLo));
1409 }
1410 }
1411}
1412
1414 auto &MFI = MF.getFrameInfo();
1415 auto &HRI = *MF.getSubtarget<HexagonSubtarget>().getRegisterInfo();
1416 bool HasExtraAlign = HRI.hasStackRealignment(MF);
1417 bool HasAlloca = MFI.hasVarSizedObjects();
1418
1419 // Insert ALLOCFRAME if we need to or at -O0 for the debugger. Think
1420 // that this shouldn't be required, but doing so now because gcc does and
1421 // gdb can't break at the start of the function without it. Will remove if
1422 // this turns out to be a gdb bug.
1423 //
1425 return true;
1426
1427 // By default we want to use SP (since it's always there). FP requires
1428 // some setup (i.e. ALLOCFRAME).
1429 // Both, alloca and stack alignment modify the stack pointer by an
1430 // undetermined value, so we need to save it at the entry to the function
1431 // (i.e. use allocframe).
1432 if (HasAlloca || HasExtraAlign)
1433 return true;
1434
1435 // If FP-elimination is disabled, we have to use FP. This must not be
1436 // gated on stack size: the user/ABI-requested frame pointer is needed
1437 // regardless of whether the function currently has a stack frame.
1438 // Every other target checks DisableFramePointerElim unconditionally.
1439 const TargetMachine &TM = MF.getTarget();
1441 return true;
1442
1443 if (MFI.getStackSize() > 0) {
1445 return true;
1446 }
1447
1448 const auto &HMFI = *MF.getInfo<HexagonMachineFunctionInfo>();
1449 if ((MFI.hasCalls() && !enableAllocFrameElim(MF)) || HMFI.hasClobberLR())
1450 return true;
1451
1452 return false;
1453}
1454
1460
1461static const char *getSpillFunctionFor(Register MaxReg, SpillKind SpillType,
1462 bool Stkchk = false) {
1463 const char * V4SpillToMemoryFunctions[] = {
1464 "__save_r16_through_r17",
1465 "__save_r16_through_r19",
1466 "__save_r16_through_r21",
1467 "__save_r16_through_r23",
1468 "__save_r16_through_r25",
1469 "__save_r16_through_r27" };
1470
1471 const char * V4SpillToMemoryStkchkFunctions[] = {
1472 "__save_r16_through_r17_stkchk",
1473 "__save_r16_through_r19_stkchk",
1474 "__save_r16_through_r21_stkchk",
1475 "__save_r16_through_r23_stkchk",
1476 "__save_r16_through_r25_stkchk",
1477 "__save_r16_through_r27_stkchk" };
1478
1479 const char * V4SpillFromMemoryFunctions[] = {
1480 "__restore_r16_through_r17_and_deallocframe",
1481 "__restore_r16_through_r19_and_deallocframe",
1482 "__restore_r16_through_r21_and_deallocframe",
1483 "__restore_r16_through_r23_and_deallocframe",
1484 "__restore_r16_through_r25_and_deallocframe",
1485 "__restore_r16_through_r27_and_deallocframe" };
1486
1487 const char * V4SpillFromMemoryTailcallFunctions[] = {
1488 "__restore_r16_through_r17_and_deallocframe_before_tailcall",
1489 "__restore_r16_through_r19_and_deallocframe_before_tailcall",
1490 "__restore_r16_through_r21_and_deallocframe_before_tailcall",
1491 "__restore_r16_through_r23_and_deallocframe_before_tailcall",
1492 "__restore_r16_through_r25_and_deallocframe_before_tailcall",
1493 "__restore_r16_through_r27_and_deallocframe_before_tailcall"
1494 };
1495
1496 const char **SpillFunc = nullptr;
1497
1498 switch(SpillType) {
1499 case SK_ToMem:
1500 SpillFunc = Stkchk ? V4SpillToMemoryStkchkFunctions
1501 : V4SpillToMemoryFunctions;
1502 break;
1503 case SK_FromMem:
1504 SpillFunc = V4SpillFromMemoryFunctions;
1505 break;
1506 case SK_FromMemTailcall:
1507 SpillFunc = V4SpillFromMemoryTailcallFunctions;
1508 break;
1509 }
1510 assert(SpillFunc && "Unknown spill kind");
1511
1512 // Spill all callee-saved registers up to the highest register used.
1513 switch (MaxReg) {
1514 case Hexagon::R17:
1515 return SpillFunc[0];
1516 case Hexagon::R19:
1517 return SpillFunc[1];
1518 case Hexagon::R21:
1519 return SpillFunc[2];
1520 case Hexagon::R23:
1521 return SpillFunc[3];
1522 case Hexagon::R25:
1523 return SpillFunc[4];
1524 case Hexagon::R27:
1525 return SpillFunc[5];
1526 default:
1527 llvm_unreachable("Unhandled maximum callee save register");
1528 }
1529 return nullptr;
1530}
1531
1532StackOffset
1534 Register &FrameReg) const {
1535 auto &MFI = MF.getFrameInfo();
1536 auto &HRI = *MF.getSubtarget<HexagonSubtarget>().getRegisterInfo();
1537
1538 int Offset = MFI.getObjectOffset(FI);
1539 bool HasAlloca = MFI.hasVarSizedObjects();
1540 bool HasExtraAlign = HRI.hasStackRealignment(MF);
1541 bool NoOpt = MF.getTarget().getOptLevel() == CodeGenOptLevel::None;
1542
1543 auto &HMFI = *MF.getInfo<HexagonMachineFunctionInfo>();
1544 unsigned FrameSize = MFI.getStackSize();
1545 Register SP = HRI.getStackRegister();
1546 Register FP = HRI.getFrameRegister();
1547 Register AP = HMFI.getStackAlignBaseReg();
1548 // It may happen that AP will be absent even HasAlloca && HasExtraAlign
1549 // is true. HasExtraAlign may be set because of vector spills, without
1550 // aligned locals or aligned outgoing function arguments. Since vector
1551 // spills will ultimately be "unaligned", it is safe to use FP as the
1552 // base register.
1553 // In fact, in such a scenario the stack is actually not required to be
1554 // aligned, although it may end up being aligned anyway, since this
1555 // particular case is not easily detectable. The alignment will be
1556 // unnecessary, but not incorrect.
1557 // Unfortunately there is no quick way to verify that the above is
1558 // indeed the case (and that it's not a result of an error), so just
1559 // assume that missing AP will be replaced by FP.
1560 // (A better fix would be to rematerialize AP from FP and always align
1561 // vector spills.)
1562 bool UseFP = false, UseAP = false; // Default: use SP (except at -O0).
1563 // Use FP at -O0, except when there are objects with extra alignment.
1564 // That additional alignment requirement may cause a pad to be inserted,
1565 // which will make it impossible to use FP to access objects located
1566 // past the pad.
1567 if (NoOpt && !HasExtraAlign)
1568 UseFP = true;
1569 if (MFI.isFixedObjectIndex(FI) || MFI.isObjectPreAllocated(FI)) {
1570 // Fixed and preallocated objects will be located before any padding
1571 // so FP must be used to access them.
1572 UseFP |= (HasAlloca || HasExtraAlign);
1573 } else {
1574 if (HasAlloca) {
1575 if (HasExtraAlign)
1576 UseAP = true;
1577 else
1578 UseFP = true;
1579 }
1580 }
1581
1582 // If FP was picked, then there had better be FP.
1583 bool HasFP = hasFP(MF);
1584 assert((HasFP || !UseFP) && "This function must have frame pointer");
1585
1586 // Having FP implies allocframe. Allocframe will store extra 8 bytes:
1587 // FP/LR. If the base register is used to access an object across these
1588 // 8 bytes, then the offset will need to be adjusted by 8.
1589 //
1590 // After allocframe:
1591 // HexagonISelLowering adds 8 to ---+
1592 // the offsets of all stack-based |
1593 // arguments (*) |
1594 // |
1595 // getObjectOffset < 0 0 8 getObjectOffset >= 8
1596 // ------------------------+-----+------------------------> increasing
1597 // <local objects> |FP/LR| <input arguments> addresses
1598 // -----------------+------+-----+------------------------>
1599 // | |
1600 // SP/AP point --+ +-- FP points here (**)
1601 // somewhere on
1602 // this side of FP/LR
1603 //
1604 // (*) See LowerFormalArguments. The FP/LR is assumed to be present.
1605 // (**) *FP == old-FP. FP+0..7 are the bytes of FP/LR.
1606
1607 // The lowering assumes that FP/LR is present, and so the offsets of
1608 // the formal arguments start at 8. If FP/LR is not there we need to
1609 // reduce the offset by 8.
1610 if (Offset > 0 && !HasFP)
1611 Offset -= 8;
1612
1613 if (UseFP)
1614 FrameReg = FP;
1615 else if (UseAP)
1616 FrameReg = AP;
1617 else
1618 FrameReg = SP;
1619
1620 // Calculate the actual offset in the instruction. If there is no FP
1621 // (in other words, no allocframe), then SP will not be adjusted (i.e.
1622 // there will be no SP -= FrameSize), so the frame size should not be
1623 // added to the calculated offset.
1624 int RealOffset = Offset;
1625 if (!UseFP && !UseAP)
1626 RealOffset = FrameSize+Offset;
1627 return StackOffset::getFixed(RealOffset);
1628}
1629
1630bool HexagonFrameLowering::insertCSRSpillsInBlock(MachineBasicBlock &MBB,
1631 const CSIVect &CSI, const HexagonRegisterInfo &HRI,
1632 bool &PrologueStubs) const {
1633 if (CSI.empty())
1634 return true;
1635
1637 PrologueStubs = false;
1638 MachineFunction &MF = *MBB.getParent();
1639 auto &HST = MF.getSubtarget<HexagonSubtarget>();
1640 auto &HII = *HST.getInstrInfo();
1641
1642 if (useSpillFunction(MF, CSI)) {
1643 PrologueStubs = true;
1644 Register MaxReg = getMaxCalleeSavedReg(CSI, HRI);
1645 bool StkOvrFlowEnabled = EnableStackOVFSanitizer;
1646 const char *SpillFun = getSpillFunctionFor(MaxReg, SK_ToMem,
1647 StkOvrFlowEnabled);
1648 auto &HTM = static_cast<const HexagonTargetMachine&>(MF.getTarget());
1649 bool IsPIC = HTM.isPositionIndependent();
1650 bool LongCalls = HST.useLongCalls() || EnableSaveRestoreLong;
1651
1652 // Call spill function.
1653 DebugLoc DL = MI != MBB.end() ? MI->getDebugLoc() : DebugLoc();
1654 unsigned SpillOpc;
1655 if (StkOvrFlowEnabled) {
1656 if (LongCalls)
1657 SpillOpc = IsPIC ? Hexagon::SAVE_REGISTERS_CALL_V4STK_EXT_PIC
1658 : Hexagon::SAVE_REGISTERS_CALL_V4STK_EXT;
1659 else
1660 SpillOpc = IsPIC ? Hexagon::SAVE_REGISTERS_CALL_V4STK_PIC
1661 : Hexagon::SAVE_REGISTERS_CALL_V4STK;
1662 } else {
1663 if (LongCalls)
1664 SpillOpc = IsPIC ? Hexagon::SAVE_REGISTERS_CALL_V4_EXT_PIC
1665 : Hexagon::SAVE_REGISTERS_CALL_V4_EXT;
1666 else
1667 SpillOpc = IsPIC ? Hexagon::SAVE_REGISTERS_CALL_V4_PIC
1668 : Hexagon::SAVE_REGISTERS_CALL_V4;
1669 }
1670
1671 MachineInstr *SaveRegsCall =
1672 BuildMI(MBB, MI, DL, HII.get(SpillOpc))
1673 .addExternalSymbol(SpillFun);
1674
1675 // Add callee-saved registers as use.
1676 addCalleeSaveRegistersAsImpOperand(SaveRegsCall, CSI, false, true);
1677 // Add live in registers.
1678 for (const CalleeSavedInfo &I : CSI)
1679 MBB.addLiveIn(I.getReg());
1680 } else {
1681 for (const CalleeSavedInfo &I : CSI) {
1682 MCRegister Reg = I.getReg();
1683 // Add live in registers. We treat eh_return callee saved register r0 - r3
1684 // specially. They are not really callee saved registers as they are not
1685 // supposed to be killed.
1686 bool IsKill = !HRI.isEHReturnCalleeSaveReg(Reg);
1687 int FI = I.getFrameIdx();
1688 const TargetRegisterClass *RC = HRI.getMinimalPhysRegClass(Reg);
1689 HII.storeRegToStackSlot(MBB, MI, Reg, IsKill, FI, RC, Register());
1690 if (IsKill)
1691 MBB.addLiveIn(Reg);
1692 }
1693 }
1694
1695 // Move PS_aligna to after all CSR spills (both inline and spill-function
1696 // paths). PS_aligna initializes the AP register (e.g. R16) with an aligned
1697 // value derived from FP. Since AP is a callee-saved register, its original
1698 // value must be saved before it is overwritten, and it must be defined
1699 // before any AP-relative stack accesses.
1700 // MI points to the first non-spill instruction; all spills are before it.
1701 auto &HFI = *MF.getSubtarget<HexagonSubtarget>().getFrameLowering();
1702 if (const MachineInstr *AlignaI = HFI.getAlignaInstr(MF)) {
1703 MachineInstr *AI = const_cast<MachineInstr *>(AlignaI);
1704 // PS_aligna is always created in EntryBB during ISEL. Since PS_aligna
1705 // causes needsStackFrame() to return true, EntryBB will be included in
1706 // the set of blocks needing a frame. Because EntryBB dominates all blocks,
1707 // shrink-wrapping will always place PrologB at EntryBB when PS_aligna
1708 // exists. Therefore, this assertion should always hold.
1709 assert(AI->getParent() == &MBB && "PS_aligna not in prologue block");
1710 MBB.splice(MI, AI->getParent(), AI->getIterator());
1711 }
1712
1713 return true;
1714}
1715
1716bool HexagonFrameLowering::insertCSRRestoresInBlock(MachineBasicBlock &MBB,
1717 const CSIVect &CSI, const HexagonRegisterInfo &HRI) const {
1718 if (CSI.empty())
1719 return false;
1720
1722 MachineFunction &MF = *MBB.getParent();
1723 auto &HST = MF.getSubtarget<HexagonSubtarget>();
1724 auto &HII = *HST.getInstrInfo();
1725
1726 if (useRestoreFunction(MF, CSI)) {
1727 bool HasTC = hasTailCall(MBB) || !hasReturn(MBB);
1728 Register MaxR = getMaxCalleeSavedReg(CSI, HRI);
1730 const char *RestoreFn = getSpillFunctionFor(MaxR, Kind);
1731 auto &HTM = static_cast<const HexagonTargetMachine&>(MF.getTarget());
1732 bool IsPIC = HTM.isPositionIndependent();
1733 bool LongCalls = HST.useLongCalls() || EnableSaveRestoreLong;
1734
1735 // Call spill function.
1736 DebugLoc DL = MI != MBB.end() ? MI->getDebugLoc()
1737 : MBB.findDebugLoc(MBB.end());
1738 MachineInstr *DeallocCall = nullptr;
1739
1740 if (HasTC) {
1741 unsigned RetOpc;
1742 if (LongCalls)
1743 RetOpc = IsPIC ? Hexagon::RESTORE_DEALLOC_BEFORE_TAILCALL_V4_EXT_PIC
1744 : Hexagon::RESTORE_DEALLOC_BEFORE_TAILCALL_V4_EXT;
1745 else
1746 RetOpc = IsPIC ? Hexagon::RESTORE_DEALLOC_BEFORE_TAILCALL_V4_PIC
1747 : Hexagon::RESTORE_DEALLOC_BEFORE_TAILCALL_V4;
1748 DeallocCall = BuildMI(MBB, MI, DL, HII.get(RetOpc))
1749 .addExternalSymbol(RestoreFn);
1750 } else {
1751 // The block has a return.
1753 assert(It->isReturn() && std::next(It) == MBB.end());
1754 unsigned RetOpc;
1755 if (LongCalls)
1756 RetOpc = IsPIC ? Hexagon::RESTORE_DEALLOC_RET_JMP_V4_EXT_PIC
1757 : Hexagon::RESTORE_DEALLOC_RET_JMP_V4_EXT;
1758 else
1759 RetOpc = IsPIC ? Hexagon::RESTORE_DEALLOC_RET_JMP_V4_PIC
1760 : Hexagon::RESTORE_DEALLOC_RET_JMP_V4;
1761 DeallocCall = BuildMI(MBB, It, DL, HII.get(RetOpc))
1762 .addExternalSymbol(RestoreFn);
1763 // Transfer the function live-out registers.
1764 DeallocCall->copyImplicitOps(MF, *It);
1765 }
1766 addCalleeSaveRegistersAsImpOperand(DeallocCall, CSI, true, false);
1767 return true;
1768 }
1769
1770 for (const CalleeSavedInfo &I : CSI) {
1771 MCRegister Reg = I.getReg();
1772 const TargetRegisterClass *RC = HRI.getMinimalPhysRegClass(Reg);
1773 int FI = I.getFrameIdx();
1774 HII.loadRegFromStackSlot(MBB, MI, Reg, FI, RC, Register());
1775 }
1776
1777 return true;
1778}
1779
1783 MachineInstr &MI = *I;
1784 unsigned Opc = MI.getOpcode();
1785 (void)Opc; // Silence compiler warning.
1786 assert((Opc == Hexagon::ADJCALLSTACKDOWN || Opc == Hexagon::ADJCALLSTACKUP) &&
1787 "Cannot handle this call frame pseudo instruction");
1788 return MBB.erase(I);
1789}
1790
1792 MachineFunction &MF, RegScavenger *RS) const {
1793 // If this function has uses aligned stack and also has variable sized stack
1794 // objects, then we need to map all spill slots to fixed positions, so that
1795 // they can be accessed through FP. Otherwise they would have to be accessed
1796 // via AP, which may not be available at the particular place in the program.
1797 MachineFrameInfo &MFI = MF.getFrameInfo();
1798 bool HasAlloca = MFI.hasVarSizedObjects();
1799 bool NeedsAlign = (MFI.getMaxAlign() > getStackAlign());
1800
1801 if (!HasAlloca || !NeedsAlign)
1802 return;
1803
1804 // Set the physical aligned-stack base address register.
1805 MCRegister AP;
1806 if (const MachineInstr *AI = getAlignaInstr(MF))
1807 AP = AI->getOperand(0).getReg();
1808 auto &HMFI = *MF.getInfo<HexagonMachineFunctionInfo>();
1809 assert(!AP.isValid() || AP.isPhysical());
1810 HMFI.setStackAlignBaseReg(AP);
1811}
1812
1813/// Returns true if there are no caller-saved registers available in class RC.
1815 const HexagonRegisterInfo &HRI, const TargetRegisterClass *RC) {
1816 MachineRegisterInfo &MRI = MF.getRegInfo();
1817
1818 auto IsUsed = [&HRI,&MRI] (Register Reg) -> bool {
1819 for (MCRegAliasIterator AI(Reg, &HRI, true); AI.isValid(); ++AI)
1820 if (MRI.isPhysRegUsed(*AI))
1821 return true;
1822 return false;
1823 };
1824
1825 // Check for an unused caller-saved register. Callee-saved registers
1826 // have become pristine by now.
1827 for (const MCPhysReg *P = HRI.getCallerSavedRegs(&MF, RC); *P; ++P)
1828 if (!IsUsed(*P))
1829 return false;
1830
1831 // All caller-saved registers are used.
1832 return true;
1833}
1834
1835#ifndef NDEBUG
1837 dbgs() << '{';
1838 for (int x = Regs.find_first(); x >= 0; x = Regs.find_next(x)) {
1839 Register R = x;
1840 dbgs() << ' ' << printReg(R, &TRI);
1841 }
1842 dbgs() << " }";
1843}
1844#endif
1845
1847 const TargetRegisterInfo *TRI, std::vector<CalleeSavedInfo> &CSI) const {
1848 LLVM_DEBUG(dbgs() << __func__ << " on " << MF.getName() << '\n');
1849 MachineFrameInfo &MFI = MF.getFrameInfo();
1850 BitVector SRegs(Hexagon::NUM_TARGET_REGS);
1851
1852 // Generate a set of unique, callee-saved registers (SRegs), where each
1853 // register in the set is maximal in terms of sub-/super-register relation,
1854 // i.e. for each R in SRegs, no proper super-register of R is also in SRegs.
1855
1856 // (1) For each callee-saved register, add that register and all of its
1857 // sub-registers to SRegs.
1858 LLVM_DEBUG(dbgs() << "Initial CS registers: {");
1859 for (const CalleeSavedInfo &I : CSI) {
1860 Register R = I.getReg();
1861 LLVM_DEBUG(dbgs() << ' ' << printReg(R, TRI));
1862 for (MCPhysReg SR : TRI->subregs_inclusive(R))
1863 SRegs[SR] = true;
1864 }
1865 LLVM_DEBUG(dbgs() << " }\n");
1866 LLVM_DEBUG(dbgs() << "SRegs.1: "; dump_registers(SRegs, *TRI);
1867 dbgs() << "\n");
1868
1869 // (2) For each reserved register, remove that register and all of its
1870 // sub- and super-registers from SRegs.
1871 BitVector Reserved = TRI->getReservedRegs(MF);
1872 // Unreserve the stack align register: it is reserved for this function
1873 // only, it still needs to be saved/restored.
1874 Register AP =
1875 MF.getInfo<HexagonMachineFunctionInfo>()->getStackAlignBaseReg();
1876 if (AP.isValid()) {
1877 Reserved[AP] = false;
1878 // Unreserve super-regs if no other subregisters are reserved.
1879 for (MCPhysReg SP : TRI->superregs(AP)) {
1880 bool HasResSub = false;
1881 for (MCPhysReg SB : TRI->subregs(SP)) {
1882 if (!Reserved[SB])
1883 continue;
1884 HasResSub = true;
1885 break;
1886 }
1887 if (!HasResSub)
1888 Reserved[SP] = false;
1889 }
1890 }
1891
1892 for (int x = Reserved.find_first(); x >= 0; x = Reserved.find_next(x)) {
1893 Register R = x;
1894 for (MCPhysReg SR : TRI->superregs_inclusive(R))
1895 SRegs[SR] = false;
1896 }
1897 LLVM_DEBUG(dbgs() << "Res: "; dump_registers(Reserved, *TRI);
1898 dbgs() << "\n");
1899 LLVM_DEBUG(dbgs() << "SRegs.2: "; dump_registers(SRegs, *TRI);
1900 dbgs() << "\n");
1901
1902 // (3) Collect all registers that have at least one sub-register in SRegs,
1903 // and also have no sub-registers that are reserved. These will be the can-
1904 // didates for saving as a whole instead of their individual sub-registers.
1905 // (Saving R17:16 instead of R16 is fine, but only if R17 was not reserved.)
1906 BitVector TmpSup(Hexagon::NUM_TARGET_REGS);
1907 for (int x = SRegs.find_first(); x >= 0; x = SRegs.find_next(x)) {
1908 Register R = x;
1909 for (MCPhysReg SR : TRI->superregs(R))
1910 TmpSup[SR] = true;
1911 }
1912 for (int x = TmpSup.find_first(); x >= 0; x = TmpSup.find_next(x)) {
1913 Register R = x;
1914 for (MCPhysReg SR : TRI->subregs_inclusive(R)) {
1915 if (!Reserved[SR])
1916 continue;
1917 TmpSup[R] = false;
1918 break;
1919 }
1920 }
1921 LLVM_DEBUG(dbgs() << "TmpSup: "; dump_registers(TmpSup, *TRI);
1922 dbgs() << "\n");
1923
1924 // (4) Include all super-registers found in (3) into SRegs.
1925 SRegs |= TmpSup;
1926 LLVM_DEBUG(dbgs() << "SRegs.4: "; dump_registers(SRegs, *TRI);
1927 dbgs() << "\n");
1928
1929 // (5) For each register R in SRegs, if any super-register of R is in SRegs,
1930 // remove R from SRegs.
1931 for (int x = SRegs.find_first(); x >= 0; x = SRegs.find_next(x)) {
1932 Register R = x;
1933 for (MCPhysReg SR : TRI->superregs(R)) {
1934 if (!SRegs[SR])
1935 continue;
1936 SRegs[R] = false;
1937 break;
1938 }
1939 }
1940 LLVM_DEBUG(dbgs() << "SRegs.5: "; dump_registers(SRegs, *TRI);
1941 dbgs() << "\n");
1942
1943 // Now, for each register that has a fixed stack slot, create the stack
1944 // object for it.
1945 CSI.clear();
1946
1948
1949 unsigned NumFixed;
1950 int64_t MinOffset = 0; // CS offsets are negative.
1951 const SpillSlot *FixedSlots = getCalleeSavedSpillSlots(NumFixed);
1952 for (const SpillSlot *S = FixedSlots; S != FixedSlots+NumFixed; ++S) {
1953 if (!SRegs[S->Reg])
1954 continue;
1955 const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(S->Reg);
1956 int FI = MFI.CreateFixedSpillStackObject(TRI->getSpillSize(*RC), S->Offset);
1957 MinOffset = std::min(MinOffset, S->Offset);
1958 CSI.push_back(CalleeSavedInfo(S->Reg, FI));
1959 SRegs[S->Reg] = false;
1960 }
1961
1962 // There can be some registers that don't have fixed slots. For example,
1963 // we need to store R0-R3 in functions with exception handling. For each
1964 // such register, create a non-fixed stack object.
1965 for (int x = SRegs.find_first(); x >= 0; x = SRegs.find_next(x)) {
1966 Register R = x;
1967 const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(R);
1968 unsigned Size = TRI->getSpillSize(*RC);
1969 int64_t Off = MinOffset - Size;
1970 Align Alignment = std::min(TRI->getSpillAlign(*RC), getStackAlign());
1971 Off &= -Alignment.value();
1972 int FI = MFI.CreateFixedSpillStackObject(Size, Off);
1973 MinOffset = std::min(MinOffset, Off);
1974 CSI.push_back(CalleeSavedInfo(R, FI));
1975 SRegs[R] = false;
1976 }
1977
1978 LLVM_DEBUG({
1979 dbgs() << "CS information: {";
1980 for (const CalleeSavedInfo &I : CSI) {
1981 int FI = I.getFrameIdx();
1982 int Off = MFI.getObjectOffset(FI);
1983 dbgs() << ' ' << printReg(I.getReg(), TRI) << ":fi#" << FI << ":sp";
1984 if (Off >= 0)
1985 dbgs() << '+';
1986 dbgs() << Off;
1987 }
1988 dbgs() << " }\n";
1989 });
1990
1991#ifndef NDEBUG
1992 // Verify that all registers were handled.
1993 bool MissedReg = false;
1994 for (int x = SRegs.find_first(); x >= 0; x = SRegs.find_next(x)) {
1995 Register R = x;
1996 dbgs() << printReg(R, TRI) << ' ';
1997 MissedReg = true;
1998 }
1999 if (MissedReg)
2000 llvm_unreachable("...there are unhandled callee-saved registers!");
2001#endif
2002
2003 return true;
2004}
2005
2006bool HexagonFrameLowering::expandCopy(MachineBasicBlock &B,
2008 const HexagonInstrInfo &HII, SmallVectorImpl<Register> &NewRegs) const {
2009 MachineInstr *MI = &*It;
2010 DebugLoc DL = MI->getDebugLoc();
2011 Register DstR = MI->getOperand(0).getReg();
2012 Register SrcR = MI->getOperand(1).getReg();
2013 if (!Hexagon::ModRegsRegClass.contains(DstR) ||
2014 !Hexagon::ModRegsRegClass.contains(SrcR))
2015 return false;
2016
2017 Register TmpR = MRI.createVirtualRegister(&Hexagon::IntRegsRegClass);
2018 BuildMI(B, It, DL, HII.get(TargetOpcode::COPY), TmpR).add(MI->getOperand(1));
2019 BuildMI(B, It, DL, HII.get(TargetOpcode::COPY), DstR)
2020 .addReg(TmpR, RegState::Kill);
2021
2022 NewRegs.push_back(TmpR);
2023 B.erase(It);
2024 return true;
2025}
2026
2027bool HexagonFrameLowering::expandStoreInt(MachineBasicBlock &B,
2029 const HexagonInstrInfo &HII, SmallVectorImpl<Register> &NewRegs) const {
2030 MachineInstr *MI = &*It;
2031 if (!MI->getOperand(0).isFI())
2032 return false;
2033
2034 DebugLoc DL = MI->getDebugLoc();
2035 unsigned Opc = MI->getOpcode();
2036 Register SrcR = MI->getOperand(2).getReg();
2037 bool IsKill = MI->getOperand(2).isKill();
2038 int FI = MI->getOperand(0).getIndex();
2039
2040 // TmpR = C2_tfrpr SrcR if SrcR is a predicate register
2041 // TmpR = A2_tfrcrr SrcR if SrcR is a modifier register
2042 Register TmpR = MRI.createVirtualRegister(&Hexagon::IntRegsRegClass);
2043 unsigned TfrOpc = (Opc == Hexagon::STriw_pred) ? Hexagon::C2_tfrpr
2044 : Hexagon::A2_tfrcrr;
2045 BuildMI(B, It, DL, HII.get(TfrOpc), TmpR)
2046 .addReg(SrcR, getKillRegState(IsKill));
2047
2048 // S2_storeri_io FI, 0, TmpR
2049 BuildMI(B, It, DL, HII.get(Hexagon::S2_storeri_io))
2050 .addFrameIndex(FI)
2051 .addImm(0)
2052 .addReg(TmpR, RegState::Kill)
2053 .cloneMemRefs(*MI);
2054
2055 NewRegs.push_back(TmpR);
2056 B.erase(It);
2057 return true;
2058}
2059
2060bool HexagonFrameLowering::expandLoadInt(MachineBasicBlock &B,
2061 MachineBasicBlock::iterator It, MachineRegisterInfo &MRI,
2062 const HexagonInstrInfo &HII, SmallVectorImpl<Register> &NewRegs) const {
2063 MachineInstr *MI = &*It;
2064 if (!MI->getOperand(1).isFI())
2065 return false;
2066
2067 DebugLoc DL = MI->getDebugLoc();
2068 unsigned Opc = MI->getOpcode();
2069 Register DstR = MI->getOperand(0).getReg();
2070 int FI = MI->getOperand(1).getIndex();
2071
2072 // TmpR = L2_loadri_io FI, 0
2073 Register TmpR = MRI.createVirtualRegister(&Hexagon::IntRegsRegClass);
2074 BuildMI(B, It, DL, HII.get(Hexagon::L2_loadri_io), TmpR)
2075 .addFrameIndex(FI)
2076 .addImm(0)
2077 .cloneMemRefs(*MI);
2078
2079 // DstR = C2_tfrrp TmpR if DstR is a predicate register
2080 // DstR = A2_tfrrcr TmpR if DstR is a modifier register
2081 unsigned TfrOpc = (Opc == Hexagon::LDriw_pred) ? Hexagon::C2_tfrrp
2082 : Hexagon::A2_tfrrcr;
2083 BuildMI(B, It, DL, HII.get(TfrOpc), DstR)
2084 .addReg(TmpR, RegState::Kill);
2085
2086 NewRegs.push_back(TmpR);
2087 B.erase(It);
2088 return true;
2089}
2090
2091bool HexagonFrameLowering::expandStoreVecPred(MachineBasicBlock &B,
2092 MachineBasicBlock::iterator It, MachineRegisterInfo &MRI,
2093 const HexagonInstrInfo &HII, SmallVectorImpl<Register> &NewRegs) const {
2094 MachineInstr *MI = &*It;
2095 if (!MI->getOperand(0).isFI())
2096 return false;
2097
2098 DebugLoc DL = MI->getDebugLoc();
2099 Register SrcR = MI->getOperand(2).getReg();
2100 bool IsKill = MI->getOperand(2).isKill();
2101 int FI = MI->getOperand(0).getIndex();
2102 auto *RC = &Hexagon::HvxVRRegClass;
2103
2104 // Insert transfer to general vector register.
2105 // TmpR0 = A2_tfrsi 0x01010101
2106 // TmpR1 = V6_vandqrt Qx, TmpR0
2107 // store FI, 0, TmpR1
2108 Register TmpR0 = MRI.createVirtualRegister(&Hexagon::IntRegsRegClass);
2109 Register TmpR1 = MRI.createVirtualRegister(RC);
2110
2111 BuildMI(B, It, DL, HII.get(Hexagon::A2_tfrsi), TmpR0)
2112 .addImm(0x01010101);
2113
2114 BuildMI(B, It, DL, HII.get(Hexagon::V6_vandqrt), TmpR1)
2115 .addReg(SrcR, getKillRegState(IsKill))
2116 .addReg(TmpR0, RegState::Kill);
2117
2118 HII.storeRegToStackSlot(B, It, TmpR1, true, FI, RC, Register());
2119 expandStoreVec(B, std::prev(It), MRI, HII, NewRegs);
2120
2121 NewRegs.push_back(TmpR0);
2122 NewRegs.push_back(TmpR1);
2123 B.erase(It);
2124 return true;
2125}
2126
2127bool HexagonFrameLowering::expandLoadVecPred(MachineBasicBlock &B,
2128 MachineBasicBlock::iterator It, MachineRegisterInfo &MRI,
2129 const HexagonInstrInfo &HII, SmallVectorImpl<Register> &NewRegs) const {
2130 MachineInstr *MI = &*It;
2131 if (!MI->getOperand(1).isFI())
2132 return false;
2133
2134 DebugLoc DL = MI->getDebugLoc();
2135 Register DstR = MI->getOperand(0).getReg();
2136 int FI = MI->getOperand(1).getIndex();
2137 auto *RC = &Hexagon::HvxVRRegClass;
2138
2139 // TmpR0 = A2_tfrsi 0x01010101
2140 // TmpR1 = load FI, 0
2141 // DstR = V6_vandvrt TmpR1, TmpR0
2142 Register TmpR0 = MRI.createVirtualRegister(&Hexagon::IntRegsRegClass);
2143 Register TmpR1 = MRI.createVirtualRegister(RC);
2144
2145 BuildMI(B, It, DL, HII.get(Hexagon::A2_tfrsi), TmpR0)
2146 .addImm(0x01010101);
2147 HII.loadRegFromStackSlot(B, It, TmpR1, FI, RC, Register());
2148 expandLoadVec(B, std::prev(It), MRI, HII, NewRegs);
2149
2150 BuildMI(B, It, DL, HII.get(Hexagon::V6_vandvrt), DstR)
2151 .addReg(TmpR1, RegState::Kill)
2152 .addReg(TmpR0, RegState::Kill);
2153
2154 NewRegs.push_back(TmpR0);
2155 NewRegs.push_back(TmpR1);
2156 B.erase(It);
2157 return true;
2158}
2159
2160bool HexagonFrameLowering::expandStoreVec2(MachineBasicBlock &B,
2161 MachineBasicBlock::iterator It, MachineRegisterInfo &MRI,
2162 const HexagonInstrInfo &HII, SmallVectorImpl<Register> &NewRegs) const {
2163 MachineFunction &MF = *B.getParent();
2164 auto &MFI = MF.getFrameInfo();
2165 auto &HRI = *MF.getSubtarget<HexagonSubtarget>().getRegisterInfo();
2166 MachineInstr *MI = &*It;
2167 if (!MI->getOperand(0).isFI())
2168 return false;
2169
2170 // It is possible that the double vector being stored is only partially
2171 // defined. From the point of view of the liveness tracking, it is ok to
2172 // store it as a whole, but if we break it up we may end up storing a
2173 // register that is entirely undefined.
2174 LivePhysRegs LPR(HRI);
2175 LPR.addLiveIns(B);
2177 for (auto R = B.begin(); R != It; ++R) {
2178 Clobbers.clear();
2179 LPR.stepForward(*R, Clobbers);
2180 }
2181
2182 DebugLoc DL = MI->getDebugLoc();
2183 Register SrcR = MI->getOperand(2).getReg();
2184 Register SrcLo = HRI.getSubReg(SrcR, Hexagon::vsub_lo);
2185 Register SrcHi = HRI.getSubReg(SrcR, Hexagon::vsub_hi);
2186 bool IsKill = MI->getOperand(2).isKill();
2187 int FI = MI->getOperand(0).getIndex();
2188
2189 unsigned Size = HRI.getSpillSize(Hexagon::HvxVRRegClass);
2190 Align NeedAlign = HRI.getSpillAlign(Hexagon::HvxVRRegClass);
2191 Align HasAlign = MFI.getObjectAlign(FI);
2192 unsigned StoreOpc;
2193
2194 // Store low part.
2195 if (LPR.contains(SrcLo)) {
2196 StoreOpc = NeedAlign <= HasAlign ? Hexagon::V6_vS32b_ai
2197 : Hexagon::V6_vS32Ub_ai;
2198 BuildMI(B, It, DL, HII.get(StoreOpc))
2199 .addFrameIndex(FI)
2200 .addImm(0)
2201 .addReg(SrcLo, getKillRegState(IsKill))
2202 .cloneMemRefs(*MI);
2203 }
2204
2205 // Store high part.
2206 if (LPR.contains(SrcHi)) {
2207 StoreOpc = NeedAlign <= HasAlign ? Hexagon::V6_vS32b_ai
2208 : Hexagon::V6_vS32Ub_ai;
2209 BuildMI(B, It, DL, HII.get(StoreOpc))
2210 .addFrameIndex(FI)
2211 .addImm(Size)
2212 .addReg(SrcHi, getKillRegState(IsKill))
2213 .cloneMemRefs(*MI);
2214 }
2215
2216 B.erase(It);
2217 return true;
2218}
2219
2220bool HexagonFrameLowering::expandLoadVec2(MachineBasicBlock &B,
2221 MachineBasicBlock::iterator It, MachineRegisterInfo &MRI,
2222 const HexagonInstrInfo &HII, SmallVectorImpl<Register> &NewRegs) const {
2223 MachineFunction &MF = *B.getParent();
2224 auto &MFI = MF.getFrameInfo();
2225 auto &HRI = *MF.getSubtarget<HexagonSubtarget>().getRegisterInfo();
2226 MachineInstr *MI = &*It;
2227 if (!MI->getOperand(1).isFI())
2228 return false;
2229
2230 DebugLoc DL = MI->getDebugLoc();
2231 Register DstR = MI->getOperand(0).getReg();
2232 Register DstHi = HRI.getSubReg(DstR, Hexagon::vsub_hi);
2233 Register DstLo = HRI.getSubReg(DstR, Hexagon::vsub_lo);
2234 int FI = MI->getOperand(1).getIndex();
2235
2236 unsigned Size = HRI.getSpillSize(Hexagon::HvxVRRegClass);
2237 Align NeedAlign = HRI.getSpillAlign(Hexagon::HvxVRRegClass);
2238 Align HasAlign = MFI.getObjectAlign(FI);
2239 unsigned LoadOpc;
2240
2241 // Load low part.
2242 LoadOpc = NeedAlign <= HasAlign ? Hexagon::V6_vL32b_ai
2243 : Hexagon::V6_vL32Ub_ai;
2244 BuildMI(B, It, DL, HII.get(LoadOpc), DstLo)
2245 .addFrameIndex(FI)
2246 .addImm(0)
2247 .cloneMemRefs(*MI);
2248
2249 // Load high part.
2250 LoadOpc = NeedAlign <= HasAlign ? Hexagon::V6_vL32b_ai
2251 : Hexagon::V6_vL32Ub_ai;
2252 BuildMI(B, It, DL, HII.get(LoadOpc), DstHi)
2253 .addFrameIndex(FI)
2254 .addImm(Size)
2255 .cloneMemRefs(*MI);
2256
2257 B.erase(It);
2258 return true;
2259}
2260
2261bool HexagonFrameLowering::expandStoreVec(MachineBasicBlock &B,
2262 MachineBasicBlock::iterator It, MachineRegisterInfo &MRI,
2263 const HexagonInstrInfo &HII, SmallVectorImpl<Register> &NewRegs) const {
2264 MachineFunction &MF = *B.getParent();
2265 auto &MFI = MF.getFrameInfo();
2266 MachineInstr *MI = &*It;
2267 if (!MI->getOperand(0).isFI())
2268 return false;
2269
2270 auto &HRI = *MF.getSubtarget<HexagonSubtarget>().getRegisterInfo();
2271 DebugLoc DL = MI->getDebugLoc();
2272 Register SrcR = MI->getOperand(2).getReg();
2273 bool IsKill = MI->getOperand(2).isKill();
2274 int FI = MI->getOperand(0).getIndex();
2275
2276 Align NeedAlign = HRI.getSpillAlign(Hexagon::HvxVRRegClass);
2277 Align HasAlign = MFI.getObjectAlign(FI);
2278 unsigned StoreOpc = NeedAlign <= HasAlign ? Hexagon::V6_vS32b_ai
2279 : Hexagon::V6_vS32Ub_ai;
2280 BuildMI(B, It, DL, HII.get(StoreOpc))
2281 .addFrameIndex(FI)
2282 .addImm(0)
2283 .addReg(SrcR, getKillRegState(IsKill))
2284 .cloneMemRefs(*MI);
2285
2286 B.erase(It);
2287 return true;
2288}
2289
2290bool HexagonFrameLowering::expandLoadVec(MachineBasicBlock &B,
2291 MachineBasicBlock::iterator It, MachineRegisterInfo &MRI,
2292 const HexagonInstrInfo &HII, SmallVectorImpl<Register> &NewRegs) const {
2293 MachineFunction &MF = *B.getParent();
2294 auto &MFI = MF.getFrameInfo();
2295 MachineInstr *MI = &*It;
2296 if (!MI->getOperand(1).isFI())
2297 return false;
2298
2299 auto &HRI = *MF.getSubtarget<HexagonSubtarget>().getRegisterInfo();
2300 DebugLoc DL = MI->getDebugLoc();
2301 Register DstR = MI->getOperand(0).getReg();
2302 int FI = MI->getOperand(1).getIndex();
2303
2304 Align NeedAlign = HRI.getSpillAlign(Hexagon::HvxVRRegClass);
2305 Align HasAlign = MFI.getObjectAlign(FI);
2306 unsigned LoadOpc = NeedAlign <= HasAlign ? Hexagon::V6_vL32b_ai
2307 : Hexagon::V6_vL32Ub_ai;
2308 BuildMI(B, It, DL, HII.get(LoadOpc), DstR)
2309 .addFrameIndex(FI)
2310 .addImm(0)
2311 .cloneMemRefs(*MI);
2312
2313 B.erase(It);
2314 return true;
2315}
2316
2317bool HexagonFrameLowering::expandSpillMacros(MachineFunction &MF,
2318 SmallVectorImpl<Register> &NewRegs) const {
2319 auto &HII = *MF.getSubtarget<HexagonSubtarget>().getInstrInfo();
2320 MachineRegisterInfo &MRI = MF.getRegInfo();
2321 bool Changed = false;
2322
2323 for (auto &B : MF) {
2324 // Traverse the basic block.
2326 for (auto I = B.begin(), E = B.end(); I != E; I = NextI) {
2327 MachineInstr *MI = &*I;
2328 NextI = std::next(I);
2329 unsigned Opc = MI->getOpcode();
2330
2331 switch (Opc) {
2332 case TargetOpcode::COPY:
2333 Changed |= expandCopy(B, I, MRI, HII, NewRegs);
2334 break;
2335 case Hexagon::STriw_pred:
2336 case Hexagon::STriw_ctr:
2337 Changed |= expandStoreInt(B, I, MRI, HII, NewRegs);
2338 break;
2339 case Hexagon::LDriw_pred:
2340 case Hexagon::LDriw_ctr:
2341 Changed |= expandLoadInt(B, I, MRI, HII, NewRegs);
2342 break;
2343 case Hexagon::PS_vstorerq_ai:
2344 Changed |= expandStoreVecPred(B, I, MRI, HII, NewRegs);
2345 break;
2346 case Hexagon::PS_vloadrq_ai:
2347 Changed |= expandLoadVecPred(B, I, MRI, HII, NewRegs);
2348 break;
2349 case Hexagon::PS_vloadrw_ai:
2350 Changed |= expandLoadVec2(B, I, MRI, HII, NewRegs);
2351 break;
2352 case Hexagon::PS_vstorerw_ai:
2353 Changed |= expandStoreVec2(B, I, MRI, HII, NewRegs);
2354 break;
2355 }
2356 }
2357 }
2358
2359 return Changed;
2360}
2361
2363 BitVector &SavedRegs,
2364 RegScavenger *RS) const {
2365 auto &HRI = *MF.getSubtarget<HexagonSubtarget>().getRegisterInfo();
2366
2367 SavedRegs.resize(HRI.getNumRegs());
2368
2369 // If we have a function containing __builtin_eh_return we want to spill and
2370 // restore all callee saved registers. Pretend that they are used.
2372 for (const MCPhysReg *R = HRI.getCalleeSavedRegs(&MF); *R; ++R)
2373 SavedRegs.set(*R);
2374
2375 // Replace predicate register pseudo spill code.
2377 expandSpillMacros(MF, NewRegs);
2378 if (OptimizeSpillSlots && !isOptNone(MF))
2379 optimizeSpillSlots(MF, NewRegs);
2380
2381 // We need to reserve a spill slot if scavenging could potentially require
2382 // spilling a scavenged register.
2383 if (!NewRegs.empty() || mayOverflowFrameOffset(MF)) {
2384 MachineFrameInfo &MFI = MF.getFrameInfo();
2385 MachineRegisterInfo &MRI = MF.getRegInfo();
2387 // Reserve an int register in any case, because it could be used to hold
2388 // the stack offset in case it does not fit into a spill instruction.
2389 SpillRCs.insert(&Hexagon::IntRegsRegClass);
2390
2391 for (Register VR : NewRegs)
2392 SpillRCs.insert(MRI.getRegClass(VR));
2393
2394 for (const auto *RC : SpillRCs) {
2395 if (!needToReserveScavengingSpillSlots(MF, HRI, RC))
2396 continue;
2397 unsigned Num = 1;
2398 switch (RC->getID()) {
2399 case Hexagon::IntRegsRegClassID:
2401 break;
2402 case Hexagon::HvxQRRegClassID:
2403 Num = 2; // Vector predicate spills also need a vector register.
2404 break;
2405 }
2406 unsigned S = HRI.getSpillSize(*RC);
2407 Align A = HRI.getSpillAlign(*RC);
2408 for (unsigned i = 0; i < Num; i++) {
2409 int NewFI = MFI.CreateSpillStackObject(S, A);
2410 RS->addScavengingFrameIndex(NewFI);
2411 }
2412 }
2413 }
2414
2416}
2417
2418Register HexagonFrameLowering::findPhysReg(MachineFunction &MF,
2422 const TargetRegisterClass *RC) const {
2423 auto &HRI = *MF.getSubtarget<HexagonSubtarget>().getRegisterInfo();
2424 auto &MRI = MF.getRegInfo();
2425
2426 auto isDead = [&FIR,&DeadMap] (Register Reg) -> bool {
2427 auto F = DeadMap.find({Reg,0});
2428 if (F == DeadMap.end())
2429 return false;
2430 for (auto &DR : F->second)
2431 if (DR.contains(FIR))
2432 return true;
2433 return false;
2434 };
2435
2436 for (Register Reg : HRI.getRawAllocationOrder(*RC, MF)) {
2437 bool Dead = true;
2438 for (auto R : HexagonBlockRanges::expandToSubRegs({Reg,0}, MRI, HRI)) {
2439 if (isDead(R.Reg))
2440 continue;
2441 Dead = false;
2442 break;
2443 }
2444 if (Dead)
2445 return Reg;
2446 }
2447 return 0;
2448}
2449
2450void HexagonFrameLowering::optimizeSpillSlots(MachineFunction &MF,
2451 SmallVectorImpl<Register> &VRegs) const {
2452 auto &HST = MF.getSubtarget<HexagonSubtarget>();
2453 auto &HII = *HST.getInstrInfo();
2454 auto &HRI = *HST.getRegisterInfo();
2455 auto &MRI = MF.getRegInfo();
2456 HexagonBlockRanges HBR(MF);
2457
2458 using BlockIndexMap =
2459 std::map<MachineBasicBlock *, HexagonBlockRanges::InstrIndexMap>;
2460 using BlockRangeMap =
2461 std::map<MachineBasicBlock *, HexagonBlockRanges::RangeList>;
2462 using IndexType = HexagonBlockRanges::IndexType;
2463
2464 struct SlotInfo {
2465 BlockRangeMap Map;
2466 unsigned Size = 0;
2467 const TargetRegisterClass *RC = nullptr;
2468
2469 SlotInfo() = default;
2470 };
2471
2472 BlockIndexMap BlockIndexes;
2473 SmallSet<int,4> BadFIs;
2474 std::map<int,SlotInfo> FIRangeMap;
2475
2476 // Accumulate register classes: get a common class for a pre-existing
2477 // class HaveRC and a new class NewRC. Return nullptr if a common class
2478 // cannot be found, otherwise return the resulting class. If HaveRC is
2479 // nullptr, assume that it is still unset.
2480 auto getCommonRC =
2481 [](const TargetRegisterClass *HaveRC,
2482 const TargetRegisterClass *NewRC) -> const TargetRegisterClass * {
2483 if (HaveRC == nullptr || HaveRC == NewRC)
2484 return NewRC;
2485 // Different classes, both non-null. Pick the more general one.
2486 if (HaveRC->hasSubClassEq(NewRC))
2487 return HaveRC;
2488 if (NewRC->hasSubClassEq(HaveRC))
2489 return NewRC;
2490 return nullptr;
2491 };
2492
2493 // Scan all blocks in the function. Check all occurrences of frame indexes,
2494 // and collect relevant information.
2495 for (auto &B : MF) {
2496 std::map<int,IndexType> LastStore, LastLoad;
2497 auto P = BlockIndexes.emplace(&B, HexagonBlockRanges::InstrIndexMap(B));
2498 auto &IndexMap = P.first->second;
2499 LLVM_DEBUG(dbgs() << "Index map for " << printMBBReference(B) << "\n"
2500 << IndexMap << '\n');
2501
2502 for (auto &In : B) {
2503 // Debug instructions do not generate any code, and their operands
2504 // (including frame index operands) must not affect the decisions made
2505 // by this optimization.
2506 if (In.isDebugInstr())
2507 continue;
2508 int LFI, SFI;
2509 bool Load = HII.isLoadFromStackSlot(In, LFI) && !HII.isPredicated(In);
2510 bool Store = HII.isStoreToStackSlot(In, SFI) && !HII.isPredicated(In);
2511 if (Load && Store) {
2512 // If it's both a load and a store, then we won't handle it.
2513 BadFIs.insert(LFI);
2514 BadFIs.insert(SFI);
2515 continue;
2516 }
2517 // Check for register classes of the register used as the source for
2518 // the store, and the register used as the destination for the load.
2519 // Also, only accept base+imm_offset addressing modes. Other addressing
2520 // modes can have side-effects (post-increments, etc.). For stack
2521 // slots they are very unlikely, so there is not much loss due to
2522 // this restriction.
2523 if (Load || Store) {
2524 int TFI = Load ? LFI : SFI;
2525 unsigned AM = HII.getAddrMode(In);
2526 SlotInfo &SI = FIRangeMap[TFI];
2527 bool Bad = (AM != HexagonII::BaseImmOffset);
2528 if (!Bad) {
2529 // If the addressing mode is ok, check the register class.
2530 unsigned OpNum = Load ? 0 : 2;
2531 auto *RC = HII.getRegClass(In.getDesc(), OpNum);
2532 RC = getCommonRC(SI.RC, RC);
2533 if (RC == nullptr)
2534 Bad = true;
2535 else
2536 SI.RC = RC;
2537 }
2538 if (!Bad) {
2539 // Check sizes.
2540 unsigned S = HII.getMemAccessSize(In);
2541 if (SI.Size != 0 && SI.Size != S)
2542 Bad = true;
2543 else
2544 SI.Size = S;
2545 }
2546 if (!Bad) {
2547 for (auto *Mo : In.memoperands()) {
2548 if (!Mo->isVolatile() && !Mo->isAtomic())
2549 continue;
2550 Bad = true;
2551 break;
2552 }
2553 }
2554 if (Bad)
2555 BadFIs.insert(TFI);
2556 }
2557
2558 // Locate uses of frame indices.
2559 for (unsigned i = 0, n = In.getNumOperands(); i < n; ++i) {
2560 const MachineOperand &Op = In.getOperand(i);
2561 if (!Op.isFI())
2562 continue;
2563 int FI = Op.getIndex();
2564 // Make sure that the following operand is an immediate and that
2565 // it is 0. This is the offset in the stack object.
2566 if (i+1 >= n || !In.getOperand(i+1).isImm() ||
2567 In.getOperand(i+1).getImm() != 0)
2568 BadFIs.insert(FI);
2569 if (BadFIs.count(FI))
2570 continue;
2571
2572 IndexType Index = IndexMap.getIndex(&In);
2573 auto &LS = LastStore[FI];
2574 auto &LL = LastLoad[FI];
2575 if (Load) {
2576 if (LS == IndexType::None)
2577 LS = IndexType::Entry;
2578 LL = Index;
2579 } else if (Store) {
2580 HexagonBlockRanges::RangeList &RL = FIRangeMap[FI].Map[&B];
2581 if (LS != IndexType::None)
2582 RL.add(LS, LL, false, false);
2583 else if (LL != IndexType::None)
2584 RL.add(IndexType::Entry, LL, false, false);
2585 LL = IndexType::None;
2586 LS = Index;
2587 } else {
2588 BadFIs.insert(FI);
2589 }
2590 }
2591 }
2592
2593 for (auto &I : LastLoad) {
2594 IndexType LL = I.second;
2595 if (LL == IndexType::None)
2596 continue;
2597 auto &RL = FIRangeMap[I.first].Map[&B];
2598 IndexType &LS = LastStore[I.first];
2599 if (LS != IndexType::None)
2600 RL.add(LS, LL, false, false);
2601 else
2602 RL.add(IndexType::Entry, LL, false, false);
2603 LS = IndexType::None;
2604 }
2605 for (auto &I : LastStore) {
2606 IndexType LS = I.second;
2607 if (LS == IndexType::None)
2608 continue;
2609 auto &RL = FIRangeMap[I.first].Map[&B];
2610 RL.add(LS, IndexType::None, false, false);
2611 }
2612 }
2613
2614 LLVM_DEBUG({
2615 for (auto &P : FIRangeMap) {
2616 dbgs() << "fi#" << P.first;
2617 if (BadFIs.count(P.first))
2618 dbgs() << " (bad)";
2619 dbgs() << " RC: ";
2620 if (P.second.RC != nullptr)
2621 dbgs() << HRI.getRegClassName(P.second.RC) << '\n';
2622 else
2623 dbgs() << "<null>\n";
2624 for (auto &R : P.second.Map)
2625 dbgs() << " " << printMBBReference(*R.first) << " { " << R.second
2626 << "}\n";
2627 }
2628 });
2629
2630 // When a slot is loaded from in a block without being stored to in the
2631 // same block, it is live-on-entry to this block. To avoid CFG analysis,
2632 // consider this slot to be live-on-exit from all blocks.
2633 SmallSet<int,4> LoxFIs;
2634
2635 std::map<MachineBasicBlock*,std::vector<int>> BlockFIMap;
2636
2637 for (auto &P : FIRangeMap) {
2638 // P = pair(FI, map: BB->RangeList)
2639 if (BadFIs.count(P.first))
2640 continue;
2641 for (auto &B : MF) {
2642 auto F = P.second.Map.find(&B);
2643 // F = pair(BB, RangeList)
2644 if (F == P.second.Map.end() || F->second.empty())
2645 continue;
2646 HexagonBlockRanges::IndexRange &IR = F->second.front();
2647 if (IR.start() == IndexType::Entry)
2648 LoxFIs.insert(P.first);
2649 BlockFIMap[&B].push_back(P.first);
2650 }
2651 }
2652
2653 LLVM_DEBUG({
2654 dbgs() << "Block-to-FI map (* -- live-on-exit):\n";
2655 for (auto &P : BlockFIMap) {
2656 auto &FIs = P.second;
2657 if (FIs.empty())
2658 continue;
2659 dbgs() << " " << printMBBReference(*P.first) << ": {";
2660 for (auto I : FIs) {
2661 dbgs() << " fi#" << I;
2662 if (LoxFIs.count(I))
2663 dbgs() << '*';
2664 }
2665 dbgs() << " }\n";
2666 }
2667 });
2668
2669#ifndef NDEBUG
2670 bool HasOptLimit = SpillOptMax.getPosition();
2671#endif
2672
2673 // eliminate loads, when all loads eliminated, eliminate all stores.
2674 for (auto &B : MF) {
2675 auto F = BlockIndexes.find(&B);
2676 assert(F != BlockIndexes.end());
2677 HexagonBlockRanges::InstrIndexMap &IM = F->second;
2678 HexagonBlockRanges::RegToRangeMap LM = HBR.computeLiveMap(IM);
2679 HexagonBlockRanges::RegToRangeMap DM = HBR.computeDeadMap(IM, LM);
2680 LLVM_DEBUG(dbgs() << printMBBReference(B) << " dead map\n"
2681 << HexagonBlockRanges::PrintRangeMap(DM, HRI));
2682
2683 for (auto FI : BlockFIMap[&B]) {
2684 if (BadFIs.count(FI))
2685 continue;
2686 LLVM_DEBUG(dbgs() << "Working on fi#" << FI << '\n');
2687 HexagonBlockRanges::RangeList &RL = FIRangeMap[FI].Map[&B];
2688 for (auto &Range : RL) {
2689 LLVM_DEBUG(dbgs() << "--Examining range:" << RL << '\n');
2690 if (!IndexType::isInstr(Range.start()) ||
2691 !IndexType::isInstr(Range.end()))
2692 continue;
2693 MachineInstr &SI = *IM.getInstr(Range.start());
2694 MachineInstr &EI = *IM.getInstr(Range.end());
2695 assert(SI.mayStore() && "Unexpected start instruction");
2696 assert(EI.mayLoad() && "Unexpected end instruction");
2697 MachineOperand &SrcOp = SI.getOperand(2);
2698
2699 HexagonBlockRanges::RegisterRef SrcRR = { SrcOp.getReg(),
2700 SrcOp.getSubReg() };
2701 auto *RC = HII.getRegClass(SI.getDesc(), 2);
2702 // The this-> is needed to unconfuse MSVC.
2703 Register FoundR = this->findPhysReg(MF, Range, IM, DM, RC);
2704 LLVM_DEBUG(dbgs() << "Replacement reg:" << printReg(FoundR, &HRI)
2705 << '\n');
2706 if (FoundR == 0)
2707 continue;
2708#ifndef NDEBUG
2709 if (HasOptLimit) {
2711 return;
2712 SpillOptCount++;
2713 }
2714#endif
2715
2716 // Generate the copy-in: "FoundR = COPY SrcR" at the store location.
2717 MachineBasicBlock::iterator StartIt = SI.getIterator(), NextIt;
2718 MachineInstr *CopyIn = nullptr;
2719 if (SrcRR.Reg != FoundR || SrcRR.Sub != 0) {
2720 const DebugLoc &DL = SI.getDebugLoc();
2721 CopyIn = BuildMI(B, StartIt, DL, HII.get(TargetOpcode::COPY), FoundR)
2722 .add(SrcOp);
2723 }
2724
2725 ++StartIt;
2726 // Check if this is a last store and the FI is live-on-exit.
2727 if (LoxFIs.count(FI) && (&Range == &RL.back())) {
2728 // Update store's source register.
2729 if (unsigned SR = SrcOp.getSubReg())
2730 SrcOp.setReg(HRI.getSubReg(FoundR, SR));
2731 else
2732 SrcOp.setReg(FoundR);
2733 SrcOp.setSubReg(0);
2734 // We are keeping this register live.
2735 SrcOp.setIsKill(false);
2736 } else {
2737 B.erase(&SI);
2738 IM.replaceInstr(&SI, CopyIn);
2739 }
2740
2741 auto EndIt = std::next(EI.getIterator());
2742 for (auto It = StartIt; It != EndIt; It = NextIt) {
2743 MachineInstr &MI = *It;
2744 NextIt = std::next(It);
2745 int TFI;
2746 if (!HII.isLoadFromStackSlot(MI, TFI) || TFI != FI)
2747 continue;
2748 Register DstR = MI.getOperand(0).getReg();
2749 assert(MI.getOperand(0).getSubReg() == 0);
2750 MachineInstr *CopyOut = nullptr;
2751 if (DstR != FoundR) {
2752 DebugLoc DL = MI.getDebugLoc();
2753 unsigned MemSize = HII.getMemAccessSize(MI);
2754 assert(HII.getAddrMode(MI) == HexagonII::BaseImmOffset);
2755 unsigned CopyOpc = TargetOpcode::COPY;
2756 if (HII.isSignExtendingLoad(MI))
2757 CopyOpc = (MemSize == 1) ? Hexagon::A2_sxtb : Hexagon::A2_sxth;
2758 else if (HII.isZeroExtendingLoad(MI))
2759 CopyOpc = (MemSize == 1) ? Hexagon::A2_zxtb : Hexagon::A2_zxth;
2760 CopyOut = BuildMI(B, It, DL, HII.get(CopyOpc), DstR)
2761 .addReg(FoundR, getKillRegState(&MI == &EI));
2762 }
2763 IM.replaceInstr(&MI, CopyOut);
2764 B.erase(It);
2765 }
2766
2767 // Update the dead map.
2768 HexagonBlockRanges::RegisterRef FoundRR = { FoundR, 0 };
2769 for (auto RR : HexagonBlockRanges::expandToSubRegs(FoundRR, MRI, HRI))
2770 DM[RR].subtract(Range);
2771 } // for Range in range list
2772 }
2773 }
2774}
2775
2776void HexagonFrameLowering::expandAlloca(MachineInstr *AI, MachineFunction &MF,
2777 const HexagonInstrInfo &HII,
2778 Register SP, unsigned CF) const {
2779 MachineBasicBlock &MB = *AI->getParent();
2780 DebugLoc DL = AI->getDebugLoc();
2781 unsigned A = AI->getOperand(2).getImm();
2782
2783 MachineOperand &RdOp = AI->getOperand(0);
2784 MachineOperand &RsOp = AI->getOperand(1);
2785 Register Rd = RdOp.getReg(), Rs = RsOp.getReg();
2786
2787 auto &HST = MF.getSubtarget<HexagonSubtarget>();
2788 auto *TLI = HST.getTargetLowering();
2789 bool NeedsProbing = TLI->hasInlineStackProbe(MF);
2790
2791 if (!NeedsProbing) {
2792 // Have
2793 // Rd = alloca Rs, #A
2794 //
2795 // If Rs and Rd are different registers, use this sequence:
2796 // Rd = sub(r29, Rs)
2797 // r29 = sub(r29, Rs)
2798 // Rd = and(Rd, #-A) ; if necessary
2799 // r29 = and(r29, #-A) ; if necessary
2800 // Rd = add(Rd, #CF) ; CF size aligned to at most A
2801 // otherwise, do
2802 // Rd = sub(r29, Rs)
2803 // Rd = and(Rd, #-A) ; if necessary
2804 // r29 = Rd
2805 // Rd = add(Rd, #CF) ; CF size aligned to at most A
2806
2807 // Rd = sub(r29, Rs)
2808 BuildMI(MB, AI, DL, HII.get(Hexagon::A2_sub), Rd).addReg(SP).addReg(Rs);
2809 if (Rs != Rd) {
2810 // r29 = sub(r29, Rs)
2811 BuildMI(MB, AI, DL, HII.get(Hexagon::A2_sub), SP).addReg(SP).addReg(Rs);
2812 }
2813 if (A > 8) {
2814 // Rd = and(Rd, #-A)
2815 BuildMI(MB, AI, DL, HII.get(Hexagon::A2_andir), Rd)
2816 .addReg(Rd)
2817 .addImm(-int64_t(A));
2818 if (Rs != Rd)
2819 BuildMI(MB, AI, DL, HII.get(Hexagon::A2_andir), SP)
2820 .addReg(SP)
2821 .addImm(-int64_t(A));
2822 }
2823 if (Rs == Rd) {
2824 // r29 = Rd
2825 BuildMI(MB, AI, DL, HII.get(TargetOpcode::COPY), SP).addReg(Rd);
2826 }
2827 if (CF > 0) {
2828 // Rd = add(Rd, #CF)
2829 BuildMI(MB, AI, DL, HII.get(Hexagon::A2_addi), Rd).addReg(Rd).addImm(CF);
2830 }
2831 return;
2832 }
2833
2834 // Stack probing for dynamic allocation. The size Rs is a runtime value
2835 // so the probe loop is always emitted; it is a no-op when Rs is small.
2836 //
2837 // Compute the target SP into Rd (with optional alignment), then probe
2838 // each page on the way down:
2839 //
2840 // Rd = sub(r29, Rs)
2841 // [Rd = and(Rd, #-A)] ; if alignment > 8
2842 // LoopMBB:
2843 // r29 = add(r29, #-ProbeSize)
2844 // memw(r29+#0) = #0
2845 // p0 = cmp.gtu(r29, Rd)
2846 // if (p0.new) jump:t LoopMBB
2847 // ExitMBB:
2848 // r29 = Rd
2849 // [Rd = add(Rd, #CF)] ; if CF > 0
2850 // <rest of original block>
2851 //
2852 // Rd holds the exact (aligned) target SP throughout the loop, so the
2853 // final "r29 = Rd" snaps SP to the correct value even when Rs is not
2854 // a multiple of ProbeSize.
2855
2856 Align StackAlign = getStackAlign();
2857 unsigned ProbeSize = TLI->getStackProbeSize(MF, StackAlign);
2859
2860 // Emit target-SP computation into Rd before splitting the block.
2861 // Rd = sub(r29, Rs)
2862 BuildMI(MB, AI, DL, HII.get(Hexagon::A2_sub), Rd)
2863 .addReg(SP)
2864 .addReg(Rs)
2865 .setMIFlags(Flags);
2866 if (A > 8) {
2867 // Rd = and(Rd, #-A)
2868 BuildMI(MB, AI, DL, HII.get(Hexagon::A2_andir), Rd)
2869 .addReg(Rd)
2870 .addImm(-int64_t(A))
2871 .setMIFlags(Flags);
2872 }
2873
2874 // Split the block: everything after AI goes into ExitMBB.
2875 MachineFunction::iterator InsertPt = std::next(MB.getIterator());
2876 MachineBasicBlock *LoopMBB = MF.CreateMachineBasicBlock(MB.getBasicBlock());
2877 MF.insert(InsertPt, LoopMBB);
2878 MachineBasicBlock *ExitMBB = MF.CreateMachineBasicBlock(MB.getBasicBlock());
2879 MF.insert(InsertPt, ExitMBB);
2880
2881 // Move instructions after AI (exclusive) into ExitMBB.
2882 ExitMBB->splice(ExitMBB->end(), &MB, std::next(AI->getIterator()), MB.end());
2883 ExitMBB->transferSuccessorsAndUpdatePHIs(&MB);
2884
2885 // LoopMBB: probe each page.
2886 // r29 = add(r29, #-ProbeSize)
2887 // memw(r29+#0) = #0
2888 // p0 = cmp.gtu(r29, Rd)
2889 // if (p0.new) jump:t LoopMBB
2890 BuildMI(*LoopMBB, LoopMBB->end(), DL, HII.get(Hexagon::A2_addi), Hexagon::R29)
2891 .addReg(Hexagon::R29)
2892 .addImm(-int(ProbeSize))
2893 .setMIFlags(Flags);
2894
2895 BuildMI(*LoopMBB, LoopMBB->end(), DL, HII.get(Hexagon::S4_storeiri_io))
2896 .addReg(Hexagon::R29)
2897 .addImm(0)
2898 .addImm(0)
2899 .setMIFlags(Flags);
2900
2901 BuildMI(*LoopMBB, LoopMBB->end(), DL, HII.get(Hexagon::C2_cmpgtu),
2902 Hexagon::P0)
2903 .addReg(Hexagon::R29)
2904 .addReg(Rd)
2905 .setMIFlags(Flags);
2906
2907 BuildMI(*LoopMBB, LoopMBB->end(), DL, HII.get(Hexagon::J2_jumpt))
2908 .addReg(Hexagon::P0)
2909 .addMBB(LoopMBB)
2910 .setMIFlags(Flags);
2911
2912 // ExitMBB: snap SP to exact target, then apply CF offset to Rd.
2913 // r29 = Rd
2914 // [Rd = add(Rd, #CF)]
2915 MachineBasicBlock::iterator ExitIt = ExitMBB->begin();
2916 BuildMI(*ExitMBB, ExitIt, DL, HII.get(Hexagon::A2_tfr), Hexagon::R29)
2917 .addReg(Rd)
2918 .setMIFlags(Flags);
2919 if (CF > 0) {
2920 BuildMI(*ExitMBB, ExitIt, DL, HII.get(Hexagon::A2_addi), Rd)
2921 .addReg(Rd)
2922 .addImm(CF)
2923 .setMIFlags(Flags);
2924 }
2925
2926 // Wire up CFG edges.
2927 MB.addSuccessor(LoopMBB);
2928 LoopMBB->addSuccessor(LoopMBB);
2929 LoopMBB->addSuccessor(ExitMBB);
2930
2931 // Recompute live-ins for the new blocks. AI is still in MB at this
2932 // point; the caller erases it after expandAlloca returns.
2933 fullyRecomputeLiveIns({ExitMBB, LoopMBB});
2934}
2935
2937 const MachineFrameInfo &MFI = MF.getFrameInfo();
2938 if (!MFI.hasVarSizedObjects())
2939 return false;
2940 // Do not check for max stack object alignment here, because the stack
2941 // may not be complete yet. Assume that we will need PS_aligna if there
2942 // are variable-sized objects.
2943 return true;
2944}
2945
2947 const MachineFunction &MF) const {
2948 for (auto &B : MF)
2949 for (auto &I : B)
2950 if (I.getOpcode() == Hexagon::PS_aligna)
2951 return &I;
2952 return nullptr;
2953}
2954
2955/// Adds all callee-saved registers as implicit uses or defs to the
2956/// instruction.
2957void HexagonFrameLowering::addCalleeSaveRegistersAsImpOperand(MachineInstr *MI,
2958 const CSIVect &CSI, bool IsDef, bool IsKill) const {
2959 // Add the callee-saved registers as implicit uses.
2960 for (auto &R : CSI)
2961 MI->addOperand(MachineOperand::CreateReg(R.getReg(), IsDef, true, IsKill));
2962}
2963
2964/// Determine whether the callee-saved register saves and restores should
2965/// be generated via inline code. If this function returns "true", inline
2966/// code will be generated. If this function returns "false", additional
2967/// checks are performed, which may still lead to the inline code.
2968bool HexagonFrameLowering::shouldInlineCSR(const MachineFunction &MF,
2969 const CSIVect &CSI) const {
2971 return true;
2973 return true;
2974 if (!hasFP(MF))
2975 return true;
2976 if (!isOptSize(MF) && !isMinSize(MF))
2978 return true;
2979
2980 // Check if CSI only has double registers, and if the registers form
2981 // a contiguous block starting from D8.
2982 BitVector Regs(Hexagon::NUM_TARGET_REGS);
2983 for (const CalleeSavedInfo &I : CSI) {
2984 MCRegister R = I.getReg();
2985 if (!Hexagon::DoubleRegsRegClass.contains(R))
2986 return true;
2987 Regs[R] = true;
2988 }
2989 int F = Regs.find_first();
2990 if (F != Hexagon::D8)
2991 return true;
2992 while (F >= 0) {
2993 int N = Regs.find_next(F);
2994 if (N >= 0 && N != F+1)
2995 return true;
2996 F = N;
2997 }
2998
2999 return false;
3000}
3001
3002bool HexagonFrameLowering::useSpillFunction(const MachineFunction &MF,
3003 const CSIVect &CSI) const {
3004 if (shouldInlineCSR(MF, CSI))
3005 return false;
3006 unsigned NumCSI = CSI.size();
3007 if (NumCSI <= 1)
3008 return false;
3009
3010 // Every spill stub saves the whole range starting at R16
3011 // (__save_r16_through_rNN), so a stub whose range reached the shadow call
3012 // stack pointer register would spill it along with the real callee-saved
3013 // registers - and since the SCS register is reserved it is absent from CSI,
3014 // so the stub's fixed frame layout would not match the one the compiler
3015 // assigned.
3016 //
3017 // shouldInlineCSR() above already makes this unreachable: it only lets a
3018 // stub through when CSI is a contiguous run of double registers starting at
3019 // D8, and reserving the SCS register always breaks the double it belongs
3020 // to, leaving its partner in CSI as a lone single register. This is a
3021 // cheap safety net so the guarantee does not rest on that reasoning alone.
3022 if (MF.getFunction().hasFnAttribute(Attribute::ShadowCallStack)) {
3023 const auto &HST = MF.getSubtarget<HexagonSubtarget>();
3024 Register MaxReg = getMaxCalleeSavedReg(CSI, *HST.getRegisterInfo());
3025 if (HST.getSCSPReg().id() <= MaxReg.id())
3026 return false;
3027 }
3028
3029 unsigned Threshold = isOptSize(MF) ? SpillFuncThresholdOs
3031 return Threshold < NumCSI;
3032}
3033
3034bool HexagonFrameLowering::useRestoreFunction(const MachineFunction &MF,
3035 const CSIVect &CSI) const {
3036 if (shouldInlineCSR(MF, CSI))
3037 return false;
3038 // The returning restore stubs do jumpr r31, this breaks ShadowCallStack:
3039 if (MF.getFunction().hasFnAttribute(Attribute::ShadowCallStack))
3040 return false;
3041 // The restore functions do a bit more than just restoring registers.
3042 // The non-returning versions will go back directly to the caller's
3043 // caller, others will clean up the stack frame in preparation for
3044 // a tail call. Using them can still save code size even if only one
3045 // register is getting restores. Make the decision based on -Oz:
3046 // using -Os will use inline restore for a single register.
3047 if (isMinSize(MF))
3048 return true;
3049 unsigned NumCSI = CSI.size();
3050 if (NumCSI <= 1)
3051 return false;
3052
3053 unsigned Threshold = isOptSize(MF) ? SpillFuncThresholdOs-1
3055 return Threshold < NumCSI;
3056}
3057
3058bool HexagonFrameLowering::mayOverflowFrameOffset(MachineFunction &MF) const {
3059 unsigned StackSize = MF.getFrameInfo().estimateStackSize(MF);
3060 auto &HST = MF.getSubtarget<HexagonSubtarget>();
3061 // A fairly simplistic guess as to whether a potential load/store to a
3062 // stack location could require an extra register.
3063 if (HST.useHVXOps() && StackSize > 256)
3064 return true;
3065
3066 // Check if the function has store-immediate instructions that access
3067 // the stack. Since the offset field is not extendable, if the stack
3068 // size exceeds the offset limit (6 bits, shifted), the stores will
3069 // require a new base register.
3070 bool HasImmStack = false;
3071 unsigned MinLS = ~0u; // Log_2 of the memory access size.
3072
3073 for (const MachineBasicBlock &B : MF) {
3074 for (const MachineInstr &MI : B) {
3075 unsigned LS = 0;
3076 switch (MI.getOpcode()) {
3077 case Hexagon::S4_storeirit_io:
3078 case Hexagon::S4_storeirif_io:
3079 case Hexagon::S4_storeiri_io:
3080 ++LS;
3081 [[fallthrough]];
3082 case Hexagon::S4_storeirht_io:
3083 case Hexagon::S4_storeirhf_io:
3084 case Hexagon::S4_storeirh_io:
3085 ++LS;
3086 [[fallthrough]];
3087 case Hexagon::S4_storeirbt_io:
3088 case Hexagon::S4_storeirbf_io:
3089 case Hexagon::S4_storeirb_io:
3090 if (MI.getOperand(0).isFI())
3091 HasImmStack = true;
3092 MinLS = std::min(MinLS, LS);
3093 break;
3094 }
3095 }
3096 }
3097
3098 if (HasImmStack)
3099 return !isUInt<6>(StackSize >> MinLS);
3100
3101 return false;
3102}
3103
3104namespace {
3105// Struct used by orderFrameObjects to help sort the stack objects.
3106struct HexagonFrameSortingObject {
3107 bool IsValid = false;
3108 unsigned Index = 0; // Index of Object into MFI list.
3109 unsigned Size = 0;
3110 Align ObjectAlignment = Align(1); // Alignment of Object in bytes.
3111};
3112
3113struct HexagonFrameSortingComparator {
3114 inline bool operator()(const HexagonFrameSortingObject &A,
3115 const HexagonFrameSortingObject &B) const {
3116 return std::make_tuple(!A.IsValid, A.ObjectAlignment, A.Size) <
3117 std::make_tuple(!B.IsValid, B.ObjectAlignment, B.Size);
3118 }
3119};
3120} // namespace
3121
3122// Sort objects on the stack by alignment value and then by size to minimize
3123// padding.
3125 const MachineFunction &MF, SmallVectorImpl<int> &ObjectsToAllocate) const {
3126
3127 if (ObjectsToAllocate.empty())
3128 return;
3129
3130 const MachineFrameInfo &MFI = MF.getFrameInfo();
3131 int NObjects = ObjectsToAllocate.size();
3132
3133 // Create an array of all MFI objects.
3135 MFI.getObjectIndexEnd());
3136
3137 for (int i = 0, j = 0, e = MFI.getObjectIndexEnd(); i < e && j != NObjects;
3138 ++i) {
3139 if (i != ObjectsToAllocate[j])
3140 continue;
3141 j++;
3142
3143 // A variable size object has size equal to 0. Since Hexagon sets
3144 // getUseLocalStackAllocationBlock() to true, a local block is allocated
3145 // earlier. This case is not handled here for now.
3146 int Size = MFI.getObjectSize(i);
3147 if (Size == 0)
3148 return;
3149
3150 SortingObjects[i].IsValid = true;
3151 SortingObjects[i].Index = i;
3152 SortingObjects[i].Size = Size;
3153 SortingObjects[i].ObjectAlignment = MFI.getObjectAlign(i);
3154 }
3155
3156 // Sort objects by alignment and then by size.
3157 llvm::stable_sort(SortingObjects, HexagonFrameSortingComparator());
3158
3159 // Modify the original list to represent the final order.
3160 int i = NObjects;
3161 for (auto &Obj : SortingObjects) {
3162 if (i == 0)
3163 break;
3164 ObjectsToAllocate[--i] = Obj.Index;
3165 }
3166}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
MachineBasicBlock & MBB
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
MachineBasicBlock MachineBasicBlock::iterator MBBI
This file contains the simple types necessary to represent the attributes associated with functions a...
This file implements the BitVector class.
static GCRegistry::Add< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static RegisterPass< DebugifyModulePass > DM("debugify", "Attach debug info to everything")
This file defines the DenseMap class.
This file contains constants used for implementing Dwarf debug support.
static MachineInstr * getReturn(MachineBasicBlock &MBB)
Returns the "return" instruction from this block, or nullptr if there isn't any.
static cl::opt< unsigned > ShrinkLimit("shrink-frame-limit", cl::init(std::numeric_limits< unsigned >::max()), cl::Hidden, cl::desc("Max count of stack frame shrink-wraps"))
static bool isOptNone(const MachineFunction &MF)
static cl::opt< int > SpillFuncThreshold("spill-func-threshold", cl::Hidden, cl::desc("Specify O2(not Os) spill func threshold"), cl::init(6))
static std::optional< MachineBasicBlock::iterator > findCFILocation(MachineBasicBlock &B)
static cl::opt< bool > EliminateFramePointer("hexagon-fp-elim", cl::init(true), cl::Hidden, cl::desc("Refrain from using FP whenever possible"))
static bool enableAllocFrameElim(const MachineFunction &MF)
static const char * getSpillFunctionFor(Register MaxReg, SpillKind SpillType, bool Stkchk=false)
static bool hasReturn(const MachineBasicBlock &MBB)
Returns true if MBB contains an instruction that returns.
static cl::opt< bool > EnableSaveRestoreLong("enable-save-restore-long", cl::Hidden, cl::desc("Enable long calls for save-restore stubs."), cl::init(false))
static bool needToReserveScavengingSpillSlots(MachineFunction &MF, const HexagonRegisterInfo &HRI, const TargetRegisterClass *RC)
Returns true if there are no caller-saved registers available in class RC.
static bool isOptSize(const MachineFunction &MF)
static Register getMax32BitSubRegister(Register Reg, const TargetRegisterInfo &TRI, bool hireg=true)
Map a register pair Reg to the subregister that has the greater "number", i.e.
static cl::opt< int > SpillFuncThresholdOs("spill-func-threshold-Os", cl::Hidden, cl::desc("Specify Os spill func threshold"), cl::init(1))
static bool needsStackFrame(const MachineBasicBlock &MBB, const BitVector &CSR, const HexagonRegisterInfo &HRI)
Checks if the basic block contains any instruction that needs a stack frame to be already in place.
static cl::opt< bool > DisableDeallocRet("disable-hexagon-dealloc-ret", cl::Hidden, cl::desc("Disable Dealloc Return for Hexagon target"))
static cl::opt< bool > EnableShrinkWrapping("hexagon-shrink-frame", cl::init(true), cl::Hidden, cl::desc("Enable stack frame shrink wrapping"))
static bool hasTailCall(const MachineBasicBlock &MBB)
Returns true if MBB has a machine instructions that indicates a tail call in the block.
static cl::opt< unsigned > NumberScavengerSlots("number-scavenger-slots", cl::Hidden, cl::desc("Set the number of scavenger slots"), cl::init(2))
static Register getMaxCalleeSavedReg(ArrayRef< CalleeSavedInfo > CSI, const TargetRegisterInfo &TRI)
Returns the callee saved register with the largest id in the vector.
static bool isMinSize(const MachineFunction &MF)
static cl::opt< unsigned > SpillOptMax("spill-opt-max", cl::Hidden, cl::init(std::numeric_limits< unsigned >::max()))
static unsigned SpillOptCount
static void dump_registers(BitVector &Regs, const TargetRegisterInfo &TRI)
static void emitSCSPrologue(MachineFunction &MF, MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, const DebugLoc &DL)
static bool isRestoreCall(unsigned Opc)
static cl::opt< bool > OptimizeSpillSlots("hexagon-opt-spill", cl::Hidden, cl::init(true), cl::desc("Optimize spill slots"))
static void emitSCSEpilogue(MachineFunction &MF, MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, const DebugLoc &DL)
static cl::opt< bool > EnableStackOVFSanitizer("enable-stackovf-sanitizer", cl::Hidden, cl::desc("Enable runtime checks for stack overflow."), cl::init(false))
IRTranslator LLVM IR MI
Legalize the Machine IR a function s Machine IR
Definition Legalizer.cpp:81
This file implements the LivePhysRegs utility for tracking liveness of physical registers.
#define F(x, y, z)
Definition MD5.cpp:54
#define I(x, y, z)
Definition MD5.cpp:57
Register Reg
Register const TargetRegisterInfo * TRI
Promote Memory to Register
Definition Mem2Reg.cpp:110
#define T
static MCRegister getReg(const MCDisassembler *D, unsigned RC, unsigned RegNo)
ConstantRange Range(APInt(BitWidth, Low), APInt(BitWidth, High))
#define P(N)
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
Definition PassSupport.h:56
This file builds on the ADT/GraphTraits.h file to build a generic graph post order iterator.
This file declares the machine register scavenger class.
bool isDead(const MachineInstr &MI, const MachineRegisterInfo &MRI)
static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)
Definition Value.cpp:484
This file implements a set that has insertion order iteration characteristics.
This file defines the SmallSet class.
This file defines the SmallVector class.
#define LLVM_DEBUG(...)
Definition Debug.h:119
Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition ArrayRef.h:40
size_t size() const
Get the array size.
Definition ArrayRef.h:141
bool empty() const
Check if the array is empty.
Definition ArrayRef.h:136
int find_first() const
Returns the index of the first set bit, -1 if none of the bits are set.
Definition BitVector.h:317
void resize(unsigned N, bool t=false)
Grow or shrink the bitvector.
Definition BitVector.h:355
BitVector & set()
Set all bits in the bitvector.
Definition BitVector.h:366
int find_next(unsigned Prev) const
Returns the index of the next set bit following the "Prev" bit.
Definition BitVector.h:324
Helper class for creating CFI instructions and inserting them into MIR.
void buildEscape(StringRef Bytes, StringRef Comment="") const
void buildRestore(MCRegister Reg) const
The CalleeSavedInfo class tracks the information need to locate where a callee saved register is in t...
A debug info location.
Definition DebugLoc.h:126
NodeT * findNearestCommonDominator(NodeT *A, NodeT *B) const
Find nearest common dominator basic block for basic block A and B.
bool dominates(const DomTreeNodeBase< NodeT > *A, const DomTreeNodeBase< NodeT > *B) const
dominates - Returns true iff A dominates B.
void recalculate(ParentType &Func)
recalculate - compute a dominator tree for the given function
FunctionPass class - This class is used to implement most global optimizations.
Definition Pass.h:314
bool hasMinSize() const
Optimize this function for minimum size (-Oz).
Definition Function.h:688
bool hasOptNone() const
Do not optimize this function (-O0).
Definition Function.h:685
bool isVarArg() const
isVarArg - Return true if this function takes a variable number of arguments.
Definition Function.h:229
bool hasFnAttribute(Attribute::AttrKind Kind) const
Return true if the function has the attribute.
Definition Function.cpp:727
void replaceInstr(MachineInstr *OldMI, MachineInstr *NewMI)
IndexType getIndex(MachineInstr *MI) const
MachineInstr * getInstr(IndexType Idx) const
void add(IndexType Start, IndexType End, bool Fixed, bool TiedEnd)
const MachineInstr * getAlignaInstr(const MachineFunction &MF) const
void insertCFIInstructions(MachineFunction &MF) const
bool hasFPImpl(const MachineFunction &MF) const override
bool enableCalleeSaveSkip(const MachineFunction &MF) const override
Returns true if the target can safely skip saving callee-saved registers for noreturn nounwind functi...
MachineBasicBlock::iterator eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB, MachineBasicBlock::iterator I) const override
This method is called during prolog/epilog code insertion to eliminate call frame setup and destroy p...
StackOffset getFrameIndexReference(const MachineFunction &MF, int FI, Register &FrameReg) const override
getFrameIndexReference - This method should return the base register and offset used to reference a f...
void emitPrologue(MachineFunction &MF, MachineBasicBlock &MBB) const override
Perform most of the PEI work here:
void determineCalleeSaves(MachineFunction &MF, BitVector &SavedRegs, RegScavenger *RS) const override
This method determines which of the registers reported by TargetRegisterInfo::getCalleeSavedRegs() sh...
void orderFrameObjects(const MachineFunction &MF, SmallVectorImpl< int > &ObjectsToAllocate) const override
Order the symbols in the local stack frame.
void processFunctionBeforeFrameFinalized(MachineFunction &MF, RegScavenger *RS=nullptr) const override
processFunctionBeforeFrameFinalized - This method is called immediately before the specified function...
void inlineStackProbe(MachineFunction &MF, MachineBasicBlock &PrologueMBB) const override
Replace a StackProbe stub (if any) with the actual probe code inline.
const SpillSlot * getCalleeSavedSpillSlots(unsigned &NumEntries) const override
getCalleeSavedSpillSlots - This method returns a pointer to an array of pairs, that contains an entry...
bool needsAligna(const MachineFunction &MF) const
bool assignCalleeSavedSpillSlots(MachineFunction &MF, const TargetRegisterInfo *TRI, std::vector< CalleeSavedInfo > &CSI) const override
assignCalleeSavedSpillSlots - Allows target to override spill slot assignment logic.
void storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, Register SrcReg, bool isKill, int FrameIndex, const TargetRegisterClass *RC, Register VReg, MachineInstr::MIFlag Flags=MachineInstr::NoFlags) const override
Store the specified register of the given register class to the specified stack frame index.
const HexagonRegisterInfo & getRegisterInfo() const
void loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, Register DestReg, int FrameIndex, const TargetRegisterClass *RC, Register VReg, unsigned SubReg=0, MachineInstr::MIFlag Flags=MachineInstr::NoFlags) const override
Load the specified register of the given register class from the specified stack frame index.
Hexagon target-specific information for each MachineFunction.
bool isEHReturnCalleeSaveReg(Register Reg) const
const MCPhysReg * getCalleeSavedRegs(const MachineFunction *MF) const override
Code Generation virtual methods...
const MCPhysReg * getCallerSavedRegs(const MachineFunction *MF, const TargetRegisterClass *RC) const
const HexagonInstrInfo * getInstrInfo() const override
const HexagonFrameLowering * getFrameLowering() const override
static MCCFIInstruction cfiDefCfa(MCSymbol *L, unsigned Register, int64_t Offset, SMLoc Loc={})
.cfi_def_cfa defines a rule for computing CFA as: take address from Register and add Offset to it.
Definition MCDwarf.h:628
static MCCFIInstruction createOffset(MCSymbol *L, unsigned Register, int64_t Offset, SMLoc Loc={})
.cfi_offset Previous value of Register is saved at offset Offset from CFA.
Definition MCDwarf.h:670
LLVM_ABI MCSymbol * createTempSymbol()
Create a temporary symbol with a unique name.
Describe properties that are true of each instruction in the target description file.
MCRegAliasIterator enumerates all registers aliasing Reg.
unsigned getID() const
getID() - Return the register class ID number.
bool hasSubClassEq(const MCRegisterClass *RC) const
Returns true if RC is a sub-class of or equal to this class.
Wrapper class representing physical registers. Should be passed by value.
Definition MCRegister.h:41
constexpr bool isValid() const
Definition MCRegister.h:84
constexpr bool isPhysical() const
Return true if the specified register number is in the physical register namespace.
Definition MCRegister.h:72
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
Definition MCSymbol.h:42
LLVM_ABI void transferSuccessorsAndUpdatePHIs(MachineBasicBlock *FromMBB)
Transfers all the successors, as in transferSuccessors, and update PHI operands in the successor bloc...
MachineInstrBundleIterator< const MachineInstr > const_iterator
int getNumber() const
MachineBasicBlocks are uniquely numbered at the function level, unless they're not in a MachineFuncti...
const BasicBlock * getBasicBlock() const
Return the LLVM basic block that this instance corresponded to originally.
LLVM_ABI iterator getFirstTerminator()
Returns an iterator to the first terminator instruction of this basic block.
LLVM_ABI void addSuccessor(MachineBasicBlock *Succ, BranchProbability Prob=BranchProbability::getUnknown())
Add Succ as a successor of this MachineBasicBlock.
LLVM_ABI DebugLoc findDebugLoc(instr_iterator MBBI)
Find the next valid DebugLoc starting at MBBI, skipping any debug instructions.
void addLiveIn(MCRegister PhysReg, LaneBitmask LaneMask=LaneBitmask::getAll())
Adds the specified register as a live in.
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
LLVM_ABI instr_iterator erase(instr_iterator I)
Remove an instruction from the instruction list and delete it.
iterator_range< succ_iterator > successors()
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
LLVM_ABI bool isLiveIn(MCRegister Reg, LaneBitmask LaneMask=LaneBitmask::getAll()) const
Return true if the specified register is in the live in set.
bool dominates(const MachineInstr *A, const MachineInstr *B) const
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted.
void setMaxCallFrameSize(uint64_t S)
bool hasVarSizedObjects() const
This method may be called any time after instruction selection is complete to determine if the stack ...
bool isObjectPreAllocated(int ObjectIdx) const
Return true if the object was pre-allocated into the local block.
uint64_t getStackSize() const
Return the number of bytes that must be allocated to hold all of the fixed size frame objects.
bool hasCalls() const
Return true if the current function has any function calls.
Align getMaxAlign() const
Return the alignment in bytes that this function must be aligned to, which is greater than the defaul...
uint64_t getMaxCallFrameSize() const
Return the maximum size of a call frame that must be allocated for an outgoing function call.
LLVM_ABI uint64_t estimateStackSize(const MachineFunction &MF) const
Estimate and return the size of the stack frame.
Align getObjectAlign(int ObjectIdx) const
Return the alignment of the specified stack object.
int64_t getObjectSize(int ObjectIdx) const
Return the size of the specified object.
LLVM_ABI int CreateSpillStackObject(uint64_t Size, Align Alignment, TargetStackID::Value StackID=TargetStackID::Default)
Create a new statically sized stack object that represents a spill slot, returning a nonnegative iden...
const std::vector< CalleeSavedInfo > & getCalleeSavedInfo() const
Returns a reference to call saved info vector for the current function.
int getObjectIndexEnd() const
Return one past the maximum frame object index.
LLVM_ABI int CreateFixedSpillStackObject(uint64_t Size, int64_t SPOffset, bool IsImmutable=false)
Create a spill slot at a fixed location on the stack.
int64_t getObjectOffset(int ObjectIdx) const
Return the assigned stack offset of the specified object from the incoming stack pointer.
void setStackSize(uint64_t Size)
Set the size of the stack.
bool isFixedObjectIndex(int ObjectIdx) const
Returns true if the specified index corresponds to a fixed stack object.
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
Properties which a MachineFunction may have at a given point in time.
unsigned addFrameInst(const MCCFIInstruction &Inst)
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.
bool needsFrameMoves() const
True if this function needs frame moves for debug or exceptions.
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
MCContext & getContext() const
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
MachineBasicBlock * getBlockNumbered(unsigned N) const
getBlockNumbered - MachineBasicBlocks are automatically numbered when they are inserted into the mach...
Function & getFunction()
Return the LLVM function that this machine code represents.
unsigned getNumBlockIDs() const
getNumBlockIDs - Return the number of MBB ID's allocated.
BasicBlockListType::iterator iterator
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
const MachineBasicBlock & front() const
MachineMemOperand * getMachineMemOperand(MachinePointerInfo PtrInfo, MachineMemOperand::Flags F, LLT MemTy, Align BaseAlignment, const MMOMetadata &Metadata=MMOMetadata(), SyncScope::ID SSID=SyncScope::System, AtomicOrdering Ordering=AtomicOrdering::NotAtomic, AtomicOrdering FailureOrdering=AtomicOrdering::NotAtomic)
getMachineMemOperand - Allocate a new MachineMemOperand.
MachineBasicBlock * CreateMachineBasicBlock(const BasicBlock *BB=nullptr, std::optional< UniqueBBID > BBID=std::nullopt)
CreateMachineInstr - Allocate a new MachineInstr.
void insert(iterator MBBI, MachineBasicBlock *MBB)
const TargetMachine & getTarget() const
getTarget - Return the target machine this machine code is compiled with
const MachineInstrBuilder & addExternalSymbol(const char *FnName, unsigned TargetFlags=0) const
const MachineInstrBuilder & addCFIIndex(unsigned CFIIndex) const
const MachineInstrBuilder & addReg(Register RegNo, RegState Flags={}, unsigned SubReg=0) const
Add a new virtual register operand.
const MachineInstrBuilder & setMIFlag(MachineInstr::MIFlag Flag) const
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
const MachineInstrBuilder & add(const MachineOperand &MO) const
const MachineInstrBuilder & addFrameIndex(int Idx) const
const MachineInstrBuilder & addMBB(MachineBasicBlock *MBB, unsigned TargetFlags=0) const
const MachineInstrBuilder & addDef(Register RegNo, RegState Flags={}, unsigned SubReg=0) const
Add a virtual register definition operand.
const MachineInstrBuilder & cloneMemRefs(const MachineInstr &OtherMI) const
const MachineInstrBuilder & setMIFlags(unsigned Flags) const
const MachineInstrBuilder & addMemOperand(MachineMemOperand *MMO) const
Representation of each machine instruction.
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
bool isReturn(QueryType Type=AnyInBundle) const
const MachineBasicBlock * getParent() const
LLVM_ABI void addOperand(MachineFunction &MF, const MachineOperand &Op)
Add the specified operand to the instruction.
LLVM_ABI void copyImplicitOps(MachineFunction &MF, const MachineInstr &MI)
Copy implicit register operands from specified instruction to this instruction.
bool mayLoad(QueryType Type=AnyInBundle) const
Return true if this instruction could possibly read memory.
const DebugLoc & getDebugLoc() const
Returns the debug location id of this MachineInstr.
const MachineOperand & getOperand(unsigned i) const
@ MOStore
The memory access writes data.
MachineOperand class - Representation of each machine instruction operand.
void setSubReg(unsigned subReg)
unsigned getSubReg() const
int64_t getImm() const
LLVM_ABI void setReg(Register Reg)
Change the register this operand corresponds to.
void setIsKill(bool Val=true)
Register getReg() const
getReg - Returns the register number.
static MachineOperand CreateReg(Register Reg, bool isDef, bool isImp=false, bool isKill=false, bool isDead=false, bool isUndef=false, bool isEarlyClobber=false, unsigned SubReg=0, bool isDebug=false, bool isInternalRead=false, bool isRenamable=false)
LLVM_ABI MachineBasicBlock * findNearestCommonDominator(ArrayRef< MachineBasicBlock * > Blocks) const
Returns the nearest common dominator of the given blocks.
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
const TargetRegisterClass * getRegClass(Register Reg) const
Return the register class of the specified virtual register.
LLVM_ABI Register createVirtualRegister(const TargetRegisterClass *RegClass, StringRef Name="")
createVirtualRegister - Create and return a new virtual register in the function with the specified r...
LLVM_ABI bool isPhysRegUsed(MCRegister PhysReg, bool SkipRegMaskTest=false) const
Return true if the specified register is modified or read in this function.
Wrapper class representing virtual and physical registers.
Definition Register.h:20
constexpr bool isValid() const
Definition Register.h:112
A vector that has set insertion semantics.
Definition SetVector.h:57
size_type size() const
Determine the number of elements in the SetVector.
Definition SetVector.h:103
bool insert(const value_type &X)
Insert a new element into the SetVector.
Definition SetVector.h:157
size_type count(const T &V) const
count - Return 1 if the element is in the set, 0 otherwise.
Definition SmallSet.h:176
std::pair< const_iterator, bool > insert(const T &V)
insert - Insert an element into the set if it isn't already there.
Definition SmallSet.h:184
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
int64_t getFixed() const
Returns the fixed component of the stack.
Definition TypeSize.h:46
Represent a constant reference to a string, i.e.
Definition StringRef.h:56
LLVM_ABI std::string lower() const
bool hasFP(const MachineFunction &MF) const
hasFP - Return true if the specified function should have a dedicated frame pointer register.
virtual void determineCalleeSaves(MachineFunction &MF, BitVector &SavedRegs, RegScavenger *RS=nullptr) const
This method determines which of the registers reported by TargetRegisterInfo::getCalleeSavedRegs() sh...
Align getStackAlign() const
getStackAlignment - This method returns the number of bytes to which the stack pointer must be aligne...
const TargetRegisterInfo & getRegisterInfo() const
Primary interface to the complete machine description for the target machine.
CodeGenOptLevel getOptLevel() const
Returns the optimization level: None, Less, Default, or Aggressive.
bool isPositionIndependent() const
TargetOptions Options
LLVM_ABI bool DisableFramePointerElim(const MachineFunction &MF) const
DisableFramePointerElim - This returns true if frame pointer elimination optimization should be disab...
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
virtual const TargetInstrInfo * getInstrInfo() const
virtual const TargetLowering * getTargetLowering() const
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition Twine.h:82
self_iterator getIterator()
Definition ilist_node.h:123
Changed
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
initializer< Ty > init(const Ty &Val)
This is an optimization pass for GlobalISel generic memory operations.
@ Offset
Definition DWP.cpp:578
void stable_sort(R &&Range)
Definition STLExtras.h:2116
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
@ Dead
Unused definition.
@ Kill
The last use of a register.
constexpr RegState getKillRegState(bool B)
@ Load
The value being inserted comes from a load (InsertElement only).
@ Store
The extracted value is stored (ExtractElement only).
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition Debug.cpp:209
FunctionPass * createHexagonCallFrameInformation()
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
Definition Error.cpp:163
constexpr uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
Definition Alignment.h:144
constexpr bool isUInt(uint64_t x)
Checks if an unsigned integer fits into the given bit width.
Definition MathExtras.h:190
@ Default
-O2, -Os, -Oz
Definition CodeGen.h:152
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
uint16_t MCPhysReg
An unsigned integer type large enough to represent all physical registers, but not necessarily virtua...
Definition MCRegister.h:21
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Count
Definition InstrProf.h:145
DWARFExpression::Operation Op
auto find_if(R &&Range, UnaryPredicate P)
Provide wrappers to std::find_if which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1772
MaybeAlign getStackAlign(const Function &F, unsigned Index)
void fullyRecomputeLiveIns(ArrayRef< MachineBasicBlock * > MBBs)
Convenience function for recomputing live-in's for a set of MBBs until the computation converges.
LLVM_ABI Printable printReg(Register Reg, const TargetRegisterInfo *TRI=nullptr, unsigned SubIdx=0, const MachineRegisterInfo *MRI=nullptr)
Prints virtual and physical registers with or without a TRI instance.
LLVM_ABI Printable printMBBReference(const MachineBasicBlock &MBB)
Prints a machine basic block reference.
MCRegisterClass TargetRegisterClass
Definition FastISel.h:58
#define N
This struct is a compact representation of a valid (non-zero power of two) alignment.
Definition Alignment.h:39
constexpr uint64_t value() const
This is a hole in the type system and should not be abused.
Definition Alignment.h:77
static RegisterSet expandToSubRegs(RegisterRef R, const MachineRegisterInfo &MRI, const TargetRegisterInfo &TRI)
std::map< RegisterRef, RangeList > RegToRangeMap
static LLVM_ABI MachinePointerInfo getStack(MachineFunction &MF, int64_t Offset, uint8_t ID=0)
Stack pointer relative access.