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