1 //=- AArch64LoadStoreOptimizer.cpp - AArch64 load/store opt. pass -*- C++ -*-=//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file contains a pass that performs load / store related peephole
11 // optimizations. This pass should be run after register allocation.
12 //
13 //===----------------------------------------------------------------------===//
14 
15 #include "AArch64InstrInfo.h"
16 #include "AArch64Subtarget.h"
17 #include "MCTargetDesc/AArch64AddressingModes.h"
18 #include "llvm/ADT/BitVector.h"
19 #include "llvm/ADT/SmallVector.h"
20 #include "llvm/ADT/Statistic.h"
21 #include "llvm/CodeGen/MachineBasicBlock.h"
22 #include "llvm/CodeGen/MachineFunctionPass.h"
23 #include "llvm/CodeGen/MachineInstr.h"
24 #include "llvm/CodeGen/MachineInstrBuilder.h"
25 #include "llvm/Support/CommandLine.h"
26 #include "llvm/Support/Debug.h"
27 #include "llvm/Support/ErrorHandling.h"
28 #include "llvm/Support/raw_ostream.h"
29 #include "llvm/Target/TargetInstrInfo.h"
30 #include "llvm/Target/TargetMachine.h"
31 #include "llvm/Target/TargetRegisterInfo.h"
32 using namespace llvm;
33 
34 #define DEBUG_TYPE "aarch64-ldst-opt"
35 
36 STATISTIC(NumPairCreated, "Number of load/store pair instructions generated");
37 STATISTIC(NumPostFolded, "Number of post-index updates folded");
38 STATISTIC(NumPreFolded, "Number of pre-index updates folded");
39 STATISTIC(NumUnscaledPairCreated,
40           "Number of load/store from unscaled generated");
41 STATISTIC(NumNarrowLoadsPromoted, "Number of narrow loads promoted");
42 STATISTIC(NumZeroStoresPromoted, "Number of narrow zero stores promoted");
43 STATISTIC(NumLoadsFromStoresPromoted, "Number of loads from stores promoted");
44 
45 // The LdStLimit limits how far we search for load/store pairs.
46 static cl::opt<unsigned> LdStLimit("aarch64-load-store-scan-limit",
47                                    cl::init(20), cl::Hidden);
48 
49 // The UpdateLimit limits how far we search for update instructions when we form
50 // pre-/post-index instructions.
51 static cl::opt<unsigned> UpdateLimit("aarch64-update-scan-limit", cl::init(100),
52                                      cl::Hidden);
53 
54 namespace llvm {
55 void initializeAArch64LoadStoreOptPass(PassRegistry &);
56 }
57 
58 #define AARCH64_LOAD_STORE_OPT_NAME "AArch64 load / store optimization pass"
59 
60 namespace {
61 
62 typedef struct LdStPairFlags {
63   // If a matching instruction is found, MergeForward is set to true if the
64   // merge is to remove the first instruction and replace the second with
65   // a pair-wise insn, and false if the reverse is true.
66   bool MergeForward;
67 
68   // SExtIdx gives the index of the result of the load pair that must be
69   // extended. The value of SExtIdx assumes that the paired load produces the
70   // value in this order: (I, returned iterator), i.e., -1 means no value has
71   // to be extended, 0 means I, and 1 means the returned iterator.
72   int SExtIdx;
73 
74   LdStPairFlags() : MergeForward(false), SExtIdx(-1) {}
75 
76   void setMergeForward(bool V = true) { MergeForward = V; }
77   bool getMergeForward() const { return MergeForward; }
78 
79   void setSExtIdx(int V) { SExtIdx = V; }
80   int getSExtIdx() const { return SExtIdx; }
81 
82 } LdStPairFlags;
83 
84 struct AArch64LoadStoreOpt : public MachineFunctionPass {
85   static char ID;
86   AArch64LoadStoreOpt() : MachineFunctionPass(ID) {
87     initializeAArch64LoadStoreOptPass(*PassRegistry::getPassRegistry());
88   }
89 
90   const AArch64InstrInfo *TII;
91   const TargetRegisterInfo *TRI;
92   const AArch64Subtarget *Subtarget;
93 
94   // Track which registers have been modified and used.
95   BitVector ModifiedRegs, UsedRegs;
96 
97   // Scan the instructions looking for a load/store that can be combined
98   // with the current instruction into a load/store pair.
99   // Return the matching instruction if one is found, else MBB->end().
100   MachineBasicBlock::iterator findMatchingInsn(MachineBasicBlock::iterator I,
101                                                LdStPairFlags &Flags,
102                                                unsigned Limit);
103 
104   // Scan the instructions looking for a store that writes to the address from
105   // which the current load instruction reads. Return true if one is found.
106   bool findMatchingStore(MachineBasicBlock::iterator I, unsigned Limit,
107                          MachineBasicBlock::iterator &StoreI);
108 
109   // Merge the two instructions indicated into a wider instruction.
110   MachineBasicBlock::iterator
111   mergeNarrowInsns(MachineBasicBlock::iterator I,
112                    MachineBasicBlock::iterator MergeMI,
113                    const LdStPairFlags &Flags);
114 
115   // Merge the two instructions indicated into a single pair-wise instruction.
116   MachineBasicBlock::iterator
117   mergePairedInsns(MachineBasicBlock::iterator I,
118                    MachineBasicBlock::iterator Paired,
119                    const LdStPairFlags &Flags);
120 
121   // Promote the load that reads directly from the address stored to.
122   MachineBasicBlock::iterator
123   promoteLoadFromStore(MachineBasicBlock::iterator LoadI,
124                        MachineBasicBlock::iterator StoreI);
125 
126   // Scan the instruction list to find a base register update that can
127   // be combined with the current instruction (a load or store) using
128   // pre or post indexed addressing with writeback. Scan forwards.
129   MachineBasicBlock::iterator
130   findMatchingUpdateInsnForward(MachineBasicBlock::iterator I,
131                                 int UnscaledOffset, unsigned Limit);
132 
133   // Scan the instruction list to find a base register update that can
134   // be combined with the current instruction (a load or store) using
135   // pre or post indexed addressing with writeback. Scan backwards.
136   MachineBasicBlock::iterator
137   findMatchingUpdateInsnBackward(MachineBasicBlock::iterator I, unsigned Limit);
138 
139   // Find an instruction that updates the base register of the ld/st
140   // instruction.
141   bool isMatchingUpdateInsn(MachineInstr *MemMI, MachineInstr *MI,
142                             unsigned BaseReg, int Offset);
143 
144   // Merge a pre- or post-index base register update into a ld/st instruction.
145   MachineBasicBlock::iterator
146   mergeUpdateInsn(MachineBasicBlock::iterator I,
147                   MachineBasicBlock::iterator Update, bool IsPreIdx);
148 
149   // Is this a candidate for ld/st merging or pairing?  For example, we don't
150   // touch volatiles or load/stores that have a hint to avoid pair formation.
151   bool isCandidateToMergeOrPair(MachineInstr *MI);
152 
153   // Find and merge foldable ldr/str instructions.
154   bool tryToMergeLdStInst(MachineBasicBlock::iterator &MBBI);
155 
156   // Find and pair ldr/str instructions.
157   bool tryToPairLdStInst(MachineBasicBlock::iterator &MBBI);
158 
159   // Find and promote load instructions which read directly from store.
160   bool tryToPromoteLoadFromStore(MachineBasicBlock::iterator &MBBI);
161 
162   // Check if converting two narrow loads into a single wider load with
163   // bitfield extracts could be enabled.
164   bool enableNarrowLdMerge(MachineFunction &Fn);
165 
166   bool optimizeBlock(MachineBasicBlock &MBB, bool enableNarrowLdOpt);
167 
168   bool runOnMachineFunction(MachineFunction &Fn) override;
169 
170   const char *getPassName() const override {
171     return AARCH64_LOAD_STORE_OPT_NAME;
172   }
173 };
174 char AArch64LoadStoreOpt::ID = 0;
175 } // namespace
176 
177 INITIALIZE_PASS(AArch64LoadStoreOpt, "aarch64-ldst-opt",
178                 AARCH64_LOAD_STORE_OPT_NAME, false, false)
179 
180 static bool isUnscaledLdSt(unsigned Opc) {
181   switch (Opc) {
182   default:
183     return false;
184   case AArch64::STURSi:
185   case AArch64::STURDi:
186   case AArch64::STURQi:
187   case AArch64::STURBBi:
188   case AArch64::STURHHi:
189   case AArch64::STURWi:
190   case AArch64::STURXi:
191   case AArch64::LDURSi:
192   case AArch64::LDURDi:
193   case AArch64::LDURQi:
194   case AArch64::LDURWi:
195   case AArch64::LDURXi:
196   case AArch64::LDURSWi:
197   case AArch64::LDURHHi:
198   case AArch64::LDURBBi:
199   case AArch64::LDURSBWi:
200   case AArch64::LDURSHWi:
201     return true;
202   }
203 }
204 
205 static bool isUnscaledLdSt(MachineInstr *MI) {
206   return isUnscaledLdSt(MI->getOpcode());
207 }
208 
209 static unsigned getBitExtrOpcode(MachineInstr *MI) {
210   switch (MI->getOpcode()) {
211   default:
212     llvm_unreachable("Unexpected opcode.");
213   case AArch64::LDRBBui:
214   case AArch64::LDURBBi:
215   case AArch64::LDRHHui:
216   case AArch64::LDURHHi:
217     return AArch64::UBFMWri;
218   case AArch64::LDRSBWui:
219   case AArch64::LDURSBWi:
220   case AArch64::LDRSHWui:
221   case AArch64::LDURSHWi:
222     return AArch64::SBFMWri;
223   }
224 }
225 
226 static bool isNarrowStore(unsigned Opc) {
227   switch (Opc) {
228   default:
229     return false;
230   case AArch64::STRBBui:
231   case AArch64::STURBBi:
232   case AArch64::STRHHui:
233   case AArch64::STURHHi:
234     return true;
235   }
236 }
237 
238 static bool isNarrowLoad(unsigned Opc) {
239   switch (Opc) {
240   default:
241     return false;
242   case AArch64::LDRHHui:
243   case AArch64::LDURHHi:
244   case AArch64::LDRBBui:
245   case AArch64::LDURBBi:
246   case AArch64::LDRSHWui:
247   case AArch64::LDURSHWi:
248   case AArch64::LDRSBWui:
249   case AArch64::LDURSBWi:
250     return true;
251   }
252 }
253 
254 static bool isNarrowLoad(MachineInstr *MI) {
255   return isNarrowLoad(MI->getOpcode());
256 }
257 
258 static bool isNarrowLoadOrStore(unsigned Opc) {
259   return isNarrowLoad(Opc) || isNarrowStore(Opc);
260 }
261 
262 // Scaling factor for unscaled load or store.
263 static int getMemScale(MachineInstr *MI) {
264   switch (MI->getOpcode()) {
265   default:
266     llvm_unreachable("Opcode has unknown scale!");
267   case AArch64::LDRBBui:
268   case AArch64::LDURBBi:
269   case AArch64::LDRSBWui:
270   case AArch64::LDURSBWi:
271   case AArch64::STRBBui:
272   case AArch64::STURBBi:
273     return 1;
274   case AArch64::LDRHHui:
275   case AArch64::LDURHHi:
276   case AArch64::LDRSHWui:
277   case AArch64::LDURSHWi:
278   case AArch64::STRHHui:
279   case AArch64::STURHHi:
280     return 2;
281   case AArch64::LDRSui:
282   case AArch64::LDURSi:
283   case AArch64::LDRSWui:
284   case AArch64::LDURSWi:
285   case AArch64::LDRWui:
286   case AArch64::LDURWi:
287   case AArch64::STRSui:
288   case AArch64::STURSi:
289   case AArch64::STRWui:
290   case AArch64::STURWi:
291   case AArch64::LDPSi:
292   case AArch64::LDPSWi:
293   case AArch64::LDPWi:
294   case AArch64::STPSi:
295   case AArch64::STPWi:
296     return 4;
297   case AArch64::LDRDui:
298   case AArch64::LDURDi:
299   case AArch64::LDRXui:
300   case AArch64::LDURXi:
301   case AArch64::STRDui:
302   case AArch64::STURDi:
303   case AArch64::STRXui:
304   case AArch64::STURXi:
305   case AArch64::LDPDi:
306   case AArch64::LDPXi:
307   case AArch64::STPDi:
308   case AArch64::STPXi:
309     return 8;
310   case AArch64::LDRQui:
311   case AArch64::LDURQi:
312   case AArch64::STRQui:
313   case AArch64::STURQi:
314   case AArch64::LDPQi:
315   case AArch64::STPQi:
316     return 16;
317   }
318 }
319 
320 static unsigned getMatchingNonSExtOpcode(unsigned Opc,
321                                          bool *IsValidLdStrOpc = nullptr) {
322   if (IsValidLdStrOpc)
323     *IsValidLdStrOpc = true;
324   switch (Opc) {
325   default:
326     if (IsValidLdStrOpc)
327       *IsValidLdStrOpc = false;
328     return UINT_MAX;
329   case AArch64::STRDui:
330   case AArch64::STURDi:
331   case AArch64::STRQui:
332   case AArch64::STURQi:
333   case AArch64::STRBBui:
334   case AArch64::STURBBi:
335   case AArch64::STRHHui:
336   case AArch64::STURHHi:
337   case AArch64::STRWui:
338   case AArch64::STURWi:
339   case AArch64::STRXui:
340   case AArch64::STURXi:
341   case AArch64::LDRDui:
342   case AArch64::LDURDi:
343   case AArch64::LDRQui:
344   case AArch64::LDURQi:
345   case AArch64::LDRWui:
346   case AArch64::LDURWi:
347   case AArch64::LDRXui:
348   case AArch64::LDURXi:
349   case AArch64::STRSui:
350   case AArch64::STURSi:
351   case AArch64::LDRSui:
352   case AArch64::LDURSi:
353   case AArch64::LDRHHui:
354   case AArch64::LDURHHi:
355   case AArch64::LDRBBui:
356   case AArch64::LDURBBi:
357     return Opc;
358   case AArch64::LDRSWui:
359     return AArch64::LDRWui;
360   case AArch64::LDURSWi:
361     return AArch64::LDURWi;
362   case AArch64::LDRSBWui:
363     return AArch64::LDRBBui;
364   case AArch64::LDRSHWui:
365     return AArch64::LDRHHui;
366   case AArch64::LDURSBWi:
367     return AArch64::LDURBBi;
368   case AArch64::LDURSHWi:
369     return AArch64::LDURHHi;
370   }
371 }
372 
373 static unsigned getMatchingWideOpcode(unsigned Opc) {
374   switch (Opc) {
375   default:
376     llvm_unreachable("Opcode has no wide equivalent!");
377   case AArch64::STRBBui:
378     return AArch64::STRHHui;
379   case AArch64::STRHHui:
380     return AArch64::STRWui;
381   case AArch64::STURBBi:
382     return AArch64::STURHHi;
383   case AArch64::STURHHi:
384     return AArch64::STURWi;
385   case AArch64::STURWi:
386     return AArch64::STURXi;
387   case AArch64::STRWui:
388     return AArch64::STRXui;
389   case AArch64::LDRHHui:
390   case AArch64::LDRSHWui:
391     return AArch64::LDRWui;
392   case AArch64::LDURHHi:
393   case AArch64::LDURSHWi:
394     return AArch64::LDURWi;
395   case AArch64::LDRBBui:
396   case AArch64::LDRSBWui:
397     return AArch64::LDRHHui;
398   case AArch64::LDURBBi:
399   case AArch64::LDURSBWi:
400     return AArch64::LDURHHi;
401   }
402 }
403 
404 static unsigned getMatchingPairOpcode(unsigned Opc) {
405   switch (Opc) {
406   default:
407     llvm_unreachable("Opcode has no pairwise equivalent!");
408   case AArch64::STRSui:
409   case AArch64::STURSi:
410     return AArch64::STPSi;
411   case AArch64::STRDui:
412   case AArch64::STURDi:
413     return AArch64::STPDi;
414   case AArch64::STRQui:
415   case AArch64::STURQi:
416     return AArch64::STPQi;
417   case AArch64::STRWui:
418   case AArch64::STURWi:
419     return AArch64::STPWi;
420   case AArch64::STRXui:
421   case AArch64::STURXi:
422     return AArch64::STPXi;
423   case AArch64::LDRSui:
424   case AArch64::LDURSi:
425     return AArch64::LDPSi;
426   case AArch64::LDRDui:
427   case AArch64::LDURDi:
428     return AArch64::LDPDi;
429   case AArch64::LDRQui:
430   case AArch64::LDURQi:
431     return AArch64::LDPQi;
432   case AArch64::LDRWui:
433   case AArch64::LDURWi:
434     return AArch64::LDPWi;
435   case AArch64::LDRXui:
436   case AArch64::LDURXi:
437     return AArch64::LDPXi;
438   case AArch64::LDRSWui:
439   case AArch64::LDURSWi:
440     return AArch64::LDPSWi;
441   }
442 }
443 
444 static unsigned isMatchingStore(MachineInstr *LoadInst,
445                                 MachineInstr *StoreInst) {
446   unsigned LdOpc = LoadInst->getOpcode();
447   unsigned StOpc = StoreInst->getOpcode();
448   switch (LdOpc) {
449   default:
450     llvm_unreachable("Unsupported load instruction!");
451   case AArch64::LDRBBui:
452     return StOpc == AArch64::STRBBui || StOpc == AArch64::STRHHui ||
453            StOpc == AArch64::STRWui || StOpc == AArch64::STRXui;
454   case AArch64::LDURBBi:
455     return StOpc == AArch64::STURBBi || StOpc == AArch64::STURHHi ||
456            StOpc == AArch64::STURWi || StOpc == AArch64::STURXi;
457   case AArch64::LDRHHui:
458     return StOpc == AArch64::STRHHui || StOpc == AArch64::STRWui ||
459            StOpc == AArch64::STRXui;
460   case AArch64::LDURHHi:
461     return StOpc == AArch64::STURHHi || StOpc == AArch64::STURWi ||
462            StOpc == AArch64::STURXi;
463   case AArch64::LDRWui:
464     return StOpc == AArch64::STRWui || StOpc == AArch64::STRXui;
465   case AArch64::LDURWi:
466     return StOpc == AArch64::STURWi || StOpc == AArch64::STURXi;
467   case AArch64::LDRXui:
468     return StOpc == AArch64::STRXui;
469   case AArch64::LDURXi:
470     return StOpc == AArch64::STURXi;
471   }
472 }
473 
474 static unsigned getPreIndexedOpcode(unsigned Opc) {
475   switch (Opc) {
476   default:
477     llvm_unreachable("Opcode has no pre-indexed equivalent!");
478   case AArch64::STRSui:
479     return AArch64::STRSpre;
480   case AArch64::STRDui:
481     return AArch64::STRDpre;
482   case AArch64::STRQui:
483     return AArch64::STRQpre;
484   case AArch64::STRBBui:
485     return AArch64::STRBBpre;
486   case AArch64::STRHHui:
487     return AArch64::STRHHpre;
488   case AArch64::STRWui:
489     return AArch64::STRWpre;
490   case AArch64::STRXui:
491     return AArch64::STRXpre;
492   case AArch64::LDRSui:
493     return AArch64::LDRSpre;
494   case AArch64::LDRDui:
495     return AArch64::LDRDpre;
496   case AArch64::LDRQui:
497     return AArch64::LDRQpre;
498   case AArch64::LDRBBui:
499     return AArch64::LDRBBpre;
500   case AArch64::LDRHHui:
501     return AArch64::LDRHHpre;
502   case AArch64::LDRWui:
503     return AArch64::LDRWpre;
504   case AArch64::LDRXui:
505     return AArch64::LDRXpre;
506   case AArch64::LDRSWui:
507     return AArch64::LDRSWpre;
508   case AArch64::LDPSi:
509     return AArch64::LDPSpre;
510   case AArch64::LDPSWi:
511     return AArch64::LDPSWpre;
512   case AArch64::LDPDi:
513     return AArch64::LDPDpre;
514   case AArch64::LDPQi:
515     return AArch64::LDPQpre;
516   case AArch64::LDPWi:
517     return AArch64::LDPWpre;
518   case AArch64::LDPXi:
519     return AArch64::LDPXpre;
520   case AArch64::STPSi:
521     return AArch64::STPSpre;
522   case AArch64::STPDi:
523     return AArch64::STPDpre;
524   case AArch64::STPQi:
525     return AArch64::STPQpre;
526   case AArch64::STPWi:
527     return AArch64::STPWpre;
528   case AArch64::STPXi:
529     return AArch64::STPXpre;
530   }
531 }
532 
533 static unsigned getPostIndexedOpcode(unsigned Opc) {
534   switch (Opc) {
535   default:
536     llvm_unreachable("Opcode has no post-indexed wise equivalent!");
537   case AArch64::STRSui:
538     return AArch64::STRSpost;
539   case AArch64::STRDui:
540     return AArch64::STRDpost;
541   case AArch64::STRQui:
542     return AArch64::STRQpost;
543   case AArch64::STRBBui:
544     return AArch64::STRBBpost;
545   case AArch64::STRHHui:
546     return AArch64::STRHHpost;
547   case AArch64::STRWui:
548     return AArch64::STRWpost;
549   case AArch64::STRXui:
550     return AArch64::STRXpost;
551   case AArch64::LDRSui:
552     return AArch64::LDRSpost;
553   case AArch64::LDRDui:
554     return AArch64::LDRDpost;
555   case AArch64::LDRQui:
556     return AArch64::LDRQpost;
557   case AArch64::LDRBBui:
558     return AArch64::LDRBBpost;
559   case AArch64::LDRHHui:
560     return AArch64::LDRHHpost;
561   case AArch64::LDRWui:
562     return AArch64::LDRWpost;
563   case AArch64::LDRXui:
564     return AArch64::LDRXpost;
565   case AArch64::LDRSWui:
566     return AArch64::LDRSWpost;
567   case AArch64::LDPSi:
568     return AArch64::LDPSpost;
569   case AArch64::LDPSWi:
570     return AArch64::LDPSWpost;
571   case AArch64::LDPDi:
572     return AArch64::LDPDpost;
573   case AArch64::LDPQi:
574     return AArch64::LDPQpost;
575   case AArch64::LDPWi:
576     return AArch64::LDPWpost;
577   case AArch64::LDPXi:
578     return AArch64::LDPXpost;
579   case AArch64::STPSi:
580     return AArch64::STPSpost;
581   case AArch64::STPDi:
582     return AArch64::STPDpost;
583   case AArch64::STPQi:
584     return AArch64::STPQpost;
585   case AArch64::STPWi:
586     return AArch64::STPWpost;
587   case AArch64::STPXi:
588     return AArch64::STPXpost;
589   }
590 }
591 
592 static bool isPairedLdSt(const MachineInstr *MI) {
593   switch (MI->getOpcode()) {
594   default:
595     return false;
596   case AArch64::LDPSi:
597   case AArch64::LDPSWi:
598   case AArch64::LDPDi:
599   case AArch64::LDPQi:
600   case AArch64::LDPWi:
601   case AArch64::LDPXi:
602   case AArch64::STPSi:
603   case AArch64::STPDi:
604   case AArch64::STPQi:
605   case AArch64::STPWi:
606   case AArch64::STPXi:
607     return true;
608   }
609 }
610 
611 static const MachineOperand &getLdStRegOp(const MachineInstr *MI,
612                                           unsigned PairedRegOp = 0) {
613   assert(PairedRegOp < 2 && "Unexpected register operand idx.");
614   unsigned Idx = isPairedLdSt(MI) ? PairedRegOp : 0;
615   return MI->getOperand(Idx);
616 }
617 
618 static const MachineOperand &getLdStBaseOp(const MachineInstr *MI) {
619   unsigned Idx = isPairedLdSt(MI) ? 2 : 1;
620   return MI->getOperand(Idx);
621 }
622 
623 static const MachineOperand &getLdStOffsetOp(const MachineInstr *MI) {
624   unsigned Idx = isPairedLdSt(MI) ? 3 : 2;
625   return MI->getOperand(Idx);
626 }
627 
628 static bool isLdOffsetInRangeOfSt(MachineInstr *LoadInst,
629                                   MachineInstr *StoreInst) {
630   assert(isMatchingStore(LoadInst, StoreInst) && "Expect only matched ld/st.");
631   int LoadSize = getMemScale(LoadInst);
632   int StoreSize = getMemScale(StoreInst);
633   int UnscaledStOffset = isUnscaledLdSt(StoreInst)
634                              ? getLdStOffsetOp(StoreInst).getImm()
635                              : getLdStOffsetOp(StoreInst).getImm() * StoreSize;
636   int UnscaledLdOffset = isUnscaledLdSt(LoadInst)
637                              ? getLdStOffsetOp(LoadInst).getImm()
638                              : getLdStOffsetOp(LoadInst).getImm() * LoadSize;
639   return (UnscaledStOffset <= UnscaledLdOffset) &&
640          (UnscaledLdOffset + LoadSize <= (UnscaledStOffset + StoreSize));
641 }
642 
643 static bool isPromotableZeroStoreOpcode(MachineInstr *MI) {
644   unsigned Opc = MI->getOpcode();
645   return isNarrowStore(Opc) || Opc == AArch64::STRWui || Opc == AArch64::STURWi;
646 }
647 
648 static bool isPromotableZeroStoreInst(MachineInstr *MI) {
649   return (isPromotableZeroStoreOpcode(MI)) &&
650          getLdStRegOp(MI).getReg() == AArch64::WZR;
651 }
652 
653 MachineBasicBlock::iterator
654 AArch64LoadStoreOpt::mergeNarrowInsns(MachineBasicBlock::iterator I,
655                                       MachineBasicBlock::iterator MergeMI,
656                                       const LdStPairFlags &Flags) {
657   MachineBasicBlock::iterator NextI = I;
658   ++NextI;
659   // If NextI is the second of the two instructions to be merged, we need
660   // to skip one further. Either way we merge will invalidate the iterator,
661   // and we don't need to scan the new instruction, as it's a pairwise
662   // instruction, which we're not considering for further action anyway.
663   if (NextI == MergeMI)
664     ++NextI;
665 
666   unsigned Opc = I->getOpcode();
667   bool IsScaled = !isUnscaledLdSt(Opc);
668   int OffsetStride = IsScaled ? 1 : getMemScale(I);
669 
670   bool MergeForward = Flags.getMergeForward();
671   // Insert our new paired instruction after whichever of the paired
672   // instructions MergeForward indicates.
673   MachineBasicBlock::iterator InsertionPoint = MergeForward ? MergeMI : I;
674   // Also based on MergeForward is from where we copy the base register operand
675   // so we get the flags compatible with the input code.
676   const MachineOperand &BaseRegOp =
677       MergeForward ? getLdStBaseOp(MergeMI) : getLdStBaseOp(I);
678 
679   // Which register is Rt and which is Rt2 depends on the offset order.
680   MachineInstr *RtMI, *Rt2MI;
681   if (getLdStOffsetOp(I).getImm() ==
682       getLdStOffsetOp(MergeMI).getImm() + OffsetStride) {
683     RtMI = MergeMI;
684     Rt2MI = I;
685   } else {
686     RtMI = I;
687     Rt2MI = MergeMI;
688   }
689 
690   int OffsetImm = getLdStOffsetOp(RtMI).getImm();
691   // Change the scaled offset from small to large type.
692   if (IsScaled) {
693     assert(((OffsetImm & 1) == 0) && "Unexpected offset to merge");
694     OffsetImm /= 2;
695   }
696 
697   DebugLoc DL = I->getDebugLoc();
698   MachineBasicBlock *MBB = I->getParent();
699   if (isNarrowLoad(Opc)) {
700     MachineInstr *RtNewDest = MergeForward ? I : MergeMI;
701     // When merging small (< 32 bit) loads for big-endian targets, the order of
702     // the component parts gets swapped.
703     if (!Subtarget->isLittleEndian())
704       std::swap(RtMI, Rt2MI);
705     // Construct the new load instruction.
706     MachineInstr *NewMemMI, *BitExtMI1, *BitExtMI2;
707     NewMemMI =
708         BuildMI(*MBB, InsertionPoint, DL, TII->get(getMatchingWideOpcode(Opc)))
709             .addOperand(getLdStRegOp(RtNewDest))
710             .addOperand(BaseRegOp)
711             .addImm(OffsetImm)
712             .setMemRefs(I->mergeMemRefsWith(*MergeMI));
713 
714     DEBUG(
715         dbgs()
716         << "Creating the new load and extract. Replacing instructions:\n    ");
717     DEBUG(I->print(dbgs()));
718     DEBUG(dbgs() << "    ");
719     DEBUG(MergeMI->print(dbgs()));
720     DEBUG(dbgs() << "  with instructions:\n    ");
721     DEBUG((NewMemMI)->print(dbgs()));
722 
723     int Width = getMemScale(I) == 1 ? 8 : 16;
724     int LSBLow = 0;
725     int LSBHigh = Width;
726     int ImmsLow = LSBLow + Width - 1;
727     int ImmsHigh = LSBHigh + Width - 1;
728     MachineInstr *ExtDestMI = MergeForward ? MergeMI : I;
729     if ((ExtDestMI == Rt2MI) == Subtarget->isLittleEndian()) {
730       // Create the bitfield extract for high bits.
731       BitExtMI1 =
732           BuildMI(*MBB, InsertionPoint, DL, TII->get(getBitExtrOpcode(Rt2MI)))
733               .addOperand(getLdStRegOp(Rt2MI))
734               .addReg(getLdStRegOp(RtNewDest).getReg())
735               .addImm(LSBHigh)
736               .addImm(ImmsHigh);
737       // Create the bitfield extract for low bits.
738       if (RtMI->getOpcode() == getMatchingNonSExtOpcode(RtMI->getOpcode())) {
739         // For unsigned, prefer to use AND for low bits.
740         BitExtMI2 = BuildMI(*MBB, InsertionPoint, DL, TII->get(AArch64::ANDWri))
741                         .addOperand(getLdStRegOp(RtMI))
742                         .addReg(getLdStRegOp(RtNewDest).getReg())
743                         .addImm(ImmsLow);
744       } else {
745         BitExtMI2 =
746             BuildMI(*MBB, InsertionPoint, DL, TII->get(getBitExtrOpcode(RtMI)))
747                 .addOperand(getLdStRegOp(RtMI))
748                 .addReg(getLdStRegOp(RtNewDest).getReg())
749                 .addImm(LSBLow)
750                 .addImm(ImmsLow);
751       }
752     } else {
753       // Create the bitfield extract for low bits.
754       if (RtMI->getOpcode() == getMatchingNonSExtOpcode(RtMI->getOpcode())) {
755         // For unsigned, prefer to use AND for low bits.
756         BitExtMI1 = BuildMI(*MBB, InsertionPoint, DL, TII->get(AArch64::ANDWri))
757                         .addOperand(getLdStRegOp(RtMI))
758                         .addReg(getLdStRegOp(RtNewDest).getReg())
759                         .addImm(ImmsLow);
760       } else {
761         BitExtMI1 =
762             BuildMI(*MBB, InsertionPoint, DL, TII->get(getBitExtrOpcode(RtMI)))
763                 .addOperand(getLdStRegOp(RtMI))
764                 .addReg(getLdStRegOp(RtNewDest).getReg())
765                 .addImm(LSBLow)
766                 .addImm(ImmsLow);
767       }
768 
769       // Create the bitfield extract for high bits.
770       BitExtMI2 =
771           BuildMI(*MBB, InsertionPoint, DL, TII->get(getBitExtrOpcode(Rt2MI)))
772               .addOperand(getLdStRegOp(Rt2MI))
773               .addReg(getLdStRegOp(RtNewDest).getReg())
774               .addImm(LSBHigh)
775               .addImm(ImmsHigh);
776     }
777     DEBUG(dbgs() << "    ");
778     DEBUG((BitExtMI1)->print(dbgs()));
779     DEBUG(dbgs() << "    ");
780     DEBUG((BitExtMI2)->print(dbgs()));
781     DEBUG(dbgs() << "\n");
782 
783     // Erase the old instructions.
784     I->eraseFromParent();
785     MergeMI->eraseFromParent();
786     return NextI;
787   }
788   assert(isPromotableZeroStoreInst(I) && "Expected promotable zero store");
789 
790   // Construct the new instruction.
791   MachineInstrBuilder MIB;
792   MIB = BuildMI(*MBB, InsertionPoint, DL, TII->get(getMatchingWideOpcode(Opc)))
793             .addReg(isNarrowStore(Opc) ? AArch64::WZR : AArch64::XZR)
794             .addOperand(BaseRegOp)
795             .addImm(OffsetImm)
796             .setMemRefs(I->mergeMemRefsWith(*MergeMI));
797 
798   (void)MIB;
799 
800   DEBUG(dbgs() << "Creating wider load/store. Replacing instructions:\n    ");
801   DEBUG(I->print(dbgs()));
802   DEBUG(dbgs() << "    ");
803   DEBUG(MergeMI->print(dbgs()));
804   DEBUG(dbgs() << "  with instruction:\n    ");
805   DEBUG(((MachineInstr *)MIB)->print(dbgs()));
806   DEBUG(dbgs() << "\n");
807 
808   // Erase the old instructions.
809   I->eraseFromParent();
810   MergeMI->eraseFromParent();
811   return NextI;
812 }
813 
814 MachineBasicBlock::iterator
815 AArch64LoadStoreOpt::mergePairedInsns(MachineBasicBlock::iterator I,
816                                       MachineBasicBlock::iterator Paired,
817                                       const LdStPairFlags &Flags) {
818   MachineBasicBlock::iterator NextI = I;
819   ++NextI;
820   // If NextI is the second of the two instructions to be merged, we need
821   // to skip one further. Either way we merge will invalidate the iterator,
822   // and we don't need to scan the new instruction, as it's a pairwise
823   // instruction, which we're not considering for further action anyway.
824   if (NextI == Paired)
825     ++NextI;
826 
827   int SExtIdx = Flags.getSExtIdx();
828   unsigned Opc =
829       SExtIdx == -1 ? I->getOpcode() : getMatchingNonSExtOpcode(I->getOpcode());
830   bool IsUnscaled = isUnscaledLdSt(Opc);
831   int OffsetStride = IsUnscaled ? getMemScale(I) : 1;
832 
833   bool MergeForward = Flags.getMergeForward();
834   // Insert our new paired instruction after whichever of the paired
835   // instructions MergeForward indicates.
836   MachineBasicBlock::iterator InsertionPoint = MergeForward ? Paired : I;
837   // Also based on MergeForward is from where we copy the base register operand
838   // so we get the flags compatible with the input code.
839   const MachineOperand &BaseRegOp =
840       MergeForward ? getLdStBaseOp(Paired) : getLdStBaseOp(I);
841 
842   int Offset = getLdStOffsetOp(I).getImm();
843   int PairedOffset = getLdStOffsetOp(Paired).getImm();
844   bool PairedIsUnscaled = isUnscaledLdSt(Paired->getOpcode());
845   if (IsUnscaled != PairedIsUnscaled) {
846     // We're trying to pair instructions that differ in how they are scaled.  If
847     // I is scaled then scale the offset of Paired accordingly.  Otherwise, do
848     // the opposite (i.e., make Paired's offset unscaled).
849     int MemSize = getMemScale(Paired);
850     if (PairedIsUnscaled) {
851       // If the unscaled offset isn't a multiple of the MemSize, we can't
852       // pair the operations together.
853       assert(!(PairedOffset % getMemScale(Paired)) &&
854              "Offset should be a multiple of the stride!");
855       PairedOffset /= MemSize;
856     } else {
857       PairedOffset *= MemSize;
858     }
859   }
860 
861   // Which register is Rt and which is Rt2 depends on the offset order.
862   MachineInstr *RtMI, *Rt2MI;
863   if (Offset == PairedOffset + OffsetStride) {
864     RtMI = Paired;
865     Rt2MI = I;
866     // Here we swapped the assumption made for SExtIdx.
867     // I.e., we turn ldp I, Paired into ldp Paired, I.
868     // Update the index accordingly.
869     if (SExtIdx != -1)
870       SExtIdx = (SExtIdx + 1) % 2;
871   } else {
872     RtMI = I;
873     Rt2MI = Paired;
874   }
875   int OffsetImm = getLdStOffsetOp(RtMI).getImm();
876   // Scale the immediate offset, if necessary.
877   if (isUnscaledLdSt(RtMI->getOpcode())) {
878     assert(!(OffsetImm % getMemScale(RtMI)) &&
879            "Unscaled offset cannot be scaled.");
880     OffsetImm /= getMemScale(RtMI);
881   }
882 
883   // Construct the new instruction.
884   MachineInstrBuilder MIB;
885   DebugLoc DL = I->getDebugLoc();
886   MachineBasicBlock *MBB = I->getParent();
887   MIB = BuildMI(*MBB, InsertionPoint, DL, TII->get(getMatchingPairOpcode(Opc)))
888             .addOperand(getLdStRegOp(RtMI))
889             .addOperand(getLdStRegOp(Rt2MI))
890             .addOperand(BaseRegOp)
891             .addImm(OffsetImm);
892   // FIXME: Copy the mem operands from the source instructions. The MI scheduler
893   // needs these to reason about loads/stores.
894 
895   (void)MIB;
896 
897   DEBUG(dbgs() << "Creating pair load/store. Replacing instructions:\n    ");
898   DEBUG(I->print(dbgs()));
899   DEBUG(dbgs() << "    ");
900   DEBUG(Paired->print(dbgs()));
901   DEBUG(dbgs() << "  with instruction:\n    ");
902   if (SExtIdx != -1) {
903     // Generate the sign extension for the proper result of the ldp.
904     // I.e., with X1, that would be:
905     // %W1<def> = KILL %W1, %X1<imp-def>
906     // %X1<def> = SBFMXri %X1<kill>, 0, 31
907     MachineOperand &DstMO = MIB->getOperand(SExtIdx);
908     // Right now, DstMO has the extended register, since it comes from an
909     // extended opcode.
910     unsigned DstRegX = DstMO.getReg();
911     // Get the W variant of that register.
912     unsigned DstRegW = TRI->getSubReg(DstRegX, AArch64::sub_32);
913     // Update the result of LDP to use the W instead of the X variant.
914     DstMO.setReg(DstRegW);
915     DEBUG(((MachineInstr *)MIB)->print(dbgs()));
916     DEBUG(dbgs() << "\n");
917     // Make the machine verifier happy by providing a definition for
918     // the X register.
919     // Insert this definition right after the generated LDP, i.e., before
920     // InsertionPoint.
921     MachineInstrBuilder MIBKill =
922         BuildMI(*MBB, InsertionPoint, DL, TII->get(TargetOpcode::KILL), DstRegW)
923             .addReg(DstRegW)
924             .addReg(DstRegX, RegState::Define);
925     MIBKill->getOperand(2).setImplicit();
926     // Create the sign extension.
927     MachineInstrBuilder MIBSXTW =
928         BuildMI(*MBB, InsertionPoint, DL, TII->get(AArch64::SBFMXri), DstRegX)
929             .addReg(DstRegX)
930             .addImm(0)
931             .addImm(31);
932     (void)MIBSXTW;
933     DEBUG(dbgs() << "  Extend operand:\n    ");
934     DEBUG(((MachineInstr *)MIBSXTW)->print(dbgs()));
935   } else {
936     DEBUG(((MachineInstr *)MIB)->print(dbgs()));
937   }
938   DEBUG(dbgs() << "\n");
939 
940   // Erase the old instructions.
941   I->eraseFromParent();
942   Paired->eraseFromParent();
943 
944   return NextI;
945 }
946 
947 MachineBasicBlock::iterator
948 AArch64LoadStoreOpt::promoteLoadFromStore(MachineBasicBlock::iterator LoadI,
949                                           MachineBasicBlock::iterator StoreI) {
950   MachineBasicBlock::iterator NextI = LoadI;
951   ++NextI;
952 
953   int LoadSize = getMemScale(LoadI);
954   int StoreSize = getMemScale(StoreI);
955   unsigned LdRt = getLdStRegOp(LoadI).getReg();
956   unsigned StRt = getLdStRegOp(StoreI).getReg();
957   bool IsStoreXReg = TRI->getRegClass(AArch64::GPR64RegClassID)->contains(StRt);
958 
959   assert((IsStoreXReg ||
960           TRI->getRegClass(AArch64::GPR32RegClassID)->contains(StRt)) &&
961          "Unexpected RegClass");
962 
963   MachineInstr *BitExtMI;
964   if (LoadSize == StoreSize && (LoadSize == 4 || LoadSize == 8)) {
965     // Remove the load, if the destination register of the loads is the same
966     // register for stored value.
967     if (StRt == LdRt && LoadSize == 8) {
968       DEBUG(dbgs() << "Remove load instruction:\n    ");
969       DEBUG(LoadI->print(dbgs()));
970       DEBUG(dbgs() << "\n");
971       LoadI->eraseFromParent();
972       return NextI;
973     }
974     // Replace the load with a mov if the load and store are in the same size.
975     BitExtMI =
976         BuildMI(*LoadI->getParent(), LoadI, LoadI->getDebugLoc(),
977                 TII->get(IsStoreXReg ? AArch64::ORRXrs : AArch64::ORRWrs), LdRt)
978             .addReg(IsStoreXReg ? AArch64::XZR : AArch64::WZR)
979             .addReg(StRt)
980             .addImm(AArch64_AM::getShifterImm(AArch64_AM::LSL, 0));
981   } else {
982     // FIXME: Currently we disable this transformation in big-endian targets as
983     // performance and correctness are verified only in little-endian.
984     if (!Subtarget->isLittleEndian())
985       return NextI;
986     bool IsUnscaled = isUnscaledLdSt(LoadI);
987     assert(IsUnscaled == isUnscaledLdSt(StoreI) && "Unsupported ld/st match");
988     assert(LoadSize <= StoreSize && "Invalid load size");
989     int UnscaledLdOffset = IsUnscaled
990                                ? getLdStOffsetOp(LoadI).getImm()
991                                : getLdStOffsetOp(LoadI).getImm() * LoadSize;
992     int UnscaledStOffset = IsUnscaled
993                                ? getLdStOffsetOp(StoreI).getImm()
994                                : getLdStOffsetOp(StoreI).getImm() * StoreSize;
995     int Width = LoadSize * 8;
996     int Immr = 8 * (UnscaledLdOffset - UnscaledStOffset);
997     int Imms = Immr + Width - 1;
998     unsigned DestReg = IsStoreXReg
999                            ? TRI->getMatchingSuperReg(LdRt, AArch64::sub_32,
1000                                                       &AArch64::GPR64RegClass)
1001                            : LdRt;
1002 
1003     assert((UnscaledLdOffset >= UnscaledStOffset &&
1004             (UnscaledLdOffset + LoadSize) <= UnscaledStOffset + StoreSize) &&
1005            "Invalid offset");
1006 
1007     Immr = 8 * (UnscaledLdOffset - UnscaledStOffset);
1008     Imms = Immr + Width - 1;
1009     if (UnscaledLdOffset == UnscaledStOffset) {
1010       uint32_t AndMaskEncoded = ((IsStoreXReg ? 1 : 0) << 12) // N
1011                                 | ((Immr) << 6)               // immr
1012                                 | ((Imms) << 0)               // imms
1013           ;
1014 
1015       BitExtMI =
1016           BuildMI(*LoadI->getParent(), LoadI, LoadI->getDebugLoc(),
1017                   TII->get(IsStoreXReg ? AArch64::ANDXri : AArch64::ANDWri),
1018                   DestReg)
1019               .addReg(StRt)
1020               .addImm(AndMaskEncoded);
1021     } else {
1022       BitExtMI =
1023           BuildMI(*LoadI->getParent(), LoadI, LoadI->getDebugLoc(),
1024                   TII->get(IsStoreXReg ? AArch64::UBFMXri : AArch64::UBFMWri),
1025                   DestReg)
1026               .addReg(StRt)
1027               .addImm(Immr)
1028               .addImm(Imms);
1029     }
1030   }
1031 
1032   DEBUG(dbgs() << "Promoting load by replacing :\n    ");
1033   DEBUG(StoreI->print(dbgs()));
1034   DEBUG(dbgs() << "    ");
1035   DEBUG(LoadI->print(dbgs()));
1036   DEBUG(dbgs() << "  with instructions:\n    ");
1037   DEBUG(StoreI->print(dbgs()));
1038   DEBUG(dbgs() << "    ");
1039   DEBUG((BitExtMI)->print(dbgs()));
1040   DEBUG(dbgs() << "\n");
1041 
1042   // Erase the old instructions.
1043   LoadI->eraseFromParent();
1044   return NextI;
1045 }
1046 
1047 /// trackRegDefsUses - Remember what registers the specified instruction uses
1048 /// and modifies.
1049 static void trackRegDefsUses(const MachineInstr *MI, BitVector &ModifiedRegs,
1050                              BitVector &UsedRegs,
1051                              const TargetRegisterInfo *TRI) {
1052   for (const MachineOperand &MO : MI->operands()) {
1053     if (MO.isRegMask())
1054       ModifiedRegs.setBitsNotInMask(MO.getRegMask());
1055 
1056     if (!MO.isReg())
1057       continue;
1058     unsigned Reg = MO.getReg();
1059     if (!Reg)
1060       continue;
1061     if (MO.isDef()) {
1062       for (MCRegAliasIterator AI(Reg, TRI, true); AI.isValid(); ++AI)
1063         ModifiedRegs.set(*AI);
1064     } else {
1065       assert(MO.isUse() && "Reg operand not a def and not a use?!?");
1066       for (MCRegAliasIterator AI(Reg, TRI, true); AI.isValid(); ++AI)
1067         UsedRegs.set(*AI);
1068     }
1069   }
1070 }
1071 
1072 static bool inBoundsForPair(bool IsUnscaled, int Offset, int OffsetStride) {
1073   // Convert the byte-offset used by unscaled into an "element" offset used
1074   // by the scaled pair load/store instructions.
1075   if (IsUnscaled) {
1076     // If the byte-offset isn't a multiple of the stride, there's no point
1077     // trying to match it.
1078     if (Offset % OffsetStride)
1079       return false;
1080     Offset /= OffsetStride;
1081   }
1082   return Offset <= 63 && Offset >= -64;
1083 }
1084 
1085 // Do alignment, specialized to power of 2 and for signed ints,
1086 // avoiding having to do a C-style cast from uint_64t to int when
1087 // using alignTo from include/llvm/Support/MathExtras.h.
1088 // FIXME: Move this function to include/MathExtras.h?
1089 static int alignTo(int Num, int PowOf2) {
1090   return (Num + PowOf2 - 1) & ~(PowOf2 - 1);
1091 }
1092 
1093 static bool mayAlias(MachineInstr *MIa, MachineInstr *MIb,
1094                      const AArch64InstrInfo *TII) {
1095   // One of the instructions must modify memory.
1096   if (!MIa->mayStore() && !MIb->mayStore())
1097     return false;
1098 
1099   // Both instructions must be memory operations.
1100   if (!MIa->mayLoadOrStore() && !MIb->mayLoadOrStore())
1101     return false;
1102 
1103   return !TII->areMemAccessesTriviallyDisjoint(MIa, MIb);
1104 }
1105 
1106 static bool mayAlias(MachineInstr *MIa,
1107                      SmallVectorImpl<MachineInstr *> &MemInsns,
1108                      const AArch64InstrInfo *TII) {
1109   for (auto &MIb : MemInsns)
1110     if (mayAlias(MIa, MIb, TII))
1111       return true;
1112 
1113   return false;
1114 }
1115 
1116 bool AArch64LoadStoreOpt::findMatchingStore(
1117     MachineBasicBlock::iterator I, unsigned Limit,
1118     MachineBasicBlock::iterator &StoreI) {
1119   MachineBasicBlock::iterator B = I->getParent()->begin();
1120   MachineBasicBlock::iterator MBBI = I;
1121   MachineInstr *LoadMI = I;
1122   unsigned BaseReg = getLdStBaseOp(LoadMI).getReg();
1123 
1124   // If the load is the first instruction in the block, there's obviously
1125   // not any matching store.
1126   if (MBBI == B)
1127     return false;
1128 
1129   // Track which registers have been modified and used between the first insn
1130   // and the second insn.
1131   ModifiedRegs.reset();
1132   UsedRegs.reset();
1133 
1134   unsigned Count = 0;
1135   do {
1136     --MBBI;
1137     MachineInstr *MI = MBBI;
1138 
1139     // Don't count DBG_VALUE instructions towards the search limit.
1140     if (!MI->isDebugValue())
1141       ++Count;
1142 
1143     // If the load instruction reads directly from the address to which the
1144     // store instruction writes and the stored value is not modified, we can
1145     // promote the load. Since we do not handle stores with pre-/post-index,
1146     // it's unnecessary to check if BaseReg is modified by the store itself.
1147     if (MI->mayStore() && isMatchingStore(LoadMI, MI) &&
1148         BaseReg == getLdStBaseOp(MI).getReg() &&
1149         isLdOffsetInRangeOfSt(LoadMI, MI) &&
1150         !ModifiedRegs[getLdStRegOp(MI).getReg()]) {
1151       StoreI = MBBI;
1152       return true;
1153     }
1154 
1155     if (MI->isCall())
1156       return false;
1157 
1158     // Update modified / uses register lists.
1159     trackRegDefsUses(MI, ModifiedRegs, UsedRegs, TRI);
1160 
1161     // Otherwise, if the base register is modified, we have no match, so
1162     // return early.
1163     if (ModifiedRegs[BaseReg])
1164       return false;
1165 
1166     // If we encounter a store aliased with the load, return early.
1167     if (MI->mayStore() && mayAlias(LoadMI, MI, TII))
1168       return false;
1169   } while (MBBI != B && Count < Limit);
1170   return false;
1171 }
1172 
1173 // Returns true if these two opcodes can be merged or paired.  Otherwise,
1174 // returns false.
1175 static bool canMergeOpc(unsigned OpcA, unsigned OpcB, LdStPairFlags &Flags) {
1176   // Opcodes match: nothing more to check.
1177   if (OpcA == OpcB)
1178     return true;
1179 
1180   // Try to match a sign-extended load/store with a zero-extended load/store.
1181   bool IsValidLdStrOpc, PairIsValidLdStrOpc;
1182   unsigned NonSExtOpc = getMatchingNonSExtOpcode(OpcA, &IsValidLdStrOpc);
1183   assert(IsValidLdStrOpc &&
1184          "Given Opc should be a Load or Store with an immediate");
1185   // OpcA will be the first instruction in the pair.
1186   if (NonSExtOpc == getMatchingNonSExtOpcode(OpcB, &PairIsValidLdStrOpc)) {
1187     Flags.setSExtIdx(NonSExtOpc == (unsigned)OpcA ? 1 : 0);
1188     return true;
1189   }
1190 
1191   // If the second instruction isn't even a load/store, bail out.
1192   if (!PairIsValidLdStrOpc)
1193     return false;
1194 
1195   // FIXME: We don't support merging narrow loads/stores with mixed
1196   // scaled/unscaled offsets.
1197   if (isNarrowLoadOrStore(OpcA) || isNarrowLoadOrStore(OpcB))
1198     return false;
1199 
1200   // Try to match an unscaled load/store with a scaled load/store.
1201   return isUnscaledLdSt(OpcA) != isUnscaledLdSt(OpcB) &&
1202          getMatchingPairOpcode(OpcA) == getMatchingPairOpcode(OpcB);
1203 
1204   // FIXME: Can we also match a mixed sext/zext unscaled/scaled pair?
1205 }
1206 
1207 /// Scan the instructions looking for a load/store that can be combined with the
1208 /// current instruction into a wider equivalent or a load/store pair.
1209 MachineBasicBlock::iterator
1210 AArch64LoadStoreOpt::findMatchingInsn(MachineBasicBlock::iterator I,
1211                                       LdStPairFlags &Flags, unsigned Limit) {
1212   MachineBasicBlock::iterator E = I->getParent()->end();
1213   MachineBasicBlock::iterator MBBI = I;
1214   MachineInstr *FirstMI = I;
1215   ++MBBI;
1216 
1217   unsigned Opc = FirstMI->getOpcode();
1218   bool MayLoad = FirstMI->mayLoad();
1219   bool IsUnscaled = isUnscaledLdSt(FirstMI);
1220   unsigned Reg = getLdStRegOp(FirstMI).getReg();
1221   unsigned BaseReg = getLdStBaseOp(FirstMI).getReg();
1222   int Offset = getLdStOffsetOp(FirstMI).getImm();
1223   int OffsetStride = IsUnscaled ? getMemScale(FirstMI) : 1;
1224   bool IsPromotableZeroStore = isPromotableZeroStoreInst(FirstMI);
1225 
1226   // Track which registers have been modified and used between the first insn
1227   // (inclusive) and the second insn.
1228   ModifiedRegs.reset();
1229   UsedRegs.reset();
1230 
1231   // Remember any instructions that read/write memory between FirstMI and MI.
1232   SmallVector<MachineInstr *, 4> MemInsns;
1233 
1234   for (unsigned Count = 0; MBBI != E && Count < Limit; ++MBBI) {
1235     MachineInstr *MI = MBBI;
1236     // Skip DBG_VALUE instructions. Otherwise debug info can affect the
1237     // optimization by changing how far we scan.
1238     if (MI->isDebugValue())
1239       continue;
1240 
1241     // Now that we know this is a real instruction, count it.
1242     ++Count;
1243 
1244     Flags.setSExtIdx(-1);
1245     if (canMergeOpc(Opc, MI->getOpcode(), Flags) &&
1246         getLdStOffsetOp(MI).isImm()) {
1247       assert(MI->mayLoadOrStore() && "Expected memory operation.");
1248       // If we've found another instruction with the same opcode, check to see
1249       // if the base and offset are compatible with our starting instruction.
1250       // These instructions all have scaled immediate operands, so we just
1251       // check for +1/-1. Make sure to check the new instruction offset is
1252       // actually an immediate and not a symbolic reference destined for
1253       // a relocation.
1254       //
1255       // Pairwise instructions have a 7-bit signed offset field. Single insns
1256       // have a 12-bit unsigned offset field. To be a valid combine, the
1257       // final offset must be in range.
1258       unsigned MIBaseReg = getLdStBaseOp(MI).getReg();
1259       int MIOffset = getLdStOffsetOp(MI).getImm();
1260       bool MIIsUnscaled = isUnscaledLdSt(MI);
1261       if (IsUnscaled != MIIsUnscaled) {
1262         // We're trying to pair instructions that differ in how they are scaled.
1263         // If FirstMI is scaled then scale the offset of MI accordingly.
1264         // Otherwise, do the opposite (i.e., make MI's offset unscaled).
1265         int MemSize = getMemScale(MI);
1266         if (MIIsUnscaled) {
1267           // If the unscaled offset isn't a multiple of the MemSize, we can't
1268           // pair the operations together: bail and keep looking.
1269           if (MIOffset % MemSize)
1270             continue;
1271           MIOffset /= MemSize;
1272         } else {
1273           MIOffset *= MemSize;
1274         }
1275       }
1276 
1277       if (BaseReg == MIBaseReg && ((Offset == MIOffset + OffsetStride) ||
1278                                    (Offset + OffsetStride == MIOffset))) {
1279         int MinOffset = Offset < MIOffset ? Offset : MIOffset;
1280         // If this is a volatile load/store that otherwise matched, stop looking
1281         // as something is going on that we don't have enough information to
1282         // safely transform. Similarly, stop if we see a hint to avoid pairs.
1283         if (MI->hasOrderedMemoryRef() || TII->isLdStPairSuppressed(MI))
1284           return E;
1285         // If the resultant immediate offset of merging these instructions
1286         // is out of range for a pairwise instruction, bail and keep looking.
1287         bool IsNarrowLoad = isNarrowLoad(MI->getOpcode());
1288         if (!IsNarrowLoad &&
1289             !inBoundsForPair(IsUnscaled, MinOffset, OffsetStride)) {
1290           trackRegDefsUses(MI, ModifiedRegs, UsedRegs, TRI);
1291           MemInsns.push_back(MI);
1292           continue;
1293         }
1294 
1295         if (IsNarrowLoad || IsPromotableZeroStore) {
1296           // If the alignment requirements of the scaled wide load/store
1297           // instruction can't express the offset of the scaled narrow
1298           // input, bail and keep looking.
1299           if (!IsUnscaled && alignTo(MinOffset, 2) != MinOffset) {
1300             trackRegDefsUses(MI, ModifiedRegs, UsedRegs, TRI);
1301             MemInsns.push_back(MI);
1302             continue;
1303           }
1304         } else {
1305           // If the alignment requirements of the paired (scaled) instruction
1306           // can't express the offset of the unscaled input, bail and keep
1307           // looking.
1308           if (IsUnscaled && (alignTo(MinOffset, OffsetStride) != MinOffset)) {
1309             trackRegDefsUses(MI, ModifiedRegs, UsedRegs, TRI);
1310             MemInsns.push_back(MI);
1311             continue;
1312           }
1313         }
1314         // If the destination register of the loads is the same register, bail
1315         // and keep looking. A load-pair instruction with both destination
1316         // registers the same is UNPREDICTABLE and will result in an exception.
1317         // For narrow stores, allow only when the stored value is the same
1318         // (i.e., WZR).
1319         if ((MayLoad && Reg == getLdStRegOp(MI).getReg()) ||
1320             (IsPromotableZeroStore && Reg != getLdStRegOp(MI).getReg())) {
1321           trackRegDefsUses(MI, ModifiedRegs, UsedRegs, TRI);
1322           MemInsns.push_back(MI);
1323           continue;
1324         }
1325 
1326         // If the Rt of the second instruction was not modified or used between
1327         // the two instructions and none of the instructions between the second
1328         // and first alias with the second, we can combine the second into the
1329         // first.
1330         if (!ModifiedRegs[getLdStRegOp(MI).getReg()] &&
1331             !(MI->mayLoad() && UsedRegs[getLdStRegOp(MI).getReg()]) &&
1332             !mayAlias(MI, MemInsns, TII)) {
1333           Flags.setMergeForward(false);
1334           return MBBI;
1335         }
1336 
1337         // Likewise, if the Rt of the first instruction is not modified or used
1338         // between the two instructions and none of the instructions between the
1339         // first and the second alias with the first, we can combine the first
1340         // into the second.
1341         if (!ModifiedRegs[getLdStRegOp(FirstMI).getReg()] &&
1342             !(MayLoad && UsedRegs[getLdStRegOp(FirstMI).getReg()]) &&
1343             !mayAlias(FirstMI, MemInsns, TII)) {
1344           Flags.setMergeForward(true);
1345           return MBBI;
1346         }
1347         // Unable to combine these instructions due to interference in between.
1348         // Keep looking.
1349       }
1350     }
1351 
1352     // If the instruction wasn't a matching load or store.  Stop searching if we
1353     // encounter a call instruction that might modify memory.
1354     if (MI->isCall())
1355       return E;
1356 
1357     // Update modified / uses register lists.
1358     trackRegDefsUses(MI, ModifiedRegs, UsedRegs, TRI);
1359 
1360     // Otherwise, if the base register is modified, we have no match, so
1361     // return early.
1362     if (ModifiedRegs[BaseReg])
1363       return E;
1364 
1365     // Update list of instructions that read/write memory.
1366     if (MI->mayLoadOrStore())
1367       MemInsns.push_back(MI);
1368   }
1369   return E;
1370 }
1371 
1372 MachineBasicBlock::iterator
1373 AArch64LoadStoreOpt::mergeUpdateInsn(MachineBasicBlock::iterator I,
1374                                      MachineBasicBlock::iterator Update,
1375                                      bool IsPreIdx) {
1376   assert((Update->getOpcode() == AArch64::ADDXri ||
1377           Update->getOpcode() == AArch64::SUBXri) &&
1378          "Unexpected base register update instruction to merge!");
1379   MachineBasicBlock::iterator NextI = I;
1380   // Return the instruction following the merged instruction, which is
1381   // the instruction following our unmerged load. Unless that's the add/sub
1382   // instruction we're merging, in which case it's the one after that.
1383   if (++NextI == Update)
1384     ++NextI;
1385 
1386   int Value = Update->getOperand(2).getImm();
1387   assert(AArch64_AM::getShiftValue(Update->getOperand(3).getImm()) == 0 &&
1388          "Can't merge 1 << 12 offset into pre-/post-indexed load / store");
1389   if (Update->getOpcode() == AArch64::SUBXri)
1390     Value = -Value;
1391 
1392   unsigned NewOpc = IsPreIdx ? getPreIndexedOpcode(I->getOpcode())
1393                              : getPostIndexedOpcode(I->getOpcode());
1394   MachineInstrBuilder MIB;
1395   if (!isPairedLdSt(I)) {
1396     // Non-paired instruction.
1397     MIB = BuildMI(*I->getParent(), I, I->getDebugLoc(), TII->get(NewOpc))
1398               .addOperand(getLdStRegOp(Update))
1399               .addOperand(getLdStRegOp(I))
1400               .addOperand(getLdStBaseOp(I))
1401               .addImm(Value)
1402               .setMemRefs(I->memoperands_begin(), I->memoperands_end());
1403   } else {
1404     // Paired instruction.
1405     int Scale = getMemScale(I);
1406     MIB = BuildMI(*I->getParent(), I, I->getDebugLoc(), TII->get(NewOpc))
1407               .addOperand(getLdStRegOp(Update))
1408               .addOperand(getLdStRegOp(I, 0))
1409               .addOperand(getLdStRegOp(I, 1))
1410               .addOperand(getLdStBaseOp(I))
1411               .addImm(Value / Scale)
1412               .setMemRefs(I->memoperands_begin(), I->memoperands_end());
1413   }
1414   (void)MIB;
1415 
1416   if (IsPreIdx)
1417     DEBUG(dbgs() << "Creating pre-indexed load/store.");
1418   else
1419     DEBUG(dbgs() << "Creating post-indexed load/store.");
1420   DEBUG(dbgs() << "    Replacing instructions:\n    ");
1421   DEBUG(I->print(dbgs()));
1422   DEBUG(dbgs() << "    ");
1423   DEBUG(Update->print(dbgs()));
1424   DEBUG(dbgs() << "  with instruction:\n    ");
1425   DEBUG(((MachineInstr *)MIB)->print(dbgs()));
1426   DEBUG(dbgs() << "\n");
1427 
1428   // Erase the old instructions for the block.
1429   I->eraseFromParent();
1430   Update->eraseFromParent();
1431 
1432   return NextI;
1433 }
1434 
1435 bool AArch64LoadStoreOpt::isMatchingUpdateInsn(MachineInstr *MemMI,
1436                                                MachineInstr *MI,
1437                                                unsigned BaseReg, int Offset) {
1438   switch (MI->getOpcode()) {
1439   default:
1440     break;
1441   case AArch64::SUBXri:
1442     // Negate the offset for a SUB instruction.
1443     Offset *= -1;
1444   // FALLTHROUGH
1445   case AArch64::ADDXri:
1446     // Make sure it's a vanilla immediate operand, not a relocation or
1447     // anything else we can't handle.
1448     if (!MI->getOperand(2).isImm())
1449       break;
1450     // Watch out for 1 << 12 shifted value.
1451     if (AArch64_AM::getShiftValue(MI->getOperand(3).getImm()))
1452       break;
1453 
1454     // The update instruction source and destination register must be the
1455     // same as the load/store base register.
1456     if (MI->getOperand(0).getReg() != BaseReg ||
1457         MI->getOperand(1).getReg() != BaseReg)
1458       break;
1459 
1460     bool IsPairedInsn = isPairedLdSt(MemMI);
1461     int UpdateOffset = MI->getOperand(2).getImm();
1462     // For non-paired load/store instructions, the immediate must fit in a
1463     // signed 9-bit integer.
1464     if (!IsPairedInsn && (UpdateOffset > 255 || UpdateOffset < -256))
1465       break;
1466 
1467     // For paired load/store instructions, the immediate must be a multiple of
1468     // the scaling factor.  The scaled offset must also fit into a signed 7-bit
1469     // integer.
1470     if (IsPairedInsn) {
1471       int Scale = getMemScale(MemMI);
1472       if (UpdateOffset % Scale != 0)
1473         break;
1474 
1475       int ScaledOffset = UpdateOffset / Scale;
1476       if (ScaledOffset > 64 || ScaledOffset < -64)
1477         break;
1478     }
1479 
1480     // If we have a non-zero Offset, we check that it matches the amount
1481     // we're adding to the register.
1482     if (!Offset || Offset == MI->getOperand(2).getImm())
1483       return true;
1484     break;
1485   }
1486   return false;
1487 }
1488 
1489 MachineBasicBlock::iterator AArch64LoadStoreOpt::findMatchingUpdateInsnForward(
1490     MachineBasicBlock::iterator I, int UnscaledOffset, unsigned Limit) {
1491   MachineBasicBlock::iterator E = I->getParent()->end();
1492   MachineInstr *MemMI = I;
1493   MachineBasicBlock::iterator MBBI = I;
1494 
1495   unsigned BaseReg = getLdStBaseOp(MemMI).getReg();
1496   int MIUnscaledOffset = getLdStOffsetOp(MemMI).getImm() * getMemScale(MemMI);
1497 
1498   // Scan forward looking for post-index opportunities.  Updating instructions
1499   // can't be formed if the memory instruction doesn't have the offset we're
1500   // looking for.
1501   if (MIUnscaledOffset != UnscaledOffset)
1502     return E;
1503 
1504   // If the base register overlaps a destination register, we can't
1505   // merge the update.
1506   bool IsPairedInsn = isPairedLdSt(MemMI);
1507   for (unsigned i = 0, e = IsPairedInsn ? 2 : 1; i != e; ++i) {
1508     unsigned DestReg = getLdStRegOp(MemMI, i).getReg();
1509     if (DestReg == BaseReg || TRI->isSubRegister(BaseReg, DestReg))
1510       return E;
1511   }
1512 
1513   // Track which registers have been modified and used between the first insn
1514   // (inclusive) and the second insn.
1515   ModifiedRegs.reset();
1516   UsedRegs.reset();
1517   ++MBBI;
1518   for (unsigned Count = 0; MBBI != E && Count < Limit; ++MBBI) {
1519     MachineInstr *MI = MBBI;
1520     // Skip DBG_VALUE instructions.
1521     if (MI->isDebugValue())
1522       continue;
1523 
1524     // Now that we know this is a real instruction, count it.
1525     ++Count;
1526 
1527     // If we found a match, return it.
1528     if (isMatchingUpdateInsn(I, MI, BaseReg, UnscaledOffset))
1529       return MBBI;
1530 
1531     // Update the status of what the instruction clobbered and used.
1532     trackRegDefsUses(MI, ModifiedRegs, UsedRegs, TRI);
1533 
1534     // Otherwise, if the base register is used or modified, we have no match, so
1535     // return early.
1536     if (ModifiedRegs[BaseReg] || UsedRegs[BaseReg])
1537       return E;
1538   }
1539   return E;
1540 }
1541 
1542 MachineBasicBlock::iterator AArch64LoadStoreOpt::findMatchingUpdateInsnBackward(
1543     MachineBasicBlock::iterator I, unsigned Limit) {
1544   MachineBasicBlock::iterator B = I->getParent()->begin();
1545   MachineBasicBlock::iterator E = I->getParent()->end();
1546   MachineInstr *MemMI = I;
1547   MachineBasicBlock::iterator MBBI = I;
1548 
1549   unsigned BaseReg = getLdStBaseOp(MemMI).getReg();
1550   int Offset = getLdStOffsetOp(MemMI).getImm();
1551 
1552   // If the load/store is the first instruction in the block, there's obviously
1553   // not any matching update. Ditto if the memory offset isn't zero.
1554   if (MBBI == B || Offset != 0)
1555     return E;
1556   // If the base register overlaps a destination register, we can't
1557   // merge the update.
1558   bool IsPairedInsn = isPairedLdSt(MemMI);
1559   for (unsigned i = 0, e = IsPairedInsn ? 2 : 1; i != e; ++i) {
1560     unsigned DestReg = getLdStRegOp(MemMI, i).getReg();
1561     if (DestReg == BaseReg || TRI->isSubRegister(BaseReg, DestReg))
1562       return E;
1563   }
1564 
1565   // Track which registers have been modified and used between the first insn
1566   // (inclusive) and the second insn.
1567   ModifiedRegs.reset();
1568   UsedRegs.reset();
1569   unsigned Count = 0;
1570   do {
1571     --MBBI;
1572     MachineInstr *MI = MBBI;
1573 
1574     // Don't count DBG_VALUE instructions towards the search limit.
1575     if (!MI->isDebugValue())
1576       ++Count;
1577 
1578     // If we found a match, return it.
1579     if (isMatchingUpdateInsn(I, MI, BaseReg, Offset))
1580       return MBBI;
1581 
1582     // Update the status of what the instruction clobbered and used.
1583     trackRegDefsUses(MI, ModifiedRegs, UsedRegs, TRI);
1584 
1585     // Otherwise, if the base register is used or modified, we have no match, so
1586     // return early.
1587     if (ModifiedRegs[BaseReg] || UsedRegs[BaseReg])
1588       return E;
1589   } while (MBBI != B && Count < Limit);
1590   return E;
1591 }
1592 
1593 bool AArch64LoadStoreOpt::tryToPromoteLoadFromStore(
1594     MachineBasicBlock::iterator &MBBI) {
1595   MachineInstr *MI = MBBI;
1596   // If this is a volatile load, don't mess with it.
1597   if (MI->hasOrderedMemoryRef())
1598     return false;
1599 
1600   // Make sure this is a reg+imm.
1601   // FIXME: It is possible to extend it to handle reg+reg cases.
1602   if (!getLdStOffsetOp(MI).isImm())
1603     return false;
1604 
1605   // Look backward up to LdStLimit instructions.
1606   MachineBasicBlock::iterator StoreI;
1607   if (findMatchingStore(MBBI, LdStLimit, StoreI)) {
1608     ++NumLoadsFromStoresPromoted;
1609     // Promote the load. Keeping the iterator straight is a
1610     // pain, so we let the merge routine tell us what the next instruction
1611     // is after it's done mucking about.
1612     MBBI = promoteLoadFromStore(MBBI, StoreI);
1613     return true;
1614   }
1615   return false;
1616 }
1617 
1618 bool AArch64LoadStoreOpt::isCandidateToMergeOrPair(MachineInstr *MI) {
1619   // If this is a volatile load/store, don't mess with it.
1620   if (MI->hasOrderedMemoryRef())
1621     return false;
1622 
1623   // Make sure this is a reg+imm (as opposed to an address reloc).
1624   if (!getLdStOffsetOp(MI).isImm())
1625     return false;
1626 
1627   // Can't merge/pair if the instruction modifies the base register.
1628   // e.g., ldr x0, [x0]
1629   unsigned BaseReg = getLdStBaseOp(MI).getReg();
1630   if (MI->modifiesRegister(BaseReg, TRI))
1631     return false;
1632 
1633   // Check if this load/store has a hint to avoid pair formation.
1634   // MachineMemOperands hints are set by the AArch64StorePairSuppress pass.
1635   if (TII->isLdStPairSuppressed(MI))
1636     return false;
1637 
1638   return true;
1639 }
1640 
1641 // Find narrow loads that can be converted into a single wider load with
1642 // bitfield extract instructions.  Also merge adjacent zero stores into a wider
1643 // store.
1644 bool AArch64LoadStoreOpt::tryToMergeLdStInst(
1645     MachineBasicBlock::iterator &MBBI) {
1646   assert((isNarrowLoad(MBBI) || isPromotableZeroStoreOpcode(MBBI)) &&
1647          "Expected narrow op.");
1648   MachineInstr *MI = MBBI;
1649   MachineBasicBlock::iterator E = MI->getParent()->end();
1650 
1651   if (!isCandidateToMergeOrPair(MI))
1652     return false;
1653 
1654   // For promotable zero stores, the stored value should be WZR.
1655   if (isPromotableZeroStoreOpcode(MI) &&
1656       getLdStRegOp(MI).getReg() != AArch64::WZR)
1657     return false;
1658 
1659   // Look ahead up to LdStLimit instructions for a mergable instruction.
1660   LdStPairFlags Flags;
1661   MachineBasicBlock::iterator MergeMI =
1662       findMatchingInsn(MBBI, Flags, LdStLimit);
1663   if (MergeMI != E) {
1664     if (isNarrowLoad(MI)) {
1665       ++NumNarrowLoadsPromoted;
1666     } else if (isPromotableZeroStoreInst(MI)) {
1667       ++NumZeroStoresPromoted;
1668     }
1669     // Keeping the iterator straight is a pain, so we let the merge routine tell
1670     // us what the next instruction is after it's done mucking about.
1671     MBBI = mergeNarrowInsns(MBBI, MergeMI, Flags);
1672     return true;
1673   }
1674   return false;
1675 }
1676 
1677 // Find loads and stores that can be merged into a single load or store pair
1678 // instruction.
1679 bool AArch64LoadStoreOpt::tryToPairLdStInst(MachineBasicBlock::iterator &MBBI) {
1680   MachineInstr *MI = MBBI;
1681   MachineBasicBlock::iterator E = MI->getParent()->end();
1682 
1683   if (!isCandidateToMergeOrPair(MI))
1684     return false;
1685 
1686   // Early exit if the offset is not possible to match. (6 bits of positive
1687   // range, plus allow an extra one in case we find a later insn that matches
1688   // with Offset-1)
1689   bool IsUnscaled = isUnscaledLdSt(MI);
1690   int Offset = getLdStOffsetOp(MI).getImm();
1691   int OffsetStride = IsUnscaled ? getMemScale(MI) : 1;
1692   if (!inBoundsForPair(IsUnscaled, Offset, OffsetStride))
1693     return false;
1694 
1695   // Look ahead up to LdStLimit instructions for a pairable instruction.
1696   LdStPairFlags Flags;
1697   MachineBasicBlock::iterator Paired = findMatchingInsn(MBBI, Flags, LdStLimit);
1698   if (Paired != E) {
1699     ++NumPairCreated;
1700     if (isUnscaledLdSt(MI))
1701       ++NumUnscaledPairCreated;
1702     // Keeping the iterator straight is a pain, so we let the merge routine tell
1703     // us what the next instruction is after it's done mucking about.
1704     MBBI = mergePairedInsns(MBBI, Paired, Flags);
1705     return true;
1706   }
1707   return false;
1708 }
1709 
1710 bool AArch64LoadStoreOpt::optimizeBlock(MachineBasicBlock &MBB,
1711                                         bool enableNarrowLdOpt) {
1712   bool Modified = false;
1713   // Four tranformations to do here:
1714   // 1) Find loads that directly read from stores and promote them by
1715   //    replacing with mov instructions. If the store is wider than the load,
1716   //    the load will be replaced with a bitfield extract.
1717   //      e.g.,
1718   //        str w1, [x0, #4]
1719   //        ldrh w2, [x0, #6]
1720   //        ; becomes
1721   //        str w1, [x0, #4]
1722   //        lsr	w2, w1, #16
1723   for (MachineBasicBlock::iterator MBBI = MBB.begin(), E = MBB.end();
1724        MBBI != E;) {
1725     MachineInstr *MI = MBBI;
1726     switch (MI->getOpcode()) {
1727     default:
1728       // Just move on to the next instruction.
1729       ++MBBI;
1730       break;
1731     // Scaled instructions.
1732     case AArch64::LDRBBui:
1733     case AArch64::LDRHHui:
1734     case AArch64::LDRWui:
1735     case AArch64::LDRXui:
1736     // Unscaled instructions.
1737     case AArch64::LDURBBi:
1738     case AArch64::LDURHHi:
1739     case AArch64::LDURWi:
1740     case AArch64::LDURXi: {
1741       if (tryToPromoteLoadFromStore(MBBI)) {
1742         Modified = true;
1743         break;
1744       }
1745       ++MBBI;
1746       break;
1747     }
1748     }
1749   }
1750   // 2) Find narrow loads that can be converted into a single wider load
1751   //    with bitfield extract instructions.
1752   //      e.g.,
1753   //        ldrh w0, [x2]
1754   //        ldrh w1, [x2, #2]
1755   //        ; becomes
1756   //        ldr w0, [x2]
1757   //        ubfx w1, w0, #16, #16
1758   //        and w0, w0, #ffff
1759   //
1760   //    Also merge adjacent zero stores into a wider store.
1761   //      e.g.,
1762   //        strh wzr, [x0]
1763   //        strh wzr, [x0, #2]
1764   //        ; becomes
1765   //        str wzr, [x0]
1766   for (MachineBasicBlock::iterator MBBI = MBB.begin(), E = MBB.end();
1767        enableNarrowLdOpt && MBBI != E;) {
1768     MachineInstr *MI = MBBI;
1769     switch (MI->getOpcode()) {
1770     default:
1771       // Just move on to the next instruction.
1772       ++MBBI;
1773       break;
1774     // Scaled instructions.
1775     case AArch64::LDRBBui:
1776     case AArch64::LDRHHui:
1777     case AArch64::LDRSBWui:
1778     case AArch64::LDRSHWui:
1779     case AArch64::STRBBui:
1780     case AArch64::STRHHui:
1781     case AArch64::STRWui:
1782     // Unscaled instructions.
1783     case AArch64::LDURBBi:
1784     case AArch64::LDURHHi:
1785     case AArch64::LDURSBWi:
1786     case AArch64::LDURSHWi:
1787     case AArch64::STURBBi:
1788     case AArch64::STURHHi:
1789     case AArch64::STURWi: {
1790       if (tryToMergeLdStInst(MBBI)) {
1791         Modified = true;
1792         break;
1793       }
1794       ++MBBI;
1795       break;
1796     }
1797     }
1798   }
1799   // 3) Find loads and stores that can be merged into a single load or store
1800   //    pair instruction.
1801   //      e.g.,
1802   //        ldr x0, [x2]
1803   //        ldr x1, [x2, #8]
1804   //        ; becomes
1805   //        ldp x0, x1, [x2]
1806   for (MachineBasicBlock::iterator MBBI = MBB.begin(), E = MBB.end();
1807        MBBI != E;) {
1808     MachineInstr *MI = MBBI;
1809     switch (MI->getOpcode()) {
1810     default:
1811       // Just move on to the next instruction.
1812       ++MBBI;
1813       break;
1814     // Scaled instructions.
1815     case AArch64::STRSui:
1816     case AArch64::STRDui:
1817     case AArch64::STRQui:
1818     case AArch64::STRXui:
1819     case AArch64::STRWui:
1820     case AArch64::LDRSui:
1821     case AArch64::LDRDui:
1822     case AArch64::LDRQui:
1823     case AArch64::LDRXui:
1824     case AArch64::LDRWui:
1825     case AArch64::LDRSWui:
1826     // Unscaled instructions.
1827     case AArch64::STURSi:
1828     case AArch64::STURDi:
1829     case AArch64::STURQi:
1830     case AArch64::STURWi:
1831     case AArch64::STURXi:
1832     case AArch64::LDURSi:
1833     case AArch64::LDURDi:
1834     case AArch64::LDURQi:
1835     case AArch64::LDURWi:
1836     case AArch64::LDURXi:
1837     case AArch64::LDURSWi: {
1838       if (tryToPairLdStInst(MBBI)) {
1839         Modified = true;
1840         break;
1841       }
1842       ++MBBI;
1843       break;
1844     }
1845     }
1846   }
1847   // 4) Find base register updates that can be merged into the load or store
1848   //    as a base-reg writeback.
1849   //      e.g.,
1850   //        ldr x0, [x2]
1851   //        add x2, x2, #4
1852   //        ; becomes
1853   //        ldr x0, [x2], #4
1854   for (MachineBasicBlock::iterator MBBI = MBB.begin(), E = MBB.end();
1855        MBBI != E;) {
1856     MachineInstr *MI = MBBI;
1857     // Do update merging. It's simpler to keep this separate from the above
1858     // switchs, though not strictly necessary.
1859     unsigned Opc = MI->getOpcode();
1860     switch (Opc) {
1861     default:
1862       // Just move on to the next instruction.
1863       ++MBBI;
1864       break;
1865     // Scaled instructions.
1866     case AArch64::STRSui:
1867     case AArch64::STRDui:
1868     case AArch64::STRQui:
1869     case AArch64::STRXui:
1870     case AArch64::STRWui:
1871     case AArch64::STRHHui:
1872     case AArch64::STRBBui:
1873     case AArch64::LDRSui:
1874     case AArch64::LDRDui:
1875     case AArch64::LDRQui:
1876     case AArch64::LDRXui:
1877     case AArch64::LDRWui:
1878     case AArch64::LDRHHui:
1879     case AArch64::LDRBBui:
1880     // Unscaled instructions.
1881     case AArch64::STURSi:
1882     case AArch64::STURDi:
1883     case AArch64::STURQi:
1884     case AArch64::STURWi:
1885     case AArch64::STURXi:
1886     case AArch64::LDURSi:
1887     case AArch64::LDURDi:
1888     case AArch64::LDURQi:
1889     case AArch64::LDURWi:
1890     case AArch64::LDURXi:
1891     // Paired instructions.
1892     case AArch64::LDPSi:
1893     case AArch64::LDPSWi:
1894     case AArch64::LDPDi:
1895     case AArch64::LDPQi:
1896     case AArch64::LDPWi:
1897     case AArch64::LDPXi:
1898     case AArch64::STPSi:
1899     case AArch64::STPDi:
1900     case AArch64::STPQi:
1901     case AArch64::STPWi:
1902     case AArch64::STPXi: {
1903       // Make sure this is a reg+imm (as opposed to an address reloc).
1904       if (!getLdStOffsetOp(MI).isImm()) {
1905         ++MBBI;
1906         break;
1907       }
1908       // Look forward to try to form a post-index instruction. For example,
1909       // ldr x0, [x20]
1910       // add x20, x20, #32
1911       //   merged into:
1912       // ldr x0, [x20], #32
1913       MachineBasicBlock::iterator Update =
1914           findMatchingUpdateInsnForward(MBBI, 0, UpdateLimit);
1915       if (Update != E) {
1916         // Merge the update into the ld/st.
1917         MBBI = mergeUpdateInsn(MBBI, Update, /*IsPreIdx=*/false);
1918         Modified = true;
1919         ++NumPostFolded;
1920         break;
1921       }
1922       // Don't know how to handle pre/post-index versions, so move to the next
1923       // instruction.
1924       if (isUnscaledLdSt(Opc)) {
1925         ++MBBI;
1926         break;
1927       }
1928 
1929       // Look back to try to find a pre-index instruction. For example,
1930       // add x0, x0, #8
1931       // ldr x1, [x0]
1932       //   merged into:
1933       // ldr x1, [x0, #8]!
1934       Update = findMatchingUpdateInsnBackward(MBBI, UpdateLimit);
1935       if (Update != E) {
1936         // Merge the update into the ld/st.
1937         MBBI = mergeUpdateInsn(MBBI, Update, /*IsPreIdx=*/true);
1938         Modified = true;
1939         ++NumPreFolded;
1940         break;
1941       }
1942       // The immediate in the load/store is scaled by the size of the memory
1943       // operation. The immediate in the add we're looking for,
1944       // however, is not, so adjust here.
1945       int UnscaledOffset = getLdStOffsetOp(MI).getImm() * getMemScale(MI);
1946 
1947       // Look forward to try to find a post-index instruction. For example,
1948       // ldr x1, [x0, #64]
1949       // add x0, x0, #64
1950       //   merged into:
1951       // ldr x1, [x0, #64]!
1952       Update = findMatchingUpdateInsnForward(MBBI, UnscaledOffset, UpdateLimit);
1953       if (Update != E) {
1954         // Merge the update into the ld/st.
1955         MBBI = mergeUpdateInsn(MBBI, Update, /*IsPreIdx=*/true);
1956         Modified = true;
1957         ++NumPreFolded;
1958         break;
1959       }
1960 
1961       // Nothing found. Just move to the next instruction.
1962       ++MBBI;
1963       break;
1964     }
1965     }
1966   }
1967 
1968   return Modified;
1969 }
1970 
1971 bool AArch64LoadStoreOpt::enableNarrowLdMerge(MachineFunction &Fn) {
1972   bool ProfitableArch = Subtarget->isCortexA57() || Subtarget->isKryo();
1973   // FIXME: The benefit from converting narrow loads into a wider load could be
1974   // microarchitectural as it assumes that a single load with two bitfield
1975   // extracts is cheaper than two narrow loads. Currently, this conversion is
1976   // enabled only in cortex-a57 on which performance benefits were verified.
1977   return ProfitableArch && !Subtarget->requiresStrictAlign();
1978 }
1979 
1980 bool AArch64LoadStoreOpt::runOnMachineFunction(MachineFunction &Fn) {
1981   Subtarget = &static_cast<const AArch64Subtarget &>(Fn.getSubtarget());
1982   TII = static_cast<const AArch64InstrInfo *>(Subtarget->getInstrInfo());
1983   TRI = Subtarget->getRegisterInfo();
1984 
1985   // Resize the modified and used register bitfield trackers.  We do this once
1986   // per function and then clear the bitfield each time we optimize a load or
1987   // store.
1988   ModifiedRegs.resize(TRI->getNumRegs());
1989   UsedRegs.resize(TRI->getNumRegs());
1990 
1991   bool Modified = false;
1992   bool enableNarrowLdOpt = enableNarrowLdMerge(Fn);
1993   for (auto &MBB : Fn)
1994     Modified |= optimizeBlock(MBB, enableNarrowLdOpt);
1995 
1996   return Modified;
1997 }
1998 
1999 // FIXME: Do we need/want a pre-alloc pass like ARM has to try to keep
2000 // loads and stores near one another?
2001 
2002 // FIXME: When pairing store instructions it's very possible for this pass to
2003 // hoist a store with a KILL marker above another use (without a KILL marker).
2004 // The resulting IR is invalid, but nothing uses the KILL markers after this
2005 // pass, so it's never caused a problem in practice.
2006 
2007 /// createAArch64LoadStoreOptimizationPass - returns an instance of the
2008 /// load / store optimization pass.
2009 FunctionPass *llvm::createAArch64LoadStoreOptimizationPass() {
2010   return new AArch64LoadStoreOpt();
2011 }
2012