blob: 87b545b186b9b7fc36b4ba9bfd3436f461a407e8 [file] [log] [blame]
Tim Northover3b0846e2014-05-24 12:50:23 +00001//===---------- AArch64CollectLOH.cpp - AArch64 collect LOH pass --*- C++ -*-=//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file contains a pass that collect the Linker Optimization Hint (LOH).
11// This pass should be run at the very end of the compilation flow, just before
12// assembly printer.
13// To be useful for the linker, the LOH must be printed into the assembly file.
14//
15// A LOH describes a sequence of instructions that may be optimized by the
16// linker.
17// This same sequence cannot be optimized by the compiler because some of
18// the information will be known at link time.
19// For instance, consider the following sequence:
20// L1: adrp xA, sym@PAGE
21// L2: add xB, xA, sym@PAGEOFF
22// L3: ldr xC, [xB, #imm]
23// This sequence can be turned into:
24// A literal load if sym@PAGE + sym@PAGEOFF + #imm - address(L3) is < 1MB:
25// L3: ldr xC, sym+#imm
26// It may also be turned into either the following more efficient
27// code sequences:
28// - If sym@PAGEOFF + #imm fits the encoding space of L3.
29// L1: adrp xA, sym@PAGE
30// L3: ldr xC, [xB, sym@PAGEOFF + #imm]
31// - If sym@PAGE + sym@PAGEOFF - address(L1) < 1MB:
32// L1: adr xA, sym
33// L3: ldr xC, [xB, #imm]
34//
35// To be valid a LOH must meet all the requirements needed by all the related
36// possible linker transformations.
37// For instance, using the running example, the constraints to emit
38// ".loh AdrpAddLdr" are:
39// - L1, L2, and L3 instructions are of the expected type, i.e.,
40// respectively ADRP, ADD (immediate), and LD.
41// - The result of L1 is used only by L2.
42// - The register argument (xA) used in the ADD instruction is defined
43// only by L1.
44// - The result of L2 is used only by L3.
45// - The base address (xB) in L3 is defined only L2.
46// - The ADRP in L1 and the ADD in L2 must reference the same symbol using
47// @PAGE/@PAGEOFF with no additional constants
48//
49// Currently supported LOHs are:
50// * So called non-ADRP-related:
51// - .loh AdrpAddLdr L1, L2, L3:
52// L1: adrp xA, sym@PAGE
53// L2: add xB, xA, sym@PAGEOFF
54// L3: ldr xC, [xB, #imm]
55// - .loh AdrpLdrGotLdr L1, L2, L3:
56// L1: adrp xA, sym@GOTPAGE
57// L2: ldr xB, [xA, sym@GOTPAGEOFF]
58// L3: ldr xC, [xB, #imm]
59// - .loh AdrpLdr L1, L3:
60// L1: adrp xA, sym@PAGE
61// L3: ldr xC, [xA, sym@PAGEOFF]
62// - .loh AdrpAddStr L1, L2, L3:
63// L1: adrp xA, sym@PAGE
64// L2: add xB, xA, sym@PAGEOFF
65// L3: str xC, [xB, #imm]
66// - .loh AdrpLdrGotStr L1, L2, L3:
67// L1: adrp xA, sym@GOTPAGE
68// L2: ldr xB, [xA, sym@GOTPAGEOFF]
69// L3: str xC, [xB, #imm]
70// - .loh AdrpAdd L1, L2:
71// L1: adrp xA, sym@PAGE
72// L2: add xB, xA, sym@PAGEOFF
73// For all these LOHs, L1, L2, L3 form a simple chain:
74// L1 result is used only by L2 and L2 result by L3.
75// L3 LOH-related argument is defined only by L2 and L2 LOH-related argument
76// by L1.
77// All these LOHs aim at using more efficient load/store patterns by folding
78// some instructions used to compute the address directly into the load/store.
79//
80// * So called ADRP-related:
81// - .loh AdrpAdrp L2, L1:
82// L2: ADRP xA, sym1@PAGE
83// L1: ADRP xA, sym2@PAGE
84// L2 dominates L1 and xA is not redifined between L2 and L1
85// This LOH aims at getting rid of redundant ADRP instructions.
86//
87// The overall design for emitting the LOHs is:
88// 1. AArch64CollectLOH (this pass) records the LOHs in the AArch64FunctionInfo.
89// 2. AArch64AsmPrinter reads the LOHs from AArch64FunctionInfo and it:
90// 1. Associates them a label.
91// 2. Emits them in a MCStreamer (EmitLOHDirective).
92// - The MCMachOStreamer records them into the MCAssembler.
93// - The MCAsmStreamer prints them.
94// - Other MCStreamers ignore them.
95// 3. Closes the MCStreamer:
96// - The MachObjectWriter gets them from the MCAssembler and writes
97// them in the object file.
98// - Other ObjectWriters ignore them.
99//===----------------------------------------------------------------------===//
100
101#include "AArch64.h"
102#include "AArch64InstrInfo.h"
103#include "AArch64MachineFunctionInfo.h"
Eric Christopherd9134482014-08-04 21:25:23 +0000104#include "AArch64Subtarget.h"
Tim Northover3b0846e2014-05-24 12:50:23 +0000105#include "MCTargetDesc/AArch64AddressingModes.h"
106#include "llvm/ADT/BitVector.h"
107#include "llvm/ADT/DenseMap.h"
108#include "llvm/ADT/MapVector.h"
109#include "llvm/ADT/SetVector.h"
110#include "llvm/ADT/SmallVector.h"
Benjamin Kramer1f8930e2014-07-25 11:42:14 +0000111#include "llvm/ADT/Statistic.h"
Tim Northover3b0846e2014-05-24 12:50:23 +0000112#include "llvm/CodeGen/MachineBasicBlock.h"
113#include "llvm/CodeGen/MachineDominators.h"
114#include "llvm/CodeGen/MachineFunctionPass.h"
115#include "llvm/CodeGen/MachineInstr.h"
116#include "llvm/CodeGen/MachineInstrBuilder.h"
Tim Northover3b0846e2014-05-24 12:50:23 +0000117#include "llvm/Support/CommandLine.h"
118#include "llvm/Support/Debug.h"
119#include "llvm/Support/ErrorHandling.h"
120#include "llvm/Support/raw_ostream.h"
Benjamin Kramer1f8930e2014-07-25 11:42:14 +0000121#include "llvm/Target/TargetInstrInfo.h"
122#include "llvm/Target/TargetMachine.h"
123#include "llvm/Target/TargetRegisterInfo.h"
Tim Northover3b0846e2014-05-24 12:50:23 +0000124using namespace llvm;
125
126#define DEBUG_TYPE "aarch64-collect-loh"
127
128static cl::opt<bool>
129PreCollectRegister("aarch64-collect-loh-pre-collect-register", cl::Hidden,
130 cl::desc("Restrict analysis to registers invovled"
131 " in LOHs"),
132 cl::init(true));
133
134static cl::opt<bool>
135BasicBlockScopeOnly("aarch64-collect-loh-bb-only", cl::Hidden,
136 cl::desc("Restrict analysis at basic block scope"),
137 cl::init(true));
138
139STATISTIC(NumADRPSimpleCandidate,
140 "Number of simplifiable ADRP dominate by another");
141STATISTIC(NumADRPComplexCandidate2,
142 "Number of simplifiable ADRP reachable by 2 defs");
143STATISTIC(NumADRPComplexCandidate3,
144 "Number of simplifiable ADRP reachable by 3 defs");
145STATISTIC(NumADRPComplexCandidateOther,
146 "Number of simplifiable ADRP reachable by 4 or more defs");
147STATISTIC(NumADDToSTRWithImm,
148 "Number of simplifiable STR with imm reachable by ADD");
149STATISTIC(NumLDRToSTRWithImm,
150 "Number of simplifiable STR with imm reachable by LDR");
151STATISTIC(NumADDToSTR, "Number of simplifiable STR reachable by ADD");
152STATISTIC(NumLDRToSTR, "Number of simplifiable STR reachable by LDR");
153STATISTIC(NumADDToLDRWithImm,
154 "Number of simplifiable LDR with imm reachable by ADD");
155STATISTIC(NumLDRToLDRWithImm,
156 "Number of simplifiable LDR with imm reachable by LDR");
157STATISTIC(NumADDToLDR, "Number of simplifiable LDR reachable by ADD");
158STATISTIC(NumLDRToLDR, "Number of simplifiable LDR reachable by LDR");
159STATISTIC(NumADRPToLDR, "Number of simplifiable LDR reachable by ADRP");
160STATISTIC(NumCplxLvl1, "Number of complex case of level 1");
161STATISTIC(NumTooCplxLvl1, "Number of too complex case of level 1");
162STATISTIC(NumCplxLvl2, "Number of complex case of level 2");
163STATISTIC(NumTooCplxLvl2, "Number of too complex case of level 2");
164STATISTIC(NumADRSimpleCandidate, "Number of simplifiable ADRP + ADD");
165STATISTIC(NumADRComplexCandidate, "Number of too complex ADRP + ADD");
166
167namespace llvm {
168void initializeAArch64CollectLOHPass(PassRegistry &);
169}
170
171namespace {
172struct AArch64CollectLOH : public MachineFunctionPass {
173 static char ID;
174 AArch64CollectLOH() : MachineFunctionPass(ID) {
175 initializeAArch64CollectLOHPass(*PassRegistry::getPassRegistry());
176 }
177
178 bool runOnMachineFunction(MachineFunction &MF) override;
179
180 const char *getPassName() const override {
181 return "AArch64 Collect Linker Optimization Hint (LOH)";
182 }
183
184 void getAnalysisUsage(AnalysisUsage &AU) const override {
185 AU.setPreservesAll();
186 MachineFunctionPass::getAnalysisUsage(AU);
187 AU.addRequired<MachineDominatorTree>();
188 }
189
190private:
191};
192
193/// A set of MachineInstruction.
194typedef SetVector<const MachineInstr *> SetOfMachineInstr;
195/// Map a basic block to a set of instructions per register.
196/// This is used to represent the exposed uses of a basic block
197/// per register.
Dylan Noblesmithb8994642014-08-25 01:59:38 +0000198typedef MapVector<const MachineBasicBlock *,
199 std::unique_ptr<SetOfMachineInstr[]>>
Tim Northover3b0846e2014-05-24 12:50:23 +0000200BlockToSetOfInstrsPerColor;
201/// Map a basic block to an instruction per register.
202/// This is used to represent the live-out definitions of a basic block
203/// per register.
Dylan Noblesmithb8994642014-08-25 01:59:38 +0000204typedef MapVector<const MachineBasicBlock *,
205 std::unique_ptr<const MachineInstr *[]>>
Tim Northover3b0846e2014-05-24 12:50:23 +0000206BlockToInstrPerColor;
207/// Map an instruction to a set of instructions. Used to represent the
208/// mapping def to reachable uses or use to definitions.
209typedef MapVector<const MachineInstr *, SetOfMachineInstr> InstrToInstrs;
210/// Map a basic block to a BitVector.
211/// This is used to record the kill registers per basic block.
212typedef MapVector<const MachineBasicBlock *, BitVector> BlockToRegSet;
213
214/// Map a register to a dense id.
215typedef DenseMap<unsigned, unsigned> MapRegToId;
216/// Map a dense id to a register. Used for debug purposes.
217typedef SmallVector<unsigned, 32> MapIdToReg;
218} // end anonymous namespace.
219
220char AArch64CollectLOH::ID = 0;
221
222INITIALIZE_PASS_BEGIN(AArch64CollectLOH, "aarch64-collect-loh",
223 "AArch64 Collect Linker Optimization Hint (LOH)", false,
224 false)
225INITIALIZE_PASS_DEPENDENCY(MachineDominatorTree)
226INITIALIZE_PASS_END(AArch64CollectLOH, "aarch64-collect-loh",
227 "AArch64 Collect Linker Optimization Hint (LOH)", false,
228 false)
229
230/// Given a couple (MBB, reg) get the corresponding set of instruction from
231/// the given "sets".
232/// If this couple does not reference any set, an empty set is added to "sets"
233/// for this couple and returned.
234/// \param nbRegs is used internally allocate some memory. It must be consistent
235/// with the way sets is used.
236static SetOfMachineInstr &getSet(BlockToSetOfInstrsPerColor &sets,
237 const MachineBasicBlock &MBB, unsigned reg,
238 unsigned nbRegs) {
239 SetOfMachineInstr *result;
240 BlockToSetOfInstrsPerColor::iterator it = sets.find(&MBB);
241 if (it != sets.end())
Dylan Noblesmithb8994642014-08-25 01:59:38 +0000242 result = it->second.get();
Tim Northover3b0846e2014-05-24 12:50:23 +0000243 else
Dylan Noblesmithb8994642014-08-25 01:59:38 +0000244 result = (sets[&MBB] = make_unique<SetOfMachineInstr[]>(nbRegs)).get();
Tim Northover3b0846e2014-05-24 12:50:23 +0000245
246 return result[reg];
247}
248
249/// Given a couple (reg, MI) get the corresponding set of instructions from the
250/// the given "sets".
251/// This is used to get the uses record in sets of a definition identified by
252/// MI and reg, i.e., MI defines reg.
253/// If the couple does not reference anything, an empty set is added to
254/// "sets[reg]".
255/// \pre set[reg] is valid.
256static SetOfMachineInstr &getUses(InstrToInstrs *sets, unsigned reg,
257 const MachineInstr &MI) {
258 return sets[reg][&MI];
259}
260
261/// Same as getUses but does not modify the input map: sets.
262/// \return NULL if the couple (reg, MI) is not in sets.
263static const SetOfMachineInstr *getUses(const InstrToInstrs *sets, unsigned reg,
264 const MachineInstr &MI) {
265 InstrToInstrs::const_iterator Res = sets[reg].find(&MI);
266 if (Res != sets[reg].end())
267 return &(Res->second);
268 return nullptr;
269}
270
271/// Initialize the reaching definition algorithm:
272/// For each basic block BB in MF, record:
273/// - its kill set.
274/// - its reachable uses (uses that are exposed to BB's predecessors).
275/// - its the generated definitions.
276/// \param DummyOp if not NULL, specifies a Dummy Operation to be added to
277/// the list of uses of exposed defintions.
278/// \param ADRPMode specifies to only consider ADRP instructions for generated
279/// definition. It also consider definitions of ADRP instructions as uses and
280/// ignore other uses. The ADRPMode is used to collect the information for LHO
281/// that involve ADRP operation only.
282static void initReachingDef(MachineFunction &MF,
283 InstrToInstrs *ColorOpToReachedUses,
284 BlockToInstrPerColor &Gen, BlockToRegSet &Kill,
285 BlockToSetOfInstrsPerColor &ReachableUses,
286 const MapRegToId &RegToId,
287 const MachineInstr *DummyOp, bool ADRPMode) {
288 const TargetMachine &TM = MF.getTarget();
Eric Christopherd9134482014-08-04 21:25:23 +0000289 const TargetRegisterInfo *TRI = TM.getSubtargetImpl()->getRegisterInfo();
Tim Northover3b0846e2014-05-24 12:50:23 +0000290
291 unsigned NbReg = RegToId.size();
292
293 for (MachineBasicBlock &MBB : MF) {
Dylan Noblesmithb8994642014-08-25 01:59:38 +0000294 auto &BBGen = Gen[&MBB];
295 BBGen = make_unique<const MachineInstr *[]>(NbReg);
Dylan Noblesmith4af4d2c2014-08-26 03:33:26 +0000296 std::fill(BBGen.get(), BBGen.get() + NbReg, nullptr);
Tim Northover3b0846e2014-05-24 12:50:23 +0000297
298 BitVector &BBKillSet = Kill[&MBB];
299 BBKillSet.resize(NbReg);
300 for (const MachineInstr &MI : MBB) {
301 bool IsADRP = MI.getOpcode() == AArch64::ADRP;
302
303 // Process uses first.
304 if (IsADRP || !ADRPMode)
305 for (const MachineOperand &MO : MI.operands()) {
306 // Treat ADRP def as use, as the goal of the analysis is to find
307 // ADRP defs reached by other ADRP defs.
308 if (!MO.isReg() || (!ADRPMode && !MO.isUse()) ||
309 (ADRPMode && (!IsADRP || !MO.isDef())))
310 continue;
311 unsigned CurReg = MO.getReg();
312 MapRegToId::const_iterator ItCurRegId = RegToId.find(CurReg);
313 if (ItCurRegId == RegToId.end())
314 continue;
315 CurReg = ItCurRegId->second;
316
317 // if CurReg has not been defined, this use is reachable.
318 if (!BBGen[CurReg] && !BBKillSet.test(CurReg))
319 getSet(ReachableUses, MBB, CurReg, NbReg).insert(&MI);
320 // current basic block definition for this color, if any, is in Gen.
321 if (BBGen[CurReg])
322 getUses(ColorOpToReachedUses, CurReg, *BBGen[CurReg]).insert(&MI);
323 }
324
325 // Process clobbers.
326 for (const MachineOperand &MO : MI.operands()) {
327 if (!MO.isRegMask())
328 continue;
329 // Clobbers kill the related colors.
330 const uint32_t *PreservedRegs = MO.getRegMask();
331
332 // Set generated regs.
333 for (const auto Entry : RegToId) {
334 unsigned Reg = Entry.second;
335 // Use the global register ID when querying APIs external to this
336 // pass.
337 if (MachineOperand::clobbersPhysReg(PreservedRegs, Entry.first)) {
338 // Do not register clobbered definition for no ADRP.
339 // This definition is not used anyway (otherwise register
340 // allocation is wrong).
341 BBGen[Reg] = ADRPMode ? &MI : nullptr;
342 BBKillSet.set(Reg);
343 }
344 }
345 }
346
347 // Process register defs.
348 for (const MachineOperand &MO : MI.operands()) {
349 if (!MO.isReg() || !MO.isDef())
350 continue;
351 unsigned CurReg = MO.getReg();
352 MapRegToId::const_iterator ItCurRegId = RegToId.find(CurReg);
353 if (ItCurRegId == RegToId.end())
354 continue;
355
356 for (MCRegAliasIterator AI(CurReg, TRI, true); AI.isValid(); ++AI) {
357 MapRegToId::const_iterator ItRegId = RegToId.find(*AI);
358 assert(ItRegId != RegToId.end() &&
359 "Sub-register of an "
360 "involved register, not recorded as involved!");
361 BBKillSet.set(ItRegId->second);
362 BBGen[ItRegId->second] = &MI;
363 }
364 BBGen[ItCurRegId->second] = &MI;
365 }
366 }
367
368 // If we restrict our analysis to basic block scope, conservatively add a
369 // dummy
370 // use for each generated value.
371 if (!ADRPMode && DummyOp && !MBB.succ_empty())
372 for (unsigned CurReg = 0; CurReg < NbReg; ++CurReg)
373 if (BBGen[CurReg])
374 getUses(ColorOpToReachedUses, CurReg, *BBGen[CurReg]).insert(DummyOp);
375 }
376}
377
378/// Reaching def core algorithm:
379/// while an Out has changed
380/// for each bb
381/// for each color
382/// In[bb][color] = U Out[bb.predecessors][color]
383/// insert reachableUses[bb][color] in each in[bb][color]
384/// op.reachedUses
385///
386/// Out[bb] = Gen[bb] U (In[bb] - Kill[bb])
387static void reachingDefAlgorithm(MachineFunction &MF,
388 InstrToInstrs *ColorOpToReachedUses,
389 BlockToSetOfInstrsPerColor &In,
390 BlockToSetOfInstrsPerColor &Out,
391 BlockToInstrPerColor &Gen, BlockToRegSet &Kill,
392 BlockToSetOfInstrsPerColor &ReachableUses,
393 unsigned NbReg) {
394 bool HasChanged;
395 do {
396 HasChanged = false;
397 for (MachineBasicBlock &MBB : MF) {
398 unsigned CurReg;
399 for (CurReg = 0; CurReg < NbReg; ++CurReg) {
400 SetOfMachineInstr &BBInSet = getSet(In, MBB, CurReg, NbReg);
401 SetOfMachineInstr &BBReachableUses =
402 getSet(ReachableUses, MBB, CurReg, NbReg);
403 SetOfMachineInstr &BBOutSet = getSet(Out, MBB, CurReg, NbReg);
404 unsigned Size = BBOutSet.size();
405 // In[bb][color] = U Out[bb.predecessors][color]
406 for (MachineBasicBlock *PredMBB : MBB.predecessors()) {
407 SetOfMachineInstr &PredOutSet = getSet(Out, *PredMBB, CurReg, NbReg);
408 BBInSet.insert(PredOutSet.begin(), PredOutSet.end());
409 }
410 // insert reachableUses[bb][color] in each in[bb][color] op.reachedses
411 for (const MachineInstr *MI : BBInSet) {
412 SetOfMachineInstr &OpReachedUses =
413 getUses(ColorOpToReachedUses, CurReg, *MI);
414 OpReachedUses.insert(BBReachableUses.begin(), BBReachableUses.end());
415 }
416 // Out[bb] = Gen[bb] U (In[bb] - Kill[bb])
417 if (!Kill[&MBB].test(CurReg))
418 BBOutSet.insert(BBInSet.begin(), BBInSet.end());
419 if (Gen[&MBB][CurReg])
420 BBOutSet.insert(Gen[&MBB][CurReg]);
421 HasChanged |= BBOutSet.size() != Size;
422 }
423 }
424 } while (HasChanged);
425}
426
Tim Northover3b0846e2014-05-24 12:50:23 +0000427/// Reaching definition algorithm.
428/// \param MF function on which the algorithm will operate.
429/// \param[out] ColorOpToReachedUses will contain the result of the reaching
430/// def algorithm.
431/// \param ADRPMode specify whether the reaching def algorithm should be tuned
432/// for ADRP optimization. \see initReachingDef for more details.
433/// \param DummyOp if not NULL, the algorithm will work at
434/// basic block scope and will set for every exposed definition a use to
435/// @p DummyOp.
436/// \pre ColorOpToReachedUses is an array of at least number of registers of
437/// InstrToInstrs.
438static void reachingDef(MachineFunction &MF,
439 InstrToInstrs *ColorOpToReachedUses,
440 const MapRegToId &RegToId, bool ADRPMode = false,
441 const MachineInstr *DummyOp = nullptr) {
442 // structures:
443 // For each basic block.
444 // Out: a set per color of definitions that reach the
445 // out boundary of this block.
446 // In: Same as Out but for in boundary.
447 // Gen: generated color in this block (one operation per color).
448 // Kill: register set of killed color in this block.
449 // ReachableUses: a set per color of uses (operation) reachable
450 // for "In" definitions.
451 BlockToSetOfInstrsPerColor Out, In, ReachableUses;
452 BlockToInstrPerColor Gen;
453 BlockToRegSet Kill;
454
455 // Initialize Gen, kill and reachableUses.
456 initReachingDef(MF, ColorOpToReachedUses, Gen, Kill, ReachableUses, RegToId,
457 DummyOp, ADRPMode);
458
459 // Algo.
460 if (!DummyOp)
461 reachingDefAlgorithm(MF, ColorOpToReachedUses, In, Out, Gen, Kill,
462 ReachableUses, RegToId.size());
Tim Northover3b0846e2014-05-24 12:50:23 +0000463}
464
465#ifndef NDEBUG
466/// print the result of the reaching definition algorithm.
467static void printReachingDef(const InstrToInstrs *ColorOpToReachedUses,
468 unsigned NbReg, const TargetRegisterInfo *TRI,
469 const MapIdToReg &IdToReg) {
470 unsigned CurReg;
471 for (CurReg = 0; CurReg < NbReg; ++CurReg) {
472 if (ColorOpToReachedUses[CurReg].empty())
473 continue;
474 DEBUG(dbgs() << "*** Reg " << PrintReg(IdToReg[CurReg], TRI) << " ***\n");
475
476 for (const auto &DefsIt : ColorOpToReachedUses[CurReg]) {
477 DEBUG(dbgs() << "Def:\n");
478 DEBUG(DefsIt.first->print(dbgs()));
479 DEBUG(dbgs() << "Reachable uses:\n");
480 for (const MachineInstr *MI : DefsIt.second) {
481 DEBUG(MI->print(dbgs()));
482 }
483 }
484 }
485}
486#endif // NDEBUG
487
488/// Answer the following question: Can Def be one of the definition
489/// involved in a part of a LOH?
490static bool canDefBePartOfLOH(const MachineInstr *Def) {
491 unsigned Opc = Def->getOpcode();
492 // Accept ADRP, ADDLow and LOADGot.
493 switch (Opc) {
494 default:
495 return false;
496 case AArch64::ADRP:
497 return true;
498 case AArch64::ADDXri:
499 // Check immediate to see if the immediate is an address.
500 switch (Def->getOperand(2).getType()) {
501 default:
502 return false;
503 case MachineOperand::MO_GlobalAddress:
504 case MachineOperand::MO_JumpTableIndex:
505 case MachineOperand::MO_ConstantPoolIndex:
506 case MachineOperand::MO_BlockAddress:
507 return true;
508 }
509 case AArch64::LDRXui:
510 // Check immediate to see if the immediate is an address.
511 switch (Def->getOperand(2).getType()) {
512 default:
513 return false;
514 case MachineOperand::MO_GlobalAddress:
515 return true;
516 }
517 }
518 // Unreachable.
519 return false;
520}
521
522/// Check whether the given instruction can the end of a LOH chain involving a
523/// store.
524static bool isCandidateStore(const MachineInstr *Instr) {
525 switch (Instr->getOpcode()) {
526 default:
527 return false;
528 case AArch64::STRBui:
529 case AArch64::STRHui:
530 case AArch64::STRWui:
531 case AArch64::STRXui:
532 case AArch64::STRSui:
533 case AArch64::STRDui:
534 case AArch64::STRQui:
535 // In case we have str xA, [xA, #imm], this is two different uses
536 // of xA and we cannot fold, otherwise the xA stored may be wrong,
537 // even if #imm == 0.
538 if (Instr->getOperand(0).getReg() != Instr->getOperand(1).getReg())
539 return true;
540 }
541 return false;
542}
543
544/// Given the result of a reaching definition algorithm in ColorOpToReachedUses,
545/// Build the Use to Defs information and filter out obvious non-LOH candidates.
546/// In ADRPMode, non-LOH candidates are "uses" with non-ADRP definitions.
547/// In non-ADRPMode, non-LOH candidates are "uses" with several definition,
548/// i.e., no simple chain.
549/// \param ADRPMode -- \see initReachingDef.
550static void reachedUsesToDefs(InstrToInstrs &UseToReachingDefs,
551 const InstrToInstrs *ColorOpToReachedUses,
552 const MapRegToId &RegToId,
553 bool ADRPMode = false) {
554
555 SetOfMachineInstr NotCandidate;
556 unsigned NbReg = RegToId.size();
557 MapRegToId::const_iterator EndIt = RegToId.end();
558 for (unsigned CurReg = 0; CurReg < NbReg; ++CurReg) {
559 // If this color is never defined, continue.
560 if (ColorOpToReachedUses[CurReg].empty())
561 continue;
562
563 for (const auto &DefsIt : ColorOpToReachedUses[CurReg]) {
564 for (const MachineInstr *MI : DefsIt.second) {
565 const MachineInstr *Def = DefsIt.first;
566 MapRegToId::const_iterator It;
567 // if all the reaching defs are not adrp, this use will not be
568 // simplifiable.
569 if ((ADRPMode && Def->getOpcode() != AArch64::ADRP) ||
570 (!ADRPMode && !canDefBePartOfLOH(Def)) ||
571 (!ADRPMode && isCandidateStore(MI) &&
572 // store are LOH candidate iff the end of the chain is used as
573 // base.
574 ((It = RegToId.find((MI)->getOperand(1).getReg())) == EndIt ||
575 It->second != CurReg))) {
576 NotCandidate.insert(MI);
577 continue;
578 }
579 // Do not consider self reaching as a simplifiable case for ADRP.
580 if (!ADRPMode || MI != DefsIt.first) {
581 UseToReachingDefs[MI].insert(DefsIt.first);
582 // If UsesIt has several reaching definitions, it is not
583 // candidate for simplificaton in non-ADRPMode.
584 if (!ADRPMode && UseToReachingDefs[MI].size() > 1)
585 NotCandidate.insert(MI);
586 }
587 }
588 }
589 }
590 for (const MachineInstr *Elem : NotCandidate) {
591 DEBUG(dbgs() << "Too many reaching defs: " << *Elem << "\n");
592 // It would have been better if we could just remove the entry
593 // from the map. Because of that, we have to filter the garbage
594 // (second.empty) in the subsequence analysis.
595 UseToReachingDefs[Elem].clear();
596 }
597}
598
599/// Based on the use to defs information (in ADRPMode), compute the
600/// opportunities of LOH ADRP-related.
601static void computeADRP(const InstrToInstrs &UseToDefs,
602 AArch64FunctionInfo &AArch64FI,
603 const MachineDominatorTree *MDT) {
604 DEBUG(dbgs() << "*** Compute LOH for ADRP\n");
605 for (const auto &Entry : UseToDefs) {
606 unsigned Size = Entry.second.size();
607 if (Size == 0)
608 continue;
609 if (Size == 1) {
610 const MachineInstr *L2 = *Entry.second.begin();
611 const MachineInstr *L1 = Entry.first;
612 if (!MDT->dominates(L2, L1)) {
613 DEBUG(dbgs() << "Dominance check failed:\n" << *L2 << '\n' << *L1
614 << '\n');
615 continue;
616 }
617 DEBUG(dbgs() << "Record AdrpAdrp:\n" << *L2 << '\n' << *L1 << '\n');
618 SmallVector<const MachineInstr *, 2> Args;
619 Args.push_back(L2);
620 Args.push_back(L1);
621 AArch64FI.addLOHDirective(MCLOH_AdrpAdrp, Args);
622 ++NumADRPSimpleCandidate;
623 }
624#ifdef DEBUG
625 else if (Size == 2)
626 ++NumADRPComplexCandidate2;
627 else if (Size == 3)
628 ++NumADRPComplexCandidate3;
629 else
630 ++NumADRPComplexCandidateOther;
631#endif
632 // if Size < 1, the use should have been removed from the candidates
633 assert(Size >= 1 && "No reaching defs for that use!");
634 }
635}
636
637/// Check whether the given instruction can be the end of a LOH chain
638/// involving a load.
639static bool isCandidateLoad(const MachineInstr *Instr) {
640 switch (Instr->getOpcode()) {
641 default:
642 return false;
643 case AArch64::LDRSBWui:
644 case AArch64::LDRSBXui:
645 case AArch64::LDRSHWui:
646 case AArch64::LDRSHXui:
647 case AArch64::LDRSWui:
648 case AArch64::LDRBui:
649 case AArch64::LDRHui:
650 case AArch64::LDRWui:
651 case AArch64::LDRXui:
652 case AArch64::LDRSui:
653 case AArch64::LDRDui:
654 case AArch64::LDRQui:
655 if (Instr->getOperand(2).getTargetFlags() & AArch64II::MO_GOT)
656 return false;
657 return true;
658 }
659 // Unreachable.
660 return false;
661}
662
663/// Check whether the given instruction can load a litteral.
664static bool supportLoadFromLiteral(const MachineInstr *Instr) {
665 switch (Instr->getOpcode()) {
666 default:
667 return false;
668 case AArch64::LDRSWui:
669 case AArch64::LDRWui:
670 case AArch64::LDRXui:
671 case AArch64::LDRSui:
672 case AArch64::LDRDui:
673 case AArch64::LDRQui:
674 return true;
675 }
676 // Unreachable.
677 return false;
678}
679
680/// Check whether the given instruction is a LOH candidate.
681/// \param UseToDefs is used to check that Instr is at the end of LOH supported
682/// chain.
683/// \pre UseToDefs contains only on def per use, i.e., obvious non candidate are
684/// already been filtered out.
685static bool isCandidate(const MachineInstr *Instr,
686 const InstrToInstrs &UseToDefs,
687 const MachineDominatorTree *MDT) {
688 if (!isCandidateLoad(Instr) && !isCandidateStore(Instr))
689 return false;
690
691 const MachineInstr *Def = *UseToDefs.find(Instr)->second.begin();
692 if (Def->getOpcode() != AArch64::ADRP) {
693 // At this point, Def is ADDXri or LDRXui of the right type of
694 // symbol, because we filtered out the uses that were not defined
695 // by these kind of instructions (+ ADRP).
696
697 // Check if this forms a simple chain: each intermediate node must
698 // dominates the next one.
699 if (!MDT->dominates(Def, Instr))
700 return false;
701 // Move one node up in the simple chain.
702 if (UseToDefs.find(Def) ==
703 UseToDefs.end()
704 // The map may contain garbage we have to ignore.
705 ||
706 UseToDefs.find(Def)->second.empty())
707 return false;
708 Instr = Def;
709 Def = *UseToDefs.find(Def)->second.begin();
710 }
711 // Check if we reached the top of the simple chain:
712 // - top is ADRP.
713 // - check the simple chain property: each intermediate node must
714 // dominates the next one.
715 if (Def->getOpcode() == AArch64::ADRP)
716 return MDT->dominates(Def, Instr);
717 return false;
718}
719
720static bool registerADRCandidate(const MachineInstr &Use,
721 const InstrToInstrs &UseToDefs,
722 const InstrToInstrs *DefsPerColorToUses,
723 AArch64FunctionInfo &AArch64FI,
724 SetOfMachineInstr *InvolvedInLOHs,
725 const MapRegToId &RegToId) {
726 // Look for opportunities to turn ADRP -> ADD or
727 // ADRP -> LDR GOTPAGEOFF into ADR.
728 // If ADRP has more than one use. Give up.
729 if (Use.getOpcode() != AArch64::ADDXri &&
730 (Use.getOpcode() != AArch64::LDRXui ||
731 !(Use.getOperand(2).getTargetFlags() & AArch64II::MO_GOT)))
732 return false;
733 InstrToInstrs::const_iterator It = UseToDefs.find(&Use);
734 // The map may contain garbage that we need to ignore.
735 if (It == UseToDefs.end() || It->second.empty())
736 return false;
737 const MachineInstr &Def = **It->second.begin();
738 if (Def.getOpcode() != AArch64::ADRP)
739 return false;
740 // Check the number of users of ADRP.
741 const SetOfMachineInstr *Users =
742 getUses(DefsPerColorToUses,
743 RegToId.find(Def.getOperand(0).getReg())->second, Def);
744 if (Users->size() > 1) {
745 ++NumADRComplexCandidate;
746 return false;
747 }
748 ++NumADRSimpleCandidate;
749 assert((!InvolvedInLOHs || InvolvedInLOHs->insert(&Def)) &&
750 "ADRP already involved in LOH.");
751 assert((!InvolvedInLOHs || InvolvedInLOHs->insert(&Use)) &&
752 "ADD already involved in LOH.");
753 DEBUG(dbgs() << "Record AdrpAdd\n" << Def << '\n' << Use << '\n');
754
755 SmallVector<const MachineInstr *, 2> Args;
756 Args.push_back(&Def);
757 Args.push_back(&Use);
758
759 AArch64FI.addLOHDirective(Use.getOpcode() == AArch64::ADDXri ? MCLOH_AdrpAdd
760 : MCLOH_AdrpLdrGot,
761 Args);
762 return true;
763}
764
765/// Based on the use to defs information (in non-ADRPMode), compute the
766/// opportunities of LOH non-ADRP-related
767static void computeOthers(const InstrToInstrs &UseToDefs,
768 const InstrToInstrs *DefsPerColorToUses,
769 AArch64FunctionInfo &AArch64FI, const MapRegToId &RegToId,
770 const MachineDominatorTree *MDT) {
771 SetOfMachineInstr *InvolvedInLOHs = nullptr;
772#ifdef DEBUG
773 SetOfMachineInstr InvolvedInLOHsStorage;
774 InvolvedInLOHs = &InvolvedInLOHsStorage;
775#endif // DEBUG
776 DEBUG(dbgs() << "*** Compute LOH for Others\n");
777 // ADRP -> ADD/LDR -> LDR/STR pattern.
778 // Fall back to ADRP -> ADD pattern if we fail to catch the bigger pattern.
779
780 // FIXME: When the statistics are not important,
781 // This initial filtering loop can be merged into the next loop.
782 // Currently, we didn't do it to have the same code for both DEBUG and
783 // NDEBUG builds. Indeed, the iterator of the second loop would need
784 // to be changed.
785 SetOfMachineInstr PotentialCandidates;
786 SetOfMachineInstr PotentialADROpportunities;
787 for (auto &Use : UseToDefs) {
788 // If no definition is available, this is a non candidate.
789 if (Use.second.empty())
790 continue;
791 // Keep only instructions that are load or store and at the end of
792 // a ADRP -> ADD/LDR/Nothing chain.
793 // We already filtered out the no-chain cases.
794 if (!isCandidate(Use.first, UseToDefs, MDT)) {
795 PotentialADROpportunities.insert(Use.first);
796 continue;
797 }
798 PotentialCandidates.insert(Use.first);
799 }
800
801 // Make the following distinctions for statistics as the linker does
802 // know how to decode instructions:
803 // - ADD/LDR/Nothing make there different patterns.
804 // - LDR/STR make two different patterns.
805 // Hence, 6 - 1 base patterns.
806 // (because ADRP-> Nothing -> STR is not simplifiable)
807
808 // The linker is only able to have a simple semantic, i.e., if pattern A
809 // do B.
810 // However, we want to see the opportunity we may miss if we were able to
811 // catch more complex cases.
812
813 // PotentialCandidates are result of a chain ADRP -> ADD/LDR ->
814 // A potential candidate becomes a candidate, if its current immediate
815 // operand is zero and all nodes of the chain have respectively only one user
816#ifdef DEBUG
817 SetOfMachineInstr DefsOfPotentialCandidates;
818#endif
819 for (const MachineInstr *Candidate : PotentialCandidates) {
820 // Get the definition of the candidate i.e., ADD or LDR.
821 const MachineInstr *Def = *UseToDefs.find(Candidate)->second.begin();
822 // Record the elements of the chain.
823 const MachineInstr *L1 = Def;
824 const MachineInstr *L2 = nullptr;
825 unsigned ImmediateDefOpc = Def->getOpcode();
826 if (Def->getOpcode() != AArch64::ADRP) {
827 // Check the number of users of this node.
828 const SetOfMachineInstr *Users =
829 getUses(DefsPerColorToUses,
830 RegToId.find(Def->getOperand(0).getReg())->second, *Def);
831 if (Users->size() > 1) {
832#ifdef DEBUG
833 // if all the uses of this def are in potential candidate, this is
834 // a complex candidate of level 2.
835 bool IsLevel2 = true;
836 for (const MachineInstr *MI : *Users) {
837 if (!PotentialCandidates.count(MI)) {
838 ++NumTooCplxLvl2;
839 IsLevel2 = false;
840 break;
841 }
842 }
843 if (IsLevel2)
844 ++NumCplxLvl2;
845#endif // DEBUG
846 PotentialADROpportunities.insert(Def);
847 continue;
848 }
849 L2 = Def;
850 Def = *UseToDefs.find(Def)->second.begin();
851 L1 = Def;
852 } // else the element in the middle of the chain is nothing, thus
853 // Def already contains the first element of the chain.
854
855 // Check the number of users of the first node in the chain, i.e., ADRP
856 const SetOfMachineInstr *Users =
857 getUses(DefsPerColorToUses,
858 RegToId.find(Def->getOperand(0).getReg())->second, *Def);
859 if (Users->size() > 1) {
860#ifdef DEBUG
861 // if all the uses of this def are in the defs of the potential candidate,
862 // this is a complex candidate of level 1
863 if (DefsOfPotentialCandidates.empty()) {
864 // lazy init
865 DefsOfPotentialCandidates = PotentialCandidates;
866 for (const MachineInstr *Candidate : PotentialCandidates) {
867 if (!UseToDefs.find(Candidate)->second.empty())
868 DefsOfPotentialCandidates.insert(
869 *UseToDefs.find(Candidate)->second.begin());
870 }
871 }
872 bool Found = false;
873 for (auto &Use : *Users) {
874 if (!DefsOfPotentialCandidates.count(Use)) {
875 ++NumTooCplxLvl1;
876 Found = true;
877 break;
878 }
879 }
880 if (!Found)
881 ++NumCplxLvl1;
882#endif // DEBUG
883 continue;
884 }
885
886 bool IsL2Add = (ImmediateDefOpc == AArch64::ADDXri);
887 // If the chain is three instructions long and ldr is the second element,
888 // then this ldr must load form GOT, otherwise this is not a correct chain.
889 if (L2 && !IsL2Add && L2->getOperand(2).getTargetFlags() != AArch64II::MO_GOT)
890 continue;
891 SmallVector<const MachineInstr *, 3> Args;
892 MCLOHType Kind;
893 if (isCandidateLoad(Candidate)) {
894 if (!L2) {
895 // At this point, the candidate LOH indicates that the ldr instruction
896 // may use a direct access to the symbol. There is not such encoding
897 // for loads of byte and half.
898 if (!supportLoadFromLiteral(Candidate))
899 continue;
900
901 DEBUG(dbgs() << "Record AdrpLdr:\n" << *L1 << '\n' << *Candidate
902 << '\n');
903 Kind = MCLOH_AdrpLdr;
904 Args.push_back(L1);
905 Args.push_back(Candidate);
906 assert((!InvolvedInLOHs || InvolvedInLOHs->insert(L1)) &&
907 "L1 already involved in LOH.");
908 assert((!InvolvedInLOHs || InvolvedInLOHs->insert(Candidate)) &&
909 "Candidate already involved in LOH.");
910 ++NumADRPToLDR;
911 } else {
912 DEBUG(dbgs() << "Record Adrp" << (IsL2Add ? "Add" : "LdrGot")
913 << "Ldr:\n" << *L1 << '\n' << *L2 << '\n' << *Candidate
914 << '\n');
915
916 Kind = IsL2Add ? MCLOH_AdrpAddLdr : MCLOH_AdrpLdrGotLdr;
917 Args.push_back(L1);
918 Args.push_back(L2);
919 Args.push_back(Candidate);
920
921 PotentialADROpportunities.remove(L2);
922 assert((!InvolvedInLOHs || InvolvedInLOHs->insert(L1)) &&
923 "L1 already involved in LOH.");
924 assert((!InvolvedInLOHs || InvolvedInLOHs->insert(L2)) &&
925 "L2 already involved in LOH.");
926 assert((!InvolvedInLOHs || InvolvedInLOHs->insert(Candidate)) &&
927 "Candidate already involved in LOH.");
928#ifdef DEBUG
929 // get the immediate of the load
930 if (Candidate->getOperand(2).getImm() == 0)
931 if (ImmediateDefOpc == AArch64::ADDXri)
932 ++NumADDToLDR;
933 else
934 ++NumLDRToLDR;
935 else if (ImmediateDefOpc == AArch64::ADDXri)
936 ++NumADDToLDRWithImm;
937 else
938 ++NumLDRToLDRWithImm;
939#endif // DEBUG
940 }
941 } else {
942 if (ImmediateDefOpc == AArch64::ADRP)
943 continue;
944 else {
945
946 DEBUG(dbgs() << "Record Adrp" << (IsL2Add ? "Add" : "LdrGot")
947 << "Str:\n" << *L1 << '\n' << *L2 << '\n' << *Candidate
948 << '\n');
949
950 Kind = IsL2Add ? MCLOH_AdrpAddStr : MCLOH_AdrpLdrGotStr;
951 Args.push_back(L1);
952 Args.push_back(L2);
953 Args.push_back(Candidate);
954
955 PotentialADROpportunities.remove(L2);
956 assert((!InvolvedInLOHs || InvolvedInLOHs->insert(L1)) &&
957 "L1 already involved in LOH.");
958 assert((!InvolvedInLOHs || InvolvedInLOHs->insert(L2)) &&
959 "L2 already involved in LOH.");
960 assert((!InvolvedInLOHs || InvolvedInLOHs->insert(Candidate)) &&
961 "Candidate already involved in LOH.");
962#ifdef DEBUG
963 // get the immediate of the store
964 if (Candidate->getOperand(2).getImm() == 0)
965 if (ImmediateDefOpc == AArch64::ADDXri)
966 ++NumADDToSTR;
967 else
968 ++NumLDRToSTR;
969 else if (ImmediateDefOpc == AArch64::ADDXri)
970 ++NumADDToSTRWithImm;
971 else
972 ++NumLDRToSTRWithImm;
973#endif // DEBUG
974 }
975 }
976 AArch64FI.addLOHDirective(Kind, Args);
977 }
978
979 // Now, we grabbed all the big patterns, check ADR opportunities.
980 for (const MachineInstr *Candidate : PotentialADROpportunities)
981 registerADRCandidate(*Candidate, UseToDefs, DefsPerColorToUses, AArch64FI,
982 InvolvedInLOHs, RegToId);
983}
984
985/// Look for every register defined by potential LOHs candidates.
986/// Map these registers with dense id in @p RegToId and vice-versa in
987/// @p IdToReg. @p IdToReg is populated only in DEBUG mode.
988static void collectInvolvedReg(MachineFunction &MF, MapRegToId &RegToId,
989 MapIdToReg &IdToReg,
990 const TargetRegisterInfo *TRI) {
991 unsigned CurRegId = 0;
992 if (!PreCollectRegister) {
993 unsigned NbReg = TRI->getNumRegs();
994 for (; CurRegId < NbReg; ++CurRegId) {
995 RegToId[CurRegId] = CurRegId;
996 DEBUG(IdToReg.push_back(CurRegId));
997 DEBUG(assert(IdToReg[CurRegId] == CurRegId && "Reg index mismatches"));
998 }
999 return;
1000 }
1001
1002 DEBUG(dbgs() << "** Collect Involved Register\n");
1003 for (const auto &MBB : MF) {
1004 for (const MachineInstr &MI : MBB) {
1005 if (!canDefBePartOfLOH(&MI))
1006 continue;
1007
1008 // Process defs
1009 for (MachineInstr::const_mop_iterator IO = MI.operands_begin(),
1010 IOEnd = MI.operands_end();
1011 IO != IOEnd; ++IO) {
1012 if (!IO->isReg() || !IO->isDef())
1013 continue;
1014 unsigned CurReg = IO->getReg();
1015 for (MCRegAliasIterator AI(CurReg, TRI, true); AI.isValid(); ++AI)
1016 if (RegToId.find(*AI) == RegToId.end()) {
1017 DEBUG(IdToReg.push_back(*AI);
1018 assert(IdToReg[CurRegId] == *AI &&
1019 "Reg index mismatches insertion index."));
1020 RegToId[*AI] = CurRegId++;
1021 DEBUG(dbgs() << "Register: " << PrintReg(*AI, TRI) << '\n');
1022 }
1023 }
1024 }
1025 }
1026}
1027
1028bool AArch64CollectLOH::runOnMachineFunction(MachineFunction &MF) {
1029 const TargetMachine &TM = MF.getTarget();
Eric Christopherd9134482014-08-04 21:25:23 +00001030 const TargetRegisterInfo *TRI = TM.getSubtargetImpl()->getRegisterInfo();
Tim Northover3b0846e2014-05-24 12:50:23 +00001031 const MachineDominatorTree *MDT = &getAnalysis<MachineDominatorTree>();
1032
1033 MapRegToId RegToId;
1034 MapIdToReg IdToReg;
1035 AArch64FunctionInfo *AArch64FI = MF.getInfo<AArch64FunctionInfo>();
1036 assert(AArch64FI && "No MachineFunctionInfo for this function!");
1037
1038 DEBUG(dbgs() << "Looking for LOH in " << MF.getName() << '\n');
1039
1040 collectInvolvedReg(MF, RegToId, IdToReg, TRI);
1041 if (RegToId.empty())
1042 return false;
1043
1044 MachineInstr *DummyOp = nullptr;
1045 if (BasicBlockScopeOnly) {
Eric Christopherd9134482014-08-04 21:25:23 +00001046 const AArch64InstrInfo *TII = static_cast<const AArch64InstrInfo *>(
1047 TM.getSubtargetImpl()->getInstrInfo());
Tim Northover3b0846e2014-05-24 12:50:23 +00001048 // For local analysis, create a dummy operation to record uses that are not
1049 // local.
1050 DummyOp = MF.CreateMachineInstr(TII->get(AArch64::COPY), DebugLoc());
1051 }
1052
1053 unsigned NbReg = RegToId.size();
1054 bool Modified = false;
1055
1056 // Start with ADRP.
Dylan Noblesmithb06f77b2014-08-26 02:03:43 +00001057 InstrToInstrs *ColorOpToReachedUses = new InstrToInstrs[NbReg];
Tim Northover3b0846e2014-05-24 12:50:23 +00001058
1059 // Compute the reaching def in ADRP mode, meaning ADRP definitions
1060 // are first considered as uses.
1061 reachingDef(MF, ColorOpToReachedUses, RegToId, true, DummyOp);
1062 DEBUG(dbgs() << "ADRP reaching defs\n");
1063 DEBUG(printReachingDef(ColorOpToReachedUses, NbReg, TRI, IdToReg));
1064
1065 // Translate the definition to uses map into a use to definitions map to ease
1066 // statistic computation.
1067 InstrToInstrs ADRPToReachingDefs;
1068 reachedUsesToDefs(ADRPToReachingDefs, ColorOpToReachedUses, RegToId, true);
1069
1070 // Compute LOH for ADRP.
1071 computeADRP(ADRPToReachingDefs, *AArch64FI, MDT);
Dylan Noblesmithb06f77b2014-08-26 02:03:43 +00001072 delete[] ColorOpToReachedUses;
1073
Tim Northover3b0846e2014-05-24 12:50:23 +00001074 // Continue with general ADRP -> ADD/LDR -> LDR/STR pattern.
Dylan Noblesmithb06f77b2014-08-26 02:03:43 +00001075 ColorOpToReachedUses = new InstrToInstrs[NbReg];
Tim Northover3b0846e2014-05-24 12:50:23 +00001076
1077 // first perform a regular reaching def analysis.
1078 reachingDef(MF, ColorOpToReachedUses, RegToId, false, DummyOp);
1079 DEBUG(dbgs() << "All reaching defs\n");
1080 DEBUG(printReachingDef(ColorOpToReachedUses, NbReg, TRI, IdToReg));
1081
1082 // Turn that into a use to defs to ease statistic computation.
1083 InstrToInstrs UsesToReachingDefs;
1084 reachedUsesToDefs(UsesToReachingDefs, ColorOpToReachedUses, RegToId, false);
1085
1086 // Compute other than AdrpAdrp LOH.
1087 computeOthers(UsesToReachingDefs, ColorOpToReachedUses, *AArch64FI, RegToId,
1088 MDT);
Dylan Noblesmithb06f77b2014-08-26 02:03:43 +00001089 delete[] ColorOpToReachedUses;
Tim Northover3b0846e2014-05-24 12:50:23 +00001090
1091 if (BasicBlockScopeOnly)
1092 MF.DeleteMachineInstr(DummyOp);
1093
1094 return Modified;
1095}
1096
1097/// createAArch64CollectLOHPass - returns an instance of the Statistic for
1098/// linker optimization pass.
1099FunctionPass *llvm::createAArch64CollectLOHPass() {
1100 return new AArch64CollectLOH();
1101}