LLVM  14.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 <sstream>
30 
31 using namespace llvm;
32 
33 #define AARCH64_LOWER_HOMOGENEOUS_PROLOG_EPILOG_NAME \
34  "AArch64 homogeneous prolog/epilog lowering pass"
35 
37  "frame-helper-size-threshold", cl::init(2), cl::Hidden,
38  cl::desc("The minimum number of instructions that are outlined in a frame "
39  "helper (default = 2)"));
40 
41 namespace {
42 
43 class AArch64LowerHomogeneousPE {
44 public:
45  const AArch64InstrInfo *TII;
46 
47  AArch64LowerHomogeneousPE(Module *M, MachineModuleInfo *MMI)
48  : M(M), MMI(MMI) {}
49 
50  bool run();
51  bool runOnMachineFunction(MachineFunction &Fn);
52 
53 private:
54  Module *M;
55  MachineModuleInfo *MMI;
56 
57  bool runOnMBB(MachineBasicBlock &MBB);
59  MachineBasicBlock::iterator &NextMBBI);
60 
61  /// Lower a HOM_Prolog pseudo instruction into a helper call
62  /// or a sequence of homogeneous stores.
63  /// When a a fp setup follows, it can be optimized.
65  MachineBasicBlock::iterator &NextMBBI);
66  /// Lower a HOM_Epilog pseudo instruction into a helper call
67  /// or a sequence of homogeneous loads.
68  /// When a return follow, it can be optimized.
70  MachineBasicBlock::iterator &NextMBBI);
71 };
72 
73 class AArch64LowerHomogeneousPrologEpilog : public ModulePass {
74 public:
75  static char ID;
76 
77  AArch64LowerHomogeneousPrologEpilog() : ModulePass(ID) {
80  }
81  void getAnalysisUsage(AnalysisUsage &AU) const override {
84  AU.setPreservesAll();
86  }
87  bool runOnModule(Module &M) override;
88 
89  StringRef getPassName() const override {
91  }
92 };
93 
94 } // end anonymous namespace
95 
97 
98 INITIALIZE_PASS(AArch64LowerHomogeneousPrologEpilog,
99  "aarch64-lower-homogeneous-prolog-epilog",
101 
102 bool AArch64LowerHomogeneousPrologEpilog::runOnModule(Module &M) {
103  if (skipModule(M))
104  return false;
105 
106  MachineModuleInfo *MMI =
107  &getAnalysis<MachineModuleInfoWrapperPass>().getMMI();
108  return AArch64LowerHomogeneousPE(&M, MMI).run();
109 }
110 
111 bool AArch64LowerHomogeneousPE::run() {
112  bool Changed = false;
113  for (auto &F : *M) {
114  if (F.empty())
115  continue;
116 
117  MachineFunction *MF = MMI->getMachineFunction(F);
118  if (!MF)
119  continue;
120  Changed |= runOnMachineFunction(*MF);
121  }
122 
123  return Changed;
124 }
126 
127 /// Return a frame helper name with the given CSRs and the helper type.
128 /// For instance, a prolog helper that saves x19 and x20 is named as
129 /// OUTLINED_FUNCTION_PROLOG_x19x20.
131  FrameHelperType Type, unsigned FpOffset) {
132  std::ostringstream RegStream;
133  switch (Type) {
135  RegStream << "OUTLINED_FUNCTION_PROLOG_";
136  break;
138  RegStream << "OUTLINED_FUNCTION_PROLOG_FRAME" << FpOffset << "_";
139  break;
141  RegStream << "OUTLINED_FUNCTION_EPILOG_";
142  break;
144  RegStream << "OUTLINED_FUNCTION_EPILOG_TAIL_";
145  break;
146  }
147 
148  for (auto Reg : Regs)
150 
151  return RegStream.str();
152 }
153 
154 /// Create a Function for the unique frame helper with the given name.
155 /// Return a newly created MachineFunction with an empty MachineBasicBlock.
157  MachineModuleInfo *MMI,
158  StringRef Name) {
159  LLVMContext &C = M->getContext();
160  Function *F = M->getFunction(Name);
161  assert(F == nullptr && "Function has been created before");
164  assert(F && "Function was null!");
165 
166  // Use ODR linkage to avoid duplication.
167  F->setLinkage(GlobalValue::LinkOnceODRLinkage);
168  F->setUnnamedAddr(GlobalValue::UnnamedAddr::Global);
169 
170  // Set no-opt/minsize, so we don't insert padding between outlined
171  // functions.
172  F->addFnAttr(Attribute::OptimizeNone);
173  F->addFnAttr(Attribute::NoInline);
174  F->addFnAttr(Attribute::MinSize);
175  F->addFnAttr(Attribute::Naked);
176 
178  // Remove unnecessary register liveness and set NoVRegs.
183 
184  // Create entry block.
185  BasicBlock *EntryBB = BasicBlock::Create(C, "entry", F);
186  IRBuilder<> Builder(EntryBB);
187  Builder.CreateRetVoid();
188 
189  // Insert the new block into the function.
191  MF.insert(MF.begin(), MBB);
192 
193  return MF;
194 }
195 
196 /// Emit a store-pair instruction for frame-setup.
199  const TargetInstrInfo &TII, unsigned Reg1, unsigned Reg2,
200  int Offset, bool IsPreDec) {
201  bool IsFloat = AArch64::FPR64RegClass.contains(Reg1);
202  assert(!(IsFloat ^ AArch64::FPR64RegClass.contains(Reg2)));
203  unsigned Opc;
204  if (IsPreDec)
205  Opc = IsFloat ? AArch64::STPDpre : AArch64::STPXpre;
206  else
207  Opc = IsFloat ? AArch64::STPDi : AArch64::STPXi;
208 
209  MachineInstrBuilder MIB = BuildMI(MBB, Pos, DebugLoc(), TII.get(Opc));
210  if (IsPreDec)
211  MIB.addDef(AArch64::SP);
212  MIB.addReg(Reg2)
213  .addReg(Reg1)
214  .addReg(AArch64::SP)
215  .addImm(Offset)
217 }
218 
219 /// Emit a load-pair instruction for frame-destroy.
222  const TargetInstrInfo &TII, unsigned Reg1, unsigned Reg2,
223  int Offset, bool IsPostDec) {
224  bool IsFloat = AArch64::FPR64RegClass.contains(Reg1);
225  assert(!(IsFloat ^ AArch64::FPR64RegClass.contains(Reg2)));
226  unsigned Opc;
227  if (IsPostDec)
228  Opc = IsFloat ? AArch64::LDPDpost : AArch64::LDPXpost;
229  else
230  Opc = IsFloat ? AArch64::LDPDi : AArch64::LDPXi;
231 
232  MachineInstrBuilder MIB = BuildMI(MBB, Pos, DebugLoc(), TII.get(Opc));
233  if (IsPostDec)
234  MIB.addDef(AArch64::SP);
235  MIB.addReg(Reg2, getDefRegState(true))
236  .addReg(Reg1, getDefRegState(true))
237  .addReg(AArch64::SP)
238  .addImm(Offset)
240 }
241 
242 /// Return a unique function if a helper can be formed with the given Regs
243 /// and frame type.
244 /// 1) _OUTLINED_FUNCTION_PROLOG_x30x29x19x20x21x22:
245 /// stp x22, x21, [sp, #-32]! ; x29/x30 has been stored at the caller
246 /// stp x20, x19, [sp, #16]
247 /// ret
248 ///
249 /// 2) _OUTLINED_FUNCTION_PROLOG_FRAME32_x30x29x19x20x21x22:
250 /// stp x22, x21, [sp, #-32]! ; x29/x30 has been stored at the caller
251 /// stp x20, x19, [sp, #16]
252 /// add fp, sp, #32
253 /// ret
254 ///
255 /// 3) _OUTLINED_FUNCTION_EPILOG_x30x29x19x20x21x22:
256 /// mov x16, x30
257 /// ldp x29, x30, [sp, #32]
258 /// ldp x20, x19, [sp, #16]
259 /// ldp x22, x21, [sp], #48
260 /// ret x16
261 ///
262 /// 4) _OUTLINED_FUNCTION_EPILOG_TAIL_x30x29x19x20x21x22:
263 /// ldp x29, x30, [sp, #32]
264 /// ldp x20, x19, [sp, #16]
265 /// ldp x22, x21, [sp], #48
266 /// ret
267 /// @param M module
268 /// @param MMI machine module info
269 /// @param Regs callee save regs that the helper will handle
270 /// @param Type frame helper type
271 /// @return a helper function
275  unsigned FpOffset = 0) {
276  assert(Regs.size() >= 2);
277  auto Name = getFrameHelperName(Regs, Type, FpOffset);
278  auto *F = M->getFunction(Name);
279  if (F)
280  return F;
281 
282  auto &MF = createFrameHelperMachineFunction(M, MMI, Name);
283  MachineBasicBlock &MBB = *MF.begin();
284  const TargetSubtargetInfo &STI = MF.getSubtarget();
285  const TargetInstrInfo &TII = *STI.getInstrInfo();
286 
287  int Size = (int)Regs.size();
288  switch (Type) {
291  // Compute the remaining SP adjust beyond FP/LR.
292  auto LRIdx = std::distance(
293  Regs.begin(), std::find(Regs.begin(), Regs.end(), 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 (std::find(Regs.begin(), Regs.end(), AArch64::LR) == Regs.end())
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  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:73
llvm::createAArch64LowerHomogeneousPrologEpilogPass
ModulePass * createAArch64LowerHomogeneousPrologEpilogPass()
Definition: AArch64LowerHomogeneousPrologEpilog.cpp:612
MI
IRTranslator LLVM IR MI
Definition: IRTranslator.cpp:103
MachineInstr.h
llvm::MachineInstrBuilder::addImm
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
Definition: MachineInstrBuilder.h:131
llvm
---------------------— PointerInfo ------------------------------------—
Definition: AllocatorList.h:23
llvm::MachineInstrBuilder::copyImplicitOps
const MachineInstrBuilder & copyImplicitOps(const MachineInstr &OtherMI) const
Copy all the implicit operands from OtherMI onto this one.
Definition: MachineInstrBuilder.h:315
Reg
unsigned Reg
Definition: MachineSink.cpp:1566
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::ModulePass
ModulePass class - This class is used to implement unstructured interprocedural optimizations and ana...
Definition: Pass.h:238
llvm::Function
Definition: Function.h:61
Pass.h
llvm::TargetSubtargetInfo::getInstrInfo
virtual const TargetInstrInfo * getInstrInfo() const
Definition: TargetSubtargetInfo.h:92
contains
return AArch64::GPR64RegClass contains(Reg)
llvm::SmallVector< unsigned, 8 >
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:325
MachineBasicBlock.h
llvm::TargetSubtargetInfo::getRegisterInfo
virtual const TargetRegisterInfo * getRegisterInfo() const
getRegisterInfo - If register information is available, return it.
Definition: TargetSubtargetInfo.h:124
llvm::cl::Hidden
@ Hidden
Definition: CommandLine.h:143
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:272
llvm::RegState::Implicit
@ Implicit
Not emitted register (e.g. carry, or temporary result).
Definition: MachineInstrBuilder.h:46
llvm::MachineFunction::insert
void insert(iterator MBBI, MachineBasicBlock *MBB)
Definition: MachineFunction.h:827
llvm::GlobalValue::UnnamedAddr::Global
@ Global
llvm::MachineFunctionProperties::Property::IsSSA
@ IsSSA
llvm::Optional< int >
AARCH64_LOWER_HOMOGENEOUS_PROLOG_EPILOG_NAME
#define AARCH64_LOWER_HOMOGENEOUS_PROLOG_EPILOG_NAME
Definition: AArch64LowerHomogeneousPrologEpilog.cpp:33
Offset
uint64_t Offset
Definition: ELFObjHandler.cpp:81
llvm::initializeAArch64LowerHomogeneousPrologEpilogPass
void initializeAArch64LowerHomogeneousPrologEpilogPass(PassRegistry &)
TRI
unsigned const TargetRegisterInfo * TRI
Definition: MachineSink.cpp:1567
llvm::ARCISD::BL
@ BL
Definition: ARCISelLowering.h:34
F
#define F(x, y, z)
Definition: MD5.cpp:56
llvm::MachineInstr::FrameDestroy
@ FrameDestroy
Definition: MachineInstr.h:84
llvm::BasicBlock
LLVM Basic Block Representation.
Definition: BasicBlock.h:58
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:502
llvm::MachineFunction::getRegInfo
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
Definition: MachineFunction.h:636
llvm::TargetInstrInfo
TargetInstrInfo - Interface to description of machine instruction set.
Definition: TargetInstrInfo.h:97
llvm::MachineBasicBlock::removeFromParent
MachineBasicBlock * removeFromParent()
This method unlinks 'this' from the containing function, and returns it, but does not delete it.
Definition: MachineBasicBlock.cpp:1325
AArch64InstrInfo.h
llvm::PassRegistry::getPassRegistry
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
Definition: PassRegistry.cpp:31
llvm::AArch64InstrInfo
Definition: AArch64InstrInfo.h:38
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:130
llvm::MachineFunction::getProperties
const MachineFunctionProperties & getProperties() const
Get the function properties.
Definition: MachineFunction.h:717
TII
const HexagonInstrInfo * TII
Definition: HexagonCopyToCombine.cpp:129
llvm::MCID::Return
@ Return
Definition: MCInstrDesc.h:151
llvm::MachineFunctionProperties::set
MachineFunctionProperties & set(Property P)
Definition: MachineFunction.h:169
llvm::MachineInstr::FrameSetup
@ FrameSetup
Definition: MachineInstr.h:82
llvm::MachineModuleInfo
This class contains meta information specific to a module.
Definition: MachineModuleInfo.h:78
LoopDeletionResult::Modified
@ Modified
llvm::MachineFunction::begin
iterator begin()
Definition: MachineFunction.h:808
llvm::MachineRegisterInfo::freezeReservedRegs
void freezeReservedRegs(const MachineFunction &)
freezeReservedRegs - Called by the register allocator to freeze the set of reserved registers before ...
Definition: MachineRegisterInfo.cpp:507
DebugLoc.h
llvm::RegState::Define
@ Define
Register definition.
Definition: MachineInstrBuilder.h:44
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:197
llvm::MachineBasicBlock
Definition: MachineBasicBlock.h:95
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:626
llvm::MachineInstrBuilder::setMIFlag
const MachineInstrBuilder & setMIFlag(MachineInstr::MIFlag Flag) const
Definition: MachineInstrBuilder.h:278
llvm::cl::opt
Definition: CommandLine.h:1434
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:125
llvm::MachineFunctionProperties::Property::TracksLiveness
@ TracksLiveness
llvm::MachineInstr
Representation of each machine instruction.
Definition: MachineInstr.h:64
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:1567
llvm::MachineModuleInfoWrapperPass
Definition: MachineModuleInfo.h:279
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:220
llvm::LLVMContext
This is an important class for using LLVM in a threaded context.
Definition: LLVMContext.h:68
I
#define I(x, y, z)
Definition: MD5.cpp:59
llvm::cl::init
initializer< Ty > init(const Ty &Val)
Definition: CommandLine.h:443
llvm::MachineFunction::CreateMachineBasicBlock
MachineBasicBlock * CreateMachineBasicBlock(const BasicBlock *bb=nullptr)
CreateMachineBasicBlock - Allocate a new MachineBasicBlock.
Definition: MachineFunction.cpp:414
MachineFunctionPass.h
llvm::Function::Create
static Function * Create(FunctionType *Ty, LinkageTypes Linkage, unsigned AddrSpace, const Twine &N="", Module *M=nullptr)
Definition: Function.h:138
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:225
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:67
Builder
assume Assume Builder
Definition: AssumeBundleBuilder.cpp:650
llvm::MachineFunction
Definition: MachineFunction.h:230
FrameHelperType
FrameHelperType
Definition: AArch64LowerHomogeneousPrologEpilog.cpp:125
AArch64InstPrinter.h
llvm::MachineBasicBlock::successors
iterator_range< succ_iterator > successors()
Definition: MachineBasicBlock.h:355
llvm::StringRef
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:58
MBBI
MachineBasicBlock MachineBasicBlock::iterator MBBI
Definition: AArch64SLSHardening.cpp:75
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:125
llvm::BasicBlock::Create
static BasicBlock * Create(LLVMContext &Context, const Twine &Name="", Function *Parent=nullptr, BasicBlock *InsertBefore=nullptr)
Creates a new BasicBlock.
Definition: BasicBlock.h:100
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:291
llvm::MachineFunctionProperties::reset
MachineFunctionProperties & reset(Property P)
Definition: MachineFunction.h:174
llvm::TargetSubtargetInfo
TargetSubtargetInfo - Generic base class for all target subtargets.
Definition: TargetSubtargetInfo.h:59
Prolog
@ Prolog
Definition: AArch64LowerHomogeneousPrologEpilog.cpp:125
MBB
MachineBasicBlock & MBB
Definition: AArch64SLSHardening.cpp:74
llvm::GraphProgram::Name
Name
Definition: GraphWriter.h:52
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:125
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:186
AArch64Subtarget.h
llvm::MachineBasicBlock::begin
iterator begin()
Definition: MachineBasicBlock.h:268
MachineInstrBuilder.h
llvm::BuildMI
MachineInstrBuilder BuildMI(MachineFunction &MF, const DebugLoc &DL, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
Definition: MachineInstrBuilder.h:328
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:156
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:93
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:414
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:98
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:270
llvm::Intrinsic::ID
unsigned ID
Definition: TargetTransformInfo.h:37