LLVM  13.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/Pass.h"
28 #include <sstream>
29 
30 using namespace llvm;
31 
32 #define AARCH64_LOWER_HOMOGENEOUS_PROLOG_EPILOG_NAME \
33  "AArch64 homogeneous prolog/epilog lowering pass"
34 
36  "frame-helper-size-threshold", cl::init(2), cl::Hidden,
37  cl::desc("The minimum number of instructions that are outlined in a frame "
38  "helper (default = 2)"));
39 
40 namespace {
41 
42 class AArch64LowerHomogeneousPE {
43 public:
44  const AArch64InstrInfo *TII;
45 
46  AArch64LowerHomogeneousPE(Module *M, MachineModuleInfo *MMI)
47  : M(M), MMI(MMI) {}
48 
49  bool run();
50  bool runOnMachineFunction(MachineFunction &Fn);
51 
52 private:
53  Module *M;
54  MachineModuleInfo *MMI;
55 
56  bool runOnMBB(MachineBasicBlock &MBB);
58  MachineBasicBlock::iterator &NextMBBI);
59 
60  /// Lower a HOM_Prolog pseudo instruction into a helper call
61  /// or a sequence of homogeneous stores.
62  /// When a a fp setup follows, it can be optimized.
64  MachineBasicBlock::iterator &NextMBBI);
65  /// Lower a HOM_Epilog pseudo instruction into a helper call
66  /// or a sequence of homogeneous loads.
67  /// When a return follow, it can be optimized.
69  MachineBasicBlock::iterator &NextMBBI);
70 };
71 
72 class AArch64LowerHomogeneousPrologEpilog : public ModulePass {
73 public:
74  static char ID;
75 
76  AArch64LowerHomogeneousPrologEpilog() : ModulePass(ID) {
79  }
80  void getAnalysisUsage(AnalysisUsage &AU) const override {
83  AU.setPreservesAll();
85  }
86  bool runOnModule(Module &M) override;
87 
88  StringRef getPassName() const override {
90  }
91 };
92 
93 } // end anonymous namespace
94 
96 
97 INITIALIZE_PASS(AArch64LowerHomogeneousPrologEpilog,
98  "aarch64-lower-homogeneous-prolog-epilog",
100 
101 bool AArch64LowerHomogeneousPrologEpilog::runOnModule(Module &M) {
102  if (skipModule(M))
103  return false;
104 
105  MachineModuleInfo *MMI =
106  &getAnalysis<MachineModuleInfoWrapperPass>().getMMI();
107  return AArch64LowerHomogeneousPE(&M, MMI).run();
108 }
109 
110 bool AArch64LowerHomogeneousPE::run() {
111  bool Changed = false;
112  for (auto &F : *M) {
113  if (F.empty())
114  continue;
115 
116  MachineFunction *MF = MMI->getMachineFunction(F);
117  if (!MF)
118  continue;
119  Changed |= runOnMachineFunction(*MF);
120  }
121 
122  return Changed;
123 }
125 
126 /// Return a frame helper name with the given CSRs and the helper type.
127 /// For instance, a prolog helper that saves x19 and x20 is named as
128 /// OUTLINED_FUNCTION_PROLOG_x19x20.
130  FrameHelperType Type, unsigned FpOffset) {
131  std::ostringstream RegStream;
132  switch (Type) {
134  RegStream << "OUTLINED_FUNCTION_PROLOG_";
135  break;
137  RegStream << "OUTLINED_FUNCTION_PROLOG_FRAME" << FpOffset << "_";
138  break;
140  RegStream << "OUTLINED_FUNCTION_EPILOG_";
141  break;
143  RegStream << "OUTLINED_FUNCTION_EPILOG_TAIL_";
144  break;
145  }
146 
147  for (auto Reg : Regs)
149 
150  return RegStream.str();
151 }
152 
153 /// Create a Function for the unique frame helper with the given name.
154 /// Return a newly created MachineFunction with an empty MachineBasicBlock.
156  MachineModuleInfo *MMI,
157  StringRef Name) {
158  LLVMContext &C = M->getContext();
159  Function *F = M->getFunction(Name);
160  assert(F == nullptr && "Function has been created before");
163  assert(F && "Function was null!");
164 
165  // Use ODR linkage to avoid duplication.
166  F->setLinkage(GlobalValue::LinkOnceODRLinkage);
167  F->setUnnamedAddr(GlobalValue::UnnamedAddr::Global);
168 
169  // Set no-opt/minsize, so we don't insert padding between outlined
170  // functions.
171  F->addFnAttr(Attribute::OptimizeNone);
172  F->addFnAttr(Attribute::NoInline);
173  F->addFnAttr(Attribute::MinSize);
174  F->addFnAttr(Attribute::Naked);
175 
177  // Remove unnecessary register liveness and set NoVRegs.
182 
183  // Create entry block.
184  BasicBlock *EntryBB = BasicBlock::Create(C, "entry", F);
185  IRBuilder<> Builder(EntryBB);
186  Builder.CreateRetVoid();
187 
188  // Insert the new block into the function.
190  MF.insert(MF.begin(), MBB);
191 
192  return MF;
193 }
194 
195 /// Emit a store-pair instruction for frame-setup.
198  const TargetInstrInfo &TII, unsigned Reg1, unsigned Reg2,
199  int Offset, bool IsPreDec) {
200  bool IsFloat = AArch64::FPR64RegClass.contains(Reg1);
201  assert(!(IsFloat ^ AArch64::FPR64RegClass.contains(Reg2)));
202  unsigned Opc;
203  if (IsPreDec)
204  Opc = IsFloat ? AArch64::STPDpre : AArch64::STPXpre;
205  else
206  Opc = IsFloat ? AArch64::STPDi : AArch64::STPXi;
207 
208  MachineInstrBuilder MIB = BuildMI(MBB, Pos, DebugLoc(), TII.get(Opc));
209  if (IsPreDec)
210  MIB.addDef(AArch64::SP);
211  MIB.addReg(Reg2)
212  .addReg(Reg1)
213  .addReg(AArch64::SP)
214  .addImm(Offset)
216 }
217 
218 /// Emit a load-pair instruction for frame-destroy.
221  const TargetInstrInfo &TII, unsigned Reg1, unsigned Reg2,
222  int Offset, bool IsPostDec) {
223  bool IsFloat = AArch64::FPR64RegClass.contains(Reg1);
224  assert(!(IsFloat ^ AArch64::FPR64RegClass.contains(Reg2)));
225  unsigned Opc;
226  if (IsPostDec)
227  Opc = IsFloat ? AArch64::LDPDpost : AArch64::LDPXpost;
228  else
229  Opc = IsFloat ? AArch64::LDPDi : AArch64::LDPXi;
230 
231  MachineInstrBuilder MIB = BuildMI(MBB, Pos, DebugLoc(), TII.get(Opc));
232  if (IsPostDec)
233  MIB.addDef(AArch64::SP);
234  MIB.addReg(Reg2, getDefRegState(true))
235  .addReg(Reg1, getDefRegState(true))
236  .addReg(AArch64::SP)
237  .addImm(Offset)
239 }
240 
241 /// Return a unique function if a helper can be formed with the given Regs
242 /// and frame type.
243 /// 1) _OUTLINED_FUNCTION_PROLOG_x30x29x19x20x21x22:
244 /// stp x22, x21, [sp, #-32]! ; x29/x30 has been stored at the caller
245 /// stp x20, x19, [sp, #16]
246 /// ret
247 ///
248 /// 2) _OUTLINED_FUNCTION_PROLOG_FRAME32_x30x29x19x20x21x22:
249 /// stp x22, x21, [sp, #-32]! ; x29/x30 has been stored at the caller
250 /// stp x20, x19, [sp, #16]
251 /// add fp, sp, #32
252 /// ret
253 ///
254 /// 3) _OUTLINED_FUNCTION_EPILOG_x30x29x19x20x21x22:
255 /// mov x16, x30
256 /// ldp x29, x30, [sp, #32]
257 /// ldp x20, x19, [sp, #16]
258 /// ldp x22, x21, [sp], #48
259 /// ret x16
260 ///
261 /// 4) _OUTLINED_FUNCTION_EPILOG_TAIL_x30x29x19x20x21x22:
262 /// ldp x29, x30, [sp, #32]
263 /// ldp x20, x19, [sp, #16]
264 /// ldp x22, x21, [sp], #48
265 /// ret
266 /// @param M module
267 /// @param MMI machine module info
268 /// @param Regs callee save regs that the helper will handle
269 /// @param Type frame helper type
270 /// @return a helper function
274  unsigned FpOffset = 0) {
275  assert(Regs.size() >= 2);
276  auto Name = getFrameHelperName(Regs, Type, FpOffset);
277  auto *F = M->getFunction(Name);
278  if (F)
279  return F;
280 
281  auto &MF = createFrameHelperMachineFunction(M, MMI, Name);
282  MachineBasicBlock &MBB = *MF.begin();
283  const TargetSubtargetInfo &STI = MF.getSubtarget();
284  const TargetInstrInfo &TII = *STI.getInstrInfo();
285 
286  int Size = (int)Regs.size();
287  switch (Type) {
290  // Compute the remaining SP adjust beyond FP/LR.
291  auto LRIdx = std::distance(
292  Regs.begin(), std::find(Regs.begin(), Regs.end(), AArch64::LR));
293 
294  // If the register stored to the lowest address is not LR, we must subtract
295  // more from SP here.
296  if (LRIdx != Size - 2) {
297  assert(Regs[Size - 2] != AArch64::LR);
298  emitStore(MF, MBB, MBB.end(), TII, Regs[Size - 2], Regs[Size - 1],
299  LRIdx - Size + 2, true);
300  }
301 
302  // Store CSRs in the reverse order.
303  for (int I = Size - 3; I >= 0; I -= 2) {
304  // FP/LR has been stored at call-site.
305  if (Regs[I - 1] == AArch64::LR)
306  continue;
307  emitStore(MF, MBB, MBB.end(), TII, Regs[I - 1], Regs[I], Size - I - 1,
308  false);
309  }
311  BuildMI(MBB, MBB.end(), DebugLoc(), TII.get(AArch64::ADDXri))
312  .addDef(AArch64::FP)
313  .addUse(AArch64::SP)
314  .addImm(FpOffset)
315  .addImm(0)
317 
318  BuildMI(MBB, MBB.end(), DebugLoc(), TII.get(AArch64::RET))
319  .addReg(AArch64::LR);
320  break;
321  }
325  // Stash LR to X16
326  BuildMI(MBB, MBB.end(), DebugLoc(), TII.get(AArch64::ORRXrs))
327  .addDef(AArch64::X16)
328  .addReg(AArch64::XZR)
329  .addUse(AArch64::LR)
330  .addImm(0);
331 
332  for (int I = 0; I < Size - 2; I += 2)
333  emitLoad(MF, MBB, MBB.end(), TII, Regs[I], Regs[I + 1], Size - I - 2,
334  false);
335  // Restore the last CSR with post-increment of SP.
336  emitLoad(MF, MBB, MBB.end(), TII, Regs[Size - 2], Regs[Size - 1], Size,
337  true);
338 
339  BuildMI(MBB, MBB.end(), DebugLoc(), TII.get(AArch64::RET))
340  .addReg(Type == FrameHelperType::Epilog ? AArch64::X16 : AArch64::LR);
341  break;
342  }
343 
344  return M->getFunction(Name);
345 }
346 
347 /// This function checks if a frame helper should be used for
348 /// HOM_Prolog/HOM_Epilog pseudo instruction expansion.
349 /// @param MBB machine basic block
350 /// @param NextMBBI next instruction following HOM_Prolog/HOM_Epilog
351 /// @param Regs callee save registers that are saved or restored.
352 /// @param Type frame helper type
353 /// @return True if a use of helper is qualified.
355  MachineBasicBlock::iterator &NextMBBI,
358  const auto *TRI = MBB.getParent()->getSubtarget().getRegisterInfo();
359  auto RegCount = Regs.size();
360  assert(RegCount > 0 && (RegCount % 2 == 0));
361  // # of instructions that will be outlined.
362  int InstCount = RegCount / 2;
363 
364  // Do not use a helper call when not saving LR.
365  if (std::find(Regs.begin(), Regs.end(), AArch64::LR) == Regs.end())
366  return false;
367 
368  switch (Type) {
370  // Prolog helper cannot save FP/LR.
371  InstCount--;
372  break;
374  // Effecitvely no change in InstCount since FpAdjusment is included.
375  break;
376  }
378  // Bail-out if X16 is live across the epilog helper because it is used in
379  // the helper to handle X30.
380  for (auto NextMI = NextMBBI; NextMI != MBB.end(); NextMI++) {
381  if (NextMI->readsRegister(AArch64::W16, TRI))
382  return false;
383  }
384  // Epilog may not be in the last block. Check the liveness in successors.
385  for (const MachineBasicBlock *SuccMBB : MBB.successors()) {
386  if (SuccMBB->isLiveIn(AArch64::W16) || SuccMBB->isLiveIn(AArch64::X16))
387  return false;
388  }
389  // No change in InstCount for the regular epilog case.
390  break;
392  // EpilogTail helper includes the caller's return.
393  if (NextMBBI == MBB.end())
394  return false;
395  if (NextMBBI->getOpcode() != AArch64::RET_ReallyLR)
396  return false;
397  InstCount++;
398  break;
399  }
400  }
401 
402  return InstCount >= FrameHelperSizeThreshold;
403 }
404 
405 /// Lower a HOM_Epilog pseudo instruction into a helper call while
406 /// creating the helper on demand. Or emit a sequence of loads in place when not
407 /// using a helper call.
408 ///
409 /// 1. With a helper including ret
410 /// HOM_Epilog x30, x29, x19, x20, x21, x22 ; MBBI
411 /// ret ; NextMBBI
412 /// =>
413 /// b _OUTLINED_FUNCTION_EPILOG_TAIL_x30x29x19x20x21x22
414 /// ... ; NextMBBI
415 ///
416 /// 2. With a helper
417 /// HOM_Epilog x30, x29, x19, x20, x21, x22
418 /// =>
419 /// bl _OUTLINED_FUNCTION_EPILOG_x30x29x19x20x21x22
420 ///
421 /// 3. Without a helper
422 /// HOM_Epilog x30, x29, x19, x20, x21, x22
423 /// =>
424 /// ldp x29, x30, [sp, #32]
425 /// ldp x20, x19, [sp, #16]
426 /// ldp x22, x21, [sp], #48
427 bool AArch64LowerHomogeneousPE::lowerEpilog(
429  MachineBasicBlock::iterator &NextMBBI) {
430  auto &MF = *MBB.getParent();
431  MachineInstr &MI = *MBBI;
432 
433  DebugLoc DL = MI.getDebugLoc();
435  for (auto &MO : MI.operands())
436  if (MO.isReg())
437  Regs.push_back(MO.getReg());
438  int Size = (int)Regs.size();
439  if (Size == 0)
440  return false;
441  // Registers are in pair.
442  assert(Size % 2 == 0);
443  assert(MI.getOpcode() == AArch64::HOM_Epilog);
444 
445  auto Return = NextMBBI;
446  if (shouldUseFrameHelper(MBB, NextMBBI, Regs, FrameHelperType::EpilogTail)) {
447  // When MBB ends with a return, emit a tail-call to the epilog helper
448  auto *EpilogTailHelper =
450  BuildMI(MBB, MBBI, DL, TII->get(AArch64::TCRETURNdi))
451  .addGlobalAddress(EpilogTailHelper)
452  .addImm(0)
455  .copyImplicitOps(*Return);
456  NextMBBI = std::next(Return);
457  Return->removeFromParent();
458  } else if (shouldUseFrameHelper(MBB, NextMBBI, Regs,
460  // The default epilog helper case.
461  auto *EpilogHelper =
463  BuildMI(MBB, MBBI, DL, TII->get(AArch64::BL))
464  .addGlobalAddress(EpilogHelper)
467  } else {
468  // Fall back to no-helper.
469  for (int I = 0; I < Size - 2; I += 2)
470  emitLoad(MF, MBB, MBBI, *TII, Regs[I], Regs[I + 1], Size - I - 2, false);
471  // Restore the last CSR with post-increment of SP.
472  emitLoad(MF, MBB, MBBI, *TII, Regs[Size - 2], Regs[Size - 1], Size, true);
473  }
474 
476  return true;
477 }
478 
479 /// Lower a HOM_Prolog pseudo instruction into a helper call while
480 /// creating the helper on demand. Or emit a sequence of stores in place when
481 /// not using a helper call.
482 ///
483 /// 1. With a helper including frame-setup
484 /// HOM_Prolog x30, x29, x19, x20, x21, x22, 32
485 /// =>
486 /// stp x29, x30, [sp, #-16]!
487 /// bl _OUTLINED_FUNCTION_PROLOG_FRAME32_x30x29x19x20x21x22
488 ///
489 /// 2. With a helper
490 /// HOM_Prolog x30, x29, x19, x20, x21, x22
491 /// =>
492 /// stp x29, x30, [sp, #-16]!
493 /// bl _OUTLINED_FUNCTION_PROLOG_x30x29x19x20x21x22
494 ///
495 /// 3. Without a helper
496 /// HOM_Prolog x30, x29, x19, x20, x21, x22
497 /// =>
498 /// stp x22, x21, [sp, #-48]!
499 /// stp x20, x19, [sp, #16]
500 /// stp x29, x30, [sp, #32]
501 bool AArch64LowerHomogeneousPE::lowerProlog(
503  MachineBasicBlock::iterator &NextMBBI) {
504  auto &MF = *MBB.getParent();
505  MachineInstr &MI = *MBBI;
506 
507  DebugLoc DL = MI.getDebugLoc();
509  int LRIdx = 0;
510  Optional<int> FpOffset;
511  for (auto &MO : MI.operands()) {
512  if (MO.isReg()) {
513  if (MO.getReg() == AArch64::LR)
514  LRIdx = Regs.size();
515  Regs.push_back(MO.getReg());
516  } else if (MO.isImm()) {
517  FpOffset = MO.getImm();
518  }
519  }
520  int Size = (int)Regs.size();
521  if (Size == 0)
522  return false;
523  // Allow compact unwind case only for oww.
524  assert(Size % 2 == 0);
525  assert(MI.getOpcode() == AArch64::HOM_Prolog);
526 
527  if (FpOffset &&
529  // FP/LR is stored at the top of stack before the prolog helper call.
530  emitStore(MF, MBB, MBBI, *TII, AArch64::LR, AArch64::FP, -LRIdx - 2, true);
531  auto *PrologFrameHelper = getOrCreateFrameHelper(
532  M, MMI, Regs, FrameHelperType::PrologFrame, *FpOffset);
533  BuildMI(MBB, MBBI, DL, TII->get(AArch64::BL))
534  .addGlobalAddress(PrologFrameHelper)
538  .addReg(AArch64::SP, RegState::Implicit);
539  } else if (!FpOffset && shouldUseFrameHelper(MBB, NextMBBI, Regs,
541  // FP/LR is stored at the top of stack before the prolog helper call.
542  emitStore(MF, MBB, MBBI, *TII, AArch64::LR, AArch64::FP, -LRIdx - 2, true);
543  auto *PrologHelper =
545  BuildMI(MBB, MBBI, DL, TII->get(AArch64::BL))
546  .addGlobalAddress(PrologHelper)
549  } else {
550  // Fall back to no-helper.
551  emitStore(MF, MBB, MBBI, *TII, Regs[Size - 2], Regs[Size - 1], -Size, true);
552  for (int I = Size - 3; I >= 0; I -= 2)
553  emitStore(MF, MBB, MBBI, *TII, Regs[I - 1], Regs[I], Size - I - 1, false);
554  if (FpOffset) {
555  BuildMI(MBB, MBBI, DL, TII->get(AArch64::ADDXri))
556  .addDef(AArch64::FP)
557  .addUse(AArch64::SP)
558  .addImm(*FpOffset)
559  .addImm(0)
561  }
562  }
563 
565  return true;
566 }
567 
568 /// Process each machine instruction
569 /// @param MBB machine basic block
570 /// @param MBBI current instruction iterator
571 /// @param NextMBBI next instruction iterator which can be updated
572 /// @return True when IR is changed.
573 bool AArch64LowerHomogeneousPE::runOnMI(MachineBasicBlock &MBB,
575  MachineBasicBlock::iterator &NextMBBI) {
576  MachineInstr &MI = *MBBI;
577  unsigned Opcode = MI.getOpcode();
578  switch (Opcode) {
579  default:
580  break;
581  case AArch64::HOM_Prolog:
582  return lowerProlog(MBB, MBBI, NextMBBI);
583  case AArch64::HOM_Epilog:
584  return lowerEpilog(MBB, MBBI, NextMBBI);
585  }
586  return false;
587 }
588 
589 bool AArch64LowerHomogeneousPE::runOnMBB(MachineBasicBlock &MBB) {
590  bool Modified = false;
591 
593  while (MBBI != E) {
594  MachineBasicBlock::iterator NMBBI = std::next(MBBI);
595  Modified |= runOnMI(MBB, MBBI, NMBBI);
596  MBBI = NMBBI;
597  }
598 
599  return Modified;
600 }
601 
602 bool AArch64LowerHomogeneousPE::runOnMachineFunction(MachineFunction &MF) {
603  TII = static_cast<const AArch64InstrInfo *>(MF.getSubtarget().getInstrInfo());
604 
605  bool Modified = false;
606  for (auto &MBB : MF)
607  Modified |= runOnMBB(MBB);
608  return Modified;
609 }
610 
612  return new AArch64LowerHomogeneousPrologEpilog();
613 }
llvm::Check::Size
@ Size
Definition: FileCheck.h:73
llvm::createAArch64LowerHomogeneousPrologEpilogPass
ModulePass * createAArch64LowerHomogeneousPrologEpilogPass()
Definition: AArch64LowerHomogeneousPrologEpilog.cpp:611
MI
IRTranslator LLVM IR MI
Definition: IRTranslator.cpp:100
MachineInstr.h
llvm::MachineInstrBuilder::addImm
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
Definition: MachineInstrBuilder.h:132
llvm
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:316
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:328
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:140
llvm::Type
The instances of the Type class are immutable: once they are created, they are never changed.
Definition: Type.h:46
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:271
llvm::MachineFunction::insert
void insert(iterator MBBI, MachineBasicBlock *MBB)
Definition: MachineFunction.h:756
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:32
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:117
llvm::getDefRegState
unsigned getDefRegState(bool B)
Definition: MachineInstrBuilder.h:503
llvm::MachineFunction::getRegInfo
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
Definition: MachineFunction.h:565
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:1348
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:129
llvm::MachineFunction::getProperties
const MachineFunctionProperties & getProperties() const
Get the function properties.
Definition: MachineFunction.h:646
TII
const HexagonInstrInfo * TII
Definition: HexagonCopyToCombine.cpp:129
llvm::MCID::Return
@ Return
Definition: MCInstrDesc.h:152
llvm::MachineFunctionProperties::set
MachineFunctionProperties & set(Property P)
Definition: MachineFunction.h:166
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:737
llvm::RegState::Define
@ Define
Register definition.
Definition: MachineInstrBuilder.h:45
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::Implicit
@ Implicit
Not emitted register (e.g. carry, or temporary result).
Definition: MachineInstrBuilder.h:47
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:196
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:555
llvm::MachineInstrBuilder::setMIFlag
const MachineInstrBuilder & setMIFlag(MachineInstr::MIFlag Flag) const
Definition: MachineInstrBuilder.h:279
llvm::cl::opt
Definition: CommandLine.h:1419
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:354
EpilogTail
@ EpilogTail
Definition: AArch64LowerHomogeneousPrologEpilog.cpp:124
llvm::MachineFunctionProperties::Property::TracksLiveness
@ TracksLiveness
llvm::MachineInstr
Representation of each machine instruction.
Definition: MachineInstr.h:64
llvm::MachineInstrBuilder
Definition: MachineInstrBuilder.h:70
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:1525
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:219
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:440
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:137
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:98
llvm::MachineInstrBuilder::addUse
const MachineInstrBuilder & addUse(Register RegNo, unsigned Flags=0, unsigned SubReg=0) const
Add a virtual register use operand.
Definition: MachineInstrBuilder.h:124
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:649
llvm::MachineFunction
Definition: MachineFunction.h:227
FrameHelperType
FrameHelperType
Definition: AArch64LowerHomogeneousPrologEpilog.cpp:124
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:57
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:124
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:284
llvm::MachineFunctionProperties::reset
MachineFunctionProperties & reset(Property P)
Definition: MachineFunction.h:171
llvm::TargetSubtargetInfo
TargetSubtargetInfo - Generic base class for all target subtargets.
Definition: TargetSubtargetInfo.h:59
Prolog
@ Prolog
Definition: AArch64LowerHomogeneousPrologEpilog.cpp:124
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:124
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:178
llvm::Type::getVoidTy
static Type * getVoidTy(LLVMContext &C)
Definition: Type.cpp:187
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:329
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:155
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:411
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:97
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:38