LLVM  4.0.0
AArch64CollectLOH.cpp
Go to the documentation of this file.
1 //===---------- AArch64CollectLOH.cpp - AArch64 collect LOH pass --*- C++ -*-=//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file contains a pass that collect the Linker Optimization Hint (LOH).
11 // This pass should be run at the very end of the compilation flow, just before
12 // assembly printer.
13 // To be useful for the linker, the LOH must be printed into the assembly file.
14 //
15 // A LOH describes a sequence of instructions that may be optimized by the
16 // linker.
17 // This same sequence cannot be optimized by the compiler because some of
18 // the information will be known at link time.
19 // For instance, consider the following sequence:
20 // L1: adrp xA, sym@PAGE
21 // L2: add xB, xA, sym@PAGEOFF
22 // L3: ldr xC, [xB, #imm]
23 // This sequence can be turned into:
24 // A literal load if sym@PAGE + sym@PAGEOFF + #imm - address(L3) is < 1MB:
25 // L3: ldr xC, sym+#imm
26 // It may also be turned into either the following more efficient
27 // code sequences:
28 // - If sym@PAGEOFF + #imm fits the encoding space of L3.
29 // L1: adrp xA, sym@PAGE
30 // L3: ldr xC, [xB, sym@PAGEOFF + #imm]
31 // - If sym@PAGE + sym@PAGEOFF - address(L1) < 1MB:
32 // L1: adr xA, sym
33 // L3: ldr xC, [xB, #imm]
34 //
35 // To be valid a LOH must meet all the requirements needed by all the related
36 // possible linker transformations.
37 // For instance, using the running example, the constraints to emit
38 // ".loh AdrpAddLdr" are:
39 // - L1, L2, and L3 instructions are of the expected type, i.e.,
40 // respectively ADRP, ADD (immediate), and LD.
41 // - The result of L1 is used only by L2.
42 // - The register argument (xA) used in the ADD instruction is defined
43 // only by L1.
44 // - The result of L2 is used only by L3.
45 // - The base address (xB) in L3 is defined only L2.
46 // - The ADRP in L1 and the ADD in L2 must reference the same symbol using
47 // @PAGE/@PAGEOFF with no additional constants
48 //
49 // Currently supported LOHs are:
50 // * So called non-ADRP-related:
51 // - .loh AdrpAddLdr L1, L2, L3:
52 // L1: adrp xA, sym@PAGE
53 // L2: add xB, xA, sym@PAGEOFF
54 // L3: ldr xC, [xB, #imm]
55 // - .loh AdrpLdrGotLdr L1, L2, L3:
56 // L1: adrp xA, sym@GOTPAGE
57 // L2: ldr xB, [xA, sym@GOTPAGEOFF]
58 // L3: ldr xC, [xB, #imm]
59 // - .loh AdrpLdr L1, L3:
60 // L1: adrp xA, sym@PAGE
61 // L3: ldr xC, [xA, sym@PAGEOFF]
62 // - .loh AdrpAddStr L1, L2, L3:
63 // L1: adrp xA, sym@PAGE
64 // L2: add xB, xA, sym@PAGEOFF
65 // L3: str xC, [xB, #imm]
66 // - .loh AdrpLdrGotStr L1, L2, L3:
67 // L1: adrp xA, sym@GOTPAGE
68 // L2: ldr xB, [xA, sym@GOTPAGEOFF]
69 // L3: str xC, [xB, #imm]
70 // - .loh AdrpAdd L1, L2:
71 // L1: adrp xA, sym@PAGE
72 // L2: add xB, xA, sym@PAGEOFF
73 // For all these LOHs, L1, L2, L3 form a simple chain:
74 // L1 result is used only by L2 and L2 result by L3.
75 // L3 LOH-related argument is defined only by L2 and L2 LOH-related argument
76 // by L1.
77 // All these LOHs aim at using more efficient load/store patterns by folding
78 // some instructions used to compute the address directly into the load/store.
79 //
80 // * So called ADRP-related:
81 // - .loh AdrpAdrp L2, L1:
82 // L2: ADRP xA, sym1@PAGE
83 // L1: ADRP xA, sym2@PAGE
84 // L2 dominates L1 and xA is not redifined between L2 and L1
85 // This LOH aims at getting rid of redundant ADRP instructions.
86 //
87 // The overall design for emitting the LOHs is:
88 // 1. AArch64CollectLOH (this pass) records the LOHs in the AArch64FunctionInfo.
89 // 2. AArch64AsmPrinter reads the LOHs from AArch64FunctionInfo and it:
90 // 1. Associates them a label.
91 // 2. Emits them in a MCStreamer (EmitLOHDirective).
92 // - The MCMachOStreamer records them into the MCAssembler.
93 // - The MCAsmStreamer prints them.
94 // - Other MCStreamers ignore them.
95 // 3. Closes the MCStreamer:
96 // - The MachObjectWriter gets them from the MCAssembler and writes
97 // them in the object file.
98 // - Other ObjectWriters ignore them.
99 //===----------------------------------------------------------------------===//
100 
101 #include "AArch64.h"
102 #include "AArch64InstrInfo.h"
104 #include "AArch64Subtarget.h"
106 #include "llvm/ADT/BitVector.h"
107 #include "llvm/ADT/DenseMap.h"
108 #include "llvm/ADT/MapVector.h"
109 #include "llvm/ADT/SetVector.h"
110 #include "llvm/ADT/SmallVector.h"
111 #include "llvm/ADT/Statistic.h"
116 #include "llvm/Support/Debug.h"
121 using namespace llvm;
122 
123 #define DEBUG_TYPE "aarch64-collect-loh"
124 
125 STATISTIC(NumADRPSimpleCandidate,
126  "Number of simplifiable ADRP dominate by another");
127 STATISTIC(NumADDToSTR, "Number of simplifiable STR reachable by ADD");
128 STATISTIC(NumLDRToSTR, "Number of simplifiable STR reachable by LDR");
129 STATISTIC(NumADDToLDR, "Number of simplifiable LDR reachable by ADD");
130 STATISTIC(NumLDRToLDR, "Number of simplifiable LDR reachable by LDR");
131 STATISTIC(NumADRPToLDR, "Number of simplifiable LDR reachable by ADRP");
132 STATISTIC(NumADRSimpleCandidate, "Number of simplifiable ADRP + ADD");
133 
134 #define AARCH64_COLLECT_LOH_NAME "AArch64 Collect Linker Optimization Hint (LOH)"
135 
136 namespace {
137 
138 struct AArch64CollectLOH : public MachineFunctionPass {
139  static char ID;
140  AArch64CollectLOH() : MachineFunctionPass(ID) {}
141 
142  bool runOnMachineFunction(MachineFunction &MF) override;
143 
144  MachineFunctionProperties getRequiredProperties() const override {
147  }
148 
149  StringRef getPassName() const override { return AARCH64_COLLECT_LOH_NAME; }
150 
151  void getAnalysisUsage(AnalysisUsage &AU) const override {
153  AU.setPreservesAll();
154  }
155 };
156 
157 char AArch64CollectLOH::ID = 0;
158 
159 } // end anonymous namespace.
160 
161 INITIALIZE_PASS(AArch64CollectLOH, "aarch64-collect-loh",
162  AARCH64_COLLECT_LOH_NAME, false, false)
163 
164 static bool canAddBePartOfLOH(const MachineInstr &MI) {
165  // Check immediate to see if the immediate is an address.
166  switch (MI.getOperand(2).getType()) {
167  default:
168  return false;
173  return true;
174  }
175 }
176 
177 /// Answer the following question: Can Def be one of the definition
178 /// involved in a part of a LOH?
179 static bool canDefBePartOfLOH(const MachineInstr &MI) {
180  // Accept ADRP, ADDLow and LOADGot.
181  switch (MI.getOpcode()) {
182  default:
183  return false;
184  case AArch64::ADRP:
185  return true;
186  case AArch64::ADDXri:
187  return canAddBePartOfLOH(MI);
188  case AArch64::LDRXui:
189  // Check immediate to see if the immediate is an address.
190  switch (MI.getOperand(2).getType()) {
191  default:
192  return false;
195  }
196  }
197 }
198 
199 /// Check whether the given instruction can the end of a LOH chain involving a
200 /// store.
201 static bool isCandidateStore(const MachineInstr &MI, const MachineOperand &MO) {
202  switch (MI.getOpcode()) {
203  default:
204  return false;
205  case AArch64::STRBBui:
206  case AArch64::STRHHui:
207  case AArch64::STRBui:
208  case AArch64::STRHui:
209  case AArch64::STRWui:
210  case AArch64::STRXui:
211  case AArch64::STRSui:
212  case AArch64::STRDui:
213  case AArch64::STRQui:
214  // We can only optimize the index operand.
215  // In case we have str xA, [xA, #imm], this is two different uses
216  // of xA and we cannot fold, otherwise the xA stored may be wrong,
217  // even if #imm == 0.
218  return MI.getOperandNo(&MO) == 1 &&
219  MI.getOperand(0).getReg() != MI.getOperand(1).getReg();
220  }
221 }
222 
223 /// Check whether the given instruction can be the end of a LOH chain
224 /// involving a load.
225 static bool isCandidateLoad(const MachineInstr &MI) {
226  switch (MI.getOpcode()) {
227  default:
228  return false;
229  case AArch64::LDRSBWui:
230  case AArch64::LDRSBXui:
231  case AArch64::LDRSHWui:
232  case AArch64::LDRSHXui:
233  case AArch64::LDRSWui:
234  case AArch64::LDRBui:
235  case AArch64::LDRHui:
236  case AArch64::LDRWui:
237  case AArch64::LDRXui:
238  case AArch64::LDRSui:
239  case AArch64::LDRDui:
240  case AArch64::LDRQui:
241  return !(MI.getOperand(2).getTargetFlags() & AArch64II::MO_GOT);
242  }
243 }
244 
245 /// Check whether the given instruction can load a litteral.
247  switch (MI.getOpcode()) {
248  default:
249  return false;
250  case AArch64::LDRSWui:
251  case AArch64::LDRWui:
252  case AArch64::LDRXui:
253  case AArch64::LDRSui:
254  case AArch64::LDRDui:
255  case AArch64::LDRQui:
256  return true;
257  }
258 }
259 
260 /// Number of GPR registers traked by mapRegToGPRIndex()
261 static const unsigned N_GPR_REGS = 31;
262 /// Map register number to index from 0-30.
264  static_assert(AArch64::X28 - AArch64::X0 + 3 == N_GPR_REGS, "Number of GPRs");
265  static_assert(AArch64::W30 - AArch64::W0 + 1 == N_GPR_REGS, "Number of GPRs");
266  if (AArch64::X0 <= Reg && Reg <= AArch64::X28)
267  return Reg - AArch64::X0;
268  if (AArch64::W0 <= Reg && Reg <= AArch64::W30)
269  return Reg - AArch64::W0;
270  // TableGen gives "FP" and "LR" an index not adjacent to X28 so we have to
271  // handle them as special cases.
272  if (Reg == AArch64::FP)
273  return 29;
274  if (Reg == AArch64::LR)
275  return 30;
276  return -1;
277 }
278 
279 /// State tracked per register.
280 /// The main algorithm walks backwards over a basic block maintaining this
281 /// datastructure for each tracked general purpose register.
282 struct LOHInfo {
283  MCLOHType Type : 8; ///< "Best" type of LOH possible.
284  bool IsCandidate : 1; ///< Possible LOH candidate.
285  bool OneUser : 1; ///< Found exactly one user (yet).
286  bool MultiUsers : 1; ///< Found multiple users.
287  const MachineInstr *MI0; ///< First instruction involved in the LOH.
288  const MachineInstr *MI1; ///< Second instruction involved in the LOH
289  /// (if any).
290  const MachineInstr *LastADRP; ///< Last ADRP in same register.
291 };
292 
293 /// Update state \p Info given \p MI uses the tracked register.
294 static void handleUse(const MachineInstr &MI, const MachineOperand &MO,
295  LOHInfo &Info) {
296  // We have multiple uses if we already found one before.
297  if (Info.MultiUsers || Info.OneUser) {
298  Info.IsCandidate = false;
299  Info.MultiUsers = true;
300  return;
301  }
302  Info.OneUser = true;
303 
304  // Start new LOHInfo if applicable.
305  if (isCandidateLoad(MI)) {
306  Info.Type = MCLOH_AdrpLdr;
307  Info.IsCandidate = true;
308  Info.MI0 = &MI;
309  // Note that even this is AdrpLdr now, we can switch to a Ldr variant
310  // later.
311  } else if (isCandidateStore(MI, MO)) {
312  Info.Type = MCLOH_AdrpAddStr;
313  Info.IsCandidate = true;
314  Info.MI0 = &MI;
315  Info.MI1 = nullptr;
316  } else if (MI.getOpcode() == AArch64::ADDXri) {
317  Info.Type = MCLOH_AdrpAdd;
318  Info.IsCandidate = true;
319  Info.MI0 = &MI;
320  } else if (MI.getOpcode() == AArch64::LDRXui &&
322  Info.Type = MCLOH_AdrpLdrGot;
323  Info.IsCandidate = true;
324  Info.MI0 = &MI;
325  }
326 }
327 
328 /// Update state \p Info given the tracked register is clobbered.
329 static void handleClobber(LOHInfo &Info) {
330  Info.IsCandidate = false;
331  Info.OneUser = false;
332  Info.MultiUsers = false;
333  Info.LastADRP = nullptr;
334 }
335 
336 /// Update state \p Info given that \p MI is possibly the middle instruction
337 /// of an LOH involving 3 instructions.
338 static bool handleMiddleInst(const MachineInstr &MI, LOHInfo &DefInfo,
339  LOHInfo &OpInfo) {
340  if (!DefInfo.IsCandidate || (&DefInfo != &OpInfo && OpInfo.OneUser))
341  return false;
342  // Copy LOHInfo for dest register to LOHInfo for source register.
343  if (&DefInfo != &OpInfo) {
344  OpInfo = DefInfo;
345  // Invalidate \p DefInfo because we track it in \p OpInfo now.
346  handleClobber(DefInfo);
347  } else
348  DefInfo.LastADRP = nullptr;
349 
350  // Advance state machine.
351  assert(OpInfo.IsCandidate && "Expect valid state");
352  if (MI.getOpcode() == AArch64::ADDXri && canAddBePartOfLOH(MI)) {
353  if (OpInfo.Type == MCLOH_AdrpLdr) {
354  OpInfo.Type = MCLOH_AdrpAddLdr;
355  OpInfo.IsCandidate = true;
356  OpInfo.MI1 = &MI;
357  return true;
358  } else if (OpInfo.Type == MCLOH_AdrpAddStr && OpInfo.MI1 == nullptr) {
359  OpInfo.Type = MCLOH_AdrpAddStr;
360  OpInfo.IsCandidate = true;
361  OpInfo.MI1 = &MI;
362  return true;
363  }
364  } else {
365  assert(MI.getOpcode() == AArch64::LDRXui && "Expect LDRXui");
367  "Expected GOT relocation");
368  if (OpInfo.Type == MCLOH_AdrpAddStr && OpInfo.MI1 == nullptr) {
369  OpInfo.Type = MCLOH_AdrpLdrGotStr;
370  OpInfo.IsCandidate = true;
371  OpInfo.MI1 = &MI;
372  return true;
373  } else if (OpInfo.Type == MCLOH_AdrpLdr) {
374  OpInfo.Type = MCLOH_AdrpLdrGotLdr;
375  OpInfo.IsCandidate = true;
376  OpInfo.MI1 = &MI;
377  return true;
378  }
379  }
380  return false;
381 }
382 
383 /// Update state when seeing and ADRP instruction.
385  LOHInfo &Info) {
386  if (Info.LastADRP != nullptr) {
387  DEBUG(dbgs() << "Adding MCLOH_AdrpAdrp:\n" << '\t' << MI << '\t'
388  << *Info.LastADRP);
389  AFI.addLOHDirective(MCLOH_AdrpAdrp, {&MI, Info.LastADRP});
390  ++NumADRPSimpleCandidate;
391  }
392 
393  // Produce LOH directive if possible.
394  if (Info.IsCandidate) {
395  switch (Info.Type) {
396  case MCLOH_AdrpAdd:
397  DEBUG(dbgs() << "Adding MCLOH_AdrpAdd:\n" << '\t' << MI << '\t'
398  << *Info.MI0);
399  AFI.addLOHDirective(MCLOH_AdrpAdd, {&MI, Info.MI0});
400  ++NumADRSimpleCandidate;
401  break;
402  case MCLOH_AdrpLdr:
403  if (supportLoadFromLiteral(*Info.MI0)) {
404  DEBUG(dbgs() << "Adding MCLOH_AdrpLdr:\n" << '\t' << MI << '\t'
405  << *Info.MI0);
406  AFI.addLOHDirective(MCLOH_AdrpLdr, {&MI, Info.MI0});
407  ++NumADRPToLDR;
408  }
409  break;
410  case MCLOH_AdrpAddLdr:
411  DEBUG(dbgs() << "Adding MCLOH_AdrpAddLdr:\n" << '\t' << MI << '\t'
412  << *Info.MI1 << '\t' << *Info.MI0);
413  AFI.addLOHDirective(MCLOH_AdrpAddLdr, {&MI, Info.MI1, Info.MI0});
414  ++NumADDToLDR;
415  break;
416  case MCLOH_AdrpAddStr:
417  if (Info.MI1 != nullptr) {
418  DEBUG(dbgs() << "Adding MCLOH_AdrpAddStr:\n" << '\t' << MI << '\t'
419  << *Info.MI1 << '\t' << *Info.MI0);
420  AFI.addLOHDirective(MCLOH_AdrpAddStr, {&MI, Info.MI1, Info.MI0});
421  ++NumADDToSTR;
422  }
423  break;
424  case MCLOH_AdrpLdrGotLdr:
425  DEBUG(dbgs() << "Adding MCLOH_AdrpLdrGotLdr:\n" << '\t' << MI << '\t'
426  << *Info.MI1 << '\t' << *Info.MI0);
427  AFI.addLOHDirective(MCLOH_AdrpLdrGotLdr, {&MI, Info.MI1, Info.MI0});
428  ++NumLDRToLDR;
429  break;
430  case MCLOH_AdrpLdrGotStr:
431  DEBUG(dbgs() << "Adding MCLOH_AdrpLdrGotStr:\n" << '\t' << MI << '\t'
432  << *Info.MI1 << '\t' << *Info.MI0);
433  AFI.addLOHDirective(MCLOH_AdrpLdrGotStr, {&MI, Info.MI1, Info.MI0});
434  ++NumLDRToSTR;
435  break;
436  case MCLOH_AdrpLdrGot:
437  DEBUG(dbgs() << "Adding MCLOH_AdrpLdrGot:\n" << '\t' << MI << '\t'
438  << *Info.MI0);
439  AFI.addLOHDirective(MCLOH_AdrpLdrGot, {&MI, Info.MI0});
440  break;
441  case MCLOH_AdrpAdrp:
442  llvm_unreachable("MCLOH_AdrpAdrp not used in state machine");
443  }
444  }
445 
446  handleClobber(Info);
447  Info.LastADRP = &MI;
448 }
449 
450 static void handleRegMaskClobber(const uint32_t *RegMask, MCPhysReg Reg,
451  LOHInfo *LOHInfos) {
452  if (!MachineOperand::clobbersPhysReg(RegMask, Reg))
453  return;
454  int Idx = mapRegToGPRIndex(Reg);
455  if (Idx >= 0)
456  handleClobber(LOHInfos[Idx]);
457 }
458 
459 static void handleNormalInst(const MachineInstr &MI, LOHInfo *LOHInfos) {
460  // Handle defs and regmasks.
461  for (const MachineOperand &MO : MI.operands()) {
462  if (MO.isRegMask()) {
463  const uint32_t *RegMask = MO.getRegMask();
464  for (MCPhysReg Reg : AArch64::GPR32RegClass)
465  handleRegMaskClobber(RegMask, Reg, LOHInfos);
466  for (MCPhysReg Reg : AArch64::GPR64RegClass)
467  handleRegMaskClobber(RegMask, Reg, LOHInfos);
468  continue;
469  }
470  if (!MO.isReg() || !MO.isDef())
471  continue;
472  int Idx = mapRegToGPRIndex(MO.getReg());
473  if (Idx < 0)
474  continue;
475  handleClobber(LOHInfos[Idx]);
476  }
477  // Handle uses.
478  for (const MachineOperand &MO : MI.uses()) {
479  if (!MO.isReg() || !MO.readsReg())
480  continue;
481  int Idx = mapRegToGPRIndex(MO.getReg());
482  if (Idx < 0)
483  continue;
484  handleUse(MI, MO, LOHInfos[Idx]);
485  }
486 }
487 
488 bool AArch64CollectLOH::runOnMachineFunction(MachineFunction &MF) {
489  if (skipFunction(*MF.getFunction()))
490  return false;
491 
492  DEBUG(dbgs() << "********** AArch64 Collect LOH **********\n"
493  << "Looking in function " << MF.getName() << '\n');
494 
495  LOHInfo LOHInfos[N_GPR_REGS];
497  for (const MachineBasicBlock &MBB : MF) {
498  // Reset register tracking state.
499  memset(LOHInfos, 0, sizeof(LOHInfos));
500  // Live-out registers are used.
501  for (const MachineBasicBlock *Succ : MBB.successors()) {
502  for (const auto &LI : Succ->liveins()) {
503  int RegIdx = mapRegToGPRIndex(LI.PhysReg);
504  if (RegIdx >= 0)
505  LOHInfos[RegIdx].OneUser = true;
506  }
507  }
508 
509  // Walk the basic block backwards and update the per register state machine
510  // in the process.
511  for (const MachineInstr &MI : make_range(MBB.rbegin(), MBB.rend())) {
512  unsigned Opcode = MI.getOpcode();
513  switch (Opcode) {
514  case AArch64::ADDXri:
515  case AArch64::LDRXui:
516  if (canDefBePartOfLOH(MI)) {
517  const MachineOperand &Def = MI.getOperand(0);
518  const MachineOperand &Op = MI.getOperand(1);
519  assert(Def.isReg() && Def.isDef() && "Expected reg def");
520  assert(Op.isReg() && Op.isUse() && "Expected reg use");
521  int DefIdx = mapRegToGPRIndex(Def.getReg());
522  int OpIdx = mapRegToGPRIndex(Op.getReg());
523  if (DefIdx >= 0 && OpIdx >= 0 &&
524  handleMiddleInst(MI, LOHInfos[DefIdx], LOHInfos[OpIdx]))
525  continue;
526  }
527  break;
528  case AArch64::ADRP:
529  const MachineOperand &Op0 = MI.getOperand(0);
530  int Idx = mapRegToGPRIndex(Op0.getReg());
531  if (Idx >= 0) {
532  handleADRP(MI, AFI, LOHInfos[Idx]);
533  continue;
534  }
535  break;
536  }
537  handleNormalInst(MI, LOHInfos);
538  }
539  }
540 
541  // Return "no change": The pass only collects information.
542  return false;
543 }
544 
546  return new AArch64CollectLOH();
547 }
static void handleNormalInst(const MachineInstr &MI, LOHInfo *LOHInfos)
AArch64FunctionInfo - This class is derived from MachineFunctionInfo and contains private AArch64-spe...
STATISTIC(NumFunctions,"Total number of functions")
iterator_range< mop_iterator > uses()
Returns a range that includes all operands that are register uses.
Definition: MachineInstr.h:334
Address of indexed Jump Table for switch.
unsigned getOperandNo(const_mop_iterator I) const
Returns the number of the operand iterator I points to.
Definition: MachineInstr.h:353
uint16_t MCPhysReg
An unsigned integer type large enough to represent all physical registers, but not necessarily virtua...
const MachineInstr * LastADRP
Last ADRP in same register.
Adrp _v -> Add _v -> Ldr.
const Function * getFunction() const
getFunction - Return the LLVM function that this machine code represents
iterator_range< mop_iterator > operands()
Definition: MachineInstr.h:301
iterator_range< succ_iterator > successors()
FunctionPass * createAArch64CollectLOHPass()
Adrp _v -> Ldr _v -> Ldr.
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
static bool isCandidateLoad(const MachineInstr &MI)
Check whether the given instruction can be the end of a LOH chain involving a load.
bool isReg() const
isReg - Tests if this is a MO_Register operand.
Reg
All possible values of the reg field in the ModR/M byte.
static int mapRegToGPRIndex(MCPhysReg Reg)
Map register number to index from 0-30.
static const unsigned N_GPR_REGS
Number of GPR registers traked by mapRegToGPRIndex()
State tracked per register.
MO_GOT - This flag indicates that a symbol operand represents the address of the GOT entry for the sy...
MachineBasicBlock * MBB
static bool isCandidateStore(const MachineInstr &MI, const MachineOperand &MO)
Check whether the given instruction can the end of a LOH chain involving a store. ...
reverse_iterator rend()
reverse_iterator rbegin()
static void handleRegMaskClobber(const uint32_t *RegMask, MCPhysReg Reg, LOHInfo *LOHInfos)
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
Definition: MachineInstr.h:273
static bool handleMiddleInst(const MachineInstr &MI, LOHInfo &DefInfo, LOHInfo &OpInfo)
Update state Info given that MI is possibly the middle instruction of an LOH involving 3 instructions...
Address of a global value.
unsigned getTargetFlags() const
The instances of the Type class are immutable: once they are created, they are never changed...
Definition: Type.h:45
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
const MachineOperand & getOperand(unsigned i) const
Definition: MachineInstr.h:279
bool MultiUsers
Found multiple users.
bool OneUser
Found exactly one user (yet).
Represent the analysis usage information of a pass.
MCLOHType
Linker Optimization Hint Type.
Address of a basic block.
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
FunctionPass class - This class is used to implement most global optimizations.
Definition: Pass.h:298
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
static void handleClobber(LOHInfo &Info)
Update state Info given the tracked register is clobbered.
Adrp _v -> Add _v -> Str.
MachineOperand class - Representation of each machine instruction operand.
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:132
static bool clobbersPhysReg(const uint32_t *RegMask, unsigned PhysReg)
clobbersPhysReg - Returns true if this RegMask clobbers PhysReg.
void setPreservesAll()
Set by analyses that do not transform their input at all.
bool IsCandidate
Possible LOH candidate.
MachineFunctionProperties & set(Property P)
Representation of each machine instruction.
Definition: MachineInstr.h:52
MachineOperandType getType() const
getType - Returns the MachineOperandType for this operand.
static void handleUse(const MachineInstr &MI, const MachineOperand &MO, LOHInfo &Info)
Update state Info given MI uses the tracked register.
MCLOHType Type
"Best" type of LOH possible.
INITIALIZE_PASS(AArch64CollectLOH,"aarch64-collect-loh", AARCH64_COLLECT_LOH_NAME, false, false) static bool canAddBePartOfLOH(const MachineInstr &MI)
Adrp xY, _v1 -> Adrp xY, _v2.
Adrp _v -> Ldr _v -> Str.
static bool canDefBePartOfLOH(const MachineInstr &MI)
Answer the following question: Can Def be one of the definition involved in a part of a LOH...
unsigned getReg() const
getReg - Returns the register number.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
const MachineInstr * MI0
First instruction involved in the LOH.
void addLOHDirective(MCLOHType Kind, MILOHArgs Args)
Add a LOH directive of this Kind and this Args.
aarch64 promote const
static bool supportLoadFromLiteral(const MachineInstr &MI)
Check whether the given instruction can load a litteral.
#define DEBUG(X)
Definition: Debug.h:100
IRTranslator LLVM IR MI
const MachineInstr * MI1
Second instruction involved in the LOH (if any).
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:47
static void handleADRP(const MachineInstr &MI, AArch64FunctionInfo &AFI, LOHInfo &Info)
Update state when seeing and ADRP instruction.
Address of indexed Constant in Constant Pool.
StringRef getName() const
getName - Return the name of the corresponding LLVM function.
#define AARCH64_COLLECT_LOH_NAME
Properties which a MachineFunction may have at a given point in time.