LLVM API Documentation

AArch64CollectLOH.cpp
Go to the documentation of this file.
00001 //===---------- AArch64CollectLOH.cpp - AArch64 collect LOH pass --*- C++ -*-=//
00002 //
00003 //                     The LLVM Compiler Infrastructure
00004 //
00005 // This file is distributed under the University of Illinois Open Source
00006 // License. See LICENSE.TXT for details.
00007 //
00008 //===----------------------------------------------------------------------===//
00009 //
00010 // This file contains a pass that collect the Linker Optimization Hint (LOH).
00011 // This pass should be run at the very end of the compilation flow, just before
00012 // assembly printer.
00013 // To be useful for the linker, the LOH must be printed into the assembly file.
00014 //
00015 // A LOH describes a sequence of instructions that may be optimized by the
00016 // linker.
00017 // This same sequence cannot be optimized by the compiler because some of
00018 // the information will be known at link time.
00019 // For instance, consider the following sequence:
00020 //     L1: adrp xA, sym@PAGE
00021 //     L2: add xB, xA, sym@PAGEOFF
00022 //     L3: ldr xC, [xB, #imm]
00023 // This sequence can be turned into:
00024 // A literal load if sym@PAGE + sym@PAGEOFF + #imm - address(L3) is < 1MB:
00025 //     L3: ldr xC, sym+#imm
00026 // It may also be turned into either the following more efficient
00027 // code sequences:
00028 // - If sym@PAGEOFF + #imm fits the encoding space of L3.
00029 //     L1: adrp xA, sym@PAGE
00030 //     L3: ldr xC, [xB, sym@PAGEOFF + #imm]
00031 // - If sym@PAGE + sym@PAGEOFF - address(L1) < 1MB:
00032 //     L1: adr xA, sym
00033 //     L3: ldr xC, [xB, #imm]
00034 //
00035 // To be valid a LOH must meet all the requirements needed by all the related
00036 // possible linker transformations.
00037 // For instance, using the running example, the constraints to emit
00038 // ".loh AdrpAddLdr" are:
00039 // - L1, L2, and L3 instructions are of the expected type, i.e.,
00040 //   respectively ADRP, ADD (immediate), and LD.
00041 // - The result of L1 is used only by L2.
00042 // - The register argument (xA) used in the ADD instruction is defined
00043 //   only by L1.
00044 // - The result of L2 is used only by L3.
00045 // - The base address (xB) in L3 is defined only L2.
00046 // - The ADRP in L1 and the ADD in L2 must reference the same symbol using
00047 //   @PAGE/@PAGEOFF with no additional constants
00048 //
00049 // Currently supported LOHs are:
00050 // * So called non-ADRP-related:
00051 //   - .loh AdrpAddLdr L1, L2, L3:
00052 //     L1: adrp xA, sym@PAGE
00053 //     L2: add xB, xA, sym@PAGEOFF
00054 //     L3: ldr xC, [xB, #imm]
00055 //   - .loh AdrpLdrGotLdr L1, L2, L3:
00056 //     L1: adrp xA, sym@GOTPAGE
00057 //     L2: ldr xB, [xA, sym@GOTPAGEOFF]
00058 //     L3: ldr xC, [xB, #imm]
00059 //   - .loh AdrpLdr L1, L3:
00060 //     L1: adrp xA, sym@PAGE
00061 //     L3: ldr xC, [xA, sym@PAGEOFF]
00062 //   - .loh AdrpAddStr L1, L2, L3:
00063 //     L1: adrp xA, sym@PAGE
00064 //     L2: add xB, xA, sym@PAGEOFF
00065 //     L3: str xC, [xB, #imm]
00066 //   - .loh AdrpLdrGotStr L1, L2, L3:
00067 //     L1: adrp xA, sym@GOTPAGE
00068 //     L2: ldr xB, [xA, sym@GOTPAGEOFF]
00069 //     L3: str xC, [xB, #imm]
00070 //   - .loh AdrpAdd L1, L2:
00071 //     L1: adrp xA, sym@PAGE
00072 //     L2: add xB, xA, sym@PAGEOFF
00073 //   For all these LOHs, L1, L2, L3 form a simple chain:
00074 //   L1 result is used only by L2 and L2 result by L3.
00075 //   L3 LOH-related argument is defined only by L2 and L2 LOH-related argument
00076 //   by L1.
00077 // All these LOHs aim at using more efficient load/store patterns by folding
00078 // some instructions used to compute the address directly into the load/store.
00079 //
00080 // * So called ADRP-related:
00081 //  - .loh AdrpAdrp L2, L1:
00082 //    L2: ADRP xA, sym1@PAGE
00083 //    L1: ADRP xA, sym2@PAGE
00084 //    L2 dominates L1 and xA is not redifined between L2 and L1
00085 // This LOH aims at getting rid of redundant ADRP instructions.
00086 //
00087 // The overall design for emitting the LOHs is:
00088 // 1. AArch64CollectLOH (this pass) records the LOHs in the AArch64FunctionInfo.
00089 // 2. AArch64AsmPrinter reads the LOHs from AArch64FunctionInfo and it:
00090 //     1. Associates them a label.
00091 //     2. Emits them in a MCStreamer (EmitLOHDirective).
00092 //         - The MCMachOStreamer records them into the MCAssembler.
00093 //         - The MCAsmStreamer prints them.
00094 //         - Other MCStreamers ignore them.
00095 //     3. Closes the MCStreamer:
00096 //         - The MachObjectWriter gets them from the MCAssembler and writes
00097 //           them in the object file.
00098 //         - Other ObjectWriters ignore them.
00099 //===----------------------------------------------------------------------===//
00100 
00101 #include "AArch64.h"
00102 #include "AArch64InstrInfo.h"
00103 #include "AArch64MachineFunctionInfo.h"
00104 #include "AArch64Subtarget.h"
00105 #include "MCTargetDesc/AArch64AddressingModes.h"
00106 #include "llvm/ADT/BitVector.h"
00107 #include "llvm/ADT/DenseMap.h"
00108 #include "llvm/ADT/MapVector.h"
00109 #include "llvm/ADT/SetVector.h"
00110 #include "llvm/ADT/SmallVector.h"
00111 #include "llvm/ADT/Statistic.h"
00112 #include "llvm/CodeGen/MachineBasicBlock.h"
00113 #include "llvm/CodeGen/MachineDominators.h"
00114 #include "llvm/CodeGen/MachineFunctionPass.h"
00115 #include "llvm/CodeGen/MachineInstr.h"
00116 #include "llvm/CodeGen/MachineInstrBuilder.h"
00117 #include "llvm/Support/CommandLine.h"
00118 #include "llvm/Support/Debug.h"
00119 #include "llvm/Support/ErrorHandling.h"
00120 #include "llvm/Support/raw_ostream.h"
00121 #include "llvm/Target/TargetInstrInfo.h"
00122 #include "llvm/Target/TargetMachine.h"
00123 #include "llvm/Target/TargetRegisterInfo.h"
00124 using namespace llvm;
00125 
00126 #define DEBUG_TYPE "aarch64-collect-loh"
00127 
00128 static cl::opt<bool>
00129 PreCollectRegister("aarch64-collect-loh-pre-collect-register", cl::Hidden,
00130                    cl::desc("Restrict analysis to registers invovled"
00131                             " in LOHs"),
00132                    cl::init(true));
00133 
00134 static cl::opt<bool>
00135 BasicBlockScopeOnly("aarch64-collect-loh-bb-only", cl::Hidden,
00136                     cl::desc("Restrict analysis at basic block scope"),
00137                     cl::init(true));
00138 
00139 STATISTIC(NumADRPSimpleCandidate,
00140           "Number of simplifiable ADRP dominate by another");
00141 STATISTIC(NumADRPComplexCandidate2,
00142           "Number of simplifiable ADRP reachable by 2 defs");
00143 STATISTIC(NumADRPComplexCandidate3,
00144           "Number of simplifiable ADRP reachable by 3 defs");
00145 STATISTIC(NumADRPComplexCandidateOther,
00146           "Number of simplifiable ADRP reachable by 4 or more defs");
00147 STATISTIC(NumADDToSTRWithImm,
00148           "Number of simplifiable STR with imm reachable by ADD");
00149 STATISTIC(NumLDRToSTRWithImm,
00150           "Number of simplifiable STR with imm reachable by LDR");
00151 STATISTIC(NumADDToSTR, "Number of simplifiable STR reachable by ADD");
00152 STATISTIC(NumLDRToSTR, "Number of simplifiable STR reachable by LDR");
00153 STATISTIC(NumADDToLDRWithImm,
00154           "Number of simplifiable LDR with imm reachable by ADD");
00155 STATISTIC(NumLDRToLDRWithImm,
00156           "Number of simplifiable LDR with imm reachable by LDR");
00157 STATISTIC(NumADDToLDR, "Number of simplifiable LDR reachable by ADD");
00158 STATISTIC(NumLDRToLDR, "Number of simplifiable LDR reachable by LDR");
00159 STATISTIC(NumADRPToLDR, "Number of simplifiable LDR reachable by ADRP");
00160 STATISTIC(NumCplxLvl1, "Number of complex case of level 1");
00161 STATISTIC(NumTooCplxLvl1, "Number of too complex case of level 1");
00162 STATISTIC(NumCplxLvl2, "Number of complex case of level 2");
00163 STATISTIC(NumTooCplxLvl2, "Number of too complex case of level 2");
00164 STATISTIC(NumADRSimpleCandidate, "Number of simplifiable ADRP + ADD");
00165 STATISTIC(NumADRComplexCandidate, "Number of too complex ADRP + ADD");
00166 
00167 namespace llvm {
00168 void initializeAArch64CollectLOHPass(PassRegistry &);
00169 }
00170 
00171 namespace {
00172 struct AArch64CollectLOH : public MachineFunctionPass {
00173   static char ID;
00174   AArch64CollectLOH() : MachineFunctionPass(ID) {
00175     initializeAArch64CollectLOHPass(*PassRegistry::getPassRegistry());
00176   }
00177 
00178   bool runOnMachineFunction(MachineFunction &MF) override;
00179 
00180   const char *getPassName() const override {
00181     return "AArch64 Collect Linker Optimization Hint (LOH)";
00182   }
00183 
00184   void getAnalysisUsage(AnalysisUsage &AU) const override {
00185     AU.setPreservesAll();
00186     MachineFunctionPass::getAnalysisUsage(AU);
00187     AU.addRequired<MachineDominatorTree>();
00188   }
00189 
00190 private:
00191 };
00192 
00193 /// A set of MachineInstruction.
00194 typedef SetVector<const MachineInstr *> SetOfMachineInstr;
00195 /// Map a basic block to a set of instructions per register.
00196 /// This is used to represent the exposed uses of a basic block
00197 /// per register.
00198 typedef MapVector<const MachineBasicBlock *,
00199                   std::unique_ptr<SetOfMachineInstr[]>>
00200 BlockToSetOfInstrsPerColor;
00201 /// Map a basic block to an instruction per register.
00202 /// This is used to represent the live-out definitions of a basic block
00203 /// per register.
00204 typedef MapVector<const MachineBasicBlock *,
00205                   std::unique_ptr<const MachineInstr *[]>>
00206 BlockToInstrPerColor;
00207 /// Map an instruction to a set of instructions. Used to represent the
00208 /// mapping def to reachable uses or use to definitions.
00209 typedef MapVector<const MachineInstr *, SetOfMachineInstr> InstrToInstrs;
00210 /// Map a basic block to a BitVector.
00211 /// This is used to record the kill registers per basic block.
00212 typedef MapVector<const MachineBasicBlock *, BitVector> BlockToRegSet;
00213 
00214 /// Map a register to a dense id.
00215 typedef DenseMap<unsigned, unsigned> MapRegToId;
00216 /// Map a dense id to a register. Used for debug purposes.
00217 typedef SmallVector<unsigned, 32> MapIdToReg;
00218 } // end anonymous namespace.
00219 
00220 char AArch64CollectLOH::ID = 0;
00221 
00222 INITIALIZE_PASS_BEGIN(AArch64CollectLOH, "aarch64-collect-loh",
00223                       "AArch64 Collect Linker Optimization Hint (LOH)", false,
00224                       false)
00225 INITIALIZE_PASS_DEPENDENCY(MachineDominatorTree)
00226 INITIALIZE_PASS_END(AArch64CollectLOH, "aarch64-collect-loh",
00227                     "AArch64 Collect Linker Optimization Hint (LOH)", false,
00228                     false)
00229 
00230 /// Given a couple (MBB, reg) get the corresponding set of instruction from
00231 /// the given "sets".
00232 /// If this couple does not reference any set, an empty set is added to "sets"
00233 /// for this couple and returned.
00234 /// \param nbRegs is used internally allocate some memory. It must be consistent
00235 /// with the way sets is used.
00236 static SetOfMachineInstr &getSet(BlockToSetOfInstrsPerColor &sets,
00237                                  const MachineBasicBlock &MBB, unsigned reg,
00238                                  unsigned nbRegs) {
00239   SetOfMachineInstr *result;
00240   BlockToSetOfInstrsPerColor::iterator it = sets.find(&MBB);
00241   if (it != sets.end())
00242     result = it->second.get();
00243   else
00244     result = (sets[&MBB] = make_unique<SetOfMachineInstr[]>(nbRegs)).get();
00245 
00246   return result[reg];
00247 }
00248 
00249 /// Given a couple (reg, MI) get the corresponding set of instructions from the
00250 /// the given "sets".
00251 /// This is used to get the uses record in sets of a definition identified by
00252 /// MI and reg, i.e., MI defines reg.
00253 /// If the couple does not reference anything, an empty set is added to
00254 /// "sets[reg]".
00255 /// \pre set[reg] is valid.
00256 static SetOfMachineInstr &getUses(InstrToInstrs *sets, unsigned reg,
00257                                   const MachineInstr &MI) {
00258   return sets[reg][&MI];
00259 }
00260 
00261 /// Same as getUses but does not modify the input map: sets.
00262 /// \return NULL if the couple (reg, MI) is not in sets.
00263 static const SetOfMachineInstr *getUses(const InstrToInstrs *sets, unsigned reg,
00264                                         const MachineInstr &MI) {
00265   InstrToInstrs::const_iterator Res = sets[reg].find(&MI);
00266   if (Res != sets[reg].end())
00267     return &(Res->second);
00268   return nullptr;
00269 }
00270 
00271 /// Initialize the reaching definition algorithm:
00272 /// For each basic block BB in MF, record:
00273 /// - its kill set.
00274 /// - its reachable uses (uses that are exposed to BB's predecessors).
00275 /// - its the generated definitions.
00276 /// \param DummyOp if not NULL, specifies a Dummy Operation to be added to
00277 /// the list of uses of exposed defintions.
00278 /// \param ADRPMode specifies to only consider ADRP instructions for generated
00279 /// definition. It also consider definitions of ADRP instructions as uses and
00280 /// ignore other uses. The ADRPMode is used to collect the information for LHO
00281 /// that involve ADRP operation only.
00282 static void initReachingDef(MachineFunction &MF,
00283                             InstrToInstrs *ColorOpToReachedUses,
00284                             BlockToInstrPerColor &Gen, BlockToRegSet &Kill,
00285                             BlockToSetOfInstrsPerColor &ReachableUses,
00286                             const MapRegToId &RegToId,
00287                             const MachineInstr *DummyOp, bool ADRPMode) {
00288   const TargetMachine &TM = MF.getTarget();
00289   const TargetRegisterInfo *TRI = TM.getSubtargetImpl()->getRegisterInfo();
00290 
00291   unsigned NbReg = RegToId.size();
00292 
00293   for (MachineBasicBlock &MBB : MF) {
00294     auto &BBGen = Gen[&MBB];
00295     BBGen = make_unique<const MachineInstr *[]>(NbReg);
00296     std::fill(BBGen.get(), BBGen.get() + NbReg, nullptr);
00297 
00298     BitVector &BBKillSet = Kill[&MBB];
00299     BBKillSet.resize(NbReg);
00300     for (const MachineInstr &MI : MBB) {
00301       bool IsADRP = MI.getOpcode() == AArch64::ADRP;
00302 
00303       // Process uses first.
00304       if (IsADRP || !ADRPMode)
00305         for (const MachineOperand &MO : MI.operands()) {
00306           // Treat ADRP def as use, as the goal of the analysis is to find
00307           // ADRP defs reached by other ADRP defs.
00308           if (!MO.isReg() || (!ADRPMode && !MO.isUse()) ||
00309               (ADRPMode && (!IsADRP || !MO.isDef())))
00310             continue;
00311           unsigned CurReg = MO.getReg();
00312           MapRegToId::const_iterator ItCurRegId = RegToId.find(CurReg);
00313           if (ItCurRegId == RegToId.end())
00314             continue;
00315           CurReg = ItCurRegId->second;
00316 
00317           // if CurReg has not been defined, this use is reachable.
00318           if (!BBGen[CurReg] && !BBKillSet.test(CurReg))
00319             getSet(ReachableUses, MBB, CurReg, NbReg).insert(&MI);
00320           // current basic block definition for this color, if any, is in Gen.
00321           if (BBGen[CurReg])
00322             getUses(ColorOpToReachedUses, CurReg, *BBGen[CurReg]).insert(&MI);
00323         }
00324 
00325       // Process clobbers.
00326       for (const MachineOperand &MO : MI.operands()) {
00327         if (!MO.isRegMask())
00328           continue;
00329         // Clobbers kill the related colors.
00330         const uint32_t *PreservedRegs = MO.getRegMask();
00331 
00332         // Set generated regs.
00333         for (const auto Entry : RegToId) {
00334           unsigned Reg = Entry.second;
00335           // Use the global register ID when querying APIs external to this
00336           // pass.
00337           if (MachineOperand::clobbersPhysReg(PreservedRegs, Entry.first)) {
00338             // Do not register clobbered definition for no ADRP.
00339             // This definition is not used anyway (otherwise register
00340             // allocation is wrong).
00341             BBGen[Reg] = ADRPMode ? &MI : nullptr;
00342             BBKillSet.set(Reg);
00343           }
00344         }
00345       }
00346 
00347       // Process register defs.
00348       for (const MachineOperand &MO : MI.operands()) {
00349         if (!MO.isReg() || !MO.isDef())
00350           continue;
00351         unsigned CurReg = MO.getReg();
00352         MapRegToId::const_iterator ItCurRegId = RegToId.find(CurReg);
00353         if (ItCurRegId == RegToId.end())
00354           continue;
00355 
00356         for (MCRegAliasIterator AI(CurReg, TRI, true); AI.isValid(); ++AI) {
00357           MapRegToId::const_iterator ItRegId = RegToId.find(*AI);
00358           assert(ItRegId != RegToId.end() &&
00359                  "Sub-register of an "
00360                  "involved register, not recorded as involved!");
00361           BBKillSet.set(ItRegId->second);
00362           BBGen[ItRegId->second] = &MI;
00363         }
00364         BBGen[ItCurRegId->second] = &MI;
00365       }
00366     }
00367 
00368     // If we restrict our analysis to basic block scope, conservatively add a
00369     // dummy
00370     // use for each generated value.
00371     if (!ADRPMode && DummyOp && !MBB.succ_empty())
00372       for (unsigned CurReg = 0; CurReg < NbReg; ++CurReg)
00373         if (BBGen[CurReg])
00374           getUses(ColorOpToReachedUses, CurReg, *BBGen[CurReg]).insert(DummyOp);
00375   }
00376 }
00377 
00378 /// Reaching def core algorithm:
00379 /// while an Out has changed
00380 ///    for each bb
00381 ///       for each color
00382 ///           In[bb][color] = U Out[bb.predecessors][color]
00383 ///           insert reachableUses[bb][color] in each in[bb][color]
00384 ///                 op.reachedUses
00385 ///
00386 ///           Out[bb] = Gen[bb] U (In[bb] - Kill[bb])
00387 static void reachingDefAlgorithm(MachineFunction &MF,
00388                                  InstrToInstrs *ColorOpToReachedUses,
00389                                  BlockToSetOfInstrsPerColor &In,
00390                                  BlockToSetOfInstrsPerColor &Out,
00391                                  BlockToInstrPerColor &Gen, BlockToRegSet &Kill,
00392                                  BlockToSetOfInstrsPerColor &ReachableUses,
00393                                  unsigned NbReg) {
00394   bool HasChanged;
00395   do {
00396     HasChanged = false;
00397     for (MachineBasicBlock &MBB : MF) {
00398       unsigned CurReg;
00399       for (CurReg = 0; CurReg < NbReg; ++CurReg) {
00400         SetOfMachineInstr &BBInSet = getSet(In, MBB, CurReg, NbReg);
00401         SetOfMachineInstr &BBReachableUses =
00402             getSet(ReachableUses, MBB, CurReg, NbReg);
00403         SetOfMachineInstr &BBOutSet = getSet(Out, MBB, CurReg, NbReg);
00404         unsigned Size = BBOutSet.size();
00405         //   In[bb][color] = U Out[bb.predecessors][color]
00406         for (MachineBasicBlock *PredMBB : MBB.predecessors()) {
00407           SetOfMachineInstr &PredOutSet = getSet(Out, *PredMBB, CurReg, NbReg);
00408           BBInSet.insert(PredOutSet.begin(), PredOutSet.end());
00409         }
00410         //   insert reachableUses[bb][color] in each in[bb][color] op.reachedses
00411         for (const MachineInstr *MI : BBInSet) {
00412           SetOfMachineInstr &OpReachedUses =
00413               getUses(ColorOpToReachedUses, CurReg, *MI);
00414           OpReachedUses.insert(BBReachableUses.begin(), BBReachableUses.end());
00415         }
00416         //           Out[bb] = Gen[bb] U (In[bb] - Kill[bb])
00417         if (!Kill[&MBB].test(CurReg))
00418           BBOutSet.insert(BBInSet.begin(), BBInSet.end());
00419         if (Gen[&MBB][CurReg])
00420           BBOutSet.insert(Gen[&MBB][CurReg]);
00421         HasChanged |= BBOutSet.size() != Size;
00422       }
00423     }
00424   } while (HasChanged);
00425 }
00426 
00427 /// Reaching definition algorithm.
00428 /// \param MF function on which the algorithm will operate.
00429 /// \param[out] ColorOpToReachedUses will contain the result of the reaching
00430 /// def algorithm.
00431 /// \param ADRPMode specify whether the reaching def algorithm should be tuned
00432 /// for ADRP optimization. \see initReachingDef for more details.
00433 /// \param DummyOp if not NULL, the algorithm will work at
00434 /// basic block scope and will set for every exposed definition a use to
00435 /// @p DummyOp.
00436 /// \pre ColorOpToReachedUses is an array of at least number of registers of
00437 /// InstrToInstrs.
00438 static void reachingDef(MachineFunction &MF,
00439                         InstrToInstrs *ColorOpToReachedUses,
00440                         const MapRegToId &RegToId, bool ADRPMode = false,
00441                         const MachineInstr *DummyOp = nullptr) {
00442   // structures:
00443   // For each basic block.
00444   // Out: a set per color of definitions that reach the
00445   //      out boundary of this block.
00446   // In: Same as Out but for in boundary.
00447   // Gen: generated color in this block (one operation per color).
00448   // Kill: register set of killed color in this block.
00449   // ReachableUses: a set per color of uses (operation) reachable
00450   //                for "In" definitions.
00451   BlockToSetOfInstrsPerColor Out, In, ReachableUses;
00452   BlockToInstrPerColor Gen;
00453   BlockToRegSet Kill;
00454 
00455   // Initialize Gen, kill and reachableUses.
00456   initReachingDef(MF, ColorOpToReachedUses, Gen, Kill, ReachableUses, RegToId,
00457                   DummyOp, ADRPMode);
00458 
00459   // Algo.
00460   if (!DummyOp)
00461     reachingDefAlgorithm(MF, ColorOpToReachedUses, In, Out, Gen, Kill,
00462                          ReachableUses, RegToId.size());
00463 }
00464 
00465 #ifndef NDEBUG
00466 /// print the result of the reaching definition algorithm.
00467 static void printReachingDef(const InstrToInstrs *ColorOpToReachedUses,
00468                              unsigned NbReg, const TargetRegisterInfo *TRI,
00469                              const MapIdToReg &IdToReg) {
00470   unsigned CurReg;
00471   for (CurReg = 0; CurReg < NbReg; ++CurReg) {
00472     if (ColorOpToReachedUses[CurReg].empty())
00473       continue;
00474     DEBUG(dbgs() << "*** Reg " << PrintReg(IdToReg[CurReg], TRI) << " ***\n");
00475 
00476     for (const auto &DefsIt : ColorOpToReachedUses[CurReg]) {
00477       DEBUG(dbgs() << "Def:\n");
00478       DEBUG(DefsIt.first->print(dbgs()));
00479       DEBUG(dbgs() << "Reachable uses:\n");
00480       for (const MachineInstr *MI : DefsIt.second) {
00481         DEBUG(MI->print(dbgs()));
00482       }
00483     }
00484   }
00485 }
00486 #endif // NDEBUG
00487 
00488 /// Answer the following question: Can Def be one of the definition
00489 /// involved in a part of a LOH?
00490 static bool canDefBePartOfLOH(const MachineInstr *Def) {
00491   unsigned Opc = Def->getOpcode();
00492   // Accept ADRP, ADDLow and LOADGot.
00493   switch (Opc) {
00494   default:
00495     return false;
00496   case AArch64::ADRP:
00497     return true;
00498   case AArch64::ADDXri:
00499     // Check immediate to see if the immediate is an address.
00500     switch (Def->getOperand(2).getType()) {
00501     default:
00502       return false;
00503     case MachineOperand::MO_GlobalAddress:
00504     case MachineOperand::MO_JumpTableIndex:
00505     case MachineOperand::MO_ConstantPoolIndex:
00506     case MachineOperand::MO_BlockAddress:
00507       return true;
00508     }
00509   case AArch64::LDRXui:
00510     // Check immediate to see if the immediate is an address.
00511     switch (Def->getOperand(2).getType()) {
00512     default:
00513       return false;
00514     case MachineOperand::MO_GlobalAddress:
00515       return true;
00516     }
00517   }
00518   // Unreachable.
00519   return false;
00520 }
00521 
00522 /// Check whether the given instruction can the end of a LOH chain involving a
00523 /// store.
00524 static bool isCandidateStore(const MachineInstr *Instr) {
00525   switch (Instr->getOpcode()) {
00526   default:
00527     return false;
00528   case AArch64::STRBui:
00529   case AArch64::STRHui:
00530   case AArch64::STRWui:
00531   case AArch64::STRXui:
00532   case AArch64::STRSui:
00533   case AArch64::STRDui:
00534   case AArch64::STRQui:
00535     // In case we have str xA, [xA, #imm], this is two different uses
00536     // of xA and we cannot fold, otherwise the xA stored may be wrong,
00537     // even if #imm == 0.
00538     if (Instr->getOperand(0).getReg() != Instr->getOperand(1).getReg())
00539       return true;
00540   }
00541   return false;
00542 }
00543 
00544 /// Given the result of a reaching definition algorithm in ColorOpToReachedUses,
00545 /// Build the Use to Defs information and filter out obvious non-LOH candidates.
00546 /// In ADRPMode, non-LOH candidates are "uses" with non-ADRP definitions.
00547 /// In non-ADRPMode, non-LOH candidates are "uses" with several definition,
00548 /// i.e., no simple chain.
00549 /// \param ADRPMode -- \see initReachingDef.
00550 static void reachedUsesToDefs(InstrToInstrs &UseToReachingDefs,
00551                               const InstrToInstrs *ColorOpToReachedUses,
00552                               const MapRegToId &RegToId,
00553                               bool ADRPMode = false) {
00554 
00555   SetOfMachineInstr NotCandidate;
00556   unsigned NbReg = RegToId.size();
00557   MapRegToId::const_iterator EndIt = RegToId.end();
00558   for (unsigned CurReg = 0; CurReg < NbReg; ++CurReg) {
00559     // If this color is never defined, continue.
00560     if (ColorOpToReachedUses[CurReg].empty())
00561       continue;
00562 
00563     for (const auto &DefsIt : ColorOpToReachedUses[CurReg]) {
00564       for (const MachineInstr *MI : DefsIt.second) {
00565         const MachineInstr *Def = DefsIt.first;
00566         MapRegToId::const_iterator It;
00567         // if all the reaching defs are not adrp, this use will not be
00568         // simplifiable.
00569         if ((ADRPMode && Def->getOpcode() != AArch64::ADRP) ||
00570             (!ADRPMode && !canDefBePartOfLOH(Def)) ||
00571             (!ADRPMode && isCandidateStore(MI) &&
00572              // store are LOH candidate iff the end of the chain is used as
00573              // base.
00574              ((It = RegToId.find((MI)->getOperand(1).getReg())) == EndIt ||
00575               It->second != CurReg))) {
00576           NotCandidate.insert(MI);
00577           continue;
00578         }
00579         // Do not consider self reaching as a simplifiable case for ADRP.
00580         if (!ADRPMode || MI != DefsIt.first) {
00581           UseToReachingDefs[MI].insert(DefsIt.first);
00582           // If UsesIt has several reaching definitions, it is not
00583           // candidate for simplificaton in non-ADRPMode.
00584           if (!ADRPMode && UseToReachingDefs[MI].size() > 1)
00585             NotCandidate.insert(MI);
00586         }
00587       }
00588     }
00589   }
00590   for (const MachineInstr *Elem : NotCandidate) {
00591     DEBUG(dbgs() << "Too many reaching defs: " << *Elem << "\n");
00592     // It would have been better if we could just remove the entry
00593     // from the map.  Because of that, we have to filter the garbage
00594     // (second.empty) in the subsequence analysis.
00595     UseToReachingDefs[Elem].clear();
00596   }
00597 }
00598 
00599 /// Based on the use to defs information (in ADRPMode), compute the
00600 /// opportunities of LOH ADRP-related.
00601 static void computeADRP(const InstrToInstrs &UseToDefs,
00602                         AArch64FunctionInfo &AArch64FI,
00603                         const MachineDominatorTree *MDT) {
00604   DEBUG(dbgs() << "*** Compute LOH for ADRP\n");
00605   for (const auto &Entry : UseToDefs) {
00606     unsigned Size = Entry.second.size();
00607     if (Size == 0)
00608       continue;
00609     if (Size == 1) {
00610       const MachineInstr *L2 = *Entry.second.begin();
00611       const MachineInstr *L1 = Entry.first;
00612       if (!MDT->dominates(L2, L1)) {
00613         DEBUG(dbgs() << "Dominance check failed:\n" << *L2 << '\n' << *L1
00614                      << '\n');
00615         continue;
00616       }
00617       DEBUG(dbgs() << "Record AdrpAdrp:\n" << *L2 << '\n' << *L1 << '\n');
00618       SmallVector<const MachineInstr *, 2> Args;
00619       Args.push_back(L2);
00620       Args.push_back(L1);
00621       AArch64FI.addLOHDirective(MCLOH_AdrpAdrp, Args);
00622       ++NumADRPSimpleCandidate;
00623     }
00624 #ifdef DEBUG
00625     else if (Size == 2)
00626       ++NumADRPComplexCandidate2;
00627     else if (Size == 3)
00628       ++NumADRPComplexCandidate3;
00629     else
00630       ++NumADRPComplexCandidateOther;
00631 #endif
00632     // if Size < 1, the use should have been removed from the candidates
00633     assert(Size >= 1 && "No reaching defs for that use!");
00634   }
00635 }
00636 
00637 /// Check whether the given instruction can be the end of a LOH chain
00638 /// involving a load.
00639 static bool isCandidateLoad(const MachineInstr *Instr) {
00640   switch (Instr->getOpcode()) {
00641   default:
00642     return false;
00643   case AArch64::LDRSBWui:
00644   case AArch64::LDRSBXui:
00645   case AArch64::LDRSHWui:
00646   case AArch64::LDRSHXui:
00647   case AArch64::LDRSWui:
00648   case AArch64::LDRBui:
00649   case AArch64::LDRHui:
00650   case AArch64::LDRWui:
00651   case AArch64::LDRXui:
00652   case AArch64::LDRSui:
00653   case AArch64::LDRDui:
00654   case AArch64::LDRQui:
00655     if (Instr->getOperand(2).getTargetFlags() & AArch64II::MO_GOT)
00656       return false;
00657     return true;
00658   }
00659   // Unreachable.
00660   return false;
00661 }
00662 
00663 /// Check whether the given instruction can load a litteral.
00664 static bool supportLoadFromLiteral(const MachineInstr *Instr) {
00665   switch (Instr->getOpcode()) {
00666   default:
00667     return false;
00668   case AArch64::LDRSWui:
00669   case AArch64::LDRWui:
00670   case AArch64::LDRXui:
00671   case AArch64::LDRSui:
00672   case AArch64::LDRDui:
00673   case AArch64::LDRQui:
00674     return true;
00675   }
00676   // Unreachable.
00677   return false;
00678 }
00679 
00680 /// Check whether the given instruction is a LOH candidate.
00681 /// \param UseToDefs is used to check that Instr is at the end of LOH supported
00682 /// chain.
00683 /// \pre UseToDefs contains only on def per use, i.e., obvious non candidate are
00684 /// already been filtered out.
00685 static bool isCandidate(const MachineInstr *Instr,
00686                         const InstrToInstrs &UseToDefs,
00687                         const MachineDominatorTree *MDT) {
00688   if (!isCandidateLoad(Instr) && !isCandidateStore(Instr))
00689     return false;
00690 
00691   const MachineInstr *Def = *UseToDefs.find(Instr)->second.begin();
00692   if (Def->getOpcode() != AArch64::ADRP) {
00693     // At this point, Def is ADDXri or LDRXui of the right type of
00694     // symbol, because we filtered out the uses that were not defined
00695     // by these kind of instructions (+ ADRP).
00696 
00697     // Check if this forms a simple chain: each intermediate node must
00698     // dominates the next one.
00699     if (!MDT->dominates(Def, Instr))
00700       return false;
00701     // Move one node up in the simple chain.
00702     if (UseToDefs.find(Def) ==
00703             UseToDefs.end()
00704             // The map may contain garbage we have to ignore.
00705         ||
00706         UseToDefs.find(Def)->second.empty())
00707       return false;
00708     Instr = Def;
00709     Def = *UseToDefs.find(Def)->second.begin();
00710   }
00711   // Check if we reached the top of the simple chain:
00712   // - top is ADRP.
00713   // - check the simple chain property: each intermediate node must
00714   // dominates the next one.
00715   if (Def->getOpcode() == AArch64::ADRP)
00716     return MDT->dominates(Def, Instr);
00717   return false;
00718 }
00719 
00720 static bool registerADRCandidate(const MachineInstr &Use,
00721                                  const InstrToInstrs &UseToDefs,
00722                                  const InstrToInstrs *DefsPerColorToUses,
00723                                  AArch64FunctionInfo &AArch64FI,
00724                                  SetOfMachineInstr *InvolvedInLOHs,
00725                                  const MapRegToId &RegToId) {
00726   // Look for opportunities to turn ADRP -> ADD or
00727   // ADRP -> LDR GOTPAGEOFF into ADR.
00728   // If ADRP has more than one use. Give up.
00729   if (Use.getOpcode() != AArch64::ADDXri &&
00730       (Use.getOpcode() != AArch64::LDRXui ||
00731        !(Use.getOperand(2).getTargetFlags() & AArch64II::MO_GOT)))
00732     return false;
00733   InstrToInstrs::const_iterator It = UseToDefs.find(&Use);
00734   // The map may contain garbage that we need to ignore.
00735   if (It == UseToDefs.end() || It->second.empty())
00736     return false;
00737   const MachineInstr &Def = **It->second.begin();
00738   if (Def.getOpcode() != AArch64::ADRP)
00739     return false;
00740   // Check the number of users of ADRP.
00741   const SetOfMachineInstr *Users =
00742       getUses(DefsPerColorToUses,
00743               RegToId.find(Def.getOperand(0).getReg())->second, Def);
00744   if (Users->size() > 1) {
00745     ++NumADRComplexCandidate;
00746     return false;
00747   }
00748   ++NumADRSimpleCandidate;
00749   assert((!InvolvedInLOHs || InvolvedInLOHs->insert(&Def)) &&
00750          "ADRP already involved in LOH.");
00751   assert((!InvolvedInLOHs || InvolvedInLOHs->insert(&Use)) &&
00752          "ADD already involved in LOH.");
00753   DEBUG(dbgs() << "Record AdrpAdd\n" << Def << '\n' << Use << '\n');
00754 
00755   SmallVector<const MachineInstr *, 2> Args;
00756   Args.push_back(&Def);
00757   Args.push_back(&Use);
00758 
00759   AArch64FI.addLOHDirective(Use.getOpcode() == AArch64::ADDXri ? MCLOH_AdrpAdd
00760                                                            : MCLOH_AdrpLdrGot,
00761                           Args);
00762   return true;
00763 }
00764 
00765 /// Based on the use to defs information (in non-ADRPMode), compute the
00766 /// opportunities of LOH non-ADRP-related
00767 static void computeOthers(const InstrToInstrs &UseToDefs,
00768                           const InstrToInstrs *DefsPerColorToUses,
00769                           AArch64FunctionInfo &AArch64FI, const MapRegToId &RegToId,
00770                           const MachineDominatorTree *MDT) {
00771   SetOfMachineInstr *InvolvedInLOHs = nullptr;
00772 #ifdef DEBUG
00773   SetOfMachineInstr InvolvedInLOHsStorage;
00774   InvolvedInLOHs = &InvolvedInLOHsStorage;
00775 #endif // DEBUG
00776   DEBUG(dbgs() << "*** Compute LOH for Others\n");
00777   // ADRP -> ADD/LDR -> LDR/STR pattern.
00778   // Fall back to ADRP -> ADD pattern if we fail to catch the bigger pattern.
00779 
00780   // FIXME: When the statistics are not important,
00781   // This initial filtering loop can be merged into the next loop.
00782   // Currently, we didn't do it to have the same code for both DEBUG and
00783   // NDEBUG builds. Indeed, the iterator of the second loop would need
00784   // to be changed.
00785   SetOfMachineInstr PotentialCandidates;
00786   SetOfMachineInstr PotentialADROpportunities;
00787   for (auto &Use : UseToDefs) {
00788     // If no definition is available, this is a non candidate.
00789     if (Use.second.empty())
00790       continue;
00791     // Keep only instructions that are load or store and at the end of
00792     // a ADRP -> ADD/LDR/Nothing chain.
00793     // We already filtered out the no-chain cases.
00794     if (!isCandidate(Use.first, UseToDefs, MDT)) {
00795       PotentialADROpportunities.insert(Use.first);
00796       continue;
00797     }
00798     PotentialCandidates.insert(Use.first);
00799   }
00800 
00801   // Make the following distinctions for statistics as the linker does
00802   // know how to decode instructions:
00803   // - ADD/LDR/Nothing make there different patterns.
00804   // - LDR/STR make two different patterns.
00805   // Hence, 6 - 1 base patterns.
00806   // (because ADRP-> Nothing -> STR is not simplifiable)
00807 
00808   // The linker is only able to have a simple semantic, i.e., if pattern A
00809   // do B.
00810   // However, we want to see the opportunity we may miss if we were able to
00811   // catch more complex cases.
00812 
00813   // PotentialCandidates are result of a chain ADRP -> ADD/LDR ->
00814   // A potential candidate becomes a candidate, if its current immediate
00815   // operand is zero and all nodes of the chain have respectively only one user
00816 #ifdef DEBUG
00817   SetOfMachineInstr DefsOfPotentialCandidates;
00818 #endif
00819   for (const MachineInstr *Candidate : PotentialCandidates) {
00820     // Get the definition of the candidate i.e., ADD or LDR.
00821     const MachineInstr *Def = *UseToDefs.find(Candidate)->second.begin();
00822     // Record the elements of the chain.
00823     const MachineInstr *L1 = Def;
00824     const MachineInstr *L2 = nullptr;
00825     unsigned ImmediateDefOpc = Def->getOpcode();
00826     if (Def->getOpcode() != AArch64::ADRP) {
00827       // Check the number of users of this node.
00828       const SetOfMachineInstr *Users =
00829           getUses(DefsPerColorToUses,
00830                   RegToId.find(Def->getOperand(0).getReg())->second, *Def);
00831       if (Users->size() > 1) {
00832 #ifdef DEBUG
00833         // if all the uses of this def are in potential candidate, this is
00834         // a complex candidate of level 2.
00835         bool IsLevel2 = true;
00836         for (const MachineInstr *MI : *Users) {
00837           if (!PotentialCandidates.count(MI)) {
00838             ++NumTooCplxLvl2;
00839             IsLevel2 = false;
00840             break;
00841           }
00842         }
00843         if (IsLevel2)
00844           ++NumCplxLvl2;
00845 #endif // DEBUG
00846         PotentialADROpportunities.insert(Def);
00847         continue;
00848       }
00849       L2 = Def;
00850       Def = *UseToDefs.find(Def)->second.begin();
00851       L1 = Def;
00852     } // else the element in the middle of the chain is nothing, thus
00853       // Def already contains the first element of the chain.
00854 
00855     // Check the number of users of the first node in the chain, i.e., ADRP
00856     const SetOfMachineInstr *Users =
00857         getUses(DefsPerColorToUses,
00858                 RegToId.find(Def->getOperand(0).getReg())->second, *Def);
00859     if (Users->size() > 1) {
00860 #ifdef DEBUG
00861       // if all the uses of this def are in the defs of the potential candidate,
00862       // this is a complex candidate of level 1
00863       if (DefsOfPotentialCandidates.empty()) {
00864         // lazy init
00865         DefsOfPotentialCandidates = PotentialCandidates;
00866         for (const MachineInstr *Candidate : PotentialCandidates) {
00867           if (!UseToDefs.find(Candidate)->second.empty())
00868             DefsOfPotentialCandidates.insert(
00869                 *UseToDefs.find(Candidate)->second.begin());
00870         }
00871       }
00872       bool Found = false;
00873       for (auto &Use : *Users) {
00874         if (!DefsOfPotentialCandidates.count(Use)) {
00875           ++NumTooCplxLvl1;
00876           Found = true;
00877           break;
00878         }
00879       }
00880       if (!Found)
00881         ++NumCplxLvl1;
00882 #endif // DEBUG
00883       continue;
00884     }
00885 
00886     bool IsL2Add = (ImmediateDefOpc == AArch64::ADDXri);
00887     // If the chain is three instructions long and ldr is the second element,
00888     // then this ldr must load form GOT, otherwise this is not a correct chain.
00889     if (L2 && !IsL2Add && L2->getOperand(2).getTargetFlags() != AArch64II::MO_GOT)
00890       continue;
00891     SmallVector<const MachineInstr *, 3> Args;
00892     MCLOHType Kind;
00893     if (isCandidateLoad(Candidate)) {
00894       if (!L2) {
00895         // At this point, the candidate LOH indicates that the ldr instruction
00896         // may use a direct access to the symbol. There is not such encoding
00897         // for loads of byte and half.
00898         if (!supportLoadFromLiteral(Candidate))
00899           continue;
00900 
00901         DEBUG(dbgs() << "Record AdrpLdr:\n" << *L1 << '\n' << *Candidate
00902                      << '\n');
00903         Kind = MCLOH_AdrpLdr;
00904         Args.push_back(L1);
00905         Args.push_back(Candidate);
00906         assert((!InvolvedInLOHs || InvolvedInLOHs->insert(L1)) &&
00907                "L1 already involved in LOH.");
00908         assert((!InvolvedInLOHs || InvolvedInLOHs->insert(Candidate)) &&
00909                "Candidate already involved in LOH.");
00910         ++NumADRPToLDR;
00911       } else {
00912         DEBUG(dbgs() << "Record Adrp" << (IsL2Add ? "Add" : "LdrGot")
00913                      << "Ldr:\n" << *L1 << '\n' << *L2 << '\n' << *Candidate
00914                      << '\n');
00915 
00916         Kind = IsL2Add ? MCLOH_AdrpAddLdr : MCLOH_AdrpLdrGotLdr;
00917         Args.push_back(L1);
00918         Args.push_back(L2);
00919         Args.push_back(Candidate);
00920 
00921         PotentialADROpportunities.remove(L2);
00922         assert((!InvolvedInLOHs || InvolvedInLOHs->insert(L1)) &&
00923                "L1 already involved in LOH.");
00924         assert((!InvolvedInLOHs || InvolvedInLOHs->insert(L2)) &&
00925                "L2 already involved in LOH.");
00926         assert((!InvolvedInLOHs || InvolvedInLOHs->insert(Candidate)) &&
00927                "Candidate already involved in LOH.");
00928 #ifdef DEBUG
00929         // get the immediate of the load
00930         if (Candidate->getOperand(2).getImm() == 0)
00931           if (ImmediateDefOpc == AArch64::ADDXri)
00932             ++NumADDToLDR;
00933           else
00934             ++NumLDRToLDR;
00935         else if (ImmediateDefOpc == AArch64::ADDXri)
00936           ++NumADDToLDRWithImm;
00937         else
00938           ++NumLDRToLDRWithImm;
00939 #endif // DEBUG
00940       }
00941     } else {
00942       if (ImmediateDefOpc == AArch64::ADRP)
00943         continue;
00944       else {
00945 
00946         DEBUG(dbgs() << "Record Adrp" << (IsL2Add ? "Add" : "LdrGot")
00947                      << "Str:\n" << *L1 << '\n' << *L2 << '\n' << *Candidate
00948                      << '\n');
00949 
00950         Kind = IsL2Add ? MCLOH_AdrpAddStr : MCLOH_AdrpLdrGotStr;
00951         Args.push_back(L1);
00952         Args.push_back(L2);
00953         Args.push_back(Candidate);
00954 
00955         PotentialADROpportunities.remove(L2);
00956         assert((!InvolvedInLOHs || InvolvedInLOHs->insert(L1)) &&
00957                "L1 already involved in LOH.");
00958         assert((!InvolvedInLOHs || InvolvedInLOHs->insert(L2)) &&
00959                "L2 already involved in LOH.");
00960         assert((!InvolvedInLOHs || InvolvedInLOHs->insert(Candidate)) &&
00961                "Candidate already involved in LOH.");
00962 #ifdef DEBUG
00963         // get the immediate of the store
00964         if (Candidate->getOperand(2).getImm() == 0)
00965           if (ImmediateDefOpc == AArch64::ADDXri)
00966             ++NumADDToSTR;
00967           else
00968             ++NumLDRToSTR;
00969         else if (ImmediateDefOpc == AArch64::ADDXri)
00970           ++NumADDToSTRWithImm;
00971         else
00972           ++NumLDRToSTRWithImm;
00973 #endif // DEBUG
00974       }
00975     }
00976     AArch64FI.addLOHDirective(Kind, Args);
00977   }
00978 
00979   // Now, we grabbed all the big patterns, check ADR opportunities.
00980   for (const MachineInstr *Candidate : PotentialADROpportunities)
00981     registerADRCandidate(*Candidate, UseToDefs, DefsPerColorToUses, AArch64FI,
00982                          InvolvedInLOHs, RegToId);
00983 }
00984 
00985 /// Look for every register defined by potential LOHs candidates.
00986 /// Map these registers with dense id in @p RegToId and vice-versa in
00987 /// @p IdToReg. @p IdToReg is populated only in DEBUG mode.
00988 static void collectInvolvedReg(MachineFunction &MF, MapRegToId &RegToId,
00989                                MapIdToReg &IdToReg,
00990                                const TargetRegisterInfo *TRI) {
00991   unsigned CurRegId = 0;
00992   if (!PreCollectRegister) {
00993     unsigned NbReg = TRI->getNumRegs();
00994     for (; CurRegId < NbReg; ++CurRegId) {
00995       RegToId[CurRegId] = CurRegId;
00996       DEBUG(IdToReg.push_back(CurRegId));
00997       DEBUG(assert(IdToReg[CurRegId] == CurRegId && "Reg index mismatches"));
00998     }
00999     return;
01000   }
01001 
01002   DEBUG(dbgs() << "** Collect Involved Register\n");
01003   for (const auto &MBB : MF) {
01004     for (const MachineInstr &MI : MBB) {
01005       if (!canDefBePartOfLOH(&MI))
01006         continue;
01007 
01008       // Process defs
01009       for (MachineInstr::const_mop_iterator IO = MI.operands_begin(),
01010                                             IOEnd = MI.operands_end();
01011            IO != IOEnd; ++IO) {
01012         if (!IO->isReg() || !IO->isDef())
01013           continue;
01014         unsigned CurReg = IO->getReg();
01015         for (MCRegAliasIterator AI(CurReg, TRI, true); AI.isValid(); ++AI)
01016           if (RegToId.find(*AI) == RegToId.end()) {
01017             DEBUG(IdToReg.push_back(*AI);
01018                   assert(IdToReg[CurRegId] == *AI &&
01019                          "Reg index mismatches insertion index."));
01020             RegToId[*AI] = CurRegId++;
01021             DEBUG(dbgs() << "Register: " << PrintReg(*AI, TRI) << '\n');
01022           }
01023       }
01024     }
01025   }
01026 }
01027 
01028 bool AArch64CollectLOH::runOnMachineFunction(MachineFunction &MF) {
01029   const TargetMachine &TM = MF.getTarget();
01030   const TargetRegisterInfo *TRI = TM.getSubtargetImpl()->getRegisterInfo();
01031   const MachineDominatorTree *MDT = &getAnalysis<MachineDominatorTree>();
01032 
01033   MapRegToId RegToId;
01034   MapIdToReg IdToReg;
01035   AArch64FunctionInfo *AArch64FI = MF.getInfo<AArch64FunctionInfo>();
01036   assert(AArch64FI && "No MachineFunctionInfo for this function!");
01037 
01038   DEBUG(dbgs() << "Looking for LOH in " << MF.getName() << '\n');
01039 
01040   collectInvolvedReg(MF, RegToId, IdToReg, TRI);
01041   if (RegToId.empty())
01042     return false;
01043 
01044   MachineInstr *DummyOp = nullptr;
01045   if (BasicBlockScopeOnly) {
01046     const AArch64InstrInfo *TII = static_cast<const AArch64InstrInfo *>(
01047         TM.getSubtargetImpl()->getInstrInfo());
01048     // For local analysis, create a dummy operation to record uses that are not
01049     // local.
01050     DummyOp = MF.CreateMachineInstr(TII->get(AArch64::COPY), DebugLoc());
01051   }
01052 
01053   unsigned NbReg = RegToId.size();
01054   bool Modified = false;
01055 
01056   // Start with ADRP.
01057   InstrToInstrs *ColorOpToReachedUses = new InstrToInstrs[NbReg];
01058 
01059   // Compute the reaching def in ADRP mode, meaning ADRP definitions
01060   // are first considered as uses.
01061   reachingDef(MF, ColorOpToReachedUses, RegToId, true, DummyOp);
01062   DEBUG(dbgs() << "ADRP reaching defs\n");
01063   DEBUG(printReachingDef(ColorOpToReachedUses, NbReg, TRI, IdToReg));
01064 
01065   // Translate the definition to uses map into a use to definitions map to ease
01066   // statistic computation.
01067   InstrToInstrs ADRPToReachingDefs;
01068   reachedUsesToDefs(ADRPToReachingDefs, ColorOpToReachedUses, RegToId, true);
01069 
01070   // Compute LOH for ADRP.
01071   computeADRP(ADRPToReachingDefs, *AArch64FI, MDT);
01072   delete[] ColorOpToReachedUses;
01073 
01074   // Continue with general ADRP -> ADD/LDR -> LDR/STR pattern.
01075   ColorOpToReachedUses = new InstrToInstrs[NbReg];
01076 
01077   // first perform a regular reaching def analysis.
01078   reachingDef(MF, ColorOpToReachedUses, RegToId, false, DummyOp);
01079   DEBUG(dbgs() << "All reaching defs\n");
01080   DEBUG(printReachingDef(ColorOpToReachedUses, NbReg, TRI, IdToReg));
01081 
01082   // Turn that into a use to defs to ease statistic computation.
01083   InstrToInstrs UsesToReachingDefs;
01084   reachedUsesToDefs(UsesToReachingDefs, ColorOpToReachedUses, RegToId, false);
01085 
01086   // Compute other than AdrpAdrp LOH.
01087   computeOthers(UsesToReachingDefs, ColorOpToReachedUses, *AArch64FI, RegToId,
01088                 MDT);
01089   delete[] ColorOpToReachedUses;
01090 
01091   if (BasicBlockScopeOnly)
01092     MF.DeleteMachineInstr(DummyOp);
01093 
01094   return Modified;
01095 }
01096 
01097 /// createAArch64CollectLOHPass - returns an instance of the Statistic for
01098 /// linker optimization pass.
01099 FunctionPass *llvm::createAArch64CollectLOHPass() {
01100   return new AArch64CollectLOH();
01101 }