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