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