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 DeallocCall = BuildMI(MBB, It, DL, HII.get(RetOpc))
1772 .addExternalSymbol(RestoreFn);
1773 // Transfer the function live-out registers.
1774 DeallocCall->copyImplicitOps(MF, *It);
1775 }
1776 addCalleeSaveRegistersAsImpOperand(DeallocCall, CSI, true, false);
1777 return true;
1778 }
1779
1780 for (const CalleeSavedInfo &I : CSI) {
1781 MCRegister Reg = I.getReg();
1782 const TargetRegisterClass *RC = HRI.getMinimalPhysRegClass(Reg);
1783 int FI = I.getFrameIdx();
1784 HII.loadRegFromStackSlot(MBB, MI, Reg, FI, RC, Register());
1785 }
1786
1787 return true;
1788}
1789
1793 MachineInstr &MI = *I;
1794 unsigned Opc = MI.getOpcode();
1795 (void)Opc; // Silence compiler warning.
1796 assert((Opc == Hexagon::ADJCALLSTACKDOWN || Opc == Hexagon::ADJCALLSTACKUP) &&
1797 "Cannot handle this call frame pseudo instruction");
1798 return MBB.erase(I);
1799}
1800
1801/// Returns true if there are no caller-saved registers available in class RC.
1803 const HexagonRegisterInfo &HRI, const TargetRegisterClass *RC) {
1804 MachineRegisterInfo &MRI = MF.getRegInfo();
1805
1806 auto IsUsed = [&HRI,&MRI] (Register Reg) -> bool {
1807 for (MCRegAliasIterator AI(Reg, &HRI, true); AI.isValid(); ++AI)
1808 if (MRI.isPhysRegUsed(*AI))
1809 return true;
1810 return false;
1811 };
1812
1813 // Check for an unused caller-saved register. Callee-saved registers
1814 // have become pristine by now.
1815 for (const MCPhysReg *P = HRI.getCallerSavedRegs(&MF, RC); *P; ++P)
1816 if (!IsUsed(*P))
1817 return false;
1818
1819 // All caller-saved registers are used.
1820 return true;
1821}
1822
1823#ifndef NDEBUG
1825 dbgs() << '{';
1826 for (int x = Regs.find_first(); x >= 0; x = Regs.find_next(x)) {
1827 Register R = x;
1828 dbgs() << ' ' << printReg(R, &TRI);
1829 }
1830 dbgs() << " }";
1831}
1832#endif
1833
1835 const TargetRegisterInfo *TRI, std::vector<CalleeSavedInfo> &CSI) const {
1836 LLVM_DEBUG(dbgs() << __func__ << " on " << MF.getName() << '\n');
1837 MachineFrameInfo &MFI = MF.getFrameInfo();
1838 BitVector SRegs(Hexagon::NUM_TARGET_REGS);
1839
1840 // Generate a set of unique, callee-saved registers (SRegs), where each
1841 // register in the set is maximal in terms of sub-/super-register relation,
1842 // i.e. for each R in SRegs, no proper super-register of R is also in SRegs.
1843
1844 // (1) For each callee-saved register, add that register and all of its
1845 // sub-registers to SRegs.
1846 LLVM_DEBUG(dbgs() << "Initial CS registers: {");
1847 for (const CalleeSavedInfo &I : CSI) {
1848 Register R = I.getReg();
1849 LLVM_DEBUG(dbgs() << ' ' << printReg(R, TRI));
1850 for (MCPhysReg SR : TRI->subregs_inclusive(R))
1851 SRegs[SR] = true;
1852 }
1853 LLVM_DEBUG(dbgs() << " }\n");
1854 LLVM_DEBUG(dbgs() << "SRegs.1: "; dump_registers(SRegs, *TRI);
1855 dbgs() << "\n");
1856
1857 // (2) For each reserved register, remove that register and all of its
1858 // sub- and super-registers from SRegs.
1859 BitVector Reserved = TRI->getReservedRegs(MF);
1860 // Unreserve the stack align register: it is reserved for this function
1861 // only, it still needs to be saved/restored.
1862 Register AP =
1863 MF.getInfo<HexagonMachineFunctionInfo>()->getStackAlignBaseReg();
1864 assert((!needsAligna(MF) || AP.isValid()) &&
1865 "AP must be assigned before register allocation");
1866 if (AP.isValid()) {
1867 Reserved[AP] = false;
1868 // Unreserve super-regs if no other subregisters are reserved.
1869 for (MCPhysReg SP : TRI->superregs(AP)) {
1870 bool HasResSub = false;
1871 for (MCPhysReg SB : TRI->subregs(SP)) {
1872 if (!Reserved[SB])
1873 continue;
1874 HasResSub = true;
1875 break;
1876 }
1877 if (!HasResSub)
1878 Reserved[SP] = false;
1879 }
1880 }
1881
1882 for (int x = Reserved.find_first(); x >= 0; x = Reserved.find_next(x)) {
1883 Register R = x;
1884 for (MCPhysReg SR : TRI->superregs_inclusive(R))
1885 SRegs[SR] = false;
1886 }
1887 LLVM_DEBUG(dbgs() << "Res: "; dump_registers(Reserved, *TRI);
1888 dbgs() << "\n");
1889 LLVM_DEBUG(dbgs() << "SRegs.2: "; dump_registers(SRegs, *TRI);
1890 dbgs() << "\n");
1891
1892 // (3) Collect all registers that have at least one sub-register in SRegs,
1893 // and also have no sub-registers that are reserved. These will be the can-
1894 // didates for saving as a whole instead of their individual sub-registers.
1895 // (Saving R17:16 instead of R16 is fine, but only if R17 was not reserved.)
1896 BitVector TmpSup(Hexagon::NUM_TARGET_REGS);
1897 for (int x = SRegs.find_first(); x >= 0; x = SRegs.find_next(x)) {
1898 Register R = x;
1899 for (MCPhysReg SR : TRI->superregs(R))
1900 TmpSup[SR] = true;
1901 }
1902 for (int x = TmpSup.find_first(); x >= 0; x = TmpSup.find_next(x)) {
1903 Register R = x;
1904 for (MCPhysReg SR : TRI->subregs_inclusive(R)) {
1905 if (!Reserved[SR])
1906 continue;
1907 TmpSup[R] = false;
1908 break;
1909 }
1910 }
1911 LLVM_DEBUG(dbgs() << "TmpSup: "; dump_registers(TmpSup, *TRI);
1912 dbgs() << "\n");
1913
1914 // (4) Include all super-registers found in (3) into SRegs.
1915 SRegs |= TmpSup;
1916 LLVM_DEBUG(dbgs() << "SRegs.4: "; dump_registers(SRegs, *TRI);
1917 dbgs() << "\n");
1918
1919 // (5) For each register R in SRegs, if any super-register of R is in SRegs,
1920 // remove R from SRegs.
1921 for (int x = SRegs.find_first(); x >= 0; x = SRegs.find_next(x)) {
1922 Register R = x;
1923 for (MCPhysReg SR : TRI->superregs(R)) {
1924 if (!SRegs[SR])
1925 continue;
1926 SRegs[R] = false;
1927 break;
1928 }
1929 }
1930 LLVM_DEBUG(dbgs() << "SRegs.5: "; dump_registers(SRegs, *TRI);
1931 dbgs() << "\n");
1932
1933 // Now, for each register that has a fixed stack slot, create the stack
1934 // object for it.
1935 CSI.clear();
1936
1938
1939 unsigned NumFixed;
1940 int64_t MinOffset = 0; // CS offsets are negative.
1941 const SpillSlot *FixedSlots = getCalleeSavedSpillSlots(NumFixed);
1942 for (const SpillSlot *S = FixedSlots; S != FixedSlots+NumFixed; ++S) {
1943 if (!SRegs[S->Reg])
1944 continue;
1945 const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(S->Reg);
1946 int FI = MFI.CreateFixedSpillStackObject(TRI->getSpillSize(*RC), S->Offset);
1947 MinOffset = std::min(MinOffset, S->Offset);
1948 CSI.push_back(CalleeSavedInfo(S->Reg, FI));
1949 SRegs[S->Reg] = false;
1950 }
1951
1952 // There can be some registers that don't have fixed slots. For example,
1953 // we need to store R0-R3 in functions with exception handling. For each
1954 // such register, create a non-fixed stack object.
1955 for (int x = SRegs.find_first(); x >= 0; x = SRegs.find_next(x)) {
1956 Register R = x;
1957 const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(R);
1958 unsigned Size = TRI->getSpillSize(*RC);
1959 int64_t Off = MinOffset - Size;
1960 Align Alignment = std::min(TRI->getSpillAlign(*RC), getStackAlign());
1961 Off &= -Alignment.value();
1962 int FI = MFI.CreateFixedSpillStackObject(Size, Off);
1963 MinOffset = std::min(MinOffset, Off);
1964 CSI.push_back(CalleeSavedInfo(R, FI));
1965 SRegs[R] = false;
1966 }
1967
1968 LLVM_DEBUG({
1969 dbgs() << "CS information: {";
1970 for (const CalleeSavedInfo &I : CSI) {
1971 int FI = I.getFrameIdx();
1972 int Off = MFI.getObjectOffset(FI);
1973 dbgs() << ' ' << printReg(I.getReg(), TRI) << ":fi#" << FI << ":sp";
1974 if (Off >= 0)
1975 dbgs() << '+';
1976 dbgs() << Off;
1977 }
1978 dbgs() << " }\n";
1979 });
1980
1981#ifndef NDEBUG
1982 // Verify that all registers were handled.
1983 bool MissedReg = false;
1984 for (int x = SRegs.find_first(); x >= 0; x = SRegs.find_next(x)) {
1985 Register R = x;
1986 dbgs() << printReg(R, TRI) << ' ';
1987 MissedReg = true;
1988 }
1989 if (MissedReg)
1990 llvm_unreachable("...there are unhandled callee-saved registers!");
1991#endif
1992
1993 return true;
1994}
1995
1996bool HexagonFrameLowering::expandCopy(MachineBasicBlock &B,
1998 const HexagonInstrInfo &HII, SmallVectorImpl<Register> &NewRegs) const {
1999 MachineInstr *MI = &*It;
2000 DebugLoc DL = MI->getDebugLoc();
2001 Register DstR = MI->getOperand(0).getReg();
2002 Register SrcR = MI->getOperand(1).getReg();
2003 if (!Hexagon::ModRegsRegClass.contains(DstR) ||
2004 !Hexagon::ModRegsRegClass.contains(SrcR))
2005 return false;
2006
2007 Register TmpR = MRI.createVirtualRegister(&Hexagon::IntRegsRegClass);
2008 BuildMI(B, It, DL, HII.get(TargetOpcode::COPY), TmpR).add(MI->getOperand(1));
2009 BuildMI(B, It, DL, HII.get(TargetOpcode::COPY), DstR)
2010 .addReg(TmpR, RegState::Kill);
2011
2012 NewRegs.push_back(TmpR);
2013 B.erase(It);
2014 return true;
2015}
2016
2017bool HexagonFrameLowering::expandStoreInt(MachineBasicBlock &B,
2019 const HexagonInstrInfo &HII, SmallVectorImpl<Register> &NewRegs) const {
2020 MachineInstr *MI = &*It;
2021 if (!MI->getOperand(0).isFI())
2022 return false;
2023
2024 DebugLoc DL = MI->getDebugLoc();
2025 unsigned Opc = MI->getOpcode();
2026 Register SrcR = MI->getOperand(2).getReg();
2027 bool IsKill = MI->getOperand(2).isKill();
2028 int FI = MI->getOperand(0).getIndex();
2029
2030 // TmpR = C2_tfrpr SrcR if SrcR is a predicate register
2031 // TmpR = A2_tfrcrr SrcR if SrcR is a modifier register
2032 Register TmpR = MRI.createVirtualRegister(&Hexagon::IntRegsRegClass);
2033 unsigned TfrOpc = (Opc == Hexagon::STriw_pred) ? Hexagon::C2_tfrpr
2034 : Hexagon::A2_tfrcrr;
2035 BuildMI(B, It, DL, HII.get(TfrOpc), TmpR)
2036 .addReg(SrcR, getKillRegState(IsKill));
2037
2038 // S2_storeri_io FI, 0, TmpR
2039 BuildMI(B, It, DL, HII.get(Hexagon::S2_storeri_io))
2040 .addFrameIndex(FI)
2041 .addImm(0)
2042 .addReg(TmpR, RegState::Kill)
2043 .cloneMemRefs(*MI);
2044
2045 NewRegs.push_back(TmpR);
2046 B.erase(It);
2047 return true;
2048}
2049
2050bool HexagonFrameLowering::expandLoadInt(MachineBasicBlock &B,
2051 MachineBasicBlock::iterator It, MachineRegisterInfo &MRI,
2052 const HexagonInstrInfo &HII, SmallVectorImpl<Register> &NewRegs) const {
2053 MachineInstr *MI = &*It;
2054 if (!MI->getOperand(1).isFI())
2055 return false;
2056
2057 DebugLoc DL = MI->getDebugLoc();
2058 unsigned Opc = MI->getOpcode();
2059 Register DstR = MI->getOperand(0).getReg();
2060 int FI = MI->getOperand(1).getIndex();
2061
2062 // TmpR = L2_loadri_io FI, 0
2063 Register TmpR = MRI.createVirtualRegister(&Hexagon::IntRegsRegClass);
2064 BuildMI(B, It, DL, HII.get(Hexagon::L2_loadri_io), TmpR)
2065 .addFrameIndex(FI)
2066 .addImm(0)
2067 .cloneMemRefs(*MI);
2068
2069 // DstR = C2_tfrrp TmpR if DstR is a predicate register
2070 // DstR = A2_tfrrcr TmpR if DstR is a modifier register
2071 unsigned TfrOpc = (Opc == Hexagon::LDriw_pred) ? Hexagon::C2_tfrrp
2072 : Hexagon::A2_tfrrcr;
2073 BuildMI(B, It, DL, HII.get(TfrOpc), DstR)
2074 .addReg(TmpR, RegState::Kill);
2075
2076 NewRegs.push_back(TmpR);
2077 B.erase(It);
2078 return true;
2079}
2080
2081bool HexagonFrameLowering::expandStoreVecPred(MachineBasicBlock &B,
2082 MachineBasicBlock::iterator It, MachineRegisterInfo &MRI,
2083 const HexagonInstrInfo &HII, SmallVectorImpl<Register> &NewRegs) const {
2084 MachineInstr *MI = &*It;
2085 if (!MI->getOperand(0).isFI())
2086 return false;
2087
2088 DebugLoc DL = MI->getDebugLoc();
2089 Register SrcR = MI->getOperand(2).getReg();
2090 bool IsKill = MI->getOperand(2).isKill();
2091 int FI = MI->getOperand(0).getIndex();
2092 auto *RC = &Hexagon::HvxVRRegClass;
2093
2094 // Insert transfer to general vector register.
2095 // TmpR0 = A2_tfrsi 0x01010101
2096 // TmpR1 = V6_vandqrt Qx, TmpR0
2097 // store FI, 0, TmpR1
2098 Register TmpR0 = MRI.createVirtualRegister(&Hexagon::IntRegsRegClass);
2099 Register TmpR1 = MRI.createVirtualRegister(RC);
2100
2101 BuildMI(B, It, DL, HII.get(Hexagon::A2_tfrsi), TmpR0)
2102 .addImm(0x01010101);
2103
2104 BuildMI(B, It, DL, HII.get(Hexagon::V6_vandqrt), TmpR1)
2105 .addReg(SrcR, getKillRegState(IsKill))
2106 .addReg(TmpR0, RegState::Kill);
2107
2108 HII.storeRegToStackSlot(B, It, TmpR1, true, FI, RC, Register());
2109 expandStoreVec(B, std::prev(It), MRI, HII, NewRegs);
2110
2111 NewRegs.push_back(TmpR0);
2112 NewRegs.push_back(TmpR1);
2113 B.erase(It);
2114 return true;
2115}
2116
2117bool HexagonFrameLowering::expandLoadVecPred(MachineBasicBlock &B,
2118 MachineBasicBlock::iterator It, MachineRegisterInfo &MRI,
2119 const HexagonInstrInfo &HII, SmallVectorImpl<Register> &NewRegs) const {
2120 MachineInstr *MI = &*It;
2121 if (!MI->getOperand(1).isFI())
2122 return false;
2123
2124 DebugLoc DL = MI->getDebugLoc();
2125 Register DstR = MI->getOperand(0).getReg();
2126 int FI = MI->getOperand(1).getIndex();
2127 auto *RC = &Hexagon::HvxVRRegClass;
2128
2129 // TmpR0 = A2_tfrsi 0x01010101
2130 // TmpR1 = load FI, 0
2131 // DstR = V6_vandvrt TmpR1, TmpR0
2132 Register TmpR0 = MRI.createVirtualRegister(&Hexagon::IntRegsRegClass);
2133 Register TmpR1 = MRI.createVirtualRegister(RC);
2134
2135 BuildMI(B, It, DL, HII.get(Hexagon::A2_tfrsi), TmpR0)
2136 .addImm(0x01010101);
2137 HII.loadRegFromStackSlot(B, It, TmpR1, FI, RC, Register());
2138 expandLoadVec(B, std::prev(It), MRI, HII, NewRegs);
2139
2140 BuildMI(B, It, DL, HII.get(Hexagon::V6_vandvrt), DstR)
2141 .addReg(TmpR1, RegState::Kill)
2142 .addReg(TmpR0, RegState::Kill);
2143
2144 NewRegs.push_back(TmpR0);
2145 NewRegs.push_back(TmpR1);
2146 B.erase(It);
2147 return true;
2148}
2149
2150bool HexagonFrameLowering::expandStoreVec2(MachineBasicBlock &B,
2151 MachineBasicBlock::iterator It, MachineRegisterInfo &MRI,
2152 const HexagonInstrInfo &HII, SmallVectorImpl<Register> &NewRegs) const {
2153 MachineFunction &MF = *B.getParent();
2154 auto &MFI = MF.getFrameInfo();
2155 auto &HRI = *MF.getSubtarget<HexagonSubtarget>().getRegisterInfo();
2156 MachineInstr *MI = &*It;
2157 if (!MI->getOperand(0).isFI())
2158 return false;
2159
2160 // It is possible that the double vector being stored is only partially
2161 // defined. From the point of view of the liveness tracking, it is ok to
2162 // store it as a whole, but if we break it up we may end up storing a
2163 // register that is entirely undefined.
2164 LivePhysRegs LPR(HRI);
2165 LPR.addLiveIns(B);
2167 for (auto R = B.begin(); R != It; ++R) {
2168 Clobbers.clear();
2169 LPR.stepForward(*R, Clobbers);
2170 }
2171
2172 DebugLoc DL = MI->getDebugLoc();
2173 Register SrcR = MI->getOperand(2).getReg();
2174 Register SrcLo = HRI.getSubReg(SrcR, Hexagon::vsub_lo);
2175 Register SrcHi = HRI.getSubReg(SrcR, Hexagon::vsub_hi);
2176 bool IsKill = MI->getOperand(2).isKill();
2177 int FI = MI->getOperand(0).getIndex();
2178
2179 unsigned Size = HRI.getSpillSize(Hexagon::HvxVRRegClass);
2180 Align NeedAlign = HRI.getSpillAlign(Hexagon::HvxVRRegClass);
2181 Align HasAlign = MFI.getObjectAlign(FI);
2182 unsigned StoreOpc;
2183
2184 // Store low part.
2185 if (LPR.contains(SrcLo)) {
2186 StoreOpc = NeedAlign <= HasAlign ? Hexagon::V6_vS32b_ai
2187 : Hexagon::V6_vS32Ub_ai;
2188 BuildMI(B, It, DL, HII.get(StoreOpc))
2189 .addFrameIndex(FI)
2190 .addImm(0)
2191 .addReg(SrcLo, getKillRegState(IsKill))
2192 .cloneMemRefs(*MI);
2193 }
2194
2195 // Store high part.
2196 if (LPR.contains(SrcHi)) {
2197 StoreOpc = NeedAlign <= HasAlign ? Hexagon::V6_vS32b_ai
2198 : Hexagon::V6_vS32Ub_ai;
2199 BuildMI(B, It, DL, HII.get(StoreOpc))
2200 .addFrameIndex(FI)
2201 .addImm(Size)
2202 .addReg(SrcHi, getKillRegState(IsKill))
2203 .cloneMemRefs(*MI);
2204 }
2205
2206 B.erase(It);
2207 return true;
2208}
2209
2210bool HexagonFrameLowering::expandLoadVec2(MachineBasicBlock &B,
2211 MachineBasicBlock::iterator It, MachineRegisterInfo &MRI,
2212 const HexagonInstrInfo &HII, SmallVectorImpl<Register> &NewRegs) const {
2213 MachineFunction &MF = *B.getParent();
2214 auto &MFI = MF.getFrameInfo();
2215 auto &HRI = *MF.getSubtarget<HexagonSubtarget>().getRegisterInfo();
2216 MachineInstr *MI = &*It;
2217 if (!MI->getOperand(1).isFI())
2218 return false;
2219
2220 DebugLoc DL = MI->getDebugLoc();
2221 Register DstR = MI->getOperand(0).getReg();
2222 Register DstHi = HRI.getSubReg(DstR, Hexagon::vsub_hi);
2223 Register DstLo = HRI.getSubReg(DstR, Hexagon::vsub_lo);
2224 int FI = MI->getOperand(1).getIndex();
2225
2226 unsigned Size = HRI.getSpillSize(Hexagon::HvxVRRegClass);
2227 Align NeedAlign = HRI.getSpillAlign(Hexagon::HvxVRRegClass);
2228 Align HasAlign = MFI.getObjectAlign(FI);
2229 unsigned LoadOpc;
2230
2231 // Load low part.
2232 LoadOpc = NeedAlign <= HasAlign ? Hexagon::V6_vL32b_ai
2233 : Hexagon::V6_vL32Ub_ai;
2234 BuildMI(B, It, DL, HII.get(LoadOpc), DstLo)
2235 .addFrameIndex(FI)
2236 .addImm(0)
2237 .cloneMemRefs(*MI);
2238
2239 // Load high part.
2240 LoadOpc = NeedAlign <= HasAlign ? Hexagon::V6_vL32b_ai
2241 : Hexagon::V6_vL32Ub_ai;
2242 BuildMI(B, It, DL, HII.get(LoadOpc), DstHi)
2243 .addFrameIndex(FI)
2244 .addImm(Size)
2245 .cloneMemRefs(*MI);
2246
2247 B.erase(It);
2248 return true;
2249}
2250
2251bool HexagonFrameLowering::expandStoreVec(MachineBasicBlock &B,
2252 MachineBasicBlock::iterator It, MachineRegisterInfo &MRI,
2253 const HexagonInstrInfo &HII, SmallVectorImpl<Register> &NewRegs) const {
2254 MachineFunction &MF = *B.getParent();
2255 auto &MFI = MF.getFrameInfo();
2256 MachineInstr *MI = &*It;
2257 if (!MI->getOperand(0).isFI())
2258 return false;
2259
2260 auto &HRI = *MF.getSubtarget<HexagonSubtarget>().getRegisterInfo();
2261 DebugLoc DL = MI->getDebugLoc();
2262 Register SrcR = MI->getOperand(2).getReg();
2263 bool IsKill = MI->getOperand(2).isKill();
2264 int FI = MI->getOperand(0).getIndex();
2265
2266 Align NeedAlign = HRI.getSpillAlign(Hexagon::HvxVRRegClass);
2267 Align HasAlign = MFI.getObjectAlign(FI);
2268 unsigned StoreOpc = NeedAlign <= HasAlign ? Hexagon::V6_vS32b_ai
2269 : Hexagon::V6_vS32Ub_ai;
2270 BuildMI(B, It, DL, HII.get(StoreOpc))
2271 .addFrameIndex(FI)
2272 .addImm(0)
2273 .addReg(SrcR, getKillRegState(IsKill))
2274 .cloneMemRefs(*MI);
2275
2276 B.erase(It);
2277 return true;
2278}
2279
2280bool HexagonFrameLowering::expandLoadVec(MachineBasicBlock &B,
2281 MachineBasicBlock::iterator It, MachineRegisterInfo &MRI,
2282 const HexagonInstrInfo &HII, SmallVectorImpl<Register> &NewRegs) const {
2283 MachineFunction &MF = *B.getParent();
2284 auto &MFI = MF.getFrameInfo();
2285 MachineInstr *MI = &*It;
2286 if (!MI->getOperand(1).isFI())
2287 return false;
2288
2289 auto &HRI = *MF.getSubtarget<HexagonSubtarget>().getRegisterInfo();
2290 DebugLoc DL = MI->getDebugLoc();
2291 Register DstR = MI->getOperand(0).getReg();
2292 int FI = MI->getOperand(1).getIndex();
2293
2294 Align NeedAlign = HRI.getSpillAlign(Hexagon::HvxVRRegClass);
2295 Align HasAlign = MFI.getObjectAlign(FI);
2296 unsigned LoadOpc = NeedAlign <= HasAlign ? Hexagon::V6_vL32b_ai
2297 : Hexagon::V6_vL32Ub_ai;
2298 BuildMI(B, It, DL, HII.get(LoadOpc), DstR)
2299 .addFrameIndex(FI)
2300 .addImm(0)
2301 .cloneMemRefs(*MI);
2302
2303 B.erase(It);
2304 return true;
2305}
2306
2307bool HexagonFrameLowering::expandSpillMacros(MachineFunction &MF,
2308 SmallVectorImpl<Register> &NewRegs) const {
2309 auto &HII = *MF.getSubtarget<HexagonSubtarget>().getInstrInfo();
2310 MachineRegisterInfo &MRI = MF.getRegInfo();
2311 bool Changed = false;
2312
2313 for (auto &B : MF) {
2314 // Traverse the basic block.
2316 for (auto I = B.begin(), E = B.end(); I != E; I = NextI) {
2317 MachineInstr *MI = &*I;
2318 NextI = std::next(I);
2319 unsigned Opc = MI->getOpcode();
2320
2321 switch (Opc) {
2322 case TargetOpcode::COPY:
2323 Changed |= expandCopy(B, I, MRI, HII, NewRegs);
2324 break;
2325 case Hexagon::STriw_pred:
2326 case Hexagon::STriw_ctr:
2327 Changed |= expandStoreInt(B, I, MRI, HII, NewRegs);
2328 break;
2329 case Hexagon::LDriw_pred:
2330 case Hexagon::LDriw_ctr:
2331 Changed |= expandLoadInt(B, I, MRI, HII, NewRegs);
2332 break;
2333 case Hexagon::PS_vstorerq_ai:
2334 Changed |= expandStoreVecPred(B, I, MRI, HII, NewRegs);
2335 break;
2336 case Hexagon::PS_vloadrq_ai:
2337 Changed |= expandLoadVecPred(B, I, MRI, HII, NewRegs);
2338 break;
2339 case Hexagon::PS_vloadrw_ai:
2340 Changed |= expandLoadVec2(B, I, MRI, HII, NewRegs);
2341 break;
2342 case Hexagon::PS_vstorerw_ai:
2343 Changed |= expandStoreVec2(B, I, MRI, HII, NewRegs);
2344 break;
2345 }
2346 }
2347 }
2348
2349 return Changed;
2350}
2351
2353 BitVector &SavedRegs,
2354 RegScavenger *RS) const {
2355 auto &HRI = *MF.getSubtarget<HexagonSubtarget>().getRegisterInfo();
2356
2357 SavedRegs.resize(HRI.getNumRegs());
2358
2359 // If we have a function containing __builtin_eh_return we want to spill and
2360 // restore all callee saved registers. Pretend that they are used.
2362 for (const MCPhysReg *R = HRI.getCalleeSavedRegs(&MF); *R; ++R)
2363 SavedRegs.set(*R);
2364
2365 // If the function needs dynamic stack realignment, AP is a callee-saved
2366 // register that gets overwritten by the PS_aligna emitted in the prologue
2367 // but PS_aligna is created during emitPrologue, which runs after this hook.
2368 if (needsAligna(MF)) {
2369 Register AP =
2370 MF.getInfo<HexagonMachineFunctionInfo>()->getStackAlignBaseReg();
2371 assert(AP.isValid() && "AP must be assigned before register allocation");
2372 SavedRegs.set(AP);
2373 }
2374
2375 // Replace predicate register pseudo spill code.
2377 expandSpillMacros(MF, NewRegs);
2378 if (OptimizeSpillSlots && !isOptNone(MF))
2379 optimizeSpillSlots(MF, NewRegs);
2380
2381 // We need to reserve a spill slot if scavenging could potentially require
2382 // spilling a scavenged register.
2383 if (!NewRegs.empty() || mayOverflowFrameOffset(MF)) {
2384 MachineFrameInfo &MFI = MF.getFrameInfo();
2385 MachineRegisterInfo &MRI = MF.getRegInfo();
2387 // Reserve an int register in any case, because it could be used to hold
2388 // the stack offset in case it does not fit into a spill instruction.
2389 SpillRCs.insert(&Hexagon::IntRegsRegClass);
2390
2391 for (Register VR : NewRegs)
2392 SpillRCs.insert(MRI.getRegClass(VR));
2393
2394 for (const auto *RC : SpillRCs) {
2395 if (!needToReserveScavengingSpillSlots(MF, HRI, RC))
2396 continue;
2397 unsigned Num = 1;
2398 switch (RC->getID()) {
2399 case Hexagon::IntRegsRegClassID:
2401 break;
2402 case Hexagon::HvxQRRegClassID:
2403 Num = 2; // Vector predicate spills also need a vector register.
2404 break;
2405 }
2406 unsigned S = HRI.getSpillSize(*RC);
2407 Align A = HRI.getSpillAlign(*RC);
2408 for (unsigned i = 0; i < Num; i++) {
2409 int NewFI = MFI.CreateSpillStackObject(S, A);
2410 RS->addScavengingFrameIndex(NewFI);
2411 }
2412 }
2413 }
2414
2416}
2417
2418Register HexagonFrameLowering::findPhysReg(MachineFunction &MF,
2422 const TargetRegisterClass *RC) const {
2423 auto &HRI = *MF.getSubtarget<HexagonSubtarget>().getRegisterInfo();
2424 auto &MRI = MF.getRegInfo();
2425
2426 auto isDead = [&FIR,&DeadMap] (Register Reg) -> bool {
2427 auto F = DeadMap.find({Reg,0});
2428 if (F == DeadMap.end())
2429 return false;
2430 for (auto &DR : F->second)
2431 if (DR.contains(FIR))
2432 return true;
2433 return false;
2434 };
2435
2436 for (Register Reg : HRI.getRawAllocationOrder(*RC, MF)) {
2437 bool Dead = true;
2438 for (auto R : HexagonBlockRanges::expandToSubRegs({Reg,0}, MRI, HRI)) {
2439 if (isDead(R.Reg))
2440 continue;
2441 Dead = false;
2442 break;
2443 }
2444 if (Dead)
2445 return Reg;
2446 }
2447 return 0;
2448}
2449
2450void HexagonFrameLowering::optimizeSpillSlots(MachineFunction &MF,
2451 SmallVectorImpl<Register> &VRegs) const {
2452 auto &HST = MF.getSubtarget<HexagonSubtarget>();
2453 auto &HII = *HST.getInstrInfo();
2454 auto &HRI = *HST.getRegisterInfo();
2455 auto &MRI = MF.getRegInfo();
2456 HexagonBlockRanges HBR(MF);
2457
2458 using BlockIndexMap =
2459 std::map<MachineBasicBlock *, HexagonBlockRanges::InstrIndexMap>;
2460 using BlockRangeMap =
2461 std::map<MachineBasicBlock *, HexagonBlockRanges::RangeList>;
2462 using IndexType = HexagonBlockRanges::IndexType;
2463
2464 struct SlotInfo {
2465 BlockRangeMap Map;
2466 unsigned Size = 0;
2467 const TargetRegisterClass *RC = nullptr;
2468
2469 SlotInfo() = default;
2470 };
2471
2472 BlockIndexMap BlockIndexes;
2473 SmallSet<int,4> BadFIs;
2474 std::map<int,SlotInfo> FIRangeMap;
2475
2476 // Accumulate register classes: get a common class for a pre-existing
2477 // class HaveRC and a new class NewRC. Return nullptr if a common class
2478 // cannot be found, otherwise return the resulting class. If HaveRC is
2479 // nullptr, assume that it is still unset.
2480 auto getCommonRC =
2481 [](const TargetRegisterClass *HaveRC,
2482 const TargetRegisterClass *NewRC) -> const TargetRegisterClass * {
2483 if (HaveRC == nullptr || HaveRC == NewRC)
2484 return NewRC;
2485 // Different classes, both non-null. Pick the more general one.
2486 if (HaveRC->hasSubClassEq(NewRC))
2487 return HaveRC;
2488 if (NewRC->hasSubClassEq(HaveRC))
2489 return NewRC;
2490 return nullptr;
2491 };
2492
2493 // Scan all blocks in the function. Check all occurrences of frame indexes,
2494 // and collect relevant information.
2495 for (auto &B : MF) {
2496 std::map<int,IndexType> LastStore, LastLoad;
2497 auto P = BlockIndexes.emplace(&B, HexagonBlockRanges::InstrIndexMap(B));
2498 auto &IndexMap = P.first->second;
2499 LLVM_DEBUG(dbgs() << "Index map for " << printMBBReference(B) << "\n"
2500 << IndexMap << '\n');
2501
2502 for (auto &In : B) {
2503 // Debug instructions do not generate any code, and their operands
2504 // (including frame index operands) must not affect the decisions made
2505 // by this optimization.
2506 if (In.isDebugInstr())
2507 continue;
2508 int LFI, SFI;
2509 bool Load = HII.isLoadFromStackSlot(In, LFI) && !HII.isPredicated(In);
2510 bool Store = HII.isStoreToStackSlot(In, SFI) && !HII.isPredicated(In);
2511 if (Load && Store) {
2512 // If it's both a load and a store, then we won't handle it.
2513 BadFIs.insert(LFI);
2514 BadFIs.insert(SFI);
2515 continue;
2516 }
2517 // Check for register classes of the register used as the source for
2518 // the store, and the register used as the destination for the load.
2519 // Also, only accept base+imm_offset addressing modes. Other addressing
2520 // modes can have side-effects (post-increments, etc.). For stack
2521 // slots they are very unlikely, so there is not much loss due to
2522 // this restriction.
2523 if (Load || Store) {
2524 int TFI = Load ? LFI : SFI;
2525 unsigned AM = HII.getAddrMode(In);
2526 SlotInfo &SI = FIRangeMap[TFI];
2527 bool Bad = (AM != HexagonII::BaseImmOffset);
2528 if (!Bad) {
2529 // If the addressing mode is ok, check the register class.
2530 unsigned OpNum = Load ? 0 : 2;
2531 auto *RC = HII.getRegClass(In.getDesc(), OpNum);
2532 RC = getCommonRC(SI.RC, RC);
2533 if (RC == nullptr)
2534 Bad = true;
2535 else
2536 SI.RC = RC;
2537 }
2538 if (!Bad) {
2539 // Check sizes.
2540 unsigned S = HII.getMemAccessSize(In);
2541 if (SI.Size != 0 && SI.Size != S)
2542 Bad = true;
2543 else
2544 SI.Size = S;
2545 }
2546 if (!Bad) {
2547 for (auto *Mo : In.memoperands()) {
2548 if (!Mo->isVolatile() && !Mo->isAtomic())
2549 continue;
2550 Bad = true;
2551 break;
2552 }
2553 }
2554 if (Bad)
2555 BadFIs.insert(TFI);
2556 }
2557
2558 // Locate uses of frame indices.
2559 for (unsigned i = 0, n = In.getNumOperands(); i < n; ++i) {
2560 const MachineOperand &Op = In.getOperand(i);
2561 if (!Op.isFI())
2562 continue;
2563 int FI = Op.getIndex();
2564 // Make sure that the following operand is an immediate and that
2565 // it is 0. This is the offset in the stack object.
2566 if (i+1 >= n || !In.getOperand(i+1).isImm() ||
2567 In.getOperand(i+1).getImm() != 0)
2568 BadFIs.insert(FI);
2569 if (BadFIs.count(FI))
2570 continue;
2571
2572 IndexType Index = IndexMap.getIndex(&In);
2573 auto &LS = LastStore[FI];
2574 auto &LL = LastLoad[FI];
2575 if (Load) {
2576 if (LS == IndexType::None)
2577 LS = IndexType::Entry;
2578 LL = Index;
2579 } else if (Store) {
2580 HexagonBlockRanges::RangeList &RL = FIRangeMap[FI].Map[&B];
2581 if (LS != IndexType::None)
2582 RL.add(LS, LL, false, false);
2583 else if (LL != IndexType::None)
2584 RL.add(IndexType::Entry, LL, false, false);
2585 LL = IndexType::None;
2586 LS = Index;
2587 } else {
2588 BadFIs.insert(FI);
2589 }
2590 }
2591 }
2592
2593 for (auto &I : LastLoad) {
2594 IndexType LL = I.second;
2595 if (LL == IndexType::None)
2596 continue;
2597 auto &RL = FIRangeMap[I.first].Map[&B];
2598 IndexType &LS = LastStore[I.first];
2599 if (LS != IndexType::None)
2600 RL.add(LS, LL, false, false);
2601 else
2602 RL.add(IndexType::Entry, LL, false, false);
2603 LS = IndexType::None;
2604 }
2605 for (auto &I : LastStore) {
2606 IndexType LS = I.second;
2607 if (LS == IndexType::None)
2608 continue;
2609 auto &RL = FIRangeMap[I.first].Map[&B];
2610 RL.add(LS, IndexType::None, false, false);
2611 }
2612 }
2613
2614 LLVM_DEBUG({
2615 for (auto &P : FIRangeMap) {
2616 dbgs() << "fi#" << P.first;
2617 if (BadFIs.count(P.first))
2618 dbgs() << " (bad)";
2619 dbgs() << " RC: ";
2620 if (P.second.RC != nullptr)
2621 dbgs() << HRI.getRegClassName(P.second.RC) << '\n';
2622 else
2623 dbgs() << "<null>\n";
2624 for (auto &R : P.second.Map)
2625 dbgs() << " " << printMBBReference(*R.first) << " { " << R.second
2626 << "}\n";
2627 }
2628 });
2629
2630 // When a slot is loaded from in a block without being stored to in the
2631 // same block, it is live-on-entry to this block. To avoid CFG analysis,
2632 // consider this slot to be live-on-exit from all blocks.
2633 SmallSet<int,4> LoxFIs;
2634
2635 std::map<MachineBasicBlock*,std::vector<int>> BlockFIMap;
2636
2637 for (auto &P : FIRangeMap) {
2638 // P = pair(FI, map: BB->RangeList)
2639 if (BadFIs.count(P.first))
2640 continue;
2641 for (auto &B : MF) {
2642 auto F = P.second.Map.find(&B);
2643 // F = pair(BB, RangeList)
2644 if (F == P.second.Map.end() || F->second.empty())
2645 continue;
2646 HexagonBlockRanges::IndexRange &IR = F->second.front();
2647 if (IR.start() == IndexType::Entry)
2648 LoxFIs.insert(P.first);
2649 BlockFIMap[&B].push_back(P.first);
2650 }
2651 }
2652
2653 LLVM_DEBUG({
2654 dbgs() << "Block-to-FI map (* -- live-on-exit):\n";
2655 for (auto &P : BlockFIMap) {
2656 auto &FIs = P.second;
2657 if (FIs.empty())
2658 continue;
2659 dbgs() << " " << printMBBReference(*P.first) << ": {";
2660 for (auto I : FIs) {
2661 dbgs() << " fi#" << I;
2662 if (LoxFIs.count(I))
2663 dbgs() << '*';
2664 }
2665 dbgs() << " }\n";
2666 }
2667 });
2668
2669#ifndef NDEBUG
2670 bool HasOptLimit = SpillOptMax.getPosition();
2671#endif
2672
2673 // eliminate loads, when all loads eliminated, eliminate all stores.
2674 for (auto &B : MF) {
2675 auto F = BlockIndexes.find(&B);
2676 assert(F != BlockIndexes.end());
2677 HexagonBlockRanges::InstrIndexMap &IM = F->second;
2678 HexagonBlockRanges::RegToRangeMap LM = HBR.computeLiveMap(IM);
2679 HexagonBlockRanges::RegToRangeMap DM = HBR.computeDeadMap(IM, LM);
2680 LLVM_DEBUG(dbgs() << printMBBReference(B) << " dead map\n"
2681 << HexagonBlockRanges::PrintRangeMap(DM, HRI));
2682
2683 for (auto FI : BlockFIMap[&B]) {
2684 if (BadFIs.count(FI))
2685 continue;
2686 LLVM_DEBUG(dbgs() << "Working on fi#" << FI << '\n');
2687 HexagonBlockRanges::RangeList &RL = FIRangeMap[FI].Map[&B];
2688 for (auto &Range : RL) {
2689 LLVM_DEBUG(dbgs() << "--Examining range:" << RL << '\n');
2690 if (!IndexType::isInstr(Range.start()) ||
2691 !IndexType::isInstr(Range.end()))
2692 continue;
2693 MachineInstr &SI = *IM.getInstr(Range.start());
2694 MachineInstr &EI = *IM.getInstr(Range.end());
2695 assert(SI.mayStore() && "Unexpected start instruction");
2696 assert(EI.mayLoad() && "Unexpected end instruction");
2697 MachineOperand &SrcOp = SI.getOperand(2);
2698
2699 HexagonBlockRanges::RegisterRef SrcRR = { SrcOp.getReg(),
2700 SrcOp.getSubReg() };
2701 auto *RC = HII.getRegClass(SI.getDesc(), 2);
2702 // The this-> is needed to unconfuse MSVC.
2703 Register FoundR = this->findPhysReg(MF, Range, IM, DM, RC);
2704 LLVM_DEBUG(dbgs() << "Replacement reg:" << printReg(FoundR, &HRI)
2705 << '\n');
2706 if (FoundR == 0)
2707 continue;
2708#ifndef NDEBUG
2709 if (HasOptLimit) {
2711 return;
2712 SpillOptCount++;
2713 }
2714#endif
2715
2716 // Generate the copy-in: "FoundR = COPY SrcR" at the store location.
2717 MachineBasicBlock::iterator StartIt = SI.getIterator(), NextIt;
2718 MachineInstr *CopyIn = nullptr;
2719 if (SrcRR.Reg != FoundR || SrcRR.Sub != 0) {
2720 const DebugLoc &DL = SI.getDebugLoc();
2721 CopyIn = BuildMI(B, StartIt, DL, HII.get(TargetOpcode::COPY), FoundR)
2722 .add(SrcOp);
2723 }
2724
2725 ++StartIt;
2726 // Check if this is a last store and the FI is live-on-exit.
2727 if (LoxFIs.count(FI) && (&Range == &RL.back())) {
2728 // Update store's source register.
2729 if (unsigned SR = SrcOp.getSubReg())
2730 SrcOp.setReg(HRI.getSubReg(FoundR, SR));
2731 else
2732 SrcOp.setReg(FoundR);
2733 SrcOp.setSubReg(0);
2734 // We are keeping this register live.
2735 SrcOp.setIsKill(false);
2736 } else {
2737 B.erase(&SI);
2738 IM.replaceInstr(&SI, CopyIn);
2739 }
2740
2741 auto EndIt = std::next(EI.getIterator());
2742 for (auto It = StartIt; It != EndIt; It = NextIt) {
2743 MachineInstr &MI = *It;
2744 NextIt = std::next(It);
2745 int TFI;
2746 if (!HII.isLoadFromStackSlot(MI, TFI) || TFI != FI)
2747 continue;
2748 Register DstR = MI.getOperand(0).getReg();
2749 assert(MI.getOperand(0).getSubReg() == 0);
2750 MachineInstr *CopyOut = nullptr;
2751 if (DstR != FoundR) {
2752 DebugLoc DL = MI.getDebugLoc();
2753 unsigned MemSize = HII.getMemAccessSize(MI);
2754 assert(HII.getAddrMode(MI) == HexagonII::BaseImmOffset);
2755 unsigned CopyOpc = TargetOpcode::COPY;
2756 if (HII.isSignExtendingLoad(MI))
2757 CopyOpc = (MemSize == 1) ? Hexagon::A2_sxtb : Hexagon::A2_sxth;
2758 else if (HII.isZeroExtendingLoad(MI))
2759 CopyOpc = (MemSize == 1) ? Hexagon::A2_zxtb : Hexagon::A2_zxth;
2760 CopyOut = BuildMI(B, It, DL, HII.get(CopyOpc), DstR)
2761 .addReg(FoundR, getKillRegState(&MI == &EI));
2762 }
2763 IM.replaceInstr(&MI, CopyOut);
2764 B.erase(It);
2765 }
2766
2767 // Update the dead map.
2768 HexagonBlockRanges::RegisterRef FoundRR = { FoundR, 0 };
2769 for (auto RR : HexagonBlockRanges::expandToSubRegs(FoundRR, MRI, HRI))
2770 DM[RR].subtract(Range);
2771 } // for Range in range list
2772 }
2773 }
2774}
2775
2776void HexagonFrameLowering::expandAlloca(MachineInstr *AI, MachineFunction &MF,
2777 const HexagonInstrInfo &HII,
2778 Register SP, unsigned CF) const {
2779 MachineBasicBlock &MB = *AI->getParent();
2780 DebugLoc DL = AI->getDebugLoc();
2781 unsigned A = AI->getOperand(2).getImm();
2782
2783 MachineOperand &RdOp = AI->getOperand(0);
2784 MachineOperand &RsOp = AI->getOperand(1);
2785 Register Rd = RdOp.getReg(), Rs = RsOp.getReg();
2786
2787 auto &HST = MF.getSubtarget<HexagonSubtarget>();
2788 auto *TLI = HST.getTargetLowering();
2789 bool NeedsProbing = TLI->hasInlineStackProbe(MF);
2790
2791 if (!NeedsProbing) {
2792 // Have
2793 // Rd = alloca Rs, #A
2794 //
2795 // If Rs and Rd are different registers, use this sequence:
2796 // Rd = sub(r29, Rs)
2797 // r29 = sub(r29, Rs)
2798 // Rd = and(Rd, #-A) ; if necessary
2799 // r29 = and(r29, #-A) ; if necessary
2800 // Rd = add(Rd, #CF) ; CF size aligned to at most A
2801 // otherwise, do
2802 // Rd = sub(r29, Rs)
2803 // Rd = and(Rd, #-A) ; if necessary
2804 // r29 = Rd
2805 // Rd = add(Rd, #CF) ; CF size aligned to at most A
2806
2807 // Rd = sub(r29, Rs)
2808 BuildMI(MB, AI, DL, HII.get(Hexagon::A2_sub), Rd).addReg(SP).addReg(Rs);
2809 if (Rs != Rd) {
2810 // r29 = sub(r29, Rs)
2811 BuildMI(MB, AI, DL, HII.get(Hexagon::A2_sub), SP).addReg(SP).addReg(Rs);
2812 }
2813 if (A > 8) {
2814 // Rd = and(Rd, #-A)
2815 BuildMI(MB, AI, DL, HII.get(Hexagon::A2_andir), Rd)
2816 .addReg(Rd)
2817 .addImm(-int64_t(A));
2818 if (Rs != Rd)
2819 BuildMI(MB, AI, DL, HII.get(Hexagon::A2_andir), SP)
2820 .addReg(SP)
2821 .addImm(-int64_t(A));
2822 }
2823 if (Rs == Rd) {
2824 // r29 = Rd
2825 BuildMI(MB, AI, DL, HII.get(TargetOpcode::COPY), SP).addReg(Rd);
2826 }
2827 if (CF > 0) {
2828 // Rd = add(Rd, #CF)
2829 BuildMI(MB, AI, DL, HII.get(Hexagon::A2_addi), Rd).addReg(Rd).addImm(CF);
2830 }
2831 return;
2832 }
2833
2834 // Stack probing for dynamic allocation. The size Rs is a runtime value
2835 // so the probe loop is always emitted; it is a no-op when Rs is small.
2836 //
2837 // Compute the target SP into Rd (with optional alignment), then probe
2838 // each page on the way down:
2839 //
2840 // Rd = sub(r29, Rs)
2841 // [Rd = and(Rd, #-A)] ; if alignment > 8
2842 // LoopMBB:
2843 // r29 = add(r29, #-ProbeSize)
2844 // memw(r29+#0) = #0
2845 // p0 = cmp.gtu(r29, Rd)
2846 // if (p0.new) jump:t LoopMBB
2847 // ExitMBB:
2848 // r29 = Rd
2849 // [Rd = add(Rd, #CF)] ; if CF > 0
2850 // <rest of original block>
2851 //
2852 // Rd holds the exact (aligned) target SP throughout the loop, so the
2853 // final "r29 = Rd" snaps SP to the correct value even when Rs is not
2854 // a multiple of ProbeSize.
2855
2856 Align StackAlign = getStackAlign();
2857 unsigned ProbeSize = TLI->getStackProbeSize(MF, StackAlign);
2859
2860 // Emit target-SP computation into Rd before splitting the block.
2861 // Rd = sub(r29, Rs)
2862 BuildMI(MB, AI, DL, HII.get(Hexagon::A2_sub), Rd)
2863 .addReg(SP)
2864 .addReg(Rs)
2865 .setMIFlags(Flags);
2866 if (A > 8) {
2867 // Rd = and(Rd, #-A)
2868 BuildMI(MB, AI, DL, HII.get(Hexagon::A2_andir), Rd)
2869 .addReg(Rd)
2870 .addImm(-int64_t(A))
2871 .setMIFlags(Flags);
2872 }
2873
2874 // Split the block: everything after AI goes into ExitMBB.
2875 MachineFunction::iterator InsertPt = std::next(MB.getIterator());
2876 MachineBasicBlock *LoopMBB = MF.CreateMachineBasicBlock(MB.getBasicBlock());
2877 MF.insert(InsertPt, LoopMBB);
2878 MachineBasicBlock *ExitMBB = MF.CreateMachineBasicBlock(MB.getBasicBlock());
2879 MF.insert(InsertPt, ExitMBB);
2880
2881 // Move instructions after AI (exclusive) into ExitMBB.
2882 ExitMBB->splice(ExitMBB->end(), &MB, std::next(AI->getIterator()), MB.end());
2883 ExitMBB->transferSuccessorsAndUpdatePHIs(&MB);
2884
2885 // LoopMBB: probe each page.
2886 // r29 = add(r29, #-ProbeSize)
2887 // memw(r29+#0) = #0
2888 // p0 = cmp.gtu(r29, Rd)
2889 // if (p0.new) jump:t LoopMBB
2890 BuildMI(*LoopMBB, LoopMBB->end(), DL, HII.get(Hexagon::A2_addi), Hexagon::R29)
2891 .addReg(Hexagon::R29)
2892 .addImm(-int(ProbeSize))
2893 .setMIFlags(Flags);
2894
2895 BuildMI(*LoopMBB, LoopMBB->end(), DL, HII.get(Hexagon::S4_storeiri_io))
2896 .addReg(Hexagon::R29)
2897 .addImm(0)
2898 .addImm(0)
2899 .setMIFlags(Flags);
2900
2901 BuildMI(*LoopMBB, LoopMBB->end(), DL, HII.get(Hexagon::C2_cmpgtu),
2902 Hexagon::P0)
2903 .addReg(Hexagon::R29)
2904 .addReg(Rd)
2905 .setMIFlags(Flags);
2906
2907 BuildMI(*LoopMBB, LoopMBB->end(), DL, HII.get(Hexagon::J2_jumpt))
2908 .addReg(Hexagon::P0)
2909 .addMBB(LoopMBB)
2910 .setMIFlags(Flags);
2911
2912 // ExitMBB: snap SP to exact target, then apply CF offset to Rd.
2913 // r29 = Rd
2914 // [Rd = add(Rd, #CF)]
2915 MachineBasicBlock::iterator ExitIt = ExitMBB->begin();
2916 BuildMI(*ExitMBB, ExitIt, DL, HII.get(Hexagon::A2_tfr), Hexagon::R29)
2917 .addReg(Rd)
2918 .setMIFlags(Flags);
2919 if (CF > 0) {
2920 BuildMI(*ExitMBB, ExitIt, DL, HII.get(Hexagon::A2_addi), Rd)
2921 .addReg(Rd)
2922 .addImm(CF)
2923 .setMIFlags(Flags);
2924 }
2925
2926 // Wire up CFG edges.
2927 MB.addSuccessor(LoopMBB);
2928 LoopMBB->addSuccessor(LoopMBB);
2929 LoopMBB->addSuccessor(ExitMBB);
2930
2931 // Recompute live-ins for the new blocks. AI is still in MB at this
2932 // point; the caller erases it after expandAlloca returns.
2933 fullyRecomputeLiveIns({ExitMBB, LoopMBB});
2934}
2935
2937 const MachineFrameInfo &MFI = MF.getFrameInfo();
2938 if (!MFI.hasVarSizedObjects())
2939 return false;
2940 // Do not check for max stack object alignment here, because the stack
2941 // may not be complete yet. Assume that we will need PS_aligna if there
2942 // are variable-sized objects.
2943 return true;
2944}
2945
2946/// Adds all callee-saved registers as implicit uses or defs to the
2947/// instruction.
2948void HexagonFrameLowering::addCalleeSaveRegistersAsImpOperand(MachineInstr *MI,
2949 const CSIVect &CSI, bool IsDef, bool IsKill) const {
2950 // Add the callee-saved registers as implicit uses.
2951 for (auto &R : CSI)
2952 MI->addOperand(MachineOperand::CreateReg(R.getReg(), IsDef, true, IsKill));
2953}
2954
2955/// Determine whether the callee-saved register saves and restores should
2956/// be generated via inline code. If this function returns "true", inline
2957/// code will be generated. If this function returns "false", additional
2958/// checks are performed, which may still lead to the inline code.
2959bool HexagonFrameLowering::shouldInlineCSR(const MachineFunction &MF,
2960 const CSIVect &CSI) const {
2962 return true;
2964 return true;
2965 if (!hasFP(MF))
2966 return true;
2967 if (!isOptSize(MF) && !isMinSize(MF))
2969 return true;
2970
2971 // Check if CSI only has double registers, and if the registers form
2972 // a contiguous block starting from D8.
2973 BitVector Regs(Hexagon::NUM_TARGET_REGS);
2974 for (const CalleeSavedInfo &I : CSI) {
2975 MCRegister R = I.getReg();
2976 if (!Hexagon::DoubleRegsRegClass.contains(R))
2977 return true;
2978 Regs[R] = true;
2979 }
2980 int F = Regs.find_first();
2981 if (F != Hexagon::D8)
2982 return true;
2983 while (F >= 0) {
2984 int N = Regs.find_next(F);
2985 if (N >= 0 && N != F+1)
2986 return true;
2987 F = N;
2988 }
2989
2990 return false;
2991}
2992
2993bool HexagonFrameLowering::useSpillFunction(const MachineFunction &MF,
2994 const CSIVect &CSI) const {
2995 if (shouldInlineCSR(MF, CSI))
2996 return false;
2997 unsigned NumCSI = CSI.size();
2998 if (NumCSI <= 1)
2999 return false;
3000
3001 // Every spill stub saves the whole range starting at R16
3002 // (__save_r16_through_rNN), so a stub whose range reached the shadow call
3003 // stack pointer register would spill it along with the real callee-saved
3004 // registers - and since the SCS register is reserved it is absent from CSI,
3005 // so the stub's fixed frame layout would not match the one the compiler
3006 // assigned.
3007 //
3008 // shouldInlineCSR() above already makes this unreachable: it only lets a
3009 // stub through when CSI is a contiguous run of double registers starting at
3010 // D8, and reserving the SCS register always breaks the double it belongs
3011 // to, leaving its partner in CSI as a lone single register. This is a
3012 // cheap safety net so the guarantee does not rest on that reasoning alone.
3013 if (MF.getFunction().hasFnAttribute(Attribute::ShadowCallStack)) {
3014 const auto &HST = MF.getSubtarget<HexagonSubtarget>();
3015 Register MaxReg = getMaxCalleeSavedReg(CSI, *HST.getRegisterInfo());
3016 if (HST.getSCSPReg().id() <= MaxReg.id())
3017 return false;
3018 }
3019
3020 unsigned Threshold = isOptSize(MF) ? SpillFuncThresholdOs
3022 return Threshold < NumCSI;
3023}
3024
3025bool HexagonFrameLowering::useRestoreFunction(const MachineFunction &MF,
3026 const CSIVect &CSI) const {
3027 if (shouldInlineCSR(MF, CSI))
3028 return false;
3029 // The returning restore stubs do jumpr r31, this breaks ShadowCallStack:
3030 if (MF.getFunction().hasFnAttribute(Attribute::ShadowCallStack))
3031 return false;
3032 // The restore functions do a bit more than just restoring registers.
3033 // The non-returning versions will go back directly to the caller's
3034 // caller, others will clean up the stack frame in preparation for
3035 // a tail call. Using them can still save code size even if only one
3036 // register is getting restores. Make the decision based on -Oz:
3037 // using -Os will use inline restore for a single register.
3038 if (isMinSize(MF))
3039 return true;
3040 unsigned NumCSI = CSI.size();
3041 if (NumCSI <= 1)
3042 return false;
3043
3044 unsigned Threshold = isOptSize(MF) ? SpillFuncThresholdOs-1
3046 return Threshold < NumCSI;
3047}
3048
3049bool HexagonFrameLowering::mayOverflowFrameOffset(MachineFunction &MF) const {
3050 unsigned StackSize = MF.getFrameInfo().estimateStackSize(MF);
3051 auto &HST = MF.getSubtarget<HexagonSubtarget>();
3052 // A fairly simplistic guess as to whether a potential load/store to a
3053 // stack location could require an extra register.
3054 if (HST.useHVXOps() && StackSize > 256)
3055 return true;
3056
3057 // Check if the function has store-immediate instructions that access
3058 // the stack. Since the offset field is not extendable, if the stack
3059 // size exceeds the offset limit (6 bits, shifted), the stores will
3060 // require a new base register.
3061 bool HasImmStack = false;
3062 unsigned MinLS = ~0u; // Log_2 of the memory access size.
3063
3064 for (const MachineBasicBlock &B : MF) {
3065 for (const MachineInstr &MI : B) {
3066 unsigned LS = 0;
3067 switch (MI.getOpcode()) {
3068 case Hexagon::S4_storeirit_io:
3069 case Hexagon::S4_storeirif_io:
3070 case Hexagon::S4_storeiri_io:
3071 ++LS;
3072 [[fallthrough]];
3073 case Hexagon::S4_storeirht_io:
3074 case Hexagon::S4_storeirhf_io:
3075 case Hexagon::S4_storeirh_io:
3076 ++LS;
3077 [[fallthrough]];
3078 case Hexagon::S4_storeirbt_io:
3079 case Hexagon::S4_storeirbf_io:
3080 case Hexagon::S4_storeirb_io:
3081 if (MI.getOperand(0).isFI())
3082 HasImmStack = true;
3083 MinLS = std::min(MinLS, LS);
3084 break;
3085 }
3086 }
3087 }
3088
3089 if (HasImmStack)
3090 return !isUInt<6>(StackSize >> MinLS);
3091
3092 return false;
3093}
3094
3095namespace {
3096// Struct used by orderFrameObjects to help sort the stack objects.
3097struct HexagonFrameSortingObject {
3098 bool IsValid = false;
3099 unsigned Index = 0; // Index of Object into MFI list.
3100 unsigned Size = 0;
3101 Align ObjectAlignment = Align(1); // Alignment of Object in bytes.
3102};
3103
3104struct HexagonFrameSortingComparator {
3105 inline bool operator()(const HexagonFrameSortingObject &A,
3106 const HexagonFrameSortingObject &B) const {
3107 return std::make_tuple(!A.IsValid, A.ObjectAlignment, A.Size) <
3108 std::make_tuple(!B.IsValid, B.ObjectAlignment, B.Size);
3109 }
3110};
3111} // namespace
3112
3113// Sort objects on the stack by alignment value and then by size to minimize
3114// padding.
3116 const MachineFunction &MF, SmallVectorImpl<int> &ObjectsToAllocate) const {
3117
3118 if (ObjectsToAllocate.empty())
3119 return;
3120
3121 const MachineFrameInfo &MFI = MF.getFrameInfo();
3122 int NObjects = ObjectsToAllocate.size();
3123
3124 // Create an array of all MFI objects.
3126 MFI.getObjectIndexEnd());
3127
3128 for (int i = 0, j = 0, e = MFI.getObjectIndexEnd(); i < e && j != NObjects;
3129 ++i) {
3130 if (i != ObjectsToAllocate[j])
3131 continue;
3132 j++;
3133
3134 // A variable size object has size equal to 0. Since Hexagon sets
3135 // getUseLocalStackAllocationBlock() to true, a local block is allocated
3136 // earlier. This case is not handled here for now.
3137 int Size = MFI.getObjectSize(i);
3138 if (Size == 0)
3139 return;
3140
3141 SortingObjects[i].IsValid = true;
3142 SortingObjects[i].Index = i;
3143 SortingObjects[i].Size = Size;
3144 SortingObjects[i].ObjectAlignment = MFI.getObjectAlign(i);
3145 }
3146
3147 // Sort objects by alignment and then by size.
3148 llvm::stable_sort(SortingObjects, HexagonFrameSortingComparator());
3149
3150 // Modify the original list to represent the final order.
3151 int i = NObjects;
3152 for (auto &Obj : SortingObjects) {
3153 if (i == 0)
3154 break;
3155 ObjectsToAllocate[--i] = Obj.Index;
3156 }
3157}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
unsigned uint64_t
MachineBasicBlock & MBB
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
MachineBasicBlock MachineBasicBlock::iterator MBBI
This file contains the simple types necessary to represent the attributes associated with functions a...
This file implements the BitVector class.
static GCRegistry::Add< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static RegisterPass< DebugifyModulePass > DM("debugify", "Attach debug info to everything")
This file defines the DenseMap class.
This file contains constants used for implementing Dwarf debug support.
static MachineInstr * getReturn(MachineBasicBlock &MBB)
Returns the "return" instruction from this block, or nullptr if there isn't any.
static cl::opt< unsigned > ShrinkLimit("shrink-frame-limit", cl::init(std::numeric_limits< unsigned >::max()), cl::Hidden, cl::desc("Max count of stack frame shrink-wraps"))
static bool isOptNone(const MachineFunction &MF)
static cl::opt< int > SpillFuncThreshold("spill-func-threshold", cl::Hidden, cl::desc("Specify O2(not Os) spill func threshold"), cl::init(6))
static std::optional< MachineBasicBlock::iterator > findCFILocation(MachineBasicBlock &B)
static cl::opt< bool > EliminateFramePointer("hexagon-fp-elim", cl::init(true), cl::Hidden, cl::desc("Refrain from using FP whenever possible"))
static bool enableAllocFrameElim(const MachineFunction &MF)
static const char * getSpillFunctionFor(Register MaxReg, SpillKind SpillType, bool Stkchk=false)
static bool hasReturn(const MachineBasicBlock &MBB)
Returns true if MBB contains an instruction that returns.
static cl::opt< bool > EnableSaveRestoreLong("enable-save-restore-long", cl::Hidden, cl::desc("Enable long calls for save-restore stubs."), cl::init(false))
static bool needToReserveScavengingSpillSlots(MachineFunction &MF, const HexagonRegisterInfo &HRI, const TargetRegisterClass *RC)
Returns true if there are no caller-saved registers available in class RC.
static bool isOptSize(const MachineFunction &MF)
static Register getMax32BitSubRegister(Register Reg, const TargetRegisterInfo &TRI, bool hireg=true)
Map a register pair Reg to the subregister that has the greater "number", i.e.
static cl::opt< int > SpillFuncThresholdOs("spill-func-threshold-Os", cl::Hidden, cl::desc("Specify Os spill func threshold"), cl::init(1))
static bool needsStackFrame(const MachineBasicBlock &MBB, const BitVector &CSR, const HexagonRegisterInfo &HRI)
Checks if the basic block contains any instruction that needs a stack frame to be already in place.
static cl::opt< bool > DisableDeallocRet("disable-hexagon-dealloc-ret", cl::Hidden, cl::desc("Disable Dealloc Return for Hexagon target"))
static cl::opt< bool > EnableShrinkWrapping("hexagon-shrink-frame", cl::init(true), cl::Hidden, cl::desc("Enable stack frame shrink wrapping"))
static bool hasTailCall(const MachineBasicBlock &MBB)
Returns true if MBB has a machine instructions that indicates a tail call in the block.
static cl::opt< unsigned > NumberScavengerSlots("number-scavenger-slots", cl::Hidden, cl::desc("Set the number of scavenger slots"), cl::init(2))
static Register getMaxCalleeSavedReg(ArrayRef< CalleeSavedInfo > CSI, const TargetRegisterInfo &TRI)
Returns the callee saved register with the largest id in the vector.
static bool isMinSize(const MachineFunction &MF)
static cl::opt< unsigned > SpillOptMax("spill-opt-max", cl::Hidden, cl::init(std::numeric_limits< unsigned >::max()))
static unsigned SpillOptCount
static void dump_registers(BitVector &Regs, const TargetRegisterInfo &TRI)
static void emitSCSPrologue(MachineFunction &MF, MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, const DebugLoc &DL)
static bool isRestoreCall(unsigned Opc)
static cl::opt< bool > OptimizeSpillSlots("hexagon-opt-spill", cl::Hidden, cl::init(true), cl::desc("Optimize spill slots"))
static void emitSCSEpilogue(MachineFunction &MF, MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, const DebugLoc &DL)
static cl::opt< bool > EnableStackOVFSanitizer("enable-stackovf-sanitizer", cl::Hidden, cl::desc("Enable runtime checks for stack overflow."), cl::init(false))
IRTranslator LLVM IR MI
Legalize the Machine IR a function s Machine IR
Definition Legalizer.cpp:85
This file implements the LivePhysRegs utility for tracking liveness of physical registers.
#define F(x, y, z)
Definition MD5.cpp:54
#define I(x, y, z)
Definition MD5.cpp:57
Register Reg
Register const TargetRegisterInfo * TRI
Promote Memory to Register
Definition Mem2Reg.cpp:110
#define T
static MCRegister getReg(const MCDisassembler *D, unsigned RC, unsigned RegNo)
ConstantRange Range(APInt(BitWidth, Low), APInt(BitWidth, High))
#define P(N)
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
Definition PassSupport.h:56
This file builds on the ADT/GraphTraits.h file to build a generic graph post order iterator.
This file declares the machine register scavenger class.
bool isDead(const MachineInstr &MI, const MachineRegisterInfo &MRI)
static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)
Definition Value.cpp:484
This file implements a set that has insertion order iteration characteristics.
This file defines the SmallSet class.
This file defines the SmallVector class.
#define LLVM_DEBUG(...)
Definition Debug.h:119
Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition ArrayRef.h:40
size_t size() const
Get the array size.
Definition ArrayRef.h:141
bool empty() const
Check if the array is empty.
Definition ArrayRef.h:136
int find_first() const
Returns the index of the first set bit, -1 if none of the bits are set.
Definition BitVector.h:317
void resize(unsigned N, bool t=false)
Grow or shrink the bitvector.
Definition BitVector.h:355
BitVector & set()
Set all bits in the bitvector.
Definition BitVector.h:366
int find_next(unsigned Prev) const
Returns the index of the next set bit following the "Prev" bit.
Definition BitVector.h:324
Helper class for creating CFI instructions and inserting them into MIR.
void buildEscape(StringRef Bytes, StringRef Comment="") const
void buildRestore(MCRegister Reg) const
The CalleeSavedInfo class tracks the information need to locate where a callee saved register is in t...
A debug info location.
Definition DebugLoc.h:126
NodeT * findNearestCommonDominator(NodeT *A, NodeT *B) const
Find nearest common dominator basic block for basic block A and B.
bool dominates(const DomTreeNodeBase< NodeT > *A, const DomTreeNodeBase< NodeT > *B) const
dominates - Returns true iff A dominates B.
void recalculate(ParentType &Func)
recalculate - compute a dominator tree for the given function
FunctionPass class - This class is used to implement most global optimizations.
Definition Pass.h:314
bool hasMinSize() const
Optimize this function for minimum size (-Oz).
Definition Function.h:696
bool hasOptNone() const
Do not optimize this function (-O0).
Definition Function.h:686
bool isVarArg() const
isVarArg - Return true if this function takes a variable number of arguments.
Definition Function.h:230
bool hasFnAttribute(Attribute::AttrKind Kind) const
Return true if the function has the attribute.
Definition Function.cpp:730
void replaceInstr(MachineInstr *OldMI, MachineInstr *NewMI)
IndexType getIndex(MachineInstr *MI) const
MachineInstr * getInstr(IndexType Idx) const
void add(IndexType Start, IndexType End, bool Fixed, bool TiedEnd)
void insertCFIInstructions(MachineFunction &MF) const
bool hasFPImpl(const MachineFunction &MF) const override
bool enableCalleeSaveSkip(const MachineFunction &MF) const override
Returns true if the target can safely skip saving callee-saved registers for noreturn nounwind functi...
MachineBasicBlock::iterator eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB, MachineBasicBlock::iterator I) const override
This method is called during prolog/epilog code insertion to eliminate call frame setup and destroy p...
StackOffset getFrameIndexReference(const MachineFunction &MF, int FI, Register &FrameReg) const override
getFrameIndexReference - This method should return the base register and offset used to reference a f...
void emitPrologue(MachineFunction &MF, MachineBasicBlock &MBB) const override
Perform most of the PEI work here:
void determineCalleeSaves(MachineFunction &MF, BitVector &SavedRegs, RegScavenger *RS) const override
This method determines which of the registers reported by TargetRegisterInfo::getCalleeSavedRegs() sh...
void orderFrameObjects(const MachineFunction &MF, SmallVectorImpl< int > &ObjectsToAllocate) const override
Order the symbols in the local stack frame.
void inlineStackProbe(MachineFunction &MF, MachineBasicBlock &PrologueMBB) const override
Replace a StackProbe stub (if any) with the actual probe code inline.
const SpillSlot * getCalleeSavedSpillSlots(unsigned &NumEntries) const override
getCalleeSavedSpillSlots - This method returns a pointer to an array of pairs, that contains an entry...
bool needsAligna(const MachineFunction &MF) const
bool assignCalleeSavedSpillSlots(MachineFunction &MF, const TargetRegisterInfo *TRI, std::vector< CalleeSavedInfo > &CSI) const override
assignCalleeSavedSpillSlots - Allows target to override spill slot assignment logic.
void storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, Register SrcReg, bool isKill, int FrameIndex, const TargetRegisterClass *RC, Register VReg, MachineInstr::MIFlag Flags=MachineInstr::NoFlags) const override
Store the specified register of the given register class to the specified stack frame index.
const HexagonRegisterInfo & getRegisterInfo() const
void loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, Register DestReg, int FrameIndex, const TargetRegisterClass *RC, Register VReg, unsigned SubReg=0, MachineInstr::MIFlag Flags=MachineInstr::NoFlags) const override
Load the specified register of the given register class from the specified stack frame index.
Hexagon target-specific information for each MachineFunction.
bool isEHReturnCalleeSaveReg(Register Reg) const
const MCPhysReg * getCalleeSavedRegs(const MachineFunction *MF) const override
Code Generation virtual methods...
const MCPhysReg * getCallerSavedRegs(const MachineFunction *MF, const TargetRegisterClass *RC) const
const HexagonInstrInfo * getInstrInfo() const override
const HexagonFrameLowering * getFrameLowering() const override
static MCCFIInstruction cfiDefCfa(MCSymbol *L, unsigned Register, int64_t Offset, SMLoc Loc={})
.cfi_def_cfa defines a rule for computing CFA as: take address from Register and add Offset to it.
Definition MCDwarf.h:628
static MCCFIInstruction createOffset(MCSymbol *L, unsigned Register, int64_t Offset, SMLoc Loc={})
.cfi_offset Previous value of Register is saved at offset Offset from CFA.
Definition MCDwarf.h:670
LLVM_ABI MCSymbol * createTempSymbol()
Create a temporary symbol with a unique name.
Describe properties that are true of each instruction in the target description file.
MCRegAliasIterator enumerates all registers aliasing Reg.
unsigned getID() const
getID() - Return the register class ID number.
bool hasSubClassEq(const MCRegisterClass *RC) const
Returns true if RC is a sub-class of or equal to this class.
Wrapper class representing physical registers. Should be passed by value.
Definition MCRegister.h:41
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
Definition MCSymbol.h:42
LLVM_ABI void transferSuccessorsAndUpdatePHIs(MachineBasicBlock *FromMBB)
Transfers all the successors, as in transferSuccessors, and update PHI operands in the successor bloc...
MachineInstrBundleIterator< const MachineInstr > const_iterator
int getNumber() const
MachineBasicBlocks are uniquely numbered at the function level, unless they're not in a MachineFuncti...
const BasicBlock * getBasicBlock() const
Return the LLVM basic block that this instance corresponded to originally.
LLVM_ABI iterator getFirstTerminator()
Returns an iterator to the first terminator instruction of this basic block.
LLVM_ABI void addSuccessor(MachineBasicBlock *Succ, BranchProbability Prob=BranchProbability::getUnknown())
Add Succ as a successor of this MachineBasicBlock.
LLVM_ABI DebugLoc findDebugLoc(instr_iterator MBBI)
Find the next valid DebugLoc starting at MBBI, skipping any debug instructions.
void addLiveIn(MCRegister PhysReg, LaneBitmask LaneMask=LaneBitmask::getAll())
Adds the specified register as a live in.
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
LLVM_ABI instr_iterator erase(instr_iterator I)
Remove an instruction from the instruction list and delete it.
iterator_range< succ_iterator > successors()
void splice(iterator Where, MachineBasicBlock *Other, iterator From)
Take an instruction from MBB 'Other' at the position From, and insert it into this MBB right before '...
MachineInstrBundleIterator< MachineInstr > iterator
LLVM_ABI bool isLiveIn(MCRegister Reg, LaneBitmask LaneMask=LaneBitmask::getAll()) const
Return true if the specified register is in the live in set.
bool dominates(const MachineInstr *A, const MachineInstr *B) const
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted.
void setMaxCallFrameSize(uint64_t S)
bool hasVarSizedObjects() const
This method may be called any time after instruction selection is complete to determine if the stack ...
bool isObjectPreAllocated(int ObjectIdx) const
Return true if the object was pre-allocated into the local block.
uint64_t getStackSize() const
Return the number of bytes that must be allocated to hold all of the fixed size frame objects.
bool hasCalls() const
Return true if the current function has any function calls.
Align getMaxAlign() const
Return alignment of this function's frame.
uint64_t getMaxCallFrameSize() const
Return the maximum size of a call frame that must be allocated for an outgoing function call.
LLVM_ABI uint64_t estimateStackSize(const MachineFunction &MF) const
Estimate and return the size of the stack frame.
Align getObjectAlign(int ObjectIdx) const
Return the alignment of the specified stack object.
int64_t getObjectSize(int ObjectIdx) const
Return the size of the specified object.
LLVM_ABI int CreateSpillStackObject(uint64_t Size, Align Alignment, TargetStackID::Value StackID=TargetStackID::Default)
Create a new statically sized stack object that represents a spill slot, returning a nonnegative iden...
const std::vector< CalleeSavedInfo > & getCalleeSavedInfo() const
Returns a reference to call saved info vector for the current function.
int getObjectIndexEnd() const
Return one past the maximum frame object index.
LLVM_ABI int CreateFixedSpillStackObject(uint64_t Size, int64_t SPOffset, bool IsImmutable=false)
Create a spill slot at a fixed location on the stack.
int64_t getObjectOffset(int ObjectIdx) const
Return the assigned stack offset of the specified object from the incoming stack pointer.
void setStackSize(uint64_t Size)
Set the size of the stack.
bool isFixedObjectIndex(int ObjectIdx) const
Returns true if the specified index corresponds to a fixed stack object.
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
Properties which a MachineFunction may have at a given point in time.
unsigned addFrameInst(const MCCFIInstruction &Inst)
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
StringRef getName() const
getName - Return the name of the corresponding LLVM function.
bool needsFrameMoves() const
True if this function needs frame moves for debug or exceptions.
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
MCContext & getContext() const
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
MachineBasicBlock * getBlockNumbered(unsigned N) const
getBlockNumbered - MachineBasicBlocks are automatically numbered when they are inserted into the mach...
Function & getFunction()
Return the LLVM function that this machine code represents.
unsigned getNumBlockIDs() const
getNumBlockIDs - Return the number of MBB ID's allocated.
BasicBlockListType::iterator iterator
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()
LLVM_ABI void copyImplicitOps(MachineFunction &MF, const MachineInstr &MI)
Copy implicit register operands from specified instruction to this instruction.
bool mayLoad(QueryType Type=AnyInBundle) const
Return true if this instruction could possibly read memory.
const DebugLoc & getDebugLoc() const
Returns the debug location id of this MachineInstr.
const MachineOperand & getOperand(unsigned i) const
@ MOStore
The memory access writes data.
MachineOperand class - Representation of each machine instruction operand.
void setSubReg(unsigned subReg)
unsigned getSubReg() const
int64_t getImm() const
LLVM_ABI void setReg(Register Reg)
Change the register this operand corresponds to.
void setIsKill(bool Val=true)
Register getReg() const
getReg - Returns the register number.
static MachineOperand CreateReg(Register Reg, bool isDef, bool isImp=false, bool isKill=false, bool isDead=false, bool isUndef=false, bool isEarlyClobber=false, unsigned SubReg=0, bool isDebug=false, bool isInternalRead=false, bool isRenamable=false)
LLVM_ABI MachineBasicBlock * findNearestCommonDominator(ArrayRef< MachineBasicBlock * > Blocks) const
Returns the nearest common dominator of the given blocks.
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
const TargetRegisterClass * getRegClass(Register Reg) const
Return the register class of the specified virtual register.
LLVM_ABI Register createVirtualRegister(const TargetRegisterClass *RegClass, StringRef Name="")
createVirtualRegister - Create and return a new virtual register in the function with the specified r...
LLVM_ABI bool isPhysRegUsed(MCRegister PhysReg, bool SkipRegMaskTest=false) const
Return true if the specified register is modified or read in this function.
Wrapper class representing virtual and physical registers.
Definition Register.h:20
constexpr bool isValid() const
Definition Register.h:112
A vector that has set insertion semantics.
Definition SetVector.h:57
size_type size() const
Determine the number of elements in the SetVector.
Definition SetVector.h:103
bool insert(const value_type &X)
Insert a new element into the SetVector.
Definition SetVector.h:157
size_type count(const T &V) const
count - Return 1 if the element is in the set, 0 otherwise.
Definition SmallSet.h:176
std::pair< const_iterator, bool > insert(const T &V)
insert - Insert an element into the set if it isn't already there.
Definition SmallSet.h:184
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
int64_t getFixed() const
Returns the fixed component of the stack.
Definition TypeSize.h:46
Represent a constant reference to a string, i.e.
Definition StringRef.h:56
LLVM_ABI std::string lower() const
bool hasFP(const MachineFunction &MF) const
hasFP - Return true if the specified function should have a dedicated frame pointer register.
virtual void determineCalleeSaves(MachineFunction &MF, BitVector &SavedRegs, RegScavenger *RS=nullptr) const
This method determines which of the registers reported by TargetRegisterInfo::getCalleeSavedRegs() sh...
Align getStackAlign() const
getStackAlignment - This method returns the number of bytes to which the stack pointer must be aligne...
const TargetRegisterInfo & getRegisterInfo() const
CodeGenOptLevel getOptLevel() const
Returns the optimization level: None, Less, Default, or Aggressive.
bool isPositionIndependent() const
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
virtual const TargetInstrInfo * getInstrInfo() const
virtual const TargetLowering * getTargetLowering() const
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition Twine.h:82
self_iterator getIterator()
Definition ilist_node.h:123
Changed
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
initializer< Ty > init(const Ty &Val)
This is an optimization pass for GlobalISel generic memory operations.
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:144
constexpr bool isUInt(uint64_t x)
Checks if an unsigned integer fits into the given bit width.
Definition MathExtras.h:190
@ Default
-O2, -Os, -Oz
Definition CodeGen.h: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)
void fullyRecomputeLiveIns(ArrayRef< MachineBasicBlock * > MBBs)
Convenience function for recomputing live-in's for a set of MBBs until the computation converges.
LLVM_ABI Printable printReg(Register Reg, const TargetRegisterInfo *TRI=nullptr, unsigned SubIdx=0, const MachineRegisterInfo *MRI=nullptr)
Prints virtual and physical registers with or without a TRI instance.
LLVM_ABI Printable printMBBReference(const MachineBasicBlock &MBB)
Prints a machine basic block reference.
MCRegisterClass TargetRegisterClass
Definition FastISel.h:58
#define N
This struct is a compact representation of a valid (non-zero power of two) alignment.
Definition Alignment.h:39
constexpr uint64_t value() const
This is a hole in the type system and should not be abused.
Definition Alignment.h:77
static RegisterSet expandToSubRegs(RegisterRef R, const MachineRegisterInfo &MRI, const TargetRegisterInfo &TRI)
std::map< RegisterRef, RangeList > RegToRangeMap
static LLVM_ABI MachinePointerInfo getStack(MachineFunction &MF, int64_t Offset, uint8_t ID=0)
Stack pointer relative access.