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