LLVM  16.0.0git
AArch64LowerHomogeneousPrologEpilog.cpp
Go to the documentation of this file.
1 //===- AArch64LowerHomogeneousPrologEpilog.cpp ----------------------------===//
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 // This file contains a pass that lowers homogeneous prolog/epilog instructions.
10 //
11 //===----------------------------------------------------------------------===//
12 
13 #include "AArch64InstrInfo.h"
14 #include "AArch64Subtarget.h"
16 #include "Utils/AArch64BaseInfo.h"
25 #include "llvm/IR/DebugLoc.h"
26 #include "llvm/IR/IRBuilder.h"
27 #include "llvm/Pass.h"
29 #include <optional>
30 #include <sstream>
31 
32 using namespace llvm;
33 
34 #define AARCH64_LOWER_HOMOGENEOUS_PROLOG_EPILOG_NAME \
35  "AArch64 homogeneous prolog/epilog lowering pass"
36 
38  "frame-helper-size-threshold", cl::init(2), cl::Hidden,
39  cl::desc("The minimum number of instructions that are outlined in a frame "
40  "helper (default = 2)"));
41 
42 namespace {
43 
44 class AArch64LowerHomogeneousPE {
45 public:
46  const AArch64InstrInfo *TII;
47 
48  AArch64LowerHomogeneousPE(Module *M, MachineModuleInfo *MMI)
49  : M(M), MMI(MMI) {}
50 
51  bool run();
52  bool runOnMachineFunction(MachineFunction &Fn);
53 
54 private:
55  Module *M;
56  MachineModuleInfo *MMI;
57 
58  bool runOnMBB(MachineBasicBlock &MBB);
60  MachineBasicBlock::iterator &NextMBBI);
61 
62  /// Lower a HOM_Prolog pseudo instruction into a helper call
63  /// or a sequence of homogeneous stores.
64  /// When a a fp setup follows, it can be optimized.
66  MachineBasicBlock::iterator &NextMBBI);
67  /// Lower a HOM_Epilog pseudo instruction into a helper call
68  /// or a sequence of homogeneous loads.
69  /// When a return follow, it can be optimized.
71  MachineBasicBlock::iterator &NextMBBI);
72 };
73 
74 class AArch64LowerHomogeneousPrologEpilog : public ModulePass {
75 public:
76  static char ID;
77 
78  AArch64LowerHomogeneousPrologEpilog() : ModulePass(ID) {
81  }
82  void getAnalysisUsage(AnalysisUsage &AU) const override {
85  AU.setPreservesAll();
87  }
88  bool runOnModule(Module &M) override;
89 
90  StringRef getPassName() const override {
92  }
93 };
94 
95 } // end anonymous namespace
96 
98 
99 INITIALIZE_PASS(AArch64LowerHomogeneousPrologEpilog,
100  "aarch64-lower-homogeneous-prolog-epilog",
102 
103 bool AArch64LowerHomogeneousPrologEpilog::runOnModule(Module &M) {
104  if (skipModule(M))
105  return false;
106 
107  MachineModuleInfo *MMI =
108  &getAnalysis<MachineModuleInfoWrapperPass>().getMMI();
109  return AArch64LowerHomogeneousPE(&M, MMI).run();
110 }
111 
113  bool Changed = false;
114  for (auto &F : *M) {
115  if (F.empty())
116  continue;
117 
118  MachineFunction *MF = MMI->getMachineFunction(F);
119  if (!MF)
120  continue;
121  Changed |= runOnMachineFunction(*MF);
122  }
123 
124  return Changed;
125 }
127 
128 /// Return a frame helper name with the given CSRs and the helper type.
129 /// For instance, a prolog helper that saves x19 and x20 is named as
130 /// OUTLINED_FUNCTION_PROLOG_x19x20.
132  FrameHelperType Type, unsigned FpOffset) {
133  std::ostringstream RegStream;
134  switch (Type) {
136  RegStream << "OUTLINED_FUNCTION_PROLOG_";
137  break;
139  RegStream << "OUTLINED_FUNCTION_PROLOG_FRAME" << FpOffset << "_";
140  break;
142  RegStream << "OUTLINED_FUNCTION_EPILOG_";
143  break;
145  RegStream << "OUTLINED_FUNCTION_EPILOG_TAIL_";
146  break;
147  }
148 
149  for (auto Reg : Regs)
151 
152  return RegStream.str();
153 }
154 
155 /// Create a Function for the unique frame helper with the given name.
156 /// Return a newly created MachineFunction with an empty MachineBasicBlock.
158  MachineModuleInfo *MMI,
159  StringRef Name) {
160  LLVMContext &C = M->getContext();
161  Function *F = M->getFunction(Name);
162  assert(F == nullptr && "Function has been created before");
165  assert(F && "Function was null!");
166 
167  // Use ODR linkage to avoid duplication.
168  F->setLinkage(GlobalValue::LinkOnceODRLinkage);
169  F->setUnnamedAddr(GlobalValue::UnnamedAddr::Global);
170 
171  // Set no-opt/minsize, so we don't insert padding between outlined
172  // functions.
173  F->addFnAttr(Attribute::OptimizeNone);
174  F->addFnAttr(Attribute::NoInline);
175  F->addFnAttr(Attribute::MinSize);
176  F->addFnAttr(Attribute::Naked);
177 
179  // Remove unnecessary register liveness and set NoVRegs.
184 
185  // Create entry block.
186  BasicBlock *EntryBB = BasicBlock::Create(C, "entry", F);
187  IRBuilder<> Builder(EntryBB);
188  Builder.CreateRetVoid();
189 
190  // Insert the new block into the function.
192  MF.insert(MF.begin(), MBB);
193 
194  return MF;
195 }
196 
197 /// Emit a store-pair instruction for frame-setup.
200  const TargetInstrInfo &TII, unsigned Reg1, unsigned Reg2,
201  int Offset, bool IsPreDec) {
202  bool IsFloat = AArch64::FPR64RegClass.contains(Reg1);
203  assert(!(IsFloat ^ AArch64::FPR64RegClass.contains(Reg2)));
204  unsigned Opc;
205  if (IsPreDec)
206  Opc = IsFloat ? AArch64::STPDpre : AArch64::STPXpre;
207  else
208  Opc = IsFloat ? AArch64::STPDi : AArch64::STPXi;
209 
210  MachineInstrBuilder MIB = BuildMI(MBB, Pos, DebugLoc(), TII.get(Opc));
211  if (IsPreDec)
212  MIB.addDef(AArch64::SP);
213  MIB.addReg(Reg2)
214  .addReg(Reg1)
215  .addReg(AArch64::SP)
216  .addImm(Offset)
218 }
219 
220 /// Emit a load-pair instruction for frame-destroy.
223  const TargetInstrInfo &TII, unsigned Reg1, unsigned Reg2,
224  int Offset, bool IsPostDec) {
225  bool IsFloat = AArch64::FPR64RegClass.contains(Reg1);
226  assert(!(IsFloat ^ AArch64::FPR64RegClass.contains(Reg2)));
227  unsigned Opc;
228  if (IsPostDec)
229  Opc = IsFloat ? AArch64::LDPDpost : AArch64::LDPXpost;
230  else
231  Opc = IsFloat ? AArch64::LDPDi : AArch64::LDPXi;
232 
233  MachineInstrBuilder MIB = BuildMI(MBB, Pos, DebugLoc(), TII.get(Opc));
234  if (IsPostDec)
235  MIB.addDef(AArch64::SP);
236  MIB.addReg(Reg2, getDefRegState(true))
237  .addReg(Reg1, getDefRegState(true))
238  .addReg(AArch64::SP)
239  .addImm(Offset)
241 }
242 
243 /// Return a unique function if a helper can be formed with the given Regs
244 /// and frame type.
245 /// 1) _OUTLINED_FUNCTION_PROLOG_x30x29x19x20x21x22:
246 /// stp x22, x21, [sp, #-32]! ; x29/x30 has been stored at the caller
247 /// stp x20, x19, [sp, #16]
248 /// ret
249 ///
250 /// 2) _OUTLINED_FUNCTION_PROLOG_FRAME32_x30x29x19x20x21x22:
251 /// stp x22, x21, [sp, #-32]! ; x29/x30 has been stored at the caller
252 /// stp x20, x19, [sp, #16]
253 /// add fp, sp, #32
254 /// ret
255 ///
256 /// 3) _OUTLINED_FUNCTION_EPILOG_x30x29x19x20x21x22:
257 /// mov x16, x30
258 /// ldp x29, x30, [sp, #32]
259 /// ldp x20, x19, [sp, #16]
260 /// ldp x22, x21, [sp], #48
261 /// ret x16
262 ///
263 /// 4) _OUTLINED_FUNCTION_EPILOG_TAIL_x30x29x19x20x21x22:
264 /// ldp x29, x30, [sp, #32]
265 /// ldp x20, x19, [sp, #16]
266 /// ldp x22, x21, [sp], #48
267 /// ret
268 /// @param M module
269 /// @param MMI machine module info
270 /// @param Regs callee save regs that the helper will handle
271 /// @param Type frame helper type
272 /// @return a helper function
276  unsigned FpOffset = 0) {
277  assert(Regs.size() >= 2);
278  auto Name = getFrameHelperName(Regs, Type, FpOffset);
279  auto *F = M->getFunction(Name);
280  if (F)
281  return F;
282 
283  auto &MF = createFrameHelperMachineFunction(M, MMI, Name);
284  MachineBasicBlock &MBB = *MF.begin();
285  const TargetSubtargetInfo &STI = MF.getSubtarget();
286  const TargetInstrInfo &TII = *STI.getInstrInfo();
287 
288  int Size = (int)Regs.size();
289  switch (Type) {
292  // Compute the remaining SP adjust beyond FP/LR.
293  auto LRIdx = std::distance(Regs.begin(), llvm::find(Regs, AArch64::LR));
294 
295  // If the register stored to the lowest address is not LR, we must subtract
296  // more from SP here.
297  if (LRIdx != Size - 2) {
298  assert(Regs[Size - 2] != AArch64::LR);
299  emitStore(MF, MBB, MBB.end(), TII, Regs[Size - 2], Regs[Size - 1],
300  LRIdx - Size + 2, true);
301  }
302 
303  // Store CSRs in the reverse order.
304  for (int I = Size - 3; I >= 0; I -= 2) {
305  // FP/LR has been stored at call-site.
306  if (Regs[I - 1] == AArch64::LR)
307  continue;
308  emitStore(MF, MBB, MBB.end(), TII, Regs[I - 1], Regs[I], Size - I - 1,
309  false);
310  }
312  BuildMI(MBB, MBB.end(), DebugLoc(), TII.get(AArch64::ADDXri))
313  .addDef(AArch64::FP)
314  .addUse(AArch64::SP)
315  .addImm(FpOffset)
316  .addImm(0)
318 
319  BuildMI(MBB, MBB.end(), DebugLoc(), TII.get(AArch64::RET))
320  .addReg(AArch64::LR);
321  break;
322  }
326  // Stash LR to X16
327  BuildMI(MBB, MBB.end(), DebugLoc(), TII.get(AArch64::ORRXrs))
328  .addDef(AArch64::X16)
329  .addReg(AArch64::XZR)
330  .addUse(AArch64::LR)
331  .addImm(0);
332 
333  for (int I = 0; I < Size - 2; I += 2)
334  emitLoad(MF, MBB, MBB.end(), TII, Regs[I], Regs[I + 1], Size - I - 2,
335  false);
336  // Restore the last CSR with post-increment of SP.
337  emitLoad(MF, MBB, MBB.end(), TII, Regs[Size - 2], Regs[Size - 1], Size,
338  true);
339 
340  BuildMI(MBB, MBB.end(), DebugLoc(), TII.get(AArch64::RET))
341  .addReg(Type == FrameHelperType::Epilog ? AArch64::X16 : AArch64::LR);
342  break;
343  }
344 
345  return M->getFunction(Name);
346 }
347 
348 /// This function checks if a frame helper should be used for
349 /// HOM_Prolog/HOM_Epilog pseudo instruction expansion.
350 /// @param MBB machine basic block
351 /// @param NextMBBI next instruction following HOM_Prolog/HOM_Epilog
352 /// @param Regs callee save registers that are saved or restored.
353 /// @param Type frame helper type
354 /// @return True if a use of helper is qualified.
356  MachineBasicBlock::iterator &NextMBBI,
359  const auto *TRI = MBB.getParent()->getSubtarget().getRegisterInfo();
360  auto RegCount = Regs.size();
361  assert(RegCount > 0 && (RegCount % 2 == 0));
362  // # of instructions that will be outlined.
363  int InstCount = RegCount / 2;
364 
365  // Do not use a helper call when not saving LR.
366  if (!llvm::is_contained(Regs, AArch64::LR))
367  return false;
368 
369  switch (Type) {
371  // Prolog helper cannot save FP/LR.
372  InstCount--;
373  break;
375  // Effecitvely no change in InstCount since FpAdjusment is included.
376  break;
377  }
379  // Bail-out if X16 is live across the epilog helper because it is used in
380  // the helper to handle X30.
381  for (auto NextMI = NextMBBI; NextMI != MBB.end(); NextMI++) {
382  if (NextMI->readsRegister(AArch64::W16, TRI))
383  return false;
384  }
385  // Epilog may not be in the last block. Check the liveness in successors.
386  for (const MachineBasicBlock *SuccMBB : MBB.successors()) {
387  if (SuccMBB->isLiveIn(AArch64::W16) || SuccMBB->isLiveIn(AArch64::X16))
388  return false;
389  }
390  // No change in InstCount for the regular epilog case.
391  break;
393  // EpilogTail helper includes the caller's return.
394  if (NextMBBI == MBB.end())
395  return false;
396  if (NextMBBI->getOpcode() != AArch64::RET_ReallyLR)
397  return false;
398  InstCount++;
399  break;
400  }
401  }
402 
403  return InstCount >= FrameHelperSizeThreshold;
404 }
405 
406 /// Lower a HOM_Epilog pseudo instruction into a helper call while
407 /// creating the helper on demand. Or emit a sequence of loads in place when not
408 /// using a helper call.
409 ///
410 /// 1. With a helper including ret
411 /// HOM_Epilog x30, x29, x19, x20, x21, x22 ; MBBI
412 /// ret ; NextMBBI
413 /// =>
414 /// b _OUTLINED_FUNCTION_EPILOG_TAIL_x30x29x19x20x21x22
415 /// ... ; NextMBBI
416 ///
417 /// 2. With a helper
418 /// HOM_Epilog x30, x29, x19, x20, x21, x22
419 /// =>
420 /// bl _OUTLINED_FUNCTION_EPILOG_x30x29x19x20x21x22
421 ///
422 /// 3. Without a helper
423 /// HOM_Epilog x30, x29, x19, x20, x21, x22
424 /// =>
425 /// ldp x29, x30, [sp, #32]
426 /// ldp x20, x19, [sp, #16]
427 /// ldp x22, x21, [sp], #48
428 bool AArch64LowerHomogeneousPE::lowerEpilog(
430  MachineBasicBlock::iterator &NextMBBI) {
431  auto &MF = *MBB.getParent();
432  MachineInstr &MI = *MBBI;
433 
434  DebugLoc DL = MI.getDebugLoc();
436  for (auto &MO : MI.operands())
437  if (MO.isReg())
438  Regs.push_back(MO.getReg());
439  int Size = (int)Regs.size();
440  if (Size == 0)
441  return false;
442  // Registers are in pair.
443  assert(Size % 2 == 0);
444  assert(MI.getOpcode() == AArch64::HOM_Epilog);
445 
446  auto Return = NextMBBI;
447  if (shouldUseFrameHelper(MBB, NextMBBI, Regs, FrameHelperType::EpilogTail)) {
448  // When MBB ends with a return, emit a tail-call to the epilog helper
449  auto *EpilogTailHelper =
451  BuildMI(MBB, MBBI, DL, TII->get(AArch64::TCRETURNdi))
452  .addGlobalAddress(EpilogTailHelper)
453  .addImm(0)
456  .copyImplicitOps(*Return);
457  NextMBBI = std::next(Return);
458  Return->removeFromParent();
459  } else if (shouldUseFrameHelper(MBB, NextMBBI, Regs,
461  // The default epilog helper case.
462  auto *EpilogHelper =
464  BuildMI(MBB, MBBI, DL, TII->get(AArch64::BL))
465  .addGlobalAddress(EpilogHelper)
468  } else {
469  // Fall back to no-helper.
470  for (int I = 0; I < Size - 2; I += 2)
471  emitLoad(MF, MBB, MBBI, *TII, Regs[I], Regs[I + 1], Size - I - 2, false);
472  // Restore the last CSR with post-increment of SP.
473  emitLoad(MF, MBB, MBBI, *TII, Regs[Size - 2], Regs[Size - 1], Size, true);
474  }
475 
477  return true;
478 }
479 
480 /// Lower a HOM_Prolog pseudo instruction into a helper call while
481 /// creating the helper on demand. Or emit a sequence of stores in place when
482 /// not using a helper call.
483 ///
484 /// 1. With a helper including frame-setup
485 /// HOM_Prolog x30, x29, x19, x20, x21, x22, 32
486 /// =>
487 /// stp x29, x30, [sp, #-16]!
488 /// bl _OUTLINED_FUNCTION_PROLOG_FRAME32_x30x29x19x20x21x22
489 ///
490 /// 2. With a helper
491 /// HOM_Prolog x30, x29, x19, x20, x21, x22
492 /// =>
493 /// stp x29, x30, [sp, #-16]!
494 /// bl _OUTLINED_FUNCTION_PROLOG_x30x29x19x20x21x22
495 ///
496 /// 3. Without a helper
497 /// HOM_Prolog x30, x29, x19, x20, x21, x22
498 /// =>
499 /// stp x22, x21, [sp, #-48]!
500 /// stp x20, x19, [sp, #16]
501 /// stp x29, x30, [sp, #32]
502 bool AArch64LowerHomogeneousPE::lowerProlog(
504  MachineBasicBlock::iterator &NextMBBI) {
505  auto &MF = *MBB.getParent();
506  MachineInstr &MI = *MBBI;
507 
508  DebugLoc DL = MI.getDebugLoc();
510  int LRIdx = 0;
511  std::optional<int> FpOffset;
512  for (auto &MO : MI.operands()) {
513  if (MO.isReg()) {
514  if (MO.getReg() == AArch64::LR)
515  LRIdx = Regs.size();
516  Regs.push_back(MO.getReg());
517  } else if (MO.isImm()) {
518  FpOffset = MO.getImm();
519  }
520  }
521  int Size = (int)Regs.size();
522  if (Size == 0)
523  return false;
524  // Allow compact unwind case only for oww.
525  assert(Size % 2 == 0);
526  assert(MI.getOpcode() == AArch64::HOM_Prolog);
527 
528  if (FpOffset &&
530  // FP/LR is stored at the top of stack before the prolog helper call.
531  emitStore(MF, MBB, MBBI, *TII, AArch64::LR, AArch64::FP, -LRIdx - 2, true);
532  auto *PrologFrameHelper = getOrCreateFrameHelper(
533  M, MMI, Regs, FrameHelperType::PrologFrame, *FpOffset);
534  BuildMI(MBB, MBBI, DL, TII->get(AArch64::BL))
535  .addGlobalAddress(PrologFrameHelper)
539  .addReg(AArch64::SP, RegState::Implicit);
540  } else if (!FpOffset && shouldUseFrameHelper(MBB, NextMBBI, Regs,
542  // FP/LR is stored at the top of stack before the prolog helper call.
543  emitStore(MF, MBB, MBBI, *TII, AArch64::LR, AArch64::FP, -LRIdx - 2, true);
544  auto *PrologHelper =
546  BuildMI(MBB, MBBI, DL, TII->get(AArch64::BL))
547  .addGlobalAddress(PrologHelper)
550  } else {
551  // Fall back to no-helper.
552  emitStore(MF, MBB, MBBI, *TII, Regs[Size - 2], Regs[Size - 1], -Size, true);
553  for (int I = Size - 3; I >= 0; I -= 2)
554  emitStore(MF, MBB, MBBI, *TII, Regs[I - 1], Regs[I], Size - I - 1, false);
555  if (FpOffset) {
556  BuildMI(MBB, MBBI, DL, TII->get(AArch64::ADDXri))
557  .addDef(AArch64::FP)
558  .addUse(AArch64::SP)
559  .addImm(*FpOffset)
560  .addImm(0)
562  }
563  }
564 
566  return true;
567 }
568 
569 /// Process each machine instruction
570 /// @param MBB machine basic block
571 /// @param MBBI current instruction iterator
572 /// @param NextMBBI next instruction iterator which can be updated
573 /// @return True when IR is changed.
574 bool AArch64LowerHomogeneousPE::runOnMI(MachineBasicBlock &MBB,
576  MachineBasicBlock::iterator &NextMBBI) {
577  MachineInstr &MI = *MBBI;
578  unsigned Opcode = MI.getOpcode();
579  switch (Opcode) {
580  default:
581  break;
582  case AArch64::HOM_Prolog:
583  return lowerProlog(MBB, MBBI, NextMBBI);
584  case AArch64::HOM_Epilog:
585  return lowerEpilog(MBB, MBBI, NextMBBI);
586  }
587  return false;
588 }
589 
590 bool AArch64LowerHomogeneousPE::runOnMBB(MachineBasicBlock &MBB) {
591  bool Modified = false;
592 
594  while (MBBI != E) {
595  MachineBasicBlock::iterator NMBBI = std::next(MBBI);
596  Modified |= runOnMI(MBB, MBBI, NMBBI);
597  MBBI = NMBBI;
598  }
599 
600  return Modified;
601 }
602 
603 bool AArch64LowerHomogeneousPE::runOnMachineFunction(MachineFunction &MF) {
604  TII = static_cast<const AArch64InstrInfo *>(MF.getSubtarget().getInstrInfo());
605 
606  bool Modified = false;
607  for (auto &MBB : MF)
608  Modified |= runOnMBB(MBB);
609  return Modified;
610 }
611 
613  return new AArch64LowerHomogeneousPrologEpilog();
614 }
llvm::Check::Size
@ Size
Definition: FileCheck.h:77
llvm::createAArch64LowerHomogeneousPrologEpilogPass
ModulePass * createAArch64LowerHomogeneousPrologEpilogPass()
Definition: AArch64LowerHomogeneousPrologEpilog.cpp:612
MI
IRTranslator LLVM IR MI
Definition: IRTranslator.cpp:108
MachineInstr.h
llvm::MachineInstrBuilder::addImm
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
Definition: MachineInstrBuilder.h:131
llvm
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
llvm::MachineInstrBuilder::copyImplicitOps
const MachineInstrBuilder & copyImplicitOps(const MachineInstr &OtherMI) const
Copy all the implicit operands from OtherMI onto this one.
Definition: MachineInstrBuilder.h:321
M
We currently emits eax Perhaps this is what we really should generate is Is imull three or four cycles eax eax The current instruction priority is based on pattern complexity The former is more complex because it folds a load so the latter will not be emitted Perhaps we should use AddedComplexity to give LEA32r a higher priority We should always try to match LEA first since the LEA matching code does some estimate to determine whether the match is profitable if we care more about code then imull is better It s two bytes shorter than movl leal On a Pentium M
Definition: README.txt:252
llvm::AArch64PACKey::ID
ID
Definition: AArch64BaseInfo.h:818
llvm::ModulePass
ModulePass class - This class is used to implement unstructured interprocedural optimizations and ana...
Definition: Pass.h:248
llvm::Function
Definition: Function.h:60
Pass.h
llvm::TargetSubtargetInfo::getInstrInfo
virtual const TargetInstrInfo * getInstrInfo() const
Definition: TargetSubtargetInfo.h:95
contains
return AArch64::GPR64RegClass contains(Reg)
llvm::SmallVector< unsigned, 8 >
llvm::X86Disassembler::Reg
Reg
All possible values of the reg field in the ModR/M byte.
Definition: X86DisassemblerDecoder.h:462
llvm::IRBuilder<>
llvm::AArch64InstPrinter::getRegisterName
static const char * getRegisterName(unsigned RegNo, unsigned AltIdx=AArch64::NoRegAltName)
AArch64BaseInfo.h
llvm::FunctionType::get
static FunctionType * get(Type *Result, ArrayRef< Type * > Params, bool isVarArg)
This static method is the primary way of constructing a FunctionType.
Definition: Type.cpp:361
llvm::RegState::Define
@ Define
Register definition.
Definition: MachineInstrBuilder.h:44
MachineBasicBlock.h
llvm::TargetSubtargetInfo::getRegisterInfo
virtual const TargetRegisterInfo * getRegisterInfo() const
getRegisterInfo - If register information is available, return it.
Definition: TargetSubtargetInfo.h:127
llvm::cl::Hidden
@ Hidden
Definition: CommandLine.h:140
llvm::Type
The instances of the Type class are immutable: once they are created, they are never changed.
Definition: Type.h:45
getOrCreateFrameHelper
static Function * getOrCreateFrameHelper(Module *M, MachineModuleInfo *MMI, SmallVectorImpl< unsigned > &Regs, FrameHelperType Type, unsigned FpOffset=0)
Return a unique function if a helper can be formed with the given Regs and frame type.
Definition: AArch64LowerHomogeneousPrologEpilog.cpp:273
llvm::MachineFunction::insert
void insert(iterator MBBI, MachineBasicBlock *MBB)
Definition: MachineFunction.h:873
llvm::GlobalValue::UnnamedAddr::Global
@ Global
llvm::MachineFunctionProperties::Property::IsSSA
@ IsSSA
AARCH64_LOWER_HOMOGENEOUS_PROLOG_EPILOG_NAME
#define AARCH64_LOWER_HOMOGENEOUS_PROLOG_EPILOG_NAME
Definition: AArch64LowerHomogeneousPrologEpilog.cpp:34
llvm::initializeAArch64LowerHomogeneousPrologEpilogPass
void initializeAArch64LowerHomogeneousPrologEpilogPass(PassRegistry &)
TRI
unsigned const TargetRegisterInfo * TRI
Definition: MachineSink.cpp:1628
llvm::ARCISD::BL
@ BL
Definition: ARCISelLowering.h:34
F
#define F(x, y, z)
Definition: MD5.cpp:55
llvm::MachineInstr::FrameDestroy
@ FrameDestroy
Definition: MachineInstr.h:86
llvm::BasicBlock
LLVM Basic Block Representation.
Definition: BasicBlock.h:55
llvm::MachineInstrBuilder::addDef
const MachineInstrBuilder & addDef(Register RegNo, unsigned Flags=0, unsigned SubReg=0) const
Add a virtual register definition operand.
Definition: MachineInstrBuilder.h:116
llvm::getDefRegState
unsigned getDefRegState(bool B)
Definition: MachineInstrBuilder.h:540
llvm::MachineFunction::getRegInfo
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
Definition: MachineFunction.h:667
llvm::TargetInstrInfo
TargetInstrInfo - Interface to description of machine instruction set.
Definition: TargetInstrInfo.h:98
llvm::MachineBasicBlock::removeFromParent
MachineBasicBlock * removeFromParent()
This method unlinks 'this' from the containing function, and returns it, but does not delete it.
Definition: MachineBasicBlock.cpp:1340
AArch64InstrInfo.h
llvm::PassRegistry::getPassRegistry
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
Definition: PassRegistry.cpp:24
llvm::AArch64InstrInfo
Definition: AArch64InstrInfo.h:36
E
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
C
(vector float) vec_cmpeq(*A, *B) C
Definition: README_ALTIVEC.txt:86
int
Clang compiles this i1 i64 store i64 i64 store i64 i64 store i64 i64 store i64 align Which gets codegen d xmm0 movaps rbp movaps rbp movaps rbp movaps rbp rbp rbp rbp rbp It would be better to have movq s of instead of the movaps s LLVM produces ret int
Definition: README.txt:536
llvm::AnalysisUsage
Represent the analysis usage information of a pass.
Definition: PassAnalysisSupport.h:47
getFrameHelperName
static std::string getFrameHelperName(SmallVectorImpl< unsigned > &Regs, FrameHelperType Type, unsigned FpOffset)
Return a frame helper name with the given CSRs and the helper type.
Definition: AArch64LowerHomogeneousPrologEpilog.cpp:131
llvm::MachineFunction::getProperties
const MachineFunctionProperties & getProperties() const
Get the function properties.
Definition: MachineFunction.h:748
TII
const HexagonInstrInfo * TII
Definition: HexagonCopyToCombine.cpp:125
llvm::MCID::Return
@ Return
Definition: MCInstrDesc.h:153
llvm::MachineFunctionProperties::set
MachineFunctionProperties & set(Property P)
Definition: MachineFunction.h:196
llvm::MachineInstr::FrameSetup
@ FrameSetup
Definition: MachineInstr.h:84
llvm::MachineModuleInfo
This class contains meta information specific to a module.
Definition: MachineModuleInfo.h:74
LoopDeletionResult::Modified
@ Modified
llvm::MachineFunction::begin
iterator begin()
Definition: MachineFunction.h:854
llvm::MachineRegisterInfo::freezeReservedRegs
void freezeReservedRegs(const MachineFunction &)
freezeReservedRegs - Called by the register allocator to freeze the set of reserved registers before ...
Definition: MachineRegisterInfo.cpp:509
DebugLoc.h
llvm::CallingConv::ID
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
Definition: CallingConv.h:24
emitStore
static void emitStore(MachineFunction &MF, MachineBasicBlock &MBB, MachineBasicBlock::iterator Pos, const TargetInstrInfo &TII, unsigned Reg1, unsigned Reg2, int Offset, bool IsPreDec)
Emit a store-pair instruction for frame-setup.
Definition: AArch64LowerHomogeneousPrologEpilog.cpp:198
llvm::MachineBasicBlock
Definition: MachineBasicBlock.h:94
llvm::dxil::PointerTypeAnalysis::run
PointerTypeMap run(const Module &M)
Compute the PointerTypeMap for the module M.
Definition: PointerTypeAnalysis.cpp:189
llvm::MachineFunctionProperties::Property::NoVRegs
@ NoVRegs
llvm::MachineFunction::getSubtarget
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
Definition: MachineFunction.h:657
llvm::MachineInstrBuilder::setMIFlag
const MachineInstrBuilder & setMIFlag(MachineInstr::MIFlag Flag) const
Definition: MachineInstrBuilder.h:278
llvm::cl::opt
Definition: CommandLine.h:1412
shouldUseFrameHelper
static bool shouldUseFrameHelper(MachineBasicBlock &MBB, MachineBasicBlock::iterator &NextMBBI, SmallVectorImpl< unsigned > &Regs, FrameHelperType Type)
This function checks if a frame helper should be used for HOM_Prolog/HOM_Epilog pseudo instruction ex...
Definition: AArch64LowerHomogeneousPrologEpilog.cpp:355
EpilogTail
@ EpilogTail
Definition: AArch64LowerHomogeneousPrologEpilog.cpp:126
llvm::MachineFunctionProperties::Property::TracksLiveness
@ TracksLiveness
llvm::MachineInstr
Representation of each machine instruction.
Definition: MachineInstr.h:66
llvm::MachineInstrBuilder
Definition: MachineInstrBuilder.h:69
llvm::find
auto find(R &&Range, const T &Val)
Provide wrappers to std::find which take ranges instead of having to pass begin/end explicitly.
Definition: STLExtras.h:1729
llvm::MachineModuleInfoWrapperPass
Definition: MachineModuleInfo.h:214
emitLoad
static void emitLoad(MachineFunction &MF, MachineBasicBlock &MBB, MachineBasicBlock::iterator Pos, const TargetInstrInfo &TII, unsigned Reg1, unsigned Reg2, int Offset, bool IsPostDec)
Emit a load-pair instruction for frame-destroy.
Definition: AArch64LowerHomogeneousPrologEpilog.cpp:221
llvm::LLVMContext
This is an important class for using LLVM in a threaded context.
Definition: LLVMContext.h:67
I
#define I(x, y, z)
Definition: MD5.cpp:58
llvm::cl::init
initializer< Ty > init(const Ty &Val)
Definition: CommandLine.h:447
llvm::is_contained
bool is_contained(R &&Range, const E &Element)
Wrapper function around std::find to detect if an element exists in a container.
Definition: STLExtras.h:1843
llvm::MachineFunction::CreateMachineBasicBlock
MachineBasicBlock * CreateMachineBasicBlock(const BasicBlock *bb=nullptr)
CreateMachineBasicBlock - Allocate a new MachineBasicBlock.
Definition: MachineFunction.cpp:439
MachineFunctionPass.h
llvm::Function::Create
static Function * Create(FunctionType *Ty, LinkageTypes Linkage, unsigned AddrSpace, const Twine &N="", Module *M=nullptr)
Definition: Function.h:137
IRBuilder.h
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
llvm::MachineBasicBlock::getParent
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
Definition: MachineBasicBlock.h:261
MachineModuleInfo.h
llvm::MachineInstrBuilder::addReg
const MachineInstrBuilder & addReg(Register RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
Definition: MachineInstrBuilder.h:97
llvm::MachineInstrBuilder::addUse
const MachineInstrBuilder & addUse(Register RegNo, unsigned Flags=0, unsigned SubReg=0) const
Add a virtual register use operand.
Definition: MachineInstrBuilder.h:123
llvm::Module
A Module instance is used to store all the information related to an LLVM module.
Definition: Module.h:65
Builder
assume Assume Builder
Definition: AssumeBundleBuilder.cpp:651
llvm::MachineFunction
Definition: MachineFunction.h:257
FrameHelperType
FrameHelperType
Definition: AArch64LowerHomogeneousPrologEpilog.cpp:126
AArch64InstPrinter.h
llvm::MachineBasicBlock::successors
iterator_range< succ_iterator > successors()
Definition: MachineBasicBlock.h:392
llvm::StringRef
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:50
MBBI
MachineBasicBlock MachineBasicBlock::iterator MBBI
Definition: AArch64SLSHardening.cpp:75
llvm::RegState::Implicit
@ Implicit
Not emitted register (e.g. carry, or temporary result).
Definition: MachineInstrBuilder.h:46
llvm::AnalysisUsage::addPreserved
AnalysisUsage & addPreserved()
Add the specified Pass class to the set of analyses preserved by this pass.
Definition: PassAnalysisSupport.h:98
PrologFrame
@ PrologFrame
Definition: AArch64LowerHomogeneousPrologEpilog.cpp:126
llvm::BasicBlock::Create
static BasicBlock * Create(LLVMContext &Context, const Twine &Name="", Function *Parent=nullptr, BasicBlock *InsertBefore=nullptr)
Creates a new BasicBlock.
Definition: BasicBlock.h:97
TargetSubtargetInfo.h
DL
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
Definition: AArch64SLSHardening.cpp:76
llvm::MachineModuleInfo::getOrCreateMachineFunction
MachineFunction & getOrCreateMachineFunction(Function &F)
Returns the MachineFunction constructed for the IR function F.
Definition: MachineModuleInfo.cpp:108
llvm::MachineFunctionProperties::reset
MachineFunctionProperties & reset(Property P)
Definition: MachineFunction.h:201
llvm::TargetSubtargetInfo
TargetSubtargetInfo - Generic base class for all target subtargets.
Definition: TargetSubtargetInfo.h:62
Prolog
@ Prolog
Definition: AArch64LowerHomogeneousPrologEpilog.cpp:126
MBB
MachineBasicBlock & MBB
Definition: AArch64SLSHardening.cpp:74
llvm::AnalysisUsage::setPreservesAll
void setPreservesAll()
Set by analyses that do not transform their input at all.
Definition: PassAnalysisSupport.h:130
Epilog
@ Epilog
Definition: AArch64LowerHomogeneousPrologEpilog.cpp:126
llvm::ARCISD::RET
@ RET
Definition: ARCISelLowering.h:52
llvm::GlobalValue::ExternalLinkage
@ ExternalLinkage
Externally visible function.
Definition: GlobalValue.h:48
llvm::MachineInstrBuilder::addGlobalAddress
const MachineInstrBuilder & addGlobalAddress(const GlobalValue *GV, int64_t Offset=0, unsigned TargetFlags=0) const
Definition: MachineInstrBuilder.h:177
llvm::Type::getVoidTy
static Type * getVoidTy(LLVMContext &C)
Definition: Type.cpp:222
AArch64Subtarget.h
llvm::BuildMI
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
Definition: MachineInstrBuilder.h:357
llvm::MachineBasicBlock::begin
iterator begin()
Definition: MachineBasicBlock.h:305
MachineInstrBuilder.h
llvm::SmallVectorImpl< unsigned >
MachineOperand.h
createFrameHelperMachineFunction
static MachineFunction & createFrameHelperMachineFunction(Module *M, MachineModuleInfo *MMI, StringRef Name)
Create a Function for the unique frame helper with the given name.
Definition: AArch64LowerHomogeneousPrologEpilog.cpp:157
llvm::Pass::getAnalysisUsage
virtual void getAnalysisUsage(AnalysisUsage &) const
getAnalysisUsage - This function should be overriden by passes that need analysis information to do t...
Definition: Pass.cpp:98
FrameHelperSizeThreshold
cl::opt< int > FrameHelperSizeThreshold("frame-helper-size-threshold", cl::init(2), cl::Hidden, cl::desc("The minimum number of instructions that are outlined in a frame " "helper (default = 2)"))
llvm::AnalysisUsage::addRequired
AnalysisUsage & addRequired()
Definition: PassAnalysisSupport.h:75
llvm::DebugLoc
A debug info location.
Definition: DebugLoc.h:33
llvm::cl::desc
Definition: CommandLine.h:413
raw_ostream.h
MachineFunction.h
INITIALIZE_PASS
INITIALIZE_PASS(AArch64LowerHomogeneousPrologEpilog, "aarch64-lower-homogeneous-prolog-epilog", AARCH64_LOWER_HOMOGENEOUS_PROLOG_EPILOG_NAME, false, false) bool AArch64LowerHomogeneousPrologEpilog
Definition: AArch64LowerHomogeneousPrologEpilog.cpp:99
llvm::GlobalValue::LinkOnceODRLinkage
@ LinkOnceODRLinkage
Same, but only replaced by something equivalent.
Definition: GlobalValue.h:51
llvm::MachineInstrBundleIterator< MachineInstr >
llvm::MachineBasicBlock::end
iterator end()
Definition: MachineBasicBlock.h:307