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