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