LLVM API Documentation
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 }