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