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