LLVM 22.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 "HexagonInstrInfo.h"
14#include "HexagonRegisterInfo.h"
15#include "HexagonSubtarget.h"
18#include "llvm/ADT/BitVector.h"
19#include "llvm/ADT/DenseMap.h"
21#include "llvm/ADT/SetVector.h"
22#include "llvm/ADT/SmallSet.h"
40#include "llvm/IR/Attributes.h"
41#include "llvm/IR/DebugLoc.h"
42#include "llvm/IR/Function.h"
43#include "llvm/MC/MCDwarf.h"
45#include "llvm/Pass.h"
49#include "llvm/Support/Debug.h"
55#include <algorithm>
56#include <cassert>
57#include <cstdint>
58#include <iterator>
59#include <limits>
60#include <map>
61#include <optional>
62#include <utility>
63#include <vector>
64
65#define DEBUG_TYPE "hexagon-pei"
66
67// Hexagon stack frame layout as defined by the ABI:
68//
69// Incoming arguments
70// passed via stack
71// |
72// |
73// SP during function's FP during function's |
74// +-- runtime (top of stack) runtime (bottom) --+ |
75// | | |
76// --++---------------------+------------------+-----------------++-+-------
77// | parameter area for | variable-size | fixed-size |LR| arg
78// | called functions | local objects | local objects |FP|
79// --+----------------------+------------------+-----------------+--+-------
80// <- size known -> <- size unknown -> <- size known ->
81//
82// Low address High address
83//
84// <--- stack growth
85//
86//
87// - In any circumstances, the outgoing function arguments are always accessi-
88// ble using the SP, and the incoming arguments are accessible using the FP.
89// - If the local objects are not aligned, they can always be accessed using
90// the FP.
91// - If there are no variable-sized objects, the local objects can always be
92// accessed using the SP, regardless whether they are aligned or not. (The
93// alignment padding will be at the bottom of the stack (highest address),
94// and so the offset with respect to the SP will be known at the compile-
95// -time.)
96//
97// The only complication occurs if there are both, local aligned objects, and
98// dynamically allocated (variable-sized) objects. The alignment pad will be
99// placed between the FP and the local objects, thus preventing the use of the
100// FP to access the local objects. At the same time, the variable-sized objects
101// will be between the SP and the local objects, thus introducing an unknown
102// distance from the SP to the locals.
103//
104// To avoid this problem, a new register is created that holds the aligned
105// address of the bottom of the stack, referred in the sources as AP (aligned
106// pointer). The AP will be equal to "FP-p", where "p" is the smallest pad
107// that aligns AP to the required boundary (a maximum of the alignments of
108// all stack objects, fixed- and variable-sized). All local objects[1] will
109// then use AP as the base pointer.
110// [1] The exception is with "fixed" stack objects. "Fixed" stack objects get
111// their name from being allocated at fixed locations on the stack, relative
112// to the FP. In the presence of dynamic allocation and local alignment, such
113// objects can only be accessed through the FP.
114//
115// Illustration of the AP:
116// FP --+
117// |
118// ---------------+---------------------+-----+-----------------------++-+--
119// Rest of the | Local stack objects | Pad | Fixed stack objects |LR|
120// stack frame | (aligned) | | (CSR, spills, etc.) |FP|
121// ---------------+---------------------+-----+-----------------+-----+--+--
122// |<-- Multiple of the -->|
123// stack alignment +-- AP
124//
125// The AP is set up at the beginning of the function. Since it is not a dedi-
126// cated (reserved) register, it needs to be kept live throughout the function
127// to be available as the base register for local object accesses.
128// Normally, an address of a stack objects is obtained by a pseudo-instruction
129// PS_fi. To access local objects with the AP register present, a different
130// pseudo-instruction needs to be used: PS_fia. The PS_fia takes one extra
131// argument compared to PS_fi: the first input register is the AP register.
132// This keeps the register live between its definition and its uses.
133
134// The AP register is originally set up using pseudo-instruction PS_aligna:
135// AP = PS_aligna A
136// where
137// A - required stack alignment
138// The alignment value must be the maximum of all alignments required by
139// any stack object.
140
141// The dynamic allocation uses a pseudo-instruction PS_alloca:
142// Rd = PS_alloca Rs, A
143// where
144// Rd - address of the allocated space
145// Rs - minimum size (the actual allocated can be larger to accommodate
146// alignment)
147// A - required alignment
148
149using namespace llvm;
150
151static cl::opt<bool> DisableDeallocRet("disable-hexagon-dealloc-ret",
152 cl::Hidden, cl::desc("Disable Dealloc Return for Hexagon target"));
153
155 NumberScavengerSlots("number-scavenger-slots", cl::Hidden,
156 cl::desc("Set the number of scavenger slots"),
157 cl::init(2));
158
159static cl::opt<int>
160 SpillFuncThreshold("spill-func-threshold", cl::Hidden,
161 cl::desc("Specify O2(not Os) spill func threshold"),
162 cl::init(6));
163
164static cl::opt<int>
165 SpillFuncThresholdOs("spill-func-threshold-Os", cl::Hidden,
166 cl::desc("Specify Os spill func threshold"),
167 cl::init(1));
168
170 "enable-stackovf-sanitizer", cl::Hidden,
171 cl::desc("Enable runtime checks for stack overflow."), cl::init(false));
172
173static cl::opt<bool>
174 EnableShrinkWrapping("hexagon-shrink-frame", cl::init(true), cl::Hidden,
175 cl::desc("Enable stack frame shrink wrapping"));
176
178 ShrinkLimit("shrink-frame-limit",
179 cl::init(std::numeric_limits<unsigned>::max()), cl::Hidden,
180 cl::desc("Max count of stack frame shrink-wraps"));
181
182static cl::opt<bool>
183 EnableSaveRestoreLong("enable-save-restore-long", cl::Hidden,
184 cl::desc("Enable long calls for save-restore stubs."),
185 cl::init(false));
186
187static cl::opt<bool> EliminateFramePointer("hexagon-fp-elim", cl::init(true),
188 cl::Hidden, cl::desc("Refrain from using FP whenever possible"));
189
190static cl::opt<bool> OptimizeSpillSlots("hexagon-opt-spill", cl::Hidden,
191 cl::init(true), cl::desc("Optimize spill slots"));
192
193#ifndef NDEBUG
195 cl::init(std::numeric_limits<unsigned>::max()));
196static unsigned SpillOptCount = 0;
197#endif
198
199namespace {
200
201 class HexagonCallFrameInformation : public MachineFunctionPass {
202 public:
203 static char ID;
204
205 HexagonCallFrameInformation() : MachineFunctionPass(ID) {}
206
207 bool runOnMachineFunction(MachineFunction &MF) override;
208
210 return MachineFunctionProperties().setNoVRegs();
211 }
212 };
213
214 char HexagonCallFrameInformation::ID = 0;
215
216} // end anonymous namespace
217
218bool HexagonCallFrameInformation::runOnMachineFunction(MachineFunction &MF) {
219 auto &HFI = *MF.getSubtarget<HexagonSubtarget>().getFrameLowering();
220 bool NeedCFI = MF.needsFrameMoves();
221
222 if (!NeedCFI)
223 return false;
224 HFI.insertCFIInstructions(MF);
225 return true;
226}
227
228INITIALIZE_PASS(HexagonCallFrameInformation, "hexagon-cfi",
229 "Hexagon call frame information", false, false)
230
232 return new HexagonCallFrameInformation();
233}
234
235/// Map a register pair Reg to the subregister that has the greater "number",
236/// i.e. D3 (aka R7:6) will be mapped to R7, etc.
238 const TargetRegisterInfo &TRI,
239 bool hireg = true) {
240 if (Reg < Hexagon::D0 || Reg > Hexagon::D15)
241 return Reg;
242
243 Register RegNo = 0;
244 for (MCPhysReg SubReg : TRI.subregs(Reg)) {
245 if (hireg) {
246 if (SubReg > RegNo)
247 RegNo = SubReg;
248 } else {
249 if (!RegNo || SubReg < RegNo)
250 RegNo = SubReg;
251 }
252 }
253 return RegNo;
254}
255
256/// Returns the callee saved register with the largest id in the vector.
258 const TargetRegisterInfo &TRI) {
259 static_assert(Hexagon::R1 > 0,
260 "Assume physical registers are encoded as positive integers");
261 if (CSI.empty())
262 return 0;
263
264 Register Max = getMax32BitSubRegister(CSI[0].getReg(), TRI);
265 for (unsigned I = 1, E = CSI.size(); I < E; ++I) {
267 if (Reg > Max)
268 Max = Reg;
269 }
270 return Max;
271}
272
273/// Checks if the basic block contains any instruction that needs a stack
274/// frame to be already in place.
275static bool needsStackFrame(const MachineBasicBlock &MBB, const BitVector &CSR,
276 const HexagonRegisterInfo &HRI) {
277 for (const MachineInstr &MI : MBB) {
278 if (MI.isCall())
279 return true;
280 unsigned Opc = MI.getOpcode();
281 switch (Opc) {
282 case Hexagon::PS_alloca:
283 case Hexagon::PS_aligna:
284 return true;
285 default:
286 break;
287 }
288 // Check individual operands.
289 for (const MachineOperand &MO : MI.operands()) {
290 // While the presence of a frame index does not prove that a stack
291 // frame will be required, all frame indexes should be within alloc-
292 // frame/deallocframe. Otherwise, the code that translates a frame
293 // index into an offset would have to be aware of the placement of
294 // the frame creation/destruction instructions.
295 if (MO.isFI())
296 return true;
297 if (MO.isReg()) {
298 Register R = MO.getReg();
299 // Debug instructions may refer to $noreg.
300 if (!R)
301 continue;
302 // Virtual registers will need scavenging, which then may require
303 // a stack slot.
304 if (R.isVirtual())
305 return true;
306 for (MCPhysReg S : HRI.subregs_inclusive(R))
307 if (CSR[S])
308 return true;
309 continue;
310 }
311 if (MO.isRegMask()) {
312 // A regmask would normally have all callee-saved registers marked
313 // as preserved, so this check would not be needed, but in case of
314 // ever having other regmasks (for other calling conventions),
315 // make sure they would be processed correctly.
316 const uint32_t *BM = MO.getRegMask();
317 for (int x = CSR.find_first(); x >= 0; x = CSR.find_next(x)) {
318 unsigned R = x;
319 // If this regmask does not preserve a CSR, a frame will be needed.
320 if (!(BM[R/32] & (1u << (R%32))))
321 return true;
322 }
323 }
324 }
325 }
326 return false;
327}
328
329 /// Returns true if MBB has a machine instructions that indicates a tail call
330 /// in the block.
331static bool hasTailCall(const MachineBasicBlock &MBB) {
333 if (I == MBB.end())
334 return false;
335 unsigned RetOpc = I->getOpcode();
336 return RetOpc == Hexagon::PS_tailcall_i || RetOpc == Hexagon::PS_tailcall_r;
337}
338
339/// Returns true if MBB contains an instruction that returns.
340static bool hasReturn(const MachineBasicBlock &MBB) {
341 for (const MachineInstr &MI : MBB.terminators())
342 if (MI.isReturn())
343 return true;
344 return false;
345}
346
347/// Returns the "return" instruction from this block, or nullptr if there
348/// isn't any.
350 for (auto &I : MBB)
351 if (I.isReturn())
352 return &I;
353 return nullptr;
354}
355
356static bool isRestoreCall(unsigned Opc) {
357 switch (Opc) {
358 case Hexagon::RESTORE_DEALLOC_RET_JMP_V4:
359 case Hexagon::RESTORE_DEALLOC_RET_JMP_V4_PIC:
360 case Hexagon::RESTORE_DEALLOC_RET_JMP_V4_EXT:
361 case Hexagon::RESTORE_DEALLOC_RET_JMP_V4_EXT_PIC:
362 case Hexagon::RESTORE_DEALLOC_BEFORE_TAILCALL_V4_EXT:
363 case Hexagon::RESTORE_DEALLOC_BEFORE_TAILCALL_V4_EXT_PIC:
364 case Hexagon::RESTORE_DEALLOC_BEFORE_TAILCALL_V4:
365 case Hexagon::RESTORE_DEALLOC_BEFORE_TAILCALL_V4_PIC:
366 return true;
367 }
368 return false;
369}
370
371static inline bool isOptNone(const MachineFunction &MF) {
372 return MF.getFunction().hasOptNone() ||
373 MF.getTarget().getOptLevel() == CodeGenOptLevel::None;
374}
375
376static inline bool isOptSize(const MachineFunction &MF) {
377 const Function &F = MF.getFunction();
378 return F.hasOptSize() && !F.hasMinSize();
379}
380
381static inline bool isMinSize(const MachineFunction &MF) {
382 return MF.getFunction().hasMinSize();
383}
384
385/// Implements shrink-wrapping of the stack frame. By default, stack frame
386/// is created in the function entry block, and is cleaned up in every block
387/// that returns. This function finds alternate blocks: one for the frame
388/// setup (prolog) and one for the cleanup (epilog).
389void HexagonFrameLowering::findShrunkPrologEpilog(MachineFunction &MF,
390 MachineBasicBlock *&PrologB, MachineBasicBlock *&EpilogB) const {
391 static unsigned ShrinkCounter = 0;
392
394 MF.getFunction().isVarArg())
395 return;
396 if (ShrinkLimit.getPosition()) {
397 if (ShrinkCounter >= ShrinkLimit)
398 return;
399 ShrinkCounter++;
400 }
401
402 auto &HRI = *MF.getSubtarget<HexagonSubtarget>().getRegisterInfo();
403
405 MDT.recalculate(MF);
407 MPT.recalculate(MF);
408
409 using UnsignedMap = DenseMap<unsigned, unsigned>;
411
412 UnsignedMap RPO;
413 RPOTType RPOT(&MF);
414 unsigned RPON = 0;
415 for (auto &I : RPOT)
416 RPO[I->getNumber()] = RPON++;
417
418 // Don't process functions that have loops, at least for now. Placement
419 // of prolog and epilog must take loop structure into account. For simpli-
420 // city don't do it right now.
421 for (auto &I : MF) {
422 unsigned BN = RPO[I.getNumber()];
423 for (MachineBasicBlock *Succ : I.successors())
424 // If found a back-edge, return.
425 if (RPO[Succ->getNumber()] <= BN)
426 return;
427 }
428
429 // Collect the set of blocks that need a stack frame to execute. Scan
430 // each block for uses/defs of callee-saved registers, calls, etc.
432 BitVector CSR(Hexagon::NUM_TARGET_REGS);
433 for (const MCPhysReg *P = HRI.getCalleeSavedRegs(&MF); *P; ++P)
434 for (MCPhysReg S : HRI.subregs_inclusive(*P))
435 CSR[S] = true;
436
437 for (auto &I : MF)
438 if (needsStackFrame(I, CSR, HRI))
439 SFBlocks.push_back(&I);
440
441 LLVM_DEBUG({
442 dbgs() << "Blocks needing SF: {";
443 for (auto &B : SFBlocks)
444 dbgs() << " " << printMBBReference(*B);
445 dbgs() << " }\n";
446 });
447 // No frame needed?
448 if (SFBlocks.empty())
449 return;
450
451 // Pick a common dominator and a common post-dominator.
452 MachineBasicBlock *DomB = SFBlocks[0];
453 for (unsigned i = 1, n = SFBlocks.size(); i < n; ++i) {
454 DomB = MDT.findNearestCommonDominator(DomB, SFBlocks[i]);
455 if (!DomB)
456 break;
457 }
458 MachineBasicBlock *PDomB = SFBlocks[0];
459 for (unsigned i = 1, n = SFBlocks.size(); i < n; ++i) {
460 PDomB = MPT.findNearestCommonDominator(PDomB, SFBlocks[i]);
461 if (!PDomB)
462 break;
463 }
464 LLVM_DEBUG({
465 dbgs() << "Computed dom block: ";
466 if (DomB)
467 dbgs() << printMBBReference(*DomB);
468 else
469 dbgs() << "<null>";
470 dbgs() << ", computed pdom block: ";
471 if (PDomB)
472 dbgs() << printMBBReference(*PDomB);
473 else
474 dbgs() << "<null>";
475 dbgs() << "\n";
476 });
477 if (!DomB || !PDomB)
478 return;
479
480 // Make sure that DomB dominates PDomB and PDomB post-dominates DomB.
481 if (!MDT.dominates(DomB, PDomB)) {
482 LLVM_DEBUG(dbgs() << "Dom block does not dominate pdom block\n");
483 return;
484 }
485 if (!MPT.dominates(PDomB, DomB)) {
486 LLVM_DEBUG(dbgs() << "PDom block does not post-dominate dom block\n");
487 return;
488 }
489
490 // Finally, everything seems right.
491 PrologB = DomB;
492 EpilogB = PDomB;
493}
494
495/// Perform most of the PEI work here:
496/// - saving/restoring of the callee-saved registers,
497/// - stack frame creation and destruction.
498/// Normally, this work is distributed among various functions, but doing it
499/// in one place allows shrink-wrapping of the stack frame.
501 MachineBasicBlock &MBB) const {
502 auto &HRI = *MF.getSubtarget<HexagonSubtarget>().getRegisterInfo();
503
504 MachineFrameInfo &MFI = MF.getFrameInfo();
505 const std::vector<CalleeSavedInfo> &CSI = MFI.getCalleeSavedInfo();
506
507 MachineBasicBlock *PrologB = &MF.front(), *EpilogB = nullptr;
509 findShrunkPrologEpilog(MF, PrologB, EpilogB);
510
511 bool PrologueStubs = false;
512 insertCSRSpillsInBlock(*PrologB, CSI, HRI, PrologueStubs);
513 insertPrologueInBlock(*PrologB, PrologueStubs);
514 updateEntryPaths(MF, *PrologB);
515
516 if (EpilogB) {
517 insertCSRRestoresInBlock(*EpilogB, CSI, HRI);
518 insertEpilogueInBlock(*EpilogB);
519 } else {
520 for (auto &B : MF)
521 if (B.isReturnBlock())
522 insertCSRRestoresInBlock(B, CSI, HRI);
523
524 for (auto &B : MF)
525 if (B.isReturnBlock())
526 insertEpilogueInBlock(B);
527
528 for (auto &B : MF) {
529 if (B.empty())
530 continue;
531 MachineInstr *RetI = getReturn(B);
532 if (!RetI || isRestoreCall(RetI->getOpcode()))
533 continue;
534 for (auto &R : CSI)
535 RetI->addOperand(MachineOperand::CreateReg(R.getReg(), false, true));
536 }
537 }
538
539 if (EpilogB) {
540 // If there is an epilog block, it may not have a return instruction.
541 // In such case, we need to add the callee-saved registers as live-ins
542 // in all blocks on all paths from the epilog to any return block.
543 unsigned MaxBN = MF.getNumBlockIDs();
544 BitVector DoneT(MaxBN+1), DoneF(MaxBN+1), Path(MaxBN+1);
545 updateExitPaths(*EpilogB, *EpilogB, DoneT, DoneF, Path);
546 }
547}
548
549/// Returns true if the target can safely skip saving callee-saved registers
550/// for noreturn nounwind functions.
552 const MachineFunction &MF) const {
553 const auto &F = MF.getFunction();
554 assert(F.hasFnAttribute(Attribute::NoReturn) &&
555 F.getFunction().hasFnAttribute(Attribute::NoUnwind) &&
556 !F.getFunction().hasFnAttribute(Attribute::UWTable));
557 (void)F;
558
559 // No need to save callee saved registers if the function does not return.
560 return MF.getSubtarget<HexagonSubtarget>().noreturnStackElim();
561}
562
563// Helper function used to determine when to eliminate the stack frame for
564// functions marked as noreturn and when the noreturn-stack-elim options are
565// specified. When both these conditions are true, then a FP may not be needed
566// if the function makes a call. It is very similar to enableCalleeSaveSkip,
567// but it used to check if the allocframe can be eliminated as well.
568static bool enableAllocFrameElim(const MachineFunction &MF) {
569 const auto &F = MF.getFunction();
570 const auto &MFI = MF.getFrameInfo();
571 const auto &HST = MF.getSubtarget<HexagonSubtarget>();
572 assert(!MFI.hasVarSizedObjects() &&
573 !HST.getRegisterInfo()->hasStackRealignment(MF));
574 return F.hasFnAttribute(Attribute::NoReturn) &&
575 F.hasFnAttribute(Attribute::NoUnwind) &&
576 !F.hasFnAttribute(Attribute::UWTable) && HST.noreturnStackElim() &&
577 MFI.getStackSize() == 0;
578}
579
580void HexagonFrameLowering::insertPrologueInBlock(MachineBasicBlock &MBB,
581 bool PrologueStubs) const {
583 MachineFrameInfo &MFI = MF.getFrameInfo();
584 auto &HST = MF.getSubtarget<HexagonSubtarget>();
585 auto &HII = *HST.getInstrInfo();
586 auto &HRI = *HST.getRegisterInfo();
587
588 Align MaxAlign = std::max(MFI.getMaxAlign(), getStackAlign());
589
590 // Calculate the total stack frame size.
591 // Get the number of bytes to allocate from the FrameInfo.
592 unsigned FrameSize = MFI.getStackSize();
593 // Round up the max call frame size to the max alignment on the stack.
594 unsigned MaxCFA = alignTo(MFI.getMaxCallFrameSize(), MaxAlign);
595 MFI.setMaxCallFrameSize(MaxCFA);
596
597 FrameSize = MaxCFA + alignTo(FrameSize, MaxAlign);
598 MFI.setStackSize(FrameSize);
599
600 bool AlignStack = (MaxAlign > getStackAlign());
601
602 // Get the number of bytes to allocate from the FrameInfo.
603 unsigned NumBytes = MFI.getStackSize();
604 Register SP = HRI.getStackRegister();
605 unsigned MaxCF = MFI.getMaxCallFrameSize();
607
609 for (auto &MBB : MF)
610 for (auto &MI : MBB)
611 if (MI.getOpcode() == Hexagon::PS_alloca)
612 AdjustRegs.push_back(&MI);
613
614 for (auto *MI : AdjustRegs) {
615 assert((MI->getOpcode() == Hexagon::PS_alloca) && "Expected alloca");
616 expandAlloca(MI, HII, SP, MaxCF);
617 MI->eraseFromParent();
618 }
619
620 DebugLoc dl = MBB.findDebugLoc(InsertPt);
621
622 if (MF.getFunction().isVarArg() &&
623 MF.getSubtarget<HexagonSubtarget>().isEnvironmentMusl()) {
624 // Calculate the size of register saved area.
625 int NumVarArgRegs = 6 - FirstVarArgSavedReg;
626 int RegisterSavedAreaSizePlusPadding = (NumVarArgRegs % 2 == 0)
627 ? NumVarArgRegs * 4
628 : NumVarArgRegs * 4 + 4;
629 if (RegisterSavedAreaSizePlusPadding > 0) {
630 // Decrement the stack pointer by size of register saved area plus
631 // padding if any.
632 BuildMI(MBB, InsertPt, dl, HII.get(Hexagon::A2_addi), SP)
633 .addReg(SP)
634 .addImm(-RegisterSavedAreaSizePlusPadding)
636
637 int NumBytes = 0;
638 // Copy all the named arguments below register saved area.
639 auto &HMFI = *MF.getInfo<HexagonMachineFunctionInfo>();
640 for (int i = HMFI.getFirstNamedArgFrameIndex(),
641 e = HMFI.getLastNamedArgFrameIndex(); i >= e; --i) {
642 uint64_t ObjSize = MFI.getObjectSize(i);
643 Align ObjAlign = MFI.getObjectAlign(i);
644
645 // Determine the kind of load/store that should be used.
646 unsigned LDOpc, STOpc;
647 uint64_t OpcodeChecker = ObjAlign.value();
648
649 // Handle cases where alignment of an object is > its size.
650 if (ObjAlign > ObjSize) {
651 if (ObjSize <= 1)
652 OpcodeChecker = 1;
653 else if (ObjSize <= 2)
654 OpcodeChecker = 2;
655 else if (ObjSize <= 4)
656 OpcodeChecker = 4;
657 else if (ObjSize > 4)
658 OpcodeChecker = 8;
659 }
660
661 switch (OpcodeChecker) {
662 case 1:
663 LDOpc = Hexagon::L2_loadrb_io;
664 STOpc = Hexagon::S2_storerb_io;
665 break;
666 case 2:
667 LDOpc = Hexagon::L2_loadrh_io;
668 STOpc = Hexagon::S2_storerh_io;
669 break;
670 case 4:
671 LDOpc = Hexagon::L2_loadri_io;
672 STOpc = Hexagon::S2_storeri_io;
673 break;
674 case 8:
675 default:
676 LDOpc = Hexagon::L2_loadrd_io;
677 STOpc = Hexagon::S2_storerd_io;
678 break;
679 }
680
681 Register RegUsed = LDOpc == Hexagon::L2_loadrd_io ? Hexagon::D3
682 : Hexagon::R6;
683 int LoadStoreCount = ObjSize / OpcodeChecker;
684
685 if (ObjSize % OpcodeChecker)
686 ++LoadStoreCount;
687
688 // Get the start location of the load. NumBytes is basically the
689 // offset from the stack pointer of previous function, which would be
690 // the caller in this case, as this function has variable argument
691 // list.
692 if (NumBytes != 0)
693 NumBytes = alignTo(NumBytes, ObjAlign);
694
695 int Count = 0;
696 while (Count < LoadStoreCount) {
697 // Load the value of the named argument on stack.
698 BuildMI(MBB, InsertPt, dl, HII.get(LDOpc), RegUsed)
699 .addReg(SP)
700 .addImm(RegisterSavedAreaSizePlusPadding +
701 ObjAlign.value() * Count + NumBytes)
703
704 // Store it below the register saved area plus padding.
705 BuildMI(MBB, InsertPt, dl, HII.get(STOpc))
706 .addReg(SP)
707 .addImm(ObjAlign.value() * Count + NumBytes)
708 .addReg(RegUsed)
710
711 Count++;
712 }
713 NumBytes += MFI.getObjectSize(i);
714 }
715
716 // Make NumBytes 8 byte aligned
717 NumBytes = alignTo(NumBytes, 8);
718
719 // If the number of registers having variable arguments is odd,
720 // leave 4 bytes of padding to get to the location where first
721 // variable argument which was passed through register was copied.
722 NumBytes = (NumVarArgRegs % 2 == 0) ? NumBytes : NumBytes + 4;
723
724 for (int j = FirstVarArgSavedReg, i = 0; j < 6; ++j, ++i) {
725 BuildMI(MBB, InsertPt, dl, HII.get(Hexagon::S2_storeri_io))
726 .addReg(SP)
727 .addImm(NumBytes + 4 * i)
728 .addReg(Hexagon::R0 + j)
730 }
731 }
732 }
733
734 if (hasFP(MF)) {
735 insertAllocframe(MBB, InsertPt, NumBytes);
736 if (AlignStack) {
737 BuildMI(MBB, InsertPt, dl, HII.get(Hexagon::A2_andir), SP)
738 .addReg(SP)
739 .addImm(-int64_t(MaxAlign.value()));
740 }
741 // If the stack-checking is enabled, and we spilled the callee-saved
742 // registers inline (i.e. did not use a spill function), then call
743 // the stack checker directly.
744 if (EnableStackOVFSanitizer && !PrologueStubs)
745 BuildMI(MBB, InsertPt, dl, HII.get(Hexagon::PS_call_stk))
746 .addExternalSymbol("__runtime_stack_check");
747 } else if (NumBytes > 0) {
748 assert(alignTo(NumBytes, 8) == NumBytes);
749 BuildMI(MBB, InsertPt, dl, HII.get(Hexagon::A2_addi), SP)
750 .addReg(SP)
751 .addImm(-int(NumBytes));
752 }
753}
754
755void HexagonFrameLowering::insertEpilogueInBlock(MachineBasicBlock &MBB) const {
757 auto &HST = MF.getSubtarget<HexagonSubtarget>();
758 auto &HII = *HST.getInstrInfo();
759 auto &HRI = *HST.getRegisterInfo();
760 Register SP = HRI.getStackRegister();
761
763 DebugLoc dl = MBB.findDebugLoc(InsertPt);
764
765 if (!hasFP(MF)) {
766 MachineFrameInfo &MFI = MF.getFrameInfo();
767 unsigned NumBytes = MFI.getStackSize();
768 if (MF.getFunction().isVarArg() &&
769 MF.getSubtarget<HexagonSubtarget>().isEnvironmentMusl()) {
770 // On Hexagon Linux, deallocate the stack for the register saved area.
771 int NumVarArgRegs = 6 - FirstVarArgSavedReg;
772 int RegisterSavedAreaSizePlusPadding = (NumVarArgRegs % 2 == 0) ?
773 (NumVarArgRegs * 4) : (NumVarArgRegs * 4 + 4);
774 NumBytes += RegisterSavedAreaSizePlusPadding;
775 }
776 if (NumBytes) {
777 BuildMI(MBB, InsertPt, dl, HII.get(Hexagon::A2_addi), SP)
778 .addReg(SP)
779 .addImm(NumBytes);
780 }
781 return;
782 }
783
784 MachineInstr *RetI = getReturn(MBB);
785 unsigned RetOpc = RetI ? RetI->getOpcode() : 0;
786
787 // Handle EH_RETURN.
788 if (RetOpc == Hexagon::EH_RETURN_JMPR) {
789 BuildMI(MBB, InsertPt, dl, HII.get(Hexagon::L2_deallocframe))
790 .addDef(Hexagon::D15)
791 .addReg(Hexagon::R30);
792 BuildMI(MBB, InsertPt, dl, HII.get(Hexagon::A2_add), SP)
793 .addReg(SP)
794 .addReg(Hexagon::R28);
795 return;
796 }
797
798 // Check for RESTORE_DEALLOC_RET* tail call. Don't emit an extra dealloc-
799 // frame instruction if we encounter it.
800 if (RetOpc == Hexagon::RESTORE_DEALLOC_RET_JMP_V4 ||
801 RetOpc == Hexagon::RESTORE_DEALLOC_RET_JMP_V4_PIC ||
802 RetOpc == Hexagon::RESTORE_DEALLOC_RET_JMP_V4_EXT ||
803 RetOpc == Hexagon::RESTORE_DEALLOC_RET_JMP_V4_EXT_PIC) {
805 ++It;
806 // Delete all instructions after the RESTORE (except labels).
807 while (It != MBB.end()) {
808 if (!It->isLabel())
809 It = MBB.erase(It);
810 else
811 ++It;
812 }
813 return;
814 }
815
816 // It is possible that the restoring code is a call to a library function.
817 // All of the restore* functions include "deallocframe", so we need to make
818 // sure that we don't add an extra one.
819 bool NeedsDeallocframe = true;
820 if (!MBB.empty() && InsertPt != MBB.begin()) {
821 MachineBasicBlock::iterator PrevIt = std::prev(InsertPt);
822 unsigned COpc = PrevIt->getOpcode();
823 if (COpc == Hexagon::RESTORE_DEALLOC_BEFORE_TAILCALL_V4 ||
824 COpc == Hexagon::RESTORE_DEALLOC_BEFORE_TAILCALL_V4_PIC ||
825 COpc == Hexagon::RESTORE_DEALLOC_BEFORE_TAILCALL_V4_EXT ||
826 COpc == Hexagon::RESTORE_DEALLOC_BEFORE_TAILCALL_V4_EXT_PIC ||
827 COpc == Hexagon::PS_call_nr || COpc == Hexagon::PS_callr_nr)
828 NeedsDeallocframe = false;
829 }
830
832 !MF.getFunction().isVarArg()) {
833 if (!NeedsDeallocframe)
834 return;
835 // If the returning instruction is PS_jmpret, replace it with
836 // dealloc_return, otherwise just add deallocframe. The function
837 // could be returning via a tail call.
838 if (RetOpc != Hexagon::PS_jmpret || DisableDeallocRet) {
839 BuildMI(MBB, InsertPt, dl, HII.get(Hexagon::L2_deallocframe))
840 .addDef(Hexagon::D15)
841 .addReg(Hexagon::R30);
842 return;
843 }
844 unsigned NewOpc = Hexagon::L4_return;
845 MachineInstr *NewI = BuildMI(MBB, RetI, dl, HII.get(NewOpc))
846 .addDef(Hexagon::D15)
847 .addReg(Hexagon::R30);
848 // Transfer the function live-out registers.
849 NewI->copyImplicitOps(MF, *RetI);
850 MBB.erase(RetI);
851 } else {
852 // L2_deallocframe instruction after it.
853 // Calculate the size of register saved area.
854 int NumVarArgRegs = 6 - FirstVarArgSavedReg;
855 int RegisterSavedAreaSizePlusPadding = (NumVarArgRegs % 2 == 0) ?
856 (NumVarArgRegs * 4) : (NumVarArgRegs * 4 + 4);
857
860 : std::prev(Term);
861 if (I == MBB.end() ||
862 (I->getOpcode() != Hexagon::RESTORE_DEALLOC_BEFORE_TAILCALL_V4_EXT &&
863 I->getOpcode() != Hexagon::RESTORE_DEALLOC_BEFORE_TAILCALL_V4_EXT_PIC &&
864 I->getOpcode() != Hexagon::RESTORE_DEALLOC_BEFORE_TAILCALL_V4 &&
865 I->getOpcode() != Hexagon::RESTORE_DEALLOC_BEFORE_TAILCALL_V4_PIC))
866 BuildMI(MBB, InsertPt, dl, HII.get(Hexagon::L2_deallocframe))
867 .addDef(Hexagon::D15)
868 .addReg(Hexagon::R30);
869 if (RegisterSavedAreaSizePlusPadding != 0)
870 BuildMI(MBB, InsertPt, dl, HII.get(Hexagon::A2_addi), SP)
871 .addReg(SP)
872 .addImm(RegisterSavedAreaSizePlusPadding);
873 }
874}
875
876void HexagonFrameLowering::insertAllocframe(MachineBasicBlock &MBB,
877 MachineBasicBlock::iterator InsertPt, unsigned NumBytes) const {
879 auto &HST = MF.getSubtarget<HexagonSubtarget>();
880 auto &HII = *HST.getInstrInfo();
881 auto &HRI = *HST.getRegisterInfo();
882
883 // Check for overflow.
884 // Hexagon_TODO: Ugh! hardcoding. Is there an API that can be used?
885 const unsigned int ALLOCFRAME_MAX = 16384;
886
887 // Create a dummy memory operand to avoid allocframe from being treated as
888 // a volatile memory reference.
891
892 DebugLoc dl = MBB.findDebugLoc(InsertPt);
893 Register SP = HRI.getStackRegister();
894
895 if (NumBytes >= ALLOCFRAME_MAX) {
896 // Emit allocframe(#0).
897 BuildMI(MBB, InsertPt, dl, HII.get(Hexagon::S2_allocframe))
898 .addDef(SP)
899 .addReg(SP)
900 .addImm(0)
901 .addMemOperand(MMO)
903
904 // Subtract the size from the stack pointer.
905 Register SP = HRI.getStackRegister();
906 BuildMI(MBB, InsertPt, dl, HII.get(Hexagon::A2_addi), SP)
907 .addReg(SP)
908 .addImm(-int(NumBytes))
910 } else {
911 BuildMI(MBB, InsertPt, dl, HII.get(Hexagon::S2_allocframe))
912 .addDef(SP)
913 .addReg(SP)
914 .addImm(NumBytes)
915 .addMemOperand(MMO)
917 }
918}
919
920void HexagonFrameLowering::updateEntryPaths(MachineFunction &MF,
921 MachineBasicBlock &SaveB) const {
922 SetVector<unsigned> Worklist;
923
924 MachineBasicBlock &EntryB = MF.front();
925 Worklist.insert(EntryB.getNumber());
926
927 unsigned SaveN = SaveB.getNumber();
928 auto &CSI = MF.getFrameInfo().getCalleeSavedInfo();
929
930 for (unsigned i = 0; i < Worklist.size(); ++i) {
931 unsigned BN = Worklist[i];
933 for (auto &R : CSI)
934 if (!MBB.isLiveIn(R.getReg()))
935 MBB.addLiveIn(R.getReg());
936 if (BN != SaveN)
937 for (auto &SB : MBB.successors())
938 Worklist.insert(SB->getNumber());
939 }
940}
941
942bool HexagonFrameLowering::updateExitPaths(MachineBasicBlock &MBB,
943 MachineBasicBlock &RestoreB, BitVector &DoneT, BitVector &DoneF,
944 BitVector &Path) const {
945 assert(MBB.getNumber() >= 0);
946 unsigned BN = MBB.getNumber();
947 if (Path[BN] || DoneF[BN])
948 return false;
949 if (DoneT[BN])
950 return true;
951
952 auto &CSI = MBB.getParent()->getFrameInfo().getCalleeSavedInfo();
953
954 Path[BN] = true;
955 bool ReachedExit = false;
956 for (auto &SB : MBB.successors())
957 ReachedExit |= updateExitPaths(*SB, RestoreB, DoneT, DoneF, Path);
958
959 if (!MBB.empty() && MBB.back().isReturn()) {
960 // Add implicit uses of all callee-saved registers to the reached
961 // return instructions. This is to prevent the anti-dependency breaker
962 // from renaming these registers.
963 MachineInstr &RetI = MBB.back();
964 if (!isRestoreCall(RetI.getOpcode()))
965 for (auto &R : CSI)
966 RetI.addOperand(MachineOperand::CreateReg(R.getReg(), false, true));
967 ReachedExit = true;
968 }
969
970 // We don't want to add unnecessary live-ins to the restore block: since
971 // the callee-saved registers are being defined in it, the entry of the
972 // restore block cannot be on the path from the definitions to any exit.
973 if (ReachedExit && &MBB != &RestoreB) {
974 for (auto &R : CSI)
975 if (!MBB.isLiveIn(R.getReg()))
976 MBB.addLiveIn(R.getReg());
977 DoneT[BN] = true;
978 }
979 if (!ReachedExit)
980 DoneF[BN] = true;
981
982 Path[BN] = false;
983 return ReachedExit;
984}
985
986static std::optional<MachineBasicBlock::iterator>
988 // The CFI instructions need to be inserted right after allocframe.
989 // An exception to this is a situation where allocframe is bundled
990 // with a call: then the CFI instructions need to be inserted before
991 // the packet with the allocframe+call (in case the call throws an
992 // exception).
993 auto End = B.instr_end();
994
995 for (MachineInstr &I : B) {
996 MachineBasicBlock::iterator It = I.getIterator();
997 if (!I.isBundle()) {
998 if (I.getOpcode() == Hexagon::S2_allocframe)
999 return std::next(It);
1000 continue;
1001 }
1002 // I is a bundle.
1003 bool HasCall = false, HasAllocFrame = false;
1004 auto T = It.getInstrIterator();
1005 while (++T != End && T->isBundled()) {
1006 if (T->getOpcode() == Hexagon::S2_allocframe)
1007 HasAllocFrame = true;
1008 else if (T->isCall())
1009 HasCall = true;
1010 }
1011 if (HasAllocFrame)
1012 return HasCall ? It : std::next(It);
1013 }
1014 return std::nullopt;
1015}
1016
1018 for (auto &B : MF)
1019 if (auto At = findCFILocation(B))
1020 insertCFIInstructionsAt(B, *At);
1021}
1022
1023void HexagonFrameLowering::insertCFIInstructionsAt(MachineBasicBlock &MBB,
1024 MachineBasicBlock::iterator At) const {
1025 MachineFunction &MF = *MBB.getParent();
1026 MachineFrameInfo &MFI = MF.getFrameInfo();
1027 auto &HST = MF.getSubtarget<HexagonSubtarget>();
1028 auto &HII = *HST.getInstrInfo();
1029 auto &HRI = *HST.getRegisterInfo();
1030
1031 // If CFI instructions have debug information attached, something goes
1032 // wrong with the final assembly generation: the prolog_end is placed
1033 // in a wrong location.
1034 DebugLoc DL;
1035 const MCInstrDesc &CFID = HII.get(TargetOpcode::CFI_INSTRUCTION);
1036
1037 MCSymbol *FrameLabel = MF.getContext().createTempSymbol();
1038 bool HasFP = hasFP(MF);
1039
1040 if (HasFP) {
1041 unsigned DwFPReg = HRI.getDwarfRegNum(HRI.getFrameRegister(), true);
1042 unsigned DwRAReg = HRI.getDwarfRegNum(HRI.getRARegister(), true);
1043
1044 // Define CFA via an offset from the value of FP.
1045 //
1046 // -8 -4 0 (SP)
1047 // --+----+----+---------------------
1048 // | FP | LR | increasing addresses -->
1049 // --+----+----+---------------------
1050 // | +-- Old SP (before allocframe)
1051 // +-- New FP (after allocframe)
1052 //
1053 // MCCFIInstruction::cfiDefCfa adds the offset from the register.
1054 // MCCFIInstruction::createOffset takes the offset without sign change.
1055 auto DefCfa = MCCFIInstruction::cfiDefCfa(FrameLabel, DwFPReg, 8);
1056 BuildMI(MBB, At, DL, CFID)
1057 .addCFIIndex(MF.addFrameInst(DefCfa));
1058 // R31 (return addr) = CFA - 4
1059 auto OffR31 = MCCFIInstruction::createOffset(FrameLabel, DwRAReg, -4);
1060 BuildMI(MBB, At, DL, CFID)
1061 .addCFIIndex(MF.addFrameInst(OffR31));
1062 // R30 (frame ptr) = CFA - 8
1063 auto OffR30 = MCCFIInstruction::createOffset(FrameLabel, DwFPReg, -8);
1064 BuildMI(MBB, At, DL, CFID)
1065 .addCFIIndex(MF.addFrameInst(OffR30));
1066 }
1067
1068 static const MCPhysReg RegsToMove[] = {
1069 Hexagon::R1, Hexagon::R0, Hexagon::R3, Hexagon::R2,
1070 Hexagon::R17, Hexagon::R16, Hexagon::R19, Hexagon::R18,
1071 Hexagon::R21, Hexagon::R20, Hexagon::R23, Hexagon::R22,
1072 Hexagon::R25, Hexagon::R24, Hexagon::R27, Hexagon::R26,
1073 Hexagon::D0, Hexagon::D1, Hexagon::D8, Hexagon::D9,
1074 Hexagon::D10, Hexagon::D11, Hexagon::D12, Hexagon::D13
1075 };
1076
1077 const std::vector<CalleeSavedInfo> &CSI = MFI.getCalleeSavedInfo();
1078
1079 for (MCPhysReg Reg : RegsToMove) {
1080 auto IfR = [Reg] (const CalleeSavedInfo &C) -> bool {
1081 return C.getReg() == Reg;
1082 };
1083 auto F = find_if(CSI, IfR);
1084 if (F == CSI.end())
1085 continue;
1086
1087 int64_t Offset;
1088 if (HasFP) {
1089 // If the function has a frame pointer (i.e. has an allocframe),
1090 // then the CFA has been defined in terms of FP. Any offsets in
1091 // the following CFI instructions have to be defined relative
1092 // to FP, which points to the bottom of the stack frame.
1093 // The function getFrameIndexReference can still choose to use SP
1094 // for the offset calculation, so we cannot simply call it here.
1095 // Instead, get the offset (relative to the FP) directly.
1096 Offset = MFI.getObjectOffset(F->getFrameIdx());
1097 } else {
1098 Register FrameReg;
1099 Offset =
1100 getFrameIndexReference(MF, F->getFrameIdx(), FrameReg).getFixed();
1101 }
1102 // Subtract 8 to make room for R30 and R31, which are added above.
1103 Offset -= 8;
1104
1105 if (Reg < Hexagon::D0 || Reg > Hexagon::D15) {
1106 unsigned DwarfReg = HRI.getDwarfRegNum(Reg, true);
1107 auto OffReg = MCCFIInstruction::createOffset(FrameLabel, DwarfReg,
1108 Offset);
1109 BuildMI(MBB, At, DL, CFID)
1110 .addCFIIndex(MF.addFrameInst(OffReg));
1111 } else {
1112 // Split the double regs into subregs, and generate appropriate
1113 // cfi_offsets.
1114 // The only reason, we are split double regs is, llvm-mc does not
1115 // understand paired registers for cfi_offset.
1116 // Eg .cfi_offset r1:0, -64
1117
1118 Register HiReg = HRI.getSubReg(Reg, Hexagon::isub_hi);
1119 Register LoReg = HRI.getSubReg(Reg, Hexagon::isub_lo);
1120 unsigned HiDwarfReg = HRI.getDwarfRegNum(HiReg, true);
1121 unsigned LoDwarfReg = HRI.getDwarfRegNum(LoReg, true);
1122 auto OffHi = MCCFIInstruction::createOffset(FrameLabel, HiDwarfReg,
1123 Offset+4);
1124 BuildMI(MBB, At, DL, CFID)
1125 .addCFIIndex(MF.addFrameInst(OffHi));
1126 auto OffLo = MCCFIInstruction::createOffset(FrameLabel, LoDwarfReg,
1127 Offset);
1128 BuildMI(MBB, At, DL, CFID)
1129 .addCFIIndex(MF.addFrameInst(OffLo));
1130 }
1131 }
1132}
1133
1135 auto &MFI = MF.getFrameInfo();
1136 auto &HRI = *MF.getSubtarget<HexagonSubtarget>().getRegisterInfo();
1137 bool HasExtraAlign = HRI.hasStackRealignment(MF);
1138 bool HasAlloca = MFI.hasVarSizedObjects();
1139
1140 // Insert ALLOCFRAME if we need to or at -O0 for the debugger. Think
1141 // that this shouldn't be required, but doing so now because gcc does and
1142 // gdb can't break at the start of the function without it. Will remove if
1143 // this turns out to be a gdb bug.
1144 //
1146 return true;
1147
1148 // By default we want to use SP (since it's always there). FP requires
1149 // some setup (i.e. ALLOCFRAME).
1150 // Both, alloca and stack alignment modify the stack pointer by an
1151 // undetermined value, so we need to save it at the entry to the function
1152 // (i.e. use allocframe).
1153 if (HasAlloca || HasExtraAlign)
1154 return true;
1155
1156 if (MFI.getStackSize() > 0) {
1157 // If FP-elimination is disabled, we have to use FP at this point.
1158 const TargetMachine &TM = MF.getTarget();
1159 if (TM.Options.DisableFramePointerElim(MF) || !EliminateFramePointer)
1160 return true;
1162 return true;
1163 }
1164
1165 const auto &HMFI = *MF.getInfo<HexagonMachineFunctionInfo>();
1166 if ((MFI.hasCalls() && !enableAllocFrameElim(MF)) || HMFI.hasClobberLR())
1167 return true;
1168
1169 return false;
1170}
1171
1177
1178static const char *getSpillFunctionFor(Register MaxReg, SpillKind SpillType,
1179 bool Stkchk = false) {
1180 const char * V4SpillToMemoryFunctions[] = {
1181 "__save_r16_through_r17",
1182 "__save_r16_through_r19",
1183 "__save_r16_through_r21",
1184 "__save_r16_through_r23",
1185 "__save_r16_through_r25",
1186 "__save_r16_through_r27" };
1187
1188 const char * V4SpillToMemoryStkchkFunctions[] = {
1189 "__save_r16_through_r17_stkchk",
1190 "__save_r16_through_r19_stkchk",
1191 "__save_r16_through_r21_stkchk",
1192 "__save_r16_through_r23_stkchk",
1193 "__save_r16_through_r25_stkchk",
1194 "__save_r16_through_r27_stkchk" };
1195
1196 const char * V4SpillFromMemoryFunctions[] = {
1197 "__restore_r16_through_r17_and_deallocframe",
1198 "__restore_r16_through_r19_and_deallocframe",
1199 "__restore_r16_through_r21_and_deallocframe",
1200 "__restore_r16_through_r23_and_deallocframe",
1201 "__restore_r16_through_r25_and_deallocframe",
1202 "__restore_r16_through_r27_and_deallocframe" };
1203
1204 const char * V4SpillFromMemoryTailcallFunctions[] = {
1205 "__restore_r16_through_r17_and_deallocframe_before_tailcall",
1206 "__restore_r16_through_r19_and_deallocframe_before_tailcall",
1207 "__restore_r16_through_r21_and_deallocframe_before_tailcall",
1208 "__restore_r16_through_r23_and_deallocframe_before_tailcall",
1209 "__restore_r16_through_r25_and_deallocframe_before_tailcall",
1210 "__restore_r16_through_r27_and_deallocframe_before_tailcall"
1211 };
1212
1213 const char **SpillFunc = nullptr;
1214
1215 switch(SpillType) {
1216 case SK_ToMem:
1217 SpillFunc = Stkchk ? V4SpillToMemoryStkchkFunctions
1218 : V4SpillToMemoryFunctions;
1219 break;
1220 case SK_FromMem:
1221 SpillFunc = V4SpillFromMemoryFunctions;
1222 break;
1223 case SK_FromMemTailcall:
1224 SpillFunc = V4SpillFromMemoryTailcallFunctions;
1225 break;
1226 }
1227 assert(SpillFunc && "Unknown spill kind");
1228
1229 // Spill all callee-saved registers up to the highest register used.
1230 switch (MaxReg) {
1231 case Hexagon::R17:
1232 return SpillFunc[0];
1233 case Hexagon::R19:
1234 return SpillFunc[1];
1235 case Hexagon::R21:
1236 return SpillFunc[2];
1237 case Hexagon::R23:
1238 return SpillFunc[3];
1239 case Hexagon::R25:
1240 return SpillFunc[4];
1241 case Hexagon::R27:
1242 return SpillFunc[5];
1243 default:
1244 llvm_unreachable("Unhandled maximum callee save register");
1245 }
1246 return nullptr;
1247}
1248
1251 Register &FrameReg) const {
1252 auto &MFI = MF.getFrameInfo();
1253 auto &HRI = *MF.getSubtarget<HexagonSubtarget>().getRegisterInfo();
1254
1255 int Offset = MFI.getObjectOffset(FI);
1256 bool HasAlloca = MFI.hasVarSizedObjects();
1257 bool HasExtraAlign = HRI.hasStackRealignment(MF);
1258 bool NoOpt = MF.getTarget().getOptLevel() == CodeGenOptLevel::None;
1259
1260 auto &HMFI = *MF.getInfo<HexagonMachineFunctionInfo>();
1261 unsigned FrameSize = MFI.getStackSize();
1262 Register SP = HRI.getStackRegister();
1263 Register FP = HRI.getFrameRegister();
1264 Register AP = HMFI.getStackAlignBaseReg();
1265 // It may happen that AP will be absent even HasAlloca && HasExtraAlign
1266 // is true. HasExtraAlign may be set because of vector spills, without
1267 // aligned locals or aligned outgoing function arguments. Since vector
1268 // spills will ultimately be "unaligned", it is safe to use FP as the
1269 // base register.
1270 // In fact, in such a scenario the stack is actually not required to be
1271 // aligned, although it may end up being aligned anyway, since this
1272 // particular case is not easily detectable. The alignment will be
1273 // unnecessary, but not incorrect.
1274 // Unfortunately there is no quick way to verify that the above is
1275 // indeed the case (and that it's not a result of an error), so just
1276 // assume that missing AP will be replaced by FP.
1277 // (A better fix would be to rematerialize AP from FP and always align
1278 // vector spills.)
1279 bool UseFP = false, UseAP = false; // Default: use SP (except at -O0).
1280 // Use FP at -O0, except when there are objects with extra alignment.
1281 // That additional alignment requirement may cause a pad to be inserted,
1282 // which will make it impossible to use FP to access objects located
1283 // past the pad.
1284 if (NoOpt && !HasExtraAlign)
1285 UseFP = true;
1286 if (MFI.isFixedObjectIndex(FI) || MFI.isObjectPreAllocated(FI)) {
1287 // Fixed and preallocated objects will be located before any padding
1288 // so FP must be used to access them.
1289 UseFP |= (HasAlloca || HasExtraAlign);
1290 } else {
1291 if (HasAlloca) {
1292 if (HasExtraAlign)
1293 UseAP = true;
1294 else
1295 UseFP = true;
1296 }
1297 }
1298
1299 // If FP was picked, then there had better be FP.
1300 bool HasFP = hasFP(MF);
1301 assert((HasFP || !UseFP) && "This function must have frame pointer");
1302
1303 // Having FP implies allocframe. Allocframe will store extra 8 bytes:
1304 // FP/LR. If the base register is used to access an object across these
1305 // 8 bytes, then the offset will need to be adjusted by 8.
1306 //
1307 // After allocframe:
1308 // HexagonISelLowering adds 8 to ---+
1309 // the offsets of all stack-based |
1310 // arguments (*) |
1311 // |
1312 // getObjectOffset < 0 0 8 getObjectOffset >= 8
1313 // ------------------------+-----+------------------------> increasing
1314 // <local objects> |FP/LR| <input arguments> addresses
1315 // -----------------+------+-----+------------------------>
1316 // | |
1317 // SP/AP point --+ +-- FP points here (**)
1318 // somewhere on
1319 // this side of FP/LR
1320 //
1321 // (*) See LowerFormalArguments. The FP/LR is assumed to be present.
1322 // (**) *FP == old-FP. FP+0..7 are the bytes of FP/LR.
1323
1324 // The lowering assumes that FP/LR is present, and so the offsets of
1325 // the formal arguments start at 8. If FP/LR is not there we need to
1326 // reduce the offset by 8.
1327 if (Offset > 0 && !HasFP)
1328 Offset -= 8;
1329
1330 if (UseFP)
1331 FrameReg = FP;
1332 else if (UseAP)
1333 FrameReg = AP;
1334 else
1335 FrameReg = SP;
1336
1337 // Calculate the actual offset in the instruction. If there is no FP
1338 // (in other words, no allocframe), then SP will not be adjusted (i.e.
1339 // there will be no SP -= FrameSize), so the frame size should not be
1340 // added to the calculated offset.
1341 int RealOffset = Offset;
1342 if (!UseFP && !UseAP)
1343 RealOffset = FrameSize+Offset;
1344 return StackOffset::getFixed(RealOffset);
1345}
1346
1347bool HexagonFrameLowering::insertCSRSpillsInBlock(MachineBasicBlock &MBB,
1348 const CSIVect &CSI, const HexagonRegisterInfo &HRI,
1349 bool &PrologueStubs) const {
1350 if (CSI.empty())
1351 return true;
1352
1354 PrologueStubs = false;
1355 MachineFunction &MF = *MBB.getParent();
1356 auto &HST = MF.getSubtarget<HexagonSubtarget>();
1357 auto &HII = *HST.getInstrInfo();
1358
1359 if (useSpillFunction(MF, CSI)) {
1360 PrologueStubs = true;
1361 Register MaxReg = getMaxCalleeSavedReg(CSI, HRI);
1362 bool StkOvrFlowEnabled = EnableStackOVFSanitizer;
1363 const char *SpillFun = getSpillFunctionFor(MaxReg, SK_ToMem,
1364 StkOvrFlowEnabled);
1365 auto &HTM = static_cast<const HexagonTargetMachine&>(MF.getTarget());
1366 bool IsPIC = HTM.isPositionIndependent();
1367 bool LongCalls = HST.useLongCalls() || EnableSaveRestoreLong;
1368
1369 // Call spill function.
1370 DebugLoc DL = MI != MBB.end() ? MI->getDebugLoc() : DebugLoc();
1371 unsigned SpillOpc;
1372 if (StkOvrFlowEnabled) {
1373 if (LongCalls)
1374 SpillOpc = IsPIC ? Hexagon::SAVE_REGISTERS_CALL_V4STK_EXT_PIC
1375 : Hexagon::SAVE_REGISTERS_CALL_V4STK_EXT;
1376 else
1377 SpillOpc = IsPIC ? Hexagon::SAVE_REGISTERS_CALL_V4STK_PIC
1378 : Hexagon::SAVE_REGISTERS_CALL_V4STK;
1379 } else {
1380 if (LongCalls)
1381 SpillOpc = IsPIC ? Hexagon::SAVE_REGISTERS_CALL_V4_EXT_PIC
1382 : Hexagon::SAVE_REGISTERS_CALL_V4_EXT;
1383 else
1384 SpillOpc = IsPIC ? Hexagon::SAVE_REGISTERS_CALL_V4_PIC
1385 : Hexagon::SAVE_REGISTERS_CALL_V4;
1386 }
1387
1388 MachineInstr *SaveRegsCall =
1389 BuildMI(MBB, MI, DL, HII.get(SpillOpc))
1390 .addExternalSymbol(SpillFun);
1391
1392 // Add callee-saved registers as use.
1393 addCalleeSaveRegistersAsImpOperand(SaveRegsCall, CSI, false, true);
1394 // Add live in registers.
1395 for (const CalleeSavedInfo &I : CSI)
1396 MBB.addLiveIn(I.getReg());
1397 return true;
1398 }
1399
1400 for (const CalleeSavedInfo &I : CSI) {
1401 MCRegister Reg = I.getReg();
1402 // Add live in registers. We treat eh_return callee saved register r0 - r3
1403 // specially. They are not really callee saved registers as they are not
1404 // supposed to be killed.
1405 bool IsKill = !HRI.isEHReturnCalleeSaveReg(Reg);
1406 int FI = I.getFrameIdx();
1407 const TargetRegisterClass *RC = HRI.getMinimalPhysRegClass(Reg);
1408 HII.storeRegToStackSlot(MBB, MI, Reg, IsKill, FI, RC, &HRI, Register());
1409 if (IsKill)
1410 MBB.addLiveIn(Reg);
1411 }
1412 return true;
1413}
1414
1415bool HexagonFrameLowering::insertCSRRestoresInBlock(MachineBasicBlock &MBB,
1416 const CSIVect &CSI, const HexagonRegisterInfo &HRI) const {
1417 if (CSI.empty())
1418 return false;
1419
1421 MachineFunction &MF = *MBB.getParent();
1422 auto &HST = MF.getSubtarget<HexagonSubtarget>();
1423 auto &HII = *HST.getInstrInfo();
1424
1425 if (useRestoreFunction(MF, CSI)) {
1426 bool HasTC = hasTailCall(MBB) || !hasReturn(MBB);
1427 Register MaxR = getMaxCalleeSavedReg(CSI, HRI);
1429 const char *RestoreFn = getSpillFunctionFor(MaxR, Kind);
1430 auto &HTM = static_cast<const HexagonTargetMachine&>(MF.getTarget());
1431 bool IsPIC = HTM.isPositionIndependent();
1432 bool LongCalls = HST.useLongCalls() || EnableSaveRestoreLong;
1433
1434 // Call spill function.
1435 DebugLoc DL = MI != MBB.end() ? MI->getDebugLoc()
1436 : MBB.findDebugLoc(MBB.end());
1437 MachineInstr *DeallocCall = nullptr;
1438
1439 if (HasTC) {
1440 unsigned RetOpc;
1441 if (LongCalls)
1442 RetOpc = IsPIC ? Hexagon::RESTORE_DEALLOC_BEFORE_TAILCALL_V4_EXT_PIC
1443 : Hexagon::RESTORE_DEALLOC_BEFORE_TAILCALL_V4_EXT;
1444 else
1445 RetOpc = IsPIC ? Hexagon::RESTORE_DEALLOC_BEFORE_TAILCALL_V4_PIC
1446 : Hexagon::RESTORE_DEALLOC_BEFORE_TAILCALL_V4;
1447 DeallocCall = BuildMI(MBB, MI, DL, HII.get(RetOpc))
1448 .addExternalSymbol(RestoreFn);
1449 } else {
1450 // The block has a return.
1452 assert(It->isReturn() && std::next(It) == MBB.end());
1453 unsigned RetOpc;
1454 if (LongCalls)
1455 RetOpc = IsPIC ? Hexagon::RESTORE_DEALLOC_RET_JMP_V4_EXT_PIC
1456 : Hexagon::RESTORE_DEALLOC_RET_JMP_V4_EXT;
1457 else
1458 RetOpc = IsPIC ? Hexagon::RESTORE_DEALLOC_RET_JMP_V4_PIC
1459 : Hexagon::RESTORE_DEALLOC_RET_JMP_V4;
1460 DeallocCall = BuildMI(MBB, It, DL, HII.get(RetOpc))
1461 .addExternalSymbol(RestoreFn);
1462 // Transfer the function live-out registers.
1463 DeallocCall->copyImplicitOps(MF, *It);
1464 }
1465 addCalleeSaveRegistersAsImpOperand(DeallocCall, CSI, true, false);
1466 return true;
1467 }
1468
1469 for (const CalleeSavedInfo &I : CSI) {
1470 MCRegister Reg = I.getReg();
1471 const TargetRegisterClass *RC = HRI.getMinimalPhysRegClass(Reg);
1472 int FI = I.getFrameIdx();
1473 HII.loadRegFromStackSlot(MBB, MI, Reg, FI, RC, &HRI, Register());
1474 }
1475
1476 return true;
1477}
1478
1482 MachineInstr &MI = *I;
1483 unsigned Opc = MI.getOpcode();
1484 (void)Opc; // Silence compiler warning.
1485 assert((Opc == Hexagon::ADJCALLSTACKDOWN || Opc == Hexagon::ADJCALLSTACKUP) &&
1486 "Cannot handle this call frame pseudo instruction");
1487 return MBB.erase(I);
1488}
1489
1491 MachineFunction &MF, RegScavenger *RS) const {
1492 // If this function has uses aligned stack and also has variable sized stack
1493 // objects, then we need to map all spill slots to fixed positions, so that
1494 // they can be accessed through FP. Otherwise they would have to be accessed
1495 // via AP, which may not be available at the particular place in the program.
1496 MachineFrameInfo &MFI = MF.getFrameInfo();
1497 bool HasAlloca = MFI.hasVarSizedObjects();
1498 bool NeedsAlign = (MFI.getMaxAlign() > getStackAlign());
1499
1500 if (!HasAlloca || !NeedsAlign)
1501 return;
1502
1503 // Set the physical aligned-stack base address register.
1504 MCRegister AP;
1505 if (const MachineInstr *AI = getAlignaInstr(MF))
1506 AP = AI->getOperand(0).getReg();
1507 auto &HMFI = *MF.getInfo<HexagonMachineFunctionInfo>();
1508 assert(!AP.isValid() || AP.isPhysical());
1509 HMFI.setStackAlignBaseReg(AP);
1510}
1511
1512/// Returns true if there are no caller-saved registers available in class RC.
1514 const HexagonRegisterInfo &HRI, const TargetRegisterClass *RC) {
1516
1517 auto IsUsed = [&HRI,&MRI] (Register Reg) -> bool {
1518 for (MCRegAliasIterator AI(Reg, &HRI, true); AI.isValid(); ++AI)
1519 if (MRI.isPhysRegUsed(*AI))
1520 return true;
1521 return false;
1522 };
1523
1524 // Check for an unused caller-saved register. Callee-saved registers
1525 // have become pristine by now.
1526 for (const MCPhysReg *P = HRI.getCallerSavedRegs(&MF, RC); *P; ++P)
1527 if (!IsUsed(*P))
1528 return false;
1529
1530 // All caller-saved registers are used.
1531 return true;
1532}
1533
1534#ifndef NDEBUG
1536 dbgs() << '{';
1537 for (int x = Regs.find_first(); x >= 0; x = Regs.find_next(x)) {
1538 Register R = x;
1539 dbgs() << ' ' << printReg(R, &TRI);
1540 }
1541 dbgs() << " }";
1542}
1543#endif
1544
1546 const TargetRegisterInfo *TRI, std::vector<CalleeSavedInfo> &CSI) const {
1547 LLVM_DEBUG(dbgs() << __func__ << " on " << MF.getName() << '\n');
1548 MachineFrameInfo &MFI = MF.getFrameInfo();
1549 BitVector SRegs(Hexagon::NUM_TARGET_REGS);
1550
1551 // Generate a set of unique, callee-saved registers (SRegs), where each
1552 // register in the set is maximal in terms of sub-/super-register relation,
1553 // i.e. for each R in SRegs, no proper super-register of R is also in SRegs.
1554
1555 // (1) For each callee-saved register, add that register and all of its
1556 // sub-registers to SRegs.
1557 LLVM_DEBUG(dbgs() << "Initial CS registers: {");
1558 for (const CalleeSavedInfo &I : CSI) {
1559 Register R = I.getReg();
1560 LLVM_DEBUG(dbgs() << ' ' << printReg(R, TRI));
1561 for (MCPhysReg SR : TRI->subregs_inclusive(R))
1562 SRegs[SR] = true;
1563 }
1564 LLVM_DEBUG(dbgs() << " }\n");
1565 LLVM_DEBUG(dbgs() << "SRegs.1: "; dump_registers(SRegs, *TRI);
1566 dbgs() << "\n");
1567
1568 // (2) For each reserved register, remove that register and all of its
1569 // sub- and super-registers from SRegs.
1570 BitVector Reserved = TRI->getReservedRegs(MF);
1571 // Unreserve the stack align register: it is reserved for this function
1572 // only, it still needs to be saved/restored.
1573 Register AP =
1574 MF.getInfo<HexagonMachineFunctionInfo>()->getStackAlignBaseReg();
1575 if (AP.isValid()) {
1576 Reserved[AP] = false;
1577 // Unreserve super-regs if no other subregisters are reserved.
1578 for (MCPhysReg SP : TRI->superregs(AP)) {
1579 bool HasResSub = false;
1580 for (MCPhysReg SB : TRI->subregs(SP)) {
1581 if (!Reserved[SB])
1582 continue;
1583 HasResSub = true;
1584 break;
1585 }
1586 if (!HasResSub)
1587 Reserved[SP] = false;
1588 }
1589 }
1590
1591 for (int x = Reserved.find_first(); x >= 0; x = Reserved.find_next(x)) {
1592 Register R = x;
1593 for (MCPhysReg SR : TRI->superregs_inclusive(R))
1594 SRegs[SR] = false;
1595 }
1596 LLVM_DEBUG(dbgs() << "Res: "; dump_registers(Reserved, *TRI);
1597 dbgs() << "\n");
1598 LLVM_DEBUG(dbgs() << "SRegs.2: "; dump_registers(SRegs, *TRI);
1599 dbgs() << "\n");
1600
1601 // (3) Collect all registers that have at least one sub-register in SRegs,
1602 // and also have no sub-registers that are reserved. These will be the can-
1603 // didates for saving as a whole instead of their individual sub-registers.
1604 // (Saving R17:16 instead of R16 is fine, but only if R17 was not reserved.)
1605 BitVector TmpSup(Hexagon::NUM_TARGET_REGS);
1606 for (int x = SRegs.find_first(); x >= 0; x = SRegs.find_next(x)) {
1607 Register R = x;
1608 for (MCPhysReg SR : TRI->superregs(R))
1609 TmpSup[SR] = true;
1610 }
1611 for (int x = TmpSup.find_first(); x >= 0; x = TmpSup.find_next(x)) {
1612 Register R = x;
1613 for (MCPhysReg SR : TRI->subregs_inclusive(R)) {
1614 if (!Reserved[SR])
1615 continue;
1616 TmpSup[R] = false;
1617 break;
1618 }
1619 }
1620 LLVM_DEBUG(dbgs() << "TmpSup: "; dump_registers(TmpSup, *TRI);
1621 dbgs() << "\n");
1622
1623 // (4) Include all super-registers found in (3) into SRegs.
1624 SRegs |= TmpSup;
1625 LLVM_DEBUG(dbgs() << "SRegs.4: "; dump_registers(SRegs, *TRI);
1626 dbgs() << "\n");
1627
1628 // (5) For each register R in SRegs, if any super-register of R is in SRegs,
1629 // remove R from SRegs.
1630 for (int x = SRegs.find_first(); x >= 0; x = SRegs.find_next(x)) {
1631 Register R = x;
1632 for (MCPhysReg SR : TRI->superregs(R)) {
1633 if (!SRegs[SR])
1634 continue;
1635 SRegs[R] = false;
1636 break;
1637 }
1638 }
1639 LLVM_DEBUG(dbgs() << "SRegs.5: "; dump_registers(SRegs, *TRI);
1640 dbgs() << "\n");
1641
1642 // Now, for each register that has a fixed stack slot, create the stack
1643 // object for it.
1644 CSI.clear();
1645
1647
1648 unsigned NumFixed;
1649 int64_t MinOffset = 0; // CS offsets are negative.
1650 const SpillSlot *FixedSlots = getCalleeSavedSpillSlots(NumFixed);
1651 for (const SpillSlot *S = FixedSlots; S != FixedSlots+NumFixed; ++S) {
1652 if (!SRegs[S->Reg])
1653 continue;
1654 const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(S->Reg);
1655 int FI = MFI.CreateFixedSpillStackObject(TRI->getSpillSize(*RC), S->Offset);
1656 MinOffset = std::min(MinOffset, S->Offset);
1657 CSI.push_back(CalleeSavedInfo(S->Reg, FI));
1658 SRegs[S->Reg] = false;
1659 }
1660
1661 // There can be some registers that don't have fixed slots. For example,
1662 // we need to store R0-R3 in functions with exception handling. For each
1663 // such register, create a non-fixed stack object.
1664 for (int x = SRegs.find_first(); x >= 0; x = SRegs.find_next(x)) {
1665 Register R = x;
1666 const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(R);
1667 unsigned Size = TRI->getSpillSize(*RC);
1668 int64_t Off = MinOffset - Size;
1669 Align Alignment = std::min(TRI->getSpillAlign(*RC), getStackAlign());
1670 Off &= -Alignment.value();
1671 int FI = MFI.CreateFixedSpillStackObject(Size, Off);
1672 MinOffset = std::min(MinOffset, Off);
1673 CSI.push_back(CalleeSavedInfo(R, FI));
1674 SRegs[R] = false;
1675 }
1676
1677 LLVM_DEBUG({
1678 dbgs() << "CS information: {";
1679 for (const CalleeSavedInfo &I : CSI) {
1680 int FI = I.getFrameIdx();
1681 int Off = MFI.getObjectOffset(FI);
1682 dbgs() << ' ' << printReg(I.getReg(), TRI) << ":fi#" << FI << ":sp";
1683 if (Off >= 0)
1684 dbgs() << '+';
1685 dbgs() << Off;
1686 }
1687 dbgs() << " }\n";
1688 });
1689
1690#ifndef NDEBUG
1691 // Verify that all registers were handled.
1692 bool MissedReg = false;
1693 for (int x = SRegs.find_first(); x >= 0; x = SRegs.find_next(x)) {
1694 Register R = x;
1695 dbgs() << printReg(R, TRI) << ' ';
1696 MissedReg = true;
1697 }
1698 if (MissedReg)
1699 llvm_unreachable("...there are unhandled callee-saved registers!");
1700#endif
1701
1702 return true;
1703}
1704
1705bool HexagonFrameLowering::expandCopy(MachineBasicBlock &B,
1707 const HexagonInstrInfo &HII, SmallVectorImpl<Register> &NewRegs) const {
1708 MachineInstr *MI = &*It;
1709 DebugLoc DL = MI->getDebugLoc();
1710 Register DstR = MI->getOperand(0).getReg();
1711 Register SrcR = MI->getOperand(1).getReg();
1712 if (!Hexagon::ModRegsRegClass.contains(DstR) ||
1713 !Hexagon::ModRegsRegClass.contains(SrcR))
1714 return false;
1715
1716 Register TmpR = MRI.createVirtualRegister(&Hexagon::IntRegsRegClass);
1717 BuildMI(B, It, DL, HII.get(TargetOpcode::COPY), TmpR).add(MI->getOperand(1));
1718 BuildMI(B, It, DL, HII.get(TargetOpcode::COPY), DstR)
1719 .addReg(TmpR, RegState::Kill);
1720
1721 NewRegs.push_back(TmpR);
1722 B.erase(It);
1723 return true;
1724}
1725
1726bool HexagonFrameLowering::expandStoreInt(MachineBasicBlock &B,
1728 const HexagonInstrInfo &HII, SmallVectorImpl<Register> &NewRegs) const {
1729 MachineInstr *MI = &*It;
1730 if (!MI->getOperand(0).isFI())
1731 return false;
1732
1733 DebugLoc DL = MI->getDebugLoc();
1734 unsigned Opc = MI->getOpcode();
1735 Register SrcR = MI->getOperand(2).getReg();
1736 bool IsKill = MI->getOperand(2).isKill();
1737 int FI = MI->getOperand(0).getIndex();
1738
1739 // TmpR = C2_tfrpr SrcR if SrcR is a predicate register
1740 // TmpR = A2_tfrcrr SrcR if SrcR is a modifier register
1741 Register TmpR = MRI.createVirtualRegister(&Hexagon::IntRegsRegClass);
1742 unsigned TfrOpc = (Opc == Hexagon::STriw_pred) ? Hexagon::C2_tfrpr
1743 : Hexagon::A2_tfrcrr;
1744 BuildMI(B, It, DL, HII.get(TfrOpc), TmpR)
1745 .addReg(SrcR, getKillRegState(IsKill));
1746
1747 // S2_storeri_io FI, 0, TmpR
1748 BuildMI(B, It, DL, HII.get(Hexagon::S2_storeri_io))
1749 .addFrameIndex(FI)
1750 .addImm(0)
1751 .addReg(TmpR, RegState::Kill)
1752 .cloneMemRefs(*MI);
1753
1754 NewRegs.push_back(TmpR);
1755 B.erase(It);
1756 return true;
1757}
1758
1759bool HexagonFrameLowering::expandLoadInt(MachineBasicBlock &B,
1761 const HexagonInstrInfo &HII, SmallVectorImpl<Register> &NewRegs) const {
1762 MachineInstr *MI = &*It;
1763 if (!MI->getOperand(1).isFI())
1764 return false;
1765
1766 DebugLoc DL = MI->getDebugLoc();
1767 unsigned Opc = MI->getOpcode();
1768 Register DstR = MI->getOperand(0).getReg();
1769 int FI = MI->getOperand(1).getIndex();
1770
1771 // TmpR = L2_loadri_io FI, 0
1772 Register TmpR = MRI.createVirtualRegister(&Hexagon::IntRegsRegClass);
1773 BuildMI(B, It, DL, HII.get(Hexagon::L2_loadri_io), TmpR)
1774 .addFrameIndex(FI)
1775 .addImm(0)
1776 .cloneMemRefs(*MI);
1777
1778 // DstR = C2_tfrrp TmpR if DstR is a predicate register
1779 // DstR = A2_tfrrcr TmpR if DstR is a modifier register
1780 unsigned TfrOpc = (Opc == Hexagon::LDriw_pred) ? Hexagon::C2_tfrrp
1781 : Hexagon::A2_tfrrcr;
1782 BuildMI(B, It, DL, HII.get(TfrOpc), DstR)
1783 .addReg(TmpR, RegState::Kill);
1784
1785 NewRegs.push_back(TmpR);
1786 B.erase(It);
1787 return true;
1788}
1789
1790bool HexagonFrameLowering::expandStoreVecPred(MachineBasicBlock &B,
1792 const HexagonInstrInfo &HII, SmallVectorImpl<Register> &NewRegs) const {
1793 MachineInstr *MI = &*It;
1794 if (!MI->getOperand(0).isFI())
1795 return false;
1796
1797 DebugLoc DL = MI->getDebugLoc();
1798 Register SrcR = MI->getOperand(2).getReg();
1799 bool IsKill = MI->getOperand(2).isKill();
1800 int FI = MI->getOperand(0).getIndex();
1801 auto *RC = &Hexagon::HvxVRRegClass;
1802
1803 // Insert transfer to general vector register.
1804 // TmpR0 = A2_tfrsi 0x01010101
1805 // TmpR1 = V6_vandqrt Qx, TmpR0
1806 // store FI, 0, TmpR1
1807 Register TmpR0 = MRI.createVirtualRegister(&Hexagon::IntRegsRegClass);
1808 Register TmpR1 = MRI.createVirtualRegister(RC);
1809
1810 BuildMI(B, It, DL, HII.get(Hexagon::A2_tfrsi), TmpR0)
1811 .addImm(0x01010101);
1812
1813 BuildMI(B, It, DL, HII.get(Hexagon::V6_vandqrt), TmpR1)
1814 .addReg(SrcR, getKillRegState(IsKill))
1815 .addReg(TmpR0, RegState::Kill);
1816
1817 auto *HRI = B.getParent()->getSubtarget<HexagonSubtarget>().getRegisterInfo();
1818 HII.storeRegToStackSlot(B, It, TmpR1, true, FI, RC, HRI, Register());
1819 expandStoreVec(B, std::prev(It), MRI, HII, NewRegs);
1820
1821 NewRegs.push_back(TmpR0);
1822 NewRegs.push_back(TmpR1);
1823 B.erase(It);
1824 return true;
1825}
1826
1827bool HexagonFrameLowering::expandLoadVecPred(MachineBasicBlock &B,
1829 const HexagonInstrInfo &HII, SmallVectorImpl<Register> &NewRegs) const {
1830 MachineInstr *MI = &*It;
1831 if (!MI->getOperand(1).isFI())
1832 return false;
1833
1834 DebugLoc DL = MI->getDebugLoc();
1835 Register DstR = MI->getOperand(0).getReg();
1836 int FI = MI->getOperand(1).getIndex();
1837 auto *RC = &Hexagon::HvxVRRegClass;
1838
1839 // TmpR0 = A2_tfrsi 0x01010101
1840 // TmpR1 = load FI, 0
1841 // DstR = V6_vandvrt TmpR1, TmpR0
1842 Register TmpR0 = MRI.createVirtualRegister(&Hexagon::IntRegsRegClass);
1843 Register TmpR1 = MRI.createVirtualRegister(RC);
1844
1845 BuildMI(B, It, DL, HII.get(Hexagon::A2_tfrsi), TmpR0)
1846 .addImm(0x01010101);
1847 MachineFunction &MF = *B.getParent();
1848 auto *HRI = MF.getSubtarget<HexagonSubtarget>().getRegisterInfo();
1849 HII.loadRegFromStackSlot(B, It, TmpR1, FI, RC, HRI, Register());
1850 expandLoadVec(B, std::prev(It), MRI, HII, NewRegs);
1851
1852 BuildMI(B, It, DL, HII.get(Hexagon::V6_vandvrt), DstR)
1853 .addReg(TmpR1, RegState::Kill)
1854 .addReg(TmpR0, RegState::Kill);
1855
1856 NewRegs.push_back(TmpR0);
1857 NewRegs.push_back(TmpR1);
1858 B.erase(It);
1859 return true;
1860}
1861
1862bool HexagonFrameLowering::expandStoreVec2(MachineBasicBlock &B,
1864 const HexagonInstrInfo &HII, SmallVectorImpl<Register> &NewRegs) const {
1865 MachineFunction &MF = *B.getParent();
1866 auto &MFI = MF.getFrameInfo();
1867 auto &HRI = *MF.getSubtarget<HexagonSubtarget>().getRegisterInfo();
1868 MachineInstr *MI = &*It;
1869 if (!MI->getOperand(0).isFI())
1870 return false;
1871
1872 // It is possible that the double vector being stored is only partially
1873 // defined. From the point of view of the liveness tracking, it is ok to
1874 // store it as a whole, but if we break it up we may end up storing a
1875 // register that is entirely undefined.
1876 LivePhysRegs LPR(HRI);
1877 LPR.addLiveIns(B);
1879 for (auto R = B.begin(); R != It; ++R) {
1880 Clobbers.clear();
1881 LPR.stepForward(*R, Clobbers);
1882 }
1883
1884 DebugLoc DL = MI->getDebugLoc();
1885 Register SrcR = MI->getOperand(2).getReg();
1886 Register SrcLo = HRI.getSubReg(SrcR, Hexagon::vsub_lo);
1887 Register SrcHi = HRI.getSubReg(SrcR, Hexagon::vsub_hi);
1888 bool IsKill = MI->getOperand(2).isKill();
1889 int FI = MI->getOperand(0).getIndex();
1890
1891 unsigned Size = HRI.getSpillSize(Hexagon::HvxVRRegClass);
1892 Align NeedAlign = HRI.getSpillAlign(Hexagon::HvxVRRegClass);
1893 Align HasAlign = MFI.getObjectAlign(FI);
1894 unsigned StoreOpc;
1895
1896 // Store low part.
1897 if (LPR.contains(SrcLo)) {
1898 StoreOpc = NeedAlign <= HasAlign ? Hexagon::V6_vS32b_ai
1899 : Hexagon::V6_vS32Ub_ai;
1900 BuildMI(B, It, DL, HII.get(StoreOpc))
1901 .addFrameIndex(FI)
1902 .addImm(0)
1903 .addReg(SrcLo, getKillRegState(IsKill))
1904 .cloneMemRefs(*MI);
1905 }
1906
1907 // Store high part.
1908 if (LPR.contains(SrcHi)) {
1909 StoreOpc = NeedAlign <= HasAlign ? Hexagon::V6_vS32b_ai
1910 : Hexagon::V6_vS32Ub_ai;
1911 BuildMI(B, It, DL, HII.get(StoreOpc))
1912 .addFrameIndex(FI)
1913 .addImm(Size)
1914 .addReg(SrcHi, getKillRegState(IsKill))
1915 .cloneMemRefs(*MI);
1916 }
1917
1918 B.erase(It);
1919 return true;
1920}
1921
1922bool HexagonFrameLowering::expandLoadVec2(MachineBasicBlock &B,
1924 const HexagonInstrInfo &HII, SmallVectorImpl<Register> &NewRegs) const {
1925 MachineFunction &MF = *B.getParent();
1926 auto &MFI = MF.getFrameInfo();
1927 auto &HRI = *MF.getSubtarget<HexagonSubtarget>().getRegisterInfo();
1928 MachineInstr *MI = &*It;
1929 if (!MI->getOperand(1).isFI())
1930 return false;
1931
1932 DebugLoc DL = MI->getDebugLoc();
1933 Register DstR = MI->getOperand(0).getReg();
1934 Register DstHi = HRI.getSubReg(DstR, Hexagon::vsub_hi);
1935 Register DstLo = HRI.getSubReg(DstR, Hexagon::vsub_lo);
1936 int FI = MI->getOperand(1).getIndex();
1937
1938 unsigned Size = HRI.getSpillSize(Hexagon::HvxVRRegClass);
1939 Align NeedAlign = HRI.getSpillAlign(Hexagon::HvxVRRegClass);
1940 Align HasAlign = MFI.getObjectAlign(FI);
1941 unsigned LoadOpc;
1942
1943 // Load low part.
1944 LoadOpc = NeedAlign <= HasAlign ? Hexagon::V6_vL32b_ai
1945 : Hexagon::V6_vL32Ub_ai;
1946 BuildMI(B, It, DL, HII.get(LoadOpc), DstLo)
1947 .addFrameIndex(FI)
1948 .addImm(0)
1949 .cloneMemRefs(*MI);
1950
1951 // Load high part.
1952 LoadOpc = NeedAlign <= HasAlign ? Hexagon::V6_vL32b_ai
1953 : Hexagon::V6_vL32Ub_ai;
1954 BuildMI(B, It, DL, HII.get(LoadOpc), DstHi)
1955 .addFrameIndex(FI)
1956 .addImm(Size)
1957 .cloneMemRefs(*MI);
1958
1959 B.erase(It);
1960 return true;
1961}
1962
1963bool HexagonFrameLowering::expandStoreVec(MachineBasicBlock &B,
1965 const HexagonInstrInfo &HII, SmallVectorImpl<Register> &NewRegs) const {
1966 MachineFunction &MF = *B.getParent();
1967 auto &MFI = MF.getFrameInfo();
1968 MachineInstr *MI = &*It;
1969 if (!MI->getOperand(0).isFI())
1970 return false;
1971
1972 auto &HRI = *MF.getSubtarget<HexagonSubtarget>().getRegisterInfo();
1973 DebugLoc DL = MI->getDebugLoc();
1974 Register SrcR = MI->getOperand(2).getReg();
1975 bool IsKill = MI->getOperand(2).isKill();
1976 int FI = MI->getOperand(0).getIndex();
1977
1978 Align NeedAlign = HRI.getSpillAlign(Hexagon::HvxVRRegClass);
1979 Align HasAlign = MFI.getObjectAlign(FI);
1980 unsigned StoreOpc = NeedAlign <= HasAlign ? Hexagon::V6_vS32b_ai
1981 : Hexagon::V6_vS32Ub_ai;
1982 BuildMI(B, It, DL, HII.get(StoreOpc))
1983 .addFrameIndex(FI)
1984 .addImm(0)
1985 .addReg(SrcR, getKillRegState(IsKill))
1986 .cloneMemRefs(*MI);
1987
1988 B.erase(It);
1989 return true;
1990}
1991
1992bool HexagonFrameLowering::expandLoadVec(MachineBasicBlock &B,
1994 const HexagonInstrInfo &HII, SmallVectorImpl<Register> &NewRegs) const {
1995 MachineFunction &MF = *B.getParent();
1996 auto &MFI = MF.getFrameInfo();
1997 MachineInstr *MI = &*It;
1998 if (!MI->getOperand(1).isFI())
1999 return false;
2000
2001 auto &HRI = *MF.getSubtarget<HexagonSubtarget>().getRegisterInfo();
2002 DebugLoc DL = MI->getDebugLoc();
2003 Register DstR = MI->getOperand(0).getReg();
2004 int FI = MI->getOperand(1).getIndex();
2005
2006 Align NeedAlign = HRI.getSpillAlign(Hexagon::HvxVRRegClass);
2007 Align HasAlign = MFI.getObjectAlign(FI);
2008 unsigned LoadOpc = NeedAlign <= HasAlign ? Hexagon::V6_vL32b_ai
2009 : Hexagon::V6_vL32Ub_ai;
2010 BuildMI(B, It, DL, HII.get(LoadOpc), DstR)
2011 .addFrameIndex(FI)
2012 .addImm(0)
2013 .cloneMemRefs(*MI);
2014
2015 B.erase(It);
2016 return true;
2017}
2018
2019bool HexagonFrameLowering::expandSpillMacros(MachineFunction &MF,
2020 SmallVectorImpl<Register> &NewRegs) const {
2021 auto &HII = *MF.getSubtarget<HexagonSubtarget>().getInstrInfo();
2023 bool Changed = false;
2024
2025 for (auto &B : MF) {
2026 // Traverse the basic block.
2028 for (auto I = B.begin(), E = B.end(); I != E; I = NextI) {
2029 MachineInstr *MI = &*I;
2030 NextI = std::next(I);
2031 unsigned Opc = MI->getOpcode();
2032
2033 switch (Opc) {
2034 case TargetOpcode::COPY:
2035 Changed |= expandCopy(B, I, MRI, HII, NewRegs);
2036 break;
2037 case Hexagon::STriw_pred:
2038 case Hexagon::STriw_ctr:
2039 Changed |= expandStoreInt(B, I, MRI, HII, NewRegs);
2040 break;
2041 case Hexagon::LDriw_pred:
2042 case Hexagon::LDriw_ctr:
2043 Changed |= expandLoadInt(B, I, MRI, HII, NewRegs);
2044 break;
2045 case Hexagon::PS_vstorerq_ai:
2046 Changed |= expandStoreVecPred(B, I, MRI, HII, NewRegs);
2047 break;
2048 case Hexagon::PS_vloadrq_ai:
2049 Changed |= expandLoadVecPred(B, I, MRI, HII, NewRegs);
2050 break;
2051 case Hexagon::PS_vloadrw_ai:
2052 Changed |= expandLoadVec2(B, I, MRI, HII, NewRegs);
2053 break;
2054 case Hexagon::PS_vstorerw_ai:
2055 Changed |= expandStoreVec2(B, I, MRI, HII, NewRegs);
2056 break;
2057 }
2058 }
2059 }
2060
2061 return Changed;
2062}
2063
2065 BitVector &SavedRegs,
2066 RegScavenger *RS) const {
2067 auto &HRI = *MF.getSubtarget<HexagonSubtarget>().getRegisterInfo();
2068
2069 SavedRegs.resize(HRI.getNumRegs());
2070
2071 // If we have a function containing __builtin_eh_return we want to spill and
2072 // restore all callee saved registers. Pretend that they are used.
2074 for (const MCPhysReg *R = HRI.getCalleeSavedRegs(&MF); *R; ++R)
2075 SavedRegs.set(*R);
2076
2077 // Replace predicate register pseudo spill code.
2079 expandSpillMacros(MF, NewRegs);
2080 if (OptimizeSpillSlots && !isOptNone(MF))
2081 optimizeSpillSlots(MF, NewRegs);
2082
2083 // We need to reserve a spill slot if scavenging could potentially require
2084 // spilling a scavenged register.
2085 if (!NewRegs.empty() || mayOverflowFrameOffset(MF)) {
2086 MachineFrameInfo &MFI = MF.getFrameInfo();
2089 // Reserve an int register in any case, because it could be used to hold
2090 // the stack offset in case it does not fit into a spill instruction.
2091 SpillRCs.insert(&Hexagon::IntRegsRegClass);
2092
2093 for (Register VR : NewRegs)
2094 SpillRCs.insert(MRI.getRegClass(VR));
2095
2096 for (const auto *RC : SpillRCs) {
2097 if (!needToReserveScavengingSpillSlots(MF, HRI, RC))
2098 continue;
2099 unsigned Num = 1;
2100 switch (RC->getID()) {
2101 case Hexagon::IntRegsRegClassID:
2103 break;
2104 case Hexagon::HvxQRRegClassID:
2105 Num = 2; // Vector predicate spills also need a vector register.
2106 break;
2107 }
2108 unsigned S = HRI.getSpillSize(*RC);
2109 Align A = HRI.getSpillAlign(*RC);
2110 for (unsigned i = 0; i < Num; i++) {
2111 int NewFI = MFI.CreateSpillStackObject(S, A);
2112 RS->addScavengingFrameIndex(NewFI);
2113 }
2114 }
2115 }
2116
2118}
2119
2120Register HexagonFrameLowering::findPhysReg(MachineFunction &MF,
2124 const TargetRegisterClass *RC) const {
2125 auto &HRI = *MF.getSubtarget<HexagonSubtarget>().getRegisterInfo();
2126 auto &MRI = MF.getRegInfo();
2127
2128 auto isDead = [&FIR,&DeadMap] (Register Reg) -> bool {
2129 auto F = DeadMap.find({Reg,0});
2130 if (F == DeadMap.end())
2131 return false;
2132 for (auto &DR : F->second)
2133 if (DR.contains(FIR))
2134 return true;
2135 return false;
2136 };
2137
2138 for (Register Reg : RC->getRawAllocationOrder(MF)) {
2139 bool Dead = true;
2140 for (auto R : HexagonBlockRanges::expandToSubRegs({Reg,0}, MRI, HRI)) {
2141 if (isDead(R.Reg))
2142 continue;
2143 Dead = false;
2144 break;
2145 }
2146 if (Dead)
2147 return Reg;
2148 }
2149 return 0;
2150}
2151
2152void HexagonFrameLowering::optimizeSpillSlots(MachineFunction &MF,
2153 SmallVectorImpl<Register> &VRegs) const {
2154 auto &HST = MF.getSubtarget<HexagonSubtarget>();
2155 auto &HII = *HST.getInstrInfo();
2156 auto &HRI = *HST.getRegisterInfo();
2157 auto &MRI = MF.getRegInfo();
2158 HexagonBlockRanges HBR(MF);
2159
2160 using BlockIndexMap =
2161 std::map<MachineBasicBlock *, HexagonBlockRanges::InstrIndexMap>;
2162 using BlockRangeMap =
2163 std::map<MachineBasicBlock *, HexagonBlockRanges::RangeList>;
2164 using IndexType = HexagonBlockRanges::IndexType;
2165
2166 struct SlotInfo {
2167 BlockRangeMap Map;
2168 unsigned Size = 0;
2169 const TargetRegisterClass *RC = nullptr;
2170
2171 SlotInfo() = default;
2172 };
2173
2174 BlockIndexMap BlockIndexes;
2175 SmallSet<int,4> BadFIs;
2176 std::map<int,SlotInfo> FIRangeMap;
2177
2178 // Accumulate register classes: get a common class for a pre-existing
2179 // class HaveRC and a new class NewRC. Return nullptr if a common class
2180 // cannot be found, otherwise return the resulting class. If HaveRC is
2181 // nullptr, assume that it is still unset.
2182 auto getCommonRC =
2183 [](const TargetRegisterClass *HaveRC,
2184 const TargetRegisterClass *NewRC) -> const TargetRegisterClass * {
2185 if (HaveRC == nullptr || HaveRC == NewRC)
2186 return NewRC;
2187 // Different classes, both non-null. Pick the more general one.
2188 if (HaveRC->hasSubClassEq(NewRC))
2189 return HaveRC;
2190 if (NewRC->hasSubClassEq(HaveRC))
2191 return NewRC;
2192 return nullptr;
2193 };
2194
2195 // Scan all blocks in the function. Check all occurrences of frame indexes,
2196 // and collect relevant information.
2197 for (auto &B : MF) {
2198 std::map<int,IndexType> LastStore, LastLoad;
2199 auto P = BlockIndexes.emplace(&B, HexagonBlockRanges::InstrIndexMap(B));
2200 auto &IndexMap = P.first->second;
2201 LLVM_DEBUG(dbgs() << "Index map for " << printMBBReference(B) << "\n"
2202 << IndexMap << '\n');
2203
2204 for (auto &In : B) {
2205 int LFI, SFI;
2206 bool Load = HII.isLoadFromStackSlot(In, LFI) && !HII.isPredicated(In);
2207 bool Store = HII.isStoreToStackSlot(In, SFI) && !HII.isPredicated(In);
2208 if (Load && Store) {
2209 // If it's both a load and a store, then we won't handle it.
2210 BadFIs.insert(LFI);
2211 BadFIs.insert(SFI);
2212 continue;
2213 }
2214 // Check for register classes of the register used as the source for
2215 // the store, and the register used as the destination for the load.
2216 // Also, only accept base+imm_offset addressing modes. Other addressing
2217 // modes can have side-effects (post-increments, etc.). For stack
2218 // slots they are very unlikely, so there is not much loss due to
2219 // this restriction.
2220 if (Load || Store) {
2221 int TFI = Load ? LFI : SFI;
2222 unsigned AM = HII.getAddrMode(In);
2223 SlotInfo &SI = FIRangeMap[TFI];
2224 bool Bad = (AM != HexagonII::BaseImmOffset);
2225 if (!Bad) {
2226 // If the addressing mode is ok, check the register class.
2227 unsigned OpNum = Load ? 0 : 2;
2228 auto *RC = HII.getRegClass(In.getDesc(), OpNum, &HRI, MF);
2229 RC = getCommonRC(SI.RC, RC);
2230 if (RC == nullptr)
2231 Bad = true;
2232 else
2233 SI.RC = RC;
2234 }
2235 if (!Bad) {
2236 // Check sizes.
2237 unsigned S = HII.getMemAccessSize(In);
2238 if (SI.Size != 0 && SI.Size != S)
2239 Bad = true;
2240 else
2241 SI.Size = S;
2242 }
2243 if (!Bad) {
2244 for (auto *Mo : In.memoperands()) {
2245 if (!Mo->isVolatile() && !Mo->isAtomic())
2246 continue;
2247 Bad = true;
2248 break;
2249 }
2250 }
2251 if (Bad)
2252 BadFIs.insert(TFI);
2253 }
2254
2255 // Locate uses of frame indices.
2256 for (unsigned i = 0, n = In.getNumOperands(); i < n; ++i) {
2257 const MachineOperand &Op = In.getOperand(i);
2258 if (!Op.isFI())
2259 continue;
2260 int FI = Op.getIndex();
2261 // Make sure that the following operand is an immediate and that
2262 // it is 0. This is the offset in the stack object.
2263 if (i+1 >= n || !In.getOperand(i+1).isImm() ||
2264 In.getOperand(i+1).getImm() != 0)
2265 BadFIs.insert(FI);
2266 if (BadFIs.count(FI))
2267 continue;
2268
2269 IndexType Index = IndexMap.getIndex(&In);
2270 auto &LS = LastStore[FI];
2271 auto &LL = LastLoad[FI];
2272 if (Load) {
2273 if (LS == IndexType::None)
2274 LS = IndexType::Entry;
2275 LL = Index;
2276 } else if (Store) {
2277 HexagonBlockRanges::RangeList &RL = FIRangeMap[FI].Map[&B];
2278 if (LS != IndexType::None)
2279 RL.add(LS, LL, false, false);
2280 else if (LL != IndexType::None)
2281 RL.add(IndexType::Entry, LL, false, false);
2282 LL = IndexType::None;
2283 LS = Index;
2284 } else {
2285 BadFIs.insert(FI);
2286 }
2287 }
2288 }
2289
2290 for (auto &I : LastLoad) {
2291 IndexType LL = I.second;
2292 if (LL == IndexType::None)
2293 continue;
2294 auto &RL = FIRangeMap[I.first].Map[&B];
2295 IndexType &LS = LastStore[I.first];
2296 if (LS != IndexType::None)
2297 RL.add(LS, LL, false, false);
2298 else
2299 RL.add(IndexType::Entry, LL, false, false);
2300 LS = IndexType::None;
2301 }
2302 for (auto &I : LastStore) {
2303 IndexType LS = I.second;
2304 if (LS == IndexType::None)
2305 continue;
2306 auto &RL = FIRangeMap[I.first].Map[&B];
2307 RL.add(LS, IndexType::None, false, false);
2308 }
2309 }
2310
2311 LLVM_DEBUG({
2312 for (auto &P : FIRangeMap) {
2313 dbgs() << "fi#" << P.first;
2314 if (BadFIs.count(P.first))
2315 dbgs() << " (bad)";
2316 dbgs() << " RC: ";
2317 if (P.second.RC != nullptr)
2318 dbgs() << HRI.getRegClassName(P.second.RC) << '\n';
2319 else
2320 dbgs() << "<null>\n";
2321 for (auto &R : P.second.Map)
2322 dbgs() << " " << printMBBReference(*R.first) << " { " << R.second
2323 << "}\n";
2324 }
2325 });
2326
2327 // When a slot is loaded from in a block without being stored to in the
2328 // same block, it is live-on-entry to this block. To avoid CFG analysis,
2329 // consider this slot to be live-on-exit from all blocks.
2330 SmallSet<int,4> LoxFIs;
2331
2332 std::map<MachineBasicBlock*,std::vector<int>> BlockFIMap;
2333
2334 for (auto &P : FIRangeMap) {
2335 // P = pair(FI, map: BB->RangeList)
2336 if (BadFIs.count(P.first))
2337 continue;
2338 for (auto &B : MF) {
2339 auto F = P.second.Map.find(&B);
2340 // F = pair(BB, RangeList)
2341 if (F == P.second.Map.end() || F->second.empty())
2342 continue;
2343 HexagonBlockRanges::IndexRange &IR = F->second.front();
2344 if (IR.start() == IndexType::Entry)
2345 LoxFIs.insert(P.first);
2346 BlockFIMap[&B].push_back(P.first);
2347 }
2348 }
2349
2350 LLVM_DEBUG({
2351 dbgs() << "Block-to-FI map (* -- live-on-exit):\n";
2352 for (auto &P : BlockFIMap) {
2353 auto &FIs = P.second;
2354 if (FIs.empty())
2355 continue;
2356 dbgs() << " " << printMBBReference(*P.first) << ": {";
2357 for (auto I : FIs) {
2358 dbgs() << " fi#" << I;
2359 if (LoxFIs.count(I))
2360 dbgs() << '*';
2361 }
2362 dbgs() << " }\n";
2363 }
2364 });
2365
2366#ifndef NDEBUG
2367 bool HasOptLimit = SpillOptMax.getPosition();
2368#endif
2369
2370 // eliminate loads, when all loads eliminated, eliminate all stores.
2371 for (auto &B : MF) {
2372 auto F = BlockIndexes.find(&B);
2373 assert(F != BlockIndexes.end());
2375 HexagonBlockRanges::RegToRangeMap LM = HBR.computeLiveMap(IM);
2376 HexagonBlockRanges::RegToRangeMap DM = HBR.computeDeadMap(IM, LM);
2377 LLVM_DEBUG(dbgs() << printMBBReference(B) << " dead map\n"
2379
2380 for (auto FI : BlockFIMap[&B]) {
2381 if (BadFIs.count(FI))
2382 continue;
2383 LLVM_DEBUG(dbgs() << "Working on fi#" << FI << '\n');
2384 HexagonBlockRanges::RangeList &RL = FIRangeMap[FI].Map[&B];
2385 for (auto &Range : RL) {
2386 LLVM_DEBUG(dbgs() << "--Examining range:" << RL << '\n');
2387 if (!IndexType::isInstr(Range.start()) ||
2388 !IndexType::isInstr(Range.end()))
2389 continue;
2390 MachineInstr &SI = *IM.getInstr(Range.start());
2391 MachineInstr &EI = *IM.getInstr(Range.end());
2392 assert(SI.mayStore() && "Unexpected start instruction");
2393 assert(EI.mayLoad() && "Unexpected end instruction");
2394 MachineOperand &SrcOp = SI.getOperand(2);
2395
2397 SrcOp.getSubReg() };
2398 auto *RC = HII.getRegClass(SI.getDesc(), 2, &HRI, MF);
2399 // The this-> is needed to unconfuse MSVC.
2400 Register FoundR = this->findPhysReg(MF, Range, IM, DM, RC);
2401 LLVM_DEBUG(dbgs() << "Replacement reg:" << printReg(FoundR, &HRI)
2402 << '\n');
2403 if (FoundR == 0)
2404 continue;
2405#ifndef NDEBUG
2406 if (HasOptLimit) {
2408 return;
2409 SpillOptCount++;
2410 }
2411#endif
2412
2413 // Generate the copy-in: "FoundR = COPY SrcR" at the store location.
2414 MachineBasicBlock::iterator StartIt = SI.getIterator(), NextIt;
2415 MachineInstr *CopyIn = nullptr;
2416 if (SrcRR.Reg != FoundR || SrcRR.Sub != 0) {
2417 const DebugLoc &DL = SI.getDebugLoc();
2418 CopyIn = BuildMI(B, StartIt, DL, HII.get(TargetOpcode::COPY), FoundR)
2419 .add(SrcOp);
2420 }
2421
2422 ++StartIt;
2423 // Check if this is a last store and the FI is live-on-exit.
2424 if (LoxFIs.count(FI) && (&Range == &RL.back())) {
2425 // Update store's source register.
2426 if (unsigned SR = SrcOp.getSubReg())
2427 SrcOp.setReg(HRI.getSubReg(FoundR, SR));
2428 else
2429 SrcOp.setReg(FoundR);
2430 SrcOp.setSubReg(0);
2431 // We are keeping this register live.
2432 SrcOp.setIsKill(false);
2433 } else {
2434 B.erase(&SI);
2435 IM.replaceInstr(&SI, CopyIn);
2436 }
2437
2438 auto EndIt = std::next(EI.getIterator());
2439 for (auto It = StartIt; It != EndIt; It = NextIt) {
2440 MachineInstr &MI = *It;
2441 NextIt = std::next(It);
2442 int TFI;
2443 if (!HII.isLoadFromStackSlot(MI, TFI) || TFI != FI)
2444 continue;
2445 Register DstR = MI.getOperand(0).getReg();
2446 assert(MI.getOperand(0).getSubReg() == 0);
2447 MachineInstr *CopyOut = nullptr;
2448 if (DstR != FoundR) {
2449 DebugLoc DL = MI.getDebugLoc();
2450 unsigned MemSize = HII.getMemAccessSize(MI);
2451 assert(HII.getAddrMode(MI) == HexagonII::BaseImmOffset);
2452 unsigned CopyOpc = TargetOpcode::COPY;
2453 if (HII.isSignExtendingLoad(MI))
2454 CopyOpc = (MemSize == 1) ? Hexagon::A2_sxtb : Hexagon::A2_sxth;
2455 else if (HII.isZeroExtendingLoad(MI))
2456 CopyOpc = (MemSize == 1) ? Hexagon::A2_zxtb : Hexagon::A2_zxth;
2457 CopyOut = BuildMI(B, It, DL, HII.get(CopyOpc), DstR)
2458 .addReg(FoundR, getKillRegState(&MI == &EI));
2459 }
2460 IM.replaceInstr(&MI, CopyOut);
2461 B.erase(It);
2462 }
2463
2464 // Update the dead map.
2465 HexagonBlockRanges::RegisterRef FoundRR = { FoundR, 0 };
2466 for (auto RR : HexagonBlockRanges::expandToSubRegs(FoundRR, MRI, HRI))
2467 DM[RR].subtract(Range);
2468 } // for Range in range list
2469 }
2470 }
2471}
2472
2473void HexagonFrameLowering::expandAlloca(MachineInstr *AI,
2474 const HexagonInstrInfo &HII, Register SP, unsigned CF) const {
2475 MachineBasicBlock &MB = *AI->getParent();
2476 DebugLoc DL = AI->getDebugLoc();
2477 unsigned A = AI->getOperand(2).getImm();
2478
2479 // Have
2480 // Rd = alloca Rs, #A
2481 //
2482 // If Rs and Rd are different registers, use this sequence:
2483 // Rd = sub(r29, Rs)
2484 // r29 = sub(r29, Rs)
2485 // Rd = and(Rd, #-A) ; if necessary
2486 // r29 = and(r29, #-A) ; if necessary
2487 // Rd = add(Rd, #CF) ; CF size aligned to at most A
2488 // otherwise, do
2489 // Rd = sub(r29, Rs)
2490 // Rd = and(Rd, #-A) ; if necessary
2491 // r29 = Rd
2492 // Rd = add(Rd, #CF) ; CF size aligned to at most A
2493
2494 MachineOperand &RdOp = AI->getOperand(0);
2495 MachineOperand &RsOp = AI->getOperand(1);
2496 Register Rd = RdOp.getReg(), Rs = RsOp.getReg();
2497
2498 // Rd = sub(r29, Rs)
2499 BuildMI(MB, AI, DL, HII.get(Hexagon::A2_sub), Rd)
2500 .addReg(SP)
2501 .addReg(Rs);
2502 if (Rs != Rd) {
2503 // r29 = sub(r29, Rs)
2504 BuildMI(MB, AI, DL, HII.get(Hexagon::A2_sub), SP)
2505 .addReg(SP)
2506 .addReg(Rs);
2507 }
2508 if (A > 8) {
2509 // Rd = and(Rd, #-A)
2510 BuildMI(MB, AI, DL, HII.get(Hexagon::A2_andir), Rd)
2511 .addReg(Rd)
2512 .addImm(-int64_t(A));
2513 if (Rs != Rd)
2514 BuildMI(MB, AI, DL, HII.get(Hexagon::A2_andir), SP)
2515 .addReg(SP)
2516 .addImm(-int64_t(A));
2517 }
2518 if (Rs == Rd) {
2519 // r29 = Rd
2520 BuildMI(MB, AI, DL, HII.get(TargetOpcode::COPY), SP)
2521 .addReg(Rd);
2522 }
2523 if (CF > 0) {
2524 // Rd = add(Rd, #CF)
2525 BuildMI(MB, AI, DL, HII.get(Hexagon::A2_addi), Rd)
2526 .addReg(Rd)
2527 .addImm(CF);
2528 }
2529}
2530
2532 const MachineFrameInfo &MFI = MF.getFrameInfo();
2533 if (!MFI.hasVarSizedObjects())
2534 return false;
2535 // Do not check for max stack object alignment here, because the stack
2536 // may not be complete yet. Assume that we will need PS_aligna if there
2537 // are variable-sized objects.
2538 return true;
2539}
2540
2542 const MachineFunction &MF) const {
2543 for (auto &B : MF)
2544 for (auto &I : B)
2545 if (I.getOpcode() == Hexagon::PS_aligna)
2546 return &I;
2547 return nullptr;
2548}
2549
2550/// Adds all callee-saved registers as implicit uses or defs to the
2551/// instruction.
2552void HexagonFrameLowering::addCalleeSaveRegistersAsImpOperand(MachineInstr *MI,
2553 const CSIVect &CSI, bool IsDef, bool IsKill) const {
2554 // Add the callee-saved registers as implicit uses.
2555 for (auto &R : CSI)
2556 MI->addOperand(MachineOperand::CreateReg(R.getReg(), IsDef, true, IsKill));
2557}
2558
2559/// Determine whether the callee-saved register saves and restores should
2560/// be generated via inline code. If this function returns "true", inline
2561/// code will be generated. If this function returns "false", additional
2562/// checks are performed, which may still lead to the inline code.
2563bool HexagonFrameLowering::shouldInlineCSR(const MachineFunction &MF,
2564 const CSIVect &CSI) const {
2566 return true;
2568 return true;
2569 if (!hasFP(MF))
2570 return true;
2571 if (!isOptSize(MF) && !isMinSize(MF))
2573 return true;
2574
2575 // Check if CSI only has double registers, and if the registers form
2576 // a contiguous block starting from D8.
2577 BitVector Regs(Hexagon::NUM_TARGET_REGS);
2578 for (const CalleeSavedInfo &I : CSI) {
2579 MCRegister R = I.getReg();
2580 if (!Hexagon::DoubleRegsRegClass.contains(R))
2581 return true;
2582 Regs[R] = true;
2583 }
2584 int F = Regs.find_first();
2585 if (F != Hexagon::D8)
2586 return true;
2587 while (F >= 0) {
2588 int N = Regs.find_next(F);
2589 if (N >= 0 && N != F+1)
2590 return true;
2591 F = N;
2592 }
2593
2594 return false;
2595}
2596
2597bool HexagonFrameLowering::useSpillFunction(const MachineFunction &MF,
2598 const CSIVect &CSI) const {
2599 if (shouldInlineCSR(MF, CSI))
2600 return false;
2601 unsigned NumCSI = CSI.size();
2602 if (NumCSI <= 1)
2603 return false;
2604
2605 unsigned Threshold = isOptSize(MF) ? SpillFuncThresholdOs
2607 return Threshold < NumCSI;
2608}
2609
2610bool HexagonFrameLowering::useRestoreFunction(const MachineFunction &MF,
2611 const CSIVect &CSI) const {
2612 if (shouldInlineCSR(MF, CSI))
2613 return false;
2614 // The restore functions do a bit more than just restoring registers.
2615 // The non-returning versions will go back directly to the caller's
2616 // caller, others will clean up the stack frame in preparation for
2617 // a tail call. Using them can still save code size even if only one
2618 // register is getting restores. Make the decision based on -Oz:
2619 // using -Os will use inline restore for a single register.
2620 if (isMinSize(MF))
2621 return true;
2622 unsigned NumCSI = CSI.size();
2623 if (NumCSI <= 1)
2624 return false;
2625
2626 unsigned Threshold = isOptSize(MF) ? SpillFuncThresholdOs-1
2628 return Threshold < NumCSI;
2629}
2630
2631bool HexagonFrameLowering::mayOverflowFrameOffset(MachineFunction &MF) const {
2632 unsigned StackSize = MF.getFrameInfo().estimateStackSize(MF);
2633 auto &HST = MF.getSubtarget<HexagonSubtarget>();
2634 // A fairly simplistic guess as to whether a potential load/store to a
2635 // stack location could require an extra register.
2636 if (HST.useHVXOps() && StackSize > 256)
2637 return true;
2638
2639 // Check if the function has store-immediate instructions that access
2640 // the stack. Since the offset field is not extendable, if the stack
2641 // size exceeds the offset limit (6 bits, shifted), the stores will
2642 // require a new base register.
2643 bool HasImmStack = false;
2644 unsigned MinLS = ~0u; // Log_2 of the memory access size.
2645
2646 for (const MachineBasicBlock &B : MF) {
2647 for (const MachineInstr &MI : B) {
2648 unsigned LS = 0;
2649 switch (MI.getOpcode()) {
2650 case Hexagon::S4_storeirit_io:
2651 case Hexagon::S4_storeirif_io:
2652 case Hexagon::S4_storeiri_io:
2653 ++LS;
2654 [[fallthrough]];
2655 case Hexagon::S4_storeirht_io:
2656 case Hexagon::S4_storeirhf_io:
2657 case Hexagon::S4_storeirh_io:
2658 ++LS;
2659 [[fallthrough]];
2660 case Hexagon::S4_storeirbt_io:
2661 case Hexagon::S4_storeirbf_io:
2662 case Hexagon::S4_storeirb_io:
2663 if (MI.getOperand(0).isFI())
2664 HasImmStack = true;
2665 MinLS = std::min(MinLS, LS);
2666 break;
2667 }
2668 }
2669 }
2670
2671 if (HasImmStack)
2672 return !isUInt<6>(StackSize >> MinLS);
2673
2674 return false;
2675}
2676
2677namespace {
2678// Struct used by orderFrameObjects to help sort the stack objects.
2679struct HexagonFrameSortingObject {
2680 bool IsValid = false;
2681 unsigned Index = 0; // Index of Object into MFI list.
2682 unsigned Size = 0;
2683 Align ObjectAlignment = Align(1); // Alignment of Object in bytes.
2684};
2685
2686struct HexagonFrameSortingComparator {
2687 inline bool operator()(const HexagonFrameSortingObject &A,
2688 const HexagonFrameSortingObject &B) const {
2689 return std::make_tuple(!A.IsValid, A.ObjectAlignment, A.Size) <
2690 std::make_tuple(!B.IsValid, B.ObjectAlignment, B.Size);
2691 }
2692};
2693} // namespace
2694
2695// Sort objects on the stack by alignment value and then by size to minimize
2696// padding.
2698 const MachineFunction &MF, SmallVectorImpl<int> &ObjectsToAllocate) const {
2699
2700 if (ObjectsToAllocate.empty())
2701 return;
2702
2703 const MachineFrameInfo &MFI = MF.getFrameInfo();
2704 int NObjects = ObjectsToAllocate.size();
2705
2706 // Create an array of all MFI objects.
2708 MFI.getObjectIndexEnd());
2709
2710 for (int i = 0, j = 0, e = MFI.getObjectIndexEnd(); i < e && j != NObjects;
2711 ++i) {
2712 if (i != ObjectsToAllocate[j])
2713 continue;
2714 j++;
2715
2716 // A variable size object has size equal to 0. Since Hexagon sets
2717 // getUseLocalStackAllocationBlock() to true, a local block is allocated
2718 // earlier. This case is not handled here for now.
2719 int Size = MFI.getObjectSize(i);
2720 if (Size == 0)
2721 return;
2722
2723 SortingObjects[i].IsValid = true;
2724 SortingObjects[i].Index = i;
2725 SortingObjects[i].Size = Size;
2726 SortingObjects[i].ObjectAlignment = MFI.getObjectAlign(i);
2727 }
2728
2729 // Sort objects by alignment and then by size.
2730 llvm::stable_sort(SortingObjects, HexagonFrameSortingComparator());
2731
2732 // Modify the original list to represent the final order.
2733 int i = NObjects;
2734 for (auto &Obj : SortingObjects) {
2735 if (i == 0)
2736 break;
2737 ObjectsToAllocate[--i] = Obj.Index;
2738 }
2739}
unsigned SubReg
unsigned const MachineRegisterInfo * MRI
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
MachineBasicBlock & MBB
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
This file contains the simple types necessary to represent the attributes associated with functions a...
This file implements the BitVector class.
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static RegisterPass< DebugifyModulePass > DM("debugify", "Attach debug info to everything")
This file defines the DenseMap class.
uint32_t Index
uint64_t Size
bool End
Definition: ELF_riscv.cpp:480
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"))
@ SK_FromMemTailcall
static bool enableAllocFrameElim(const MachineFunction &MF)
static const char * getSpillFunctionFor(Register MaxReg, SpillKind SpillType, bool Stkchk=false)
static bool hasReturn(const MachineBasicBlock &MBB)
Returns true if MBB contains an instruction that returns.
static cl::opt< bool > EnableSaveRestoreLong("enable-save-restore-long", cl::Hidden, cl::desc("Enable long calls for save-restore stubs."), cl::init(false))
static bool needToReserveScavengingSpillSlots(MachineFunction &MF, const HexagonRegisterInfo &HRI, const TargetRegisterClass *RC)
Returns true if there are no caller-saved registers available in class RC.
static bool isOptSize(const MachineFunction &MF)
static Register getMax32BitSubRegister(Register Reg, const TargetRegisterInfo &TRI, bool hireg=true)
Map a register pair Reg to the subregister that has the greater "number", i.e.
static cl::opt< int > SpillFuncThresholdOs("spill-func-threshold-Os", cl::Hidden, cl::desc("Specify Os spill func threshold"), cl::init(1))
static bool needsStackFrame(const MachineBasicBlock &MBB, const BitVector &CSR, const HexagonRegisterInfo &HRI)
Checks if the basic block contains any instruction that needs a stack frame to be already in place.
static cl::opt< bool > DisableDeallocRet("disable-hexagon-dealloc-ret", cl::Hidden, cl::desc("Disable Dealloc Return for Hexagon target"))
static cl::opt< bool > EnableShrinkWrapping("hexagon-shrink-frame", cl::init(true), cl::Hidden, cl::desc("Enable stack frame shrink wrapping"))
static bool hasTailCall(const MachineBasicBlock &MBB)
Returns true if MBB has a machine instructions that indicates a tail call in the block.
static cl::opt< unsigned > NumberScavengerSlots("number-scavenger-slots", cl::Hidden, cl::desc("Set the number of scavenger slots"), cl::init(2))
static Register getMaxCalleeSavedReg(ArrayRef< CalleeSavedInfo > CSI, const TargetRegisterInfo &TRI)
Returns the callee saved register with the largest id in the vector.
static bool isMinSize(const MachineFunction &MF)
static cl::opt< unsigned > SpillOptMax("spill-opt-max", cl::Hidden, cl::init(std::numeric_limits< unsigned >::max()))
static unsigned SpillOptCount
static void dump_registers(BitVector &Regs, const TargetRegisterInfo &TRI)
static bool isRestoreCall(unsigned Opc)
static cl::opt< bool > OptimizeSpillSlots("hexagon-opt-spill", cl::Hidden, cl::init(true), cl::desc("Optimize spill slots"))
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:80
This file implements the LivePhysRegs utility for tracking liveness of physical registers.
#define F(x, y, z)
Definition: MD5.cpp:55
#define I(x, y, z)
Definition: MD5.cpp:58
Register const TargetRegisterInfo * TRI
static unsigned getReg(const MCDisassembler *D, unsigned RC, unsigned RegNo)
ConstantRange Range(APInt(BitWidth, Low), APInt(BitWidth, High))
#define P(N)
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
Definition: PassSupport.h:56
This file builds on the ADT/GraphTraits.h file to build a generic graph post order iterator.
This file declares the machine register scavenger class.
bool isDead(const MachineInstr &MI, const MachineRegisterInfo &MRI)
static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)
Definition: Value.cpp:480
This file implements a set that has insertion order iteration characteristics.
This file defines the SmallSet class.
This file defines the SmallVector class.
#define LLVM_DEBUG(...)
Definition: Debug.h:119
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition: ArrayRef.h:41
size_t size() const
size - Get the array size.
Definition: ArrayRef.h:147
bool empty() const
empty - Check if the array is empty.
Definition: ArrayRef.h:142
int find_first() const
find_first - Returns the index of the first set bit, -1 if none of the bits are set.
Definition: BitVector.h:300
void resize(unsigned N, bool t=false)
resize - Grow or shrink the bitvector.
Definition: BitVector.h:341
BitVector & set()
Definition: BitVector.h:351
int find_next(unsigned Prev) const
find_next - Returns the index of the next set bit following the "Prev" bit.
Definition: BitVector.h:308
The CalleeSavedInfo class tracks the information need to locate where a callee saved register is in t...
This class represents an Operation in the Expression.
A debug info location.
Definition: DebugLoc.h:124
NodeT * findNearestCommonDominator(NodeT *A, NodeT *B) const
Find nearest common dominator basic block for basic block A and B.
bool dominates(const DomTreeNodeBase< NodeT > *A, const DomTreeNodeBase< NodeT > *B) const
dominates - Returns true iff A dominates B.
void recalculate(ParentType &Func)
recalculate - compute a dominator tree for the given function
FunctionPass class - This class is used to implement most global optimizations.
Definition: Pass.h:314
bool hasMinSize() const
Optimize this function for minimum size (-Oz).
Definition: Function.h:703
bool hasOptNone() const
Do not optimize this function (-O0).
Definition: Function.h:700
bool isVarArg() const
isVarArg - Return true if this function takes a variable number of arguments.
Definition: Function.h:227
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)
const MachineInstr * getAlignaInstr(const MachineFunction &MF) const
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...
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
void storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, Register SrcReg, bool isKill, int FrameIndex, const TargetRegisterClass *RC, const TargetRegisterInfo *TRI, Register VReg, MachineInstr::MIFlag Flags=MachineInstr::NoFlags) const override
Store the specified register of the given register class to the specified stack frame index.
void loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, Register DestReg, int FrameIndex, const TargetRegisterClass *RC, const TargetRegisterInfo *TRI, Register VReg, MachineInstr::MIFlag Flags=MachineInstr::NoFlags) const override
Load the specified register of the given register class from the specified stack frame index.
Hexagon target-specific information for each MachineFunction.
bool isEHReturnCalleeSaveReg(Register Reg) const
const MCPhysReg * getCalleeSavedRegs(const MachineFunction *MF) const override
Code Generation virtual methods...
const MCPhysReg * getCallerSavedRegs(const MachineFunction *MF, const TargetRegisterClass *RC) const
const HexagonInstrInfo * getInstrInfo() const override
bool isEnvironmentMusl() const
A set of physical registers with utility functions to track liveness when walking backward/forward th...
Definition: LivePhysRegs.h:52
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:585
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:627
LLVM_ABI MCSymbol * createTempSymbol()
Create a temporary symbol with a unique name.
Definition: MCContext.cpp:386
Describe properties that are true of each instruction in the target description file.
Definition: MCInstrDesc.h:199
MCRegAliasIterator enumerates all registers aliasing Reg.
Wrapper class representing physical registers. Should be passed by value.
Definition: MCRegister.h:33
constexpr bool isValid() const
Definition: MCRegister.h:76
constexpr bool isPhysical() const
Return true if the specified register number is in the physical register namespace.
Definition: MCRegister.h:64
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
Definition: MCSymbol.h:42
int getNumber() const
MachineBasicBlocks are uniquely numbered at the function level, unless they're not in a MachineFuncti...
LLVM_ABI iterator getFirstTerminator()
Returns an iterator to the first terminator instruction of this basic block.
LLVM_ABI DebugLoc findDebugLoc(instr_iterator MBBI)
Find the next valid DebugLoc starting at MBBI, skipping any debug instructions.
LLVM_ABI iterator getLastNonDebugInstr(bool SkipPseudoOp=true)
Returns an iterator to the last non-debug instruction in the basic block, or end().
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< iterator > terminators()
iterator_range< succ_iterator > successors()
LLVM_ABI bool isLiveIn(MCRegister Reg, LaneBitmask LaneMask=LaneBitmask::getAll()) const
Return true if the specified register is in the live in set.
DominatorTree Class - Concrete subclass of DominatorTreeBase that is used to compute a normal dominat...
bool dominates(const MachineInstr *A, const MachineInstr *B) const
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted.
void setMaxCallFrameSize(uint64_t S)
bool hasVarSizedObjects() const
This method may be called any time after instruction selection is complete to determine if the stack ...
bool isObjectPreAllocated(int ObjectIdx) const
Return true if the object was pre-allocated into the local block.
uint64_t getStackSize() const
Return the number of bytes that must be allocated to hold all of the fixed size frame objects.
bool hasCalls() const
Return true if the current function has any function calls.
Align getMaxAlign() const
Return the alignment in bytes that this function must be aligned to, which is greater than the defaul...
uint64_t getMaxCallFrameSize() const
Return the maximum size of a call frame that must be allocated for an outgoing function call.
LLVM_ABI int CreateSpillStackObject(uint64_t Size, Align Alignment)
Create a new statically sized stack object that represents a spill slot, returning a nonnegative iden...
LLVM_ABI uint64_t estimateStackSize(const MachineFunction &MF) const
Estimate and return the size of the stack frame.
Align getObjectAlign(int ObjectIdx) const
Return the alignment of the specified stack object.
int64_t getObjectSize(int ObjectIdx) const
Return the size of the specified object.
const std::vector< CalleeSavedInfo > & getCalleeSavedInfo() const
Returns a reference to call saved info vector for the current function.
int getObjectIndexEnd() const
Return one past the maximum frame object index.
LLVM_ABI int CreateFixedSpillStackObject(uint64_t Size, int64_t SPOffset, bool IsImmutable=false)
Create a spill slot at a fixed location on the stack.
int64_t getObjectOffset(int ObjectIdx) const
Return the assigned stack offset of the specified object from the incoming stack pointer.
void setStackSize(uint64_t Size)
Set the size of the stack.
bool isFixedObjectIndex(int ObjectIdx) const
Returns true if the specified index corresponds to a fixed stack object.
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
virtual bool runOnMachineFunction(MachineFunction &MF)=0
runOnMachineFunction - This method must be overloaded to perform the desired machine code transformat...
virtual MachineFunctionProperties getRequiredProperties() const
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.
MachineMemOperand * getMachineMemOperand(MachinePointerInfo PtrInfo, MachineMemOperand::Flags f, LLT MemTy, Align base_alignment, const AAMDNodes &AAInfo=AAMDNodes(), const MDNode *Ranges=nullptr, SyncScope::ID SSID=SyncScope::System, AtomicOrdering Ordering=AtomicOrdering::NotAtomic, AtomicOrdering FailureOrdering=AtomicOrdering::NotAtomic)
getMachineMemOperand - Allocate a new MachineMemOperand.
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.
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
const MachineBasicBlock & front() const
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 & 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 & addReg(Register RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
const MachineInstrBuilder & cloneMemRefs(const MachineInstr &OtherMI) const
const MachineInstrBuilder & addMemOperand(MachineMemOperand *MMO) const
const MachineInstrBuilder & addDef(Register RegNo, unsigned Flags=0, unsigned SubReg=0) const
Add a virtual register definition operand.
Representation of each machine instruction.
Definition: MachineInstr.h:72
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
Definition: MachineInstr.h:587
bool isReturn(QueryType Type=AnyInBundle) const
Definition: MachineInstr.h:938
const MachineBasicBlock * getParent() const
Definition: MachineInstr.h:359
LLVM_ABI void addOperand(MachineFunction &MF, const MachineOperand &Op)
Add the specified operand to the instruction.
LLVM_ABI void copyImplicitOps(MachineFunction &MF, const MachineInstr &MI)
Copy implicit register operands from specified instruction to this instruction.
bool mayLoad(QueryType Type=AnyInBundle) const
Return true if this instruction could possibly read memory.
const DebugLoc & getDebugLoc() const
Returns the debug location id of this MachineInstr.
Definition: MachineInstr.h:511
const MachineOperand & getOperand(unsigned i) const
Definition: MachineInstr.h:595
@ MOStore
The memory access writes data.
MachineOperand class - Representation of each machine instruction operand.
int64_t getImm() const
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)
MachinePostDominatorTree - an analysis pass wrapper for DominatorTree used to compute the post-domina...
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,...
void addScavengingFrameIndex(int FI)
Add a scavenging frame index.
Wrapper class representing virtual and physical registers.
Definition: Register.h:19
constexpr bool isValid() const
Definition: Register.h:107
A vector that has set insertion semantics.
Definition: SetVector.h:59
size_type size() const
Determine the number of elements in the SetVector.
Definition: SetVector.h:104
bool insert(const value_type &X)
Insert a new element into the SetVector.
Definition: SetVector.h:168
SmallSet - This maintains a set of unique values, optimizing for the case when the set is small (less...
Definition: SmallSet.h:134
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:182
bool empty() const
Definition: SmallVector.h:82
size_t size() const
Definition: SmallVector.h:79
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Definition: SmallVector.h:574
void push_back(const T &Elt)
Definition: SmallVector.h:414
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1197
Register getReg() const
StackOffset holds a fixed and a scalable offset in bytes.
Definition: TypeSize.h:34
int64_t getFixed() const
Returns the fixed component of the stack.
Definition: TypeSize.h:50
static StackOffset getFixed(int64_t Fixed)
Definition: TypeSize.h:43
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...
Primary interface to the complete machine description for the target machine.
Definition: TargetMachine.h:83
CodeGenOptLevel getOptLevel() const
Returns the optimization level: None, Less, Default, or Aggressive.
bool isPositionIndependent() const
unsigned getID() const
Return the register class ID number.
ArrayRef< MCPhysReg > getRawAllocationOrder(const MachineFunction &MF, bool Rev=false) const
Returns the preferred order for allocating registers from this register class in MF.
bool hasSubClassEq(const TargetRegisterClass *RC) const
Returns true if RC is a sub-class of or equal to this class.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
self_iterator getIterator()
Definition: ilist_node.h:134
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
Definition: CallingConv.h:24
@ C
The default llvm calling convention, compatible with C.
Definition: CallingConv.h:34
@ Dead
Unused definition.
@ Kill
The last use of a register.
Reg
All possible values of the reg field in the ModR/M byte.
initializer< Ty > init(const Ty &Val)
Definition: CommandLine.h:444
constexpr double e
Definition: MathExtras.h:47
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
@ Offset
Definition: DWP.cpp:477
void stable_sort(R &&Range)
Definition: STLExtras.h:2077
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:207
FunctionPass * createHexagonCallFrameInformation()
unsigned getKillRegState(bool B)
uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
Definition: Alignment.h:155
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:1777
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.
#define N
This struct is a compact representation of a valid (non-zero power of two) alignment.
Definition: Alignment.h:39
uint64_t value() const
This is a hole in the type system and should not be abused.
Definition: Alignment.h:85
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.