[AArch64] Remove some redundant cases. NFC.
[oota-llvm.git] / lib / Target / AArch64 / AArch64LoadStoreOptimizer.cpp
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 /// AArch64AllocLoadStoreOpt - Post-register allocation pass to combine
37 /// load / store instructions to form ldp / stp instructions.
38
39 STATISTIC(NumPairCreated, "Number of load/store pair instructions generated");
40 STATISTIC(NumPostFolded, "Number of post-index updates folded");
41 STATISTIC(NumPreFolded, "Number of pre-index updates folded");
42 STATISTIC(NumUnscaledPairCreated,
43           "Number of load/store from unscaled generated");
44
45 static cl::opt<unsigned> ScanLimit("aarch64-load-store-scan-limit",
46                                    cl::init(20), cl::Hidden);
47
48 // Place holder while testing unscaled load/store combining
49 static cl::opt<bool> EnableAArch64UnscaledMemOp(
50     "aarch64-unscaled-mem-op", cl::Hidden,
51     cl::desc("Allow AArch64 unscaled load/store combining"), cl::init(true));
52
53 namespace llvm {
54 void initializeAArch64LoadStoreOptPass(PassRegistry &);
55 }
56
57 #define AARCH64_LOAD_STORE_OPT_NAME "AArch64 load / store optimization pass"
58
59 namespace {
60
61 typedef struct LdStPairFlags {
62   // If a matching instruction is found, MergeForward is set to true if the
63   // merge is to remove the first instruction and replace the second with
64   // a pair-wise insn, and false if the reverse is true.
65   bool MergeForward;
66
67   // SExtIdx gives the index of the result of the load pair that must be
68   // extended. The value of SExtIdx assumes that the paired load produces the
69   // value in this order: (I, returned iterator), i.e., -1 means no value has
70   // to be extended, 0 means I, and 1 means the returned iterator.
71   int SExtIdx;
72
73   LdStPairFlags() : MergeForward(false), SExtIdx(-1) {}
74
75   void setMergeForward(bool V = true) { MergeForward = V; }
76   bool getMergeForward() const { return MergeForward; }
77
78   void setSExtIdx(int V) { SExtIdx = V; }
79   int getSExtIdx() const { return SExtIdx; }
80
81 } LdStPairFlags;
82
83 struct AArch64LoadStoreOpt : public MachineFunctionPass {
84   static char ID;
85   AArch64LoadStoreOpt() : MachineFunctionPass(ID) {
86     initializeAArch64LoadStoreOptPass(*PassRegistry::getPassRegistry());
87   }
88
89   const AArch64InstrInfo *TII;
90   const TargetRegisterInfo *TRI;
91
92   // Scan the instructions looking for a load/store that can be combined
93   // with the current instruction into a load/store pair.
94   // Return the matching instruction if one is found, else MBB->end().
95   MachineBasicBlock::iterator findMatchingInsn(MachineBasicBlock::iterator I,
96                                                LdStPairFlags &Flags,
97                                                unsigned Limit);
98   // Merge the two instructions indicated into a single pair-wise instruction.
99   // If MergeForward is true, erase the first instruction and fold its
100   // operation into the second. If false, the reverse. Return the instruction
101   // following the first instruction (which may change during processing).
102   MachineBasicBlock::iterator
103   mergePairedInsns(MachineBasicBlock::iterator I,
104                    MachineBasicBlock::iterator Paired,
105                    const LdStPairFlags &Flags);
106
107   // Scan the instruction list to find a base register update that can
108   // be combined with the current instruction (a load or store) using
109   // pre or post indexed addressing with writeback. Scan forwards.
110   MachineBasicBlock::iterator
111   findMatchingUpdateInsnForward(MachineBasicBlock::iterator I, unsigned Limit,
112                                 int Value);
113
114   // Scan the instruction list to find a base register update that can
115   // be combined with the current instruction (a load or store) using
116   // pre or post indexed addressing with writeback. Scan backwards.
117   MachineBasicBlock::iterator
118   findMatchingUpdateInsnBackward(MachineBasicBlock::iterator I, unsigned Limit);
119
120   // Find an instruction that updates the base register of the ld/st
121   // instruction.
122   bool isMatchingUpdateInsn(MachineInstr *MemMI, MachineInstr *MI,
123                             unsigned BaseReg, int Offset);
124
125   // Merge a pre- or post-index base register update into a ld/st instruction.
126   MachineBasicBlock::iterator
127   mergeUpdateInsn(MachineBasicBlock::iterator I,
128                   MachineBasicBlock::iterator Update, bool IsPreIdx);
129
130   bool optimizeBlock(MachineBasicBlock &MBB);
131
132   bool runOnMachineFunction(MachineFunction &Fn) override;
133
134   const char *getPassName() const override {
135     return AARCH64_LOAD_STORE_OPT_NAME;
136   }
137 };
138 char AArch64LoadStoreOpt::ID = 0;
139 } // namespace
140
141 INITIALIZE_PASS(AArch64LoadStoreOpt, "aarch64-ldst-opt",
142                 AARCH64_LOAD_STORE_OPT_NAME, false, false)
143
144 static bool isUnscaledLdSt(unsigned Opc) {
145   switch (Opc) {
146   default:
147     return false;
148   case AArch64::STURSi:
149   case AArch64::STURDi:
150   case AArch64::STURQi:
151   case AArch64::STURWi:
152   case AArch64::STURXi:
153   case AArch64::LDURSi:
154   case AArch64::LDURDi:
155   case AArch64::LDURQi:
156   case AArch64::LDURWi:
157   case AArch64::LDURXi:
158   case AArch64::LDURSWi:
159     return true;
160   }
161 }
162
163 static bool isUnscaledLdSt(MachineInstr *MI) {
164   return isUnscaledLdSt(MI->getOpcode());
165 }
166
167 // Size in bytes of the data moved by an unscaled load or store.
168 static int getMemSize(MachineInstr *MI) {
169   switch (MI->getOpcode()) {
170   default:
171     llvm_unreachable("Opcode has unknown size!");
172   case AArch64::LDRSui:
173   case AArch64::LDURSi:
174   case AArch64::LDRSWui:
175   case AArch64::LDURSWi:
176   case AArch64::LDRWui:
177   case AArch64::LDURWi:
178   case AArch64::STRSui:
179   case AArch64::STURSi:
180   case AArch64::STRWui:
181   case AArch64::STURWi:
182     return 4;
183   case AArch64::LDRDui:
184   case AArch64::LDURDi:
185   case AArch64::LDRXui:
186   case AArch64::LDURXi:
187   case AArch64::STRDui:
188   case AArch64::STURDi:
189   case AArch64::STRXui:
190   case AArch64::STURXi:
191     return 8;
192   case AArch64::LDRQui:
193   case AArch64::LDURQi:
194   case AArch64::STRQui:
195   case AArch64::STURQi:
196     return 16;
197   }
198 }
199
200 static unsigned getMatchingNonSExtOpcode(unsigned Opc,
201                                          bool *IsValidLdStrOpc = nullptr) {
202   if (IsValidLdStrOpc)
203     *IsValidLdStrOpc = true;
204   switch (Opc) {
205   default:
206     if (IsValidLdStrOpc)
207       *IsValidLdStrOpc = false;
208     return UINT_MAX;
209   case AArch64::STRDui:
210   case AArch64::STURDi:
211   case AArch64::STRQui:
212   case AArch64::STURQi:
213   case AArch64::STRWui:
214   case AArch64::STURWi:
215   case AArch64::STRXui:
216   case AArch64::STURXi:
217   case AArch64::LDRDui:
218   case AArch64::LDURDi:
219   case AArch64::LDRQui:
220   case AArch64::LDURQi:
221   case AArch64::LDRWui:
222   case AArch64::LDURWi:
223   case AArch64::LDRXui:
224   case AArch64::LDURXi:
225   case AArch64::STRSui:
226   case AArch64::STURSi:
227   case AArch64::LDRSui:
228   case AArch64::LDURSi:
229     return Opc;
230   case AArch64::LDRSWui:
231     return AArch64::LDRWui;
232   case AArch64::LDURSWi:
233     return AArch64::LDURWi;
234   }
235 }
236
237 static unsigned getMatchingPairOpcode(unsigned Opc) {
238   switch (Opc) {
239   default:
240     llvm_unreachable("Opcode has no pairwise equivalent!");
241   case AArch64::STRSui:
242   case AArch64::STURSi:
243     return AArch64::STPSi;
244   case AArch64::STRDui:
245   case AArch64::STURDi:
246     return AArch64::STPDi;
247   case AArch64::STRQui:
248   case AArch64::STURQi:
249     return AArch64::STPQi;
250   case AArch64::STRWui:
251   case AArch64::STURWi:
252     return AArch64::STPWi;
253   case AArch64::STRXui:
254   case AArch64::STURXi:
255     return AArch64::STPXi;
256   case AArch64::LDRSui:
257   case AArch64::LDURSi:
258     return AArch64::LDPSi;
259   case AArch64::LDRDui:
260   case AArch64::LDURDi:
261     return AArch64::LDPDi;
262   case AArch64::LDRQui:
263   case AArch64::LDURQi:
264     return AArch64::LDPQi;
265   case AArch64::LDRWui:
266   case AArch64::LDURWi:
267     return AArch64::LDPWi;
268   case AArch64::LDRXui:
269   case AArch64::LDURXi:
270     return AArch64::LDPXi;
271   case AArch64::LDRSWui:
272   case AArch64::LDURSWi:
273     return AArch64::LDPSWi;
274   }
275 }
276
277 static unsigned getPreIndexedOpcode(unsigned Opc) {
278   switch (Opc) {
279   default:
280     llvm_unreachable("Opcode has no pre-indexed equivalent!");
281   case AArch64::STRSui:
282     return AArch64::STRSpre;
283   case AArch64::STRDui:
284     return AArch64::STRDpre;
285   case AArch64::STRQui:
286     return AArch64::STRQpre;
287   case AArch64::STRWui:
288     return AArch64::STRWpre;
289   case AArch64::STRXui:
290     return AArch64::STRXpre;
291   case AArch64::LDRSui:
292     return AArch64::LDRSpre;
293   case AArch64::LDRDui:
294     return AArch64::LDRDpre;
295   case AArch64::LDRQui:
296     return AArch64::LDRQpre;
297   case AArch64::LDRWui:
298     return AArch64::LDRWpre;
299   case AArch64::LDRXui:
300     return AArch64::LDRXpre;
301   case AArch64::LDRSWui:
302     return AArch64::LDRSWpre;
303   case AArch64::LDPSi:
304     return AArch64::LDPSpre;
305   case AArch64::LDPDi:
306     return AArch64::LDPDpre;
307   case AArch64::LDPQi:
308     return AArch64::LDPQpre;
309   case AArch64::LDPWi:
310     return AArch64::LDPWpre;
311   case AArch64::LDPXi:
312     return AArch64::LDPXpre;
313   case AArch64::STPSi:
314     return AArch64::STPSpre;
315   case AArch64::STPDi:
316     return AArch64::STPDpre;
317   case AArch64::STPQi:
318     return AArch64::STPQpre;
319   case AArch64::STPWi:
320     return AArch64::STPWpre;
321   case AArch64::STPXi:
322     return AArch64::STPXpre;
323   }
324 }
325
326 static unsigned getPostIndexedOpcode(unsigned Opc) {
327   switch (Opc) {
328   default:
329     llvm_unreachable("Opcode has no post-indexed wise equivalent!");
330   case AArch64::STRSui:
331     return AArch64::STRSpost;
332   case AArch64::STRDui:
333     return AArch64::STRDpost;
334   case AArch64::STRQui:
335     return AArch64::STRQpost;
336   case AArch64::STRWui:
337     return AArch64::STRWpost;
338   case AArch64::STRXui:
339     return AArch64::STRXpost;
340   case AArch64::LDRSui:
341     return AArch64::LDRSpost;
342   case AArch64::LDRDui:
343     return AArch64::LDRDpost;
344   case AArch64::LDRQui:
345     return AArch64::LDRQpost;
346   case AArch64::LDRWui:
347     return AArch64::LDRWpost;
348   case AArch64::LDRXui:
349     return AArch64::LDRXpost;
350   case AArch64::LDRSWui:
351     return AArch64::LDRSWpost;
352   case AArch64::LDPSi:
353     return AArch64::LDPSpost;
354   case AArch64::LDPDi:
355     return AArch64::LDPDpost;
356   case AArch64::LDPQi:
357     return AArch64::LDPQpost;
358   case AArch64::LDPWi:
359     return AArch64::LDPWpost;
360   case AArch64::LDPXi:
361     return AArch64::LDPXpost;
362   case AArch64::STPSi:
363     return AArch64::STPSpost;
364   case AArch64::STPDi:
365     return AArch64::STPDpost;
366   case AArch64::STPQi:
367     return AArch64::STPQpost;
368   case AArch64::STPWi:
369     return AArch64::STPWpost;
370   case AArch64::STPXi:
371     return AArch64::STPXpost;
372   }
373 }
374
375 static bool isPairedLdSt(const MachineInstr *MI) {
376   switch (MI->getOpcode()) {
377   default:
378     return false;
379   case AArch64::LDPSi:
380   case AArch64::LDPDi:
381   case AArch64::LDPQi:
382   case AArch64::LDPWi:
383   case AArch64::LDPXi:
384   case AArch64::STPSi:
385   case AArch64::STPDi:
386   case AArch64::STPQi:
387   case AArch64::STPWi:
388   case AArch64::STPXi:
389     return true;
390   }
391 }
392
393 static const MachineOperand &getLdStRegOp(const MachineInstr *MI,
394                                           unsigned PairedRegOp = 0) {
395   assert(PairedRegOp < 2 && "Unexpected register operand idx.");
396   unsigned Idx = isPairedLdSt(MI) ? PairedRegOp : 0;
397   return MI->getOperand(Idx);
398 }
399
400 static const MachineOperand &getLdStBaseOp(const MachineInstr *MI) {
401   unsigned Idx = isPairedLdSt(MI) ? 2 : 1;
402   return MI->getOperand(Idx);
403 }
404
405 static const MachineOperand &getLdStOffsetOp(const MachineInstr *MI) {
406   unsigned Idx = isPairedLdSt(MI) ? 3 : 2;
407   return MI->getOperand(Idx);
408 }
409
410 MachineBasicBlock::iterator
411 AArch64LoadStoreOpt::mergePairedInsns(MachineBasicBlock::iterator I,
412                                       MachineBasicBlock::iterator Paired,
413                                       const LdStPairFlags &Flags) {
414   MachineBasicBlock::iterator NextI = I;
415   ++NextI;
416   // If NextI is the second of the two instructions to be merged, we need
417   // to skip one further. Either way we merge will invalidate the iterator,
418   // and we don't need to scan the new instruction, as it's a pairwise
419   // instruction, which we're not considering for further action anyway.
420   if (NextI == Paired)
421     ++NextI;
422
423   int SExtIdx = Flags.getSExtIdx();
424   unsigned Opc =
425       SExtIdx == -1 ? I->getOpcode() : getMatchingNonSExtOpcode(I->getOpcode());
426   bool IsUnscaled = isUnscaledLdSt(Opc);
427   int OffsetStride =
428       IsUnscaled && EnableAArch64UnscaledMemOp ? getMemSize(I) : 1;
429
430   bool MergeForward = Flags.getMergeForward();
431   unsigned NewOpc = getMatchingPairOpcode(Opc);
432   // Insert our new paired instruction after whichever of the paired
433   // instructions MergeForward indicates.
434   MachineBasicBlock::iterator InsertionPoint = MergeForward ? Paired : I;
435   // Also based on MergeForward is from where we copy the base register operand
436   // so we get the flags compatible with the input code.
437   const MachineOperand &BaseRegOp =
438       MergeForward ? getLdStBaseOp(Paired) : getLdStBaseOp(I);
439
440   // Which register is Rt and which is Rt2 depends on the offset order.
441   MachineInstr *RtMI, *Rt2MI;
442   if (getLdStOffsetOp(I).getImm() ==
443       getLdStOffsetOp(Paired).getImm() + OffsetStride) {
444     RtMI = Paired;
445     Rt2MI = I;
446     // Here we swapped the assumption made for SExtIdx.
447     // I.e., we turn ldp I, Paired into ldp Paired, I.
448     // Update the index accordingly.
449     if (SExtIdx != -1)
450       SExtIdx = (SExtIdx + 1) % 2;
451   } else {
452     RtMI = I;
453     Rt2MI = Paired;
454   }
455   // Handle Unscaled
456   int OffsetImm = getLdStOffsetOp(RtMI).getImm();
457   if (IsUnscaled && EnableAArch64UnscaledMemOp)
458     OffsetImm /= OffsetStride;
459
460   // Construct the new instruction.
461   MachineInstrBuilder MIB = BuildMI(*I->getParent(), InsertionPoint,
462                                     I->getDebugLoc(), TII->get(NewOpc))
463                                 .addOperand(getLdStRegOp(RtMI))
464                                 .addOperand(getLdStRegOp(Rt2MI))
465                                 .addOperand(BaseRegOp)
466                                 .addImm(OffsetImm);
467   (void)MIB;
468
469   // FIXME: Do we need/want to copy the mem operands from the source
470   //        instructions? Probably. What uses them after this?
471
472   DEBUG(dbgs() << "Creating pair load/store. Replacing instructions:\n    ");
473   DEBUG(I->print(dbgs()));
474   DEBUG(dbgs() << "    ");
475   DEBUG(Paired->print(dbgs()));
476   DEBUG(dbgs() << "  with instruction:\n    ");
477
478   if (SExtIdx != -1) {
479     // Generate the sign extension for the proper result of the ldp.
480     // I.e., with X1, that would be:
481     // %W1<def> = KILL %W1, %X1<imp-def>
482     // %X1<def> = SBFMXri %X1<kill>, 0, 31
483     MachineOperand &DstMO = MIB->getOperand(SExtIdx);
484     // Right now, DstMO has the extended register, since it comes from an
485     // extended opcode.
486     unsigned DstRegX = DstMO.getReg();
487     // Get the W variant of that register.
488     unsigned DstRegW = TRI->getSubReg(DstRegX, AArch64::sub_32);
489     // Update the result of LDP to use the W instead of the X variant.
490     DstMO.setReg(DstRegW);
491     DEBUG(((MachineInstr *)MIB)->print(dbgs()));
492     DEBUG(dbgs() << "\n");
493     // Make the machine verifier happy by providing a definition for
494     // the X register.
495     // Insert this definition right after the generated LDP, i.e., before
496     // InsertionPoint.
497     MachineInstrBuilder MIBKill =
498         BuildMI(*I->getParent(), InsertionPoint, I->getDebugLoc(),
499                 TII->get(TargetOpcode::KILL), DstRegW)
500             .addReg(DstRegW)
501             .addReg(DstRegX, RegState::Define);
502     MIBKill->getOperand(2).setImplicit();
503     // Create the sign extension.
504     MachineInstrBuilder MIBSXTW =
505         BuildMI(*I->getParent(), InsertionPoint, I->getDebugLoc(),
506                 TII->get(AArch64::SBFMXri), DstRegX)
507             .addReg(DstRegX)
508             .addImm(0)
509             .addImm(31);
510     (void)MIBSXTW;
511     DEBUG(dbgs() << "  Extend operand:\n    ");
512     DEBUG(((MachineInstr *)MIBSXTW)->print(dbgs()));
513     DEBUG(dbgs() << "\n");
514   } else {
515     DEBUG(((MachineInstr *)MIB)->print(dbgs()));
516     DEBUG(dbgs() << "\n");
517   }
518
519   // Erase the old instructions.
520   I->eraseFromParent();
521   Paired->eraseFromParent();
522
523   return NextI;
524 }
525
526 /// trackRegDefsUses - Remember what registers the specified instruction uses
527 /// and modifies.
528 static void trackRegDefsUses(const MachineInstr *MI, BitVector &ModifiedRegs,
529                              BitVector &UsedRegs,
530                              const TargetRegisterInfo *TRI) {
531   for (const MachineOperand &MO : MI->operands()) {
532     if (MO.isRegMask())
533       ModifiedRegs.setBitsNotInMask(MO.getRegMask());
534
535     if (!MO.isReg())
536       continue;
537     unsigned Reg = MO.getReg();
538     if (MO.isDef()) {
539       for (MCRegAliasIterator AI(Reg, TRI, true); AI.isValid(); ++AI)
540         ModifiedRegs.set(*AI);
541     } else {
542       assert(MO.isUse() && "Reg operand not a def and not a use?!?");
543       for (MCRegAliasIterator AI(Reg, TRI, true); AI.isValid(); ++AI)
544         UsedRegs.set(*AI);
545     }
546   }
547 }
548
549 static bool inBoundsForPair(bool IsUnscaled, int Offset, int OffsetStride) {
550   // Convert the byte-offset used by unscaled into an "element" offset used
551   // by the scaled pair load/store instructions.
552   if (IsUnscaled)
553     Offset /= OffsetStride;
554
555   return Offset <= 63 && Offset >= -64;
556 }
557
558 // Do alignment, specialized to power of 2 and for signed ints,
559 // avoiding having to do a C-style cast from uint_64t to int when
560 // using RoundUpToAlignment from include/llvm/Support/MathExtras.h.
561 // FIXME: Move this function to include/MathExtras.h?
562 static int alignTo(int Num, int PowOf2) {
563   return (Num + PowOf2 - 1) & ~(PowOf2 - 1);
564 }
565
566 static bool mayAlias(MachineInstr *MIa, MachineInstr *MIb,
567                      const AArch64InstrInfo *TII) {
568   // One of the instructions must modify memory.
569   if (!MIa->mayStore() && !MIb->mayStore())
570     return false;
571
572   // Both instructions must be memory operations.
573   if (!MIa->mayLoadOrStore() && !MIb->mayLoadOrStore())
574     return false;
575
576   return !TII->areMemAccessesTriviallyDisjoint(MIa, MIb);
577 }
578
579 static bool mayAlias(MachineInstr *MIa,
580                      SmallVectorImpl<MachineInstr *> &MemInsns,
581                      const AArch64InstrInfo *TII) {
582   for (auto &MIb : MemInsns)
583     if (mayAlias(MIa, MIb, TII))
584       return true;
585
586   return false;
587 }
588
589 /// findMatchingInsn - Scan the instructions looking for a load/store that can
590 /// be combined with the current instruction into a load/store pair.
591 MachineBasicBlock::iterator
592 AArch64LoadStoreOpt::findMatchingInsn(MachineBasicBlock::iterator I,
593                                       LdStPairFlags &Flags,
594                                       unsigned Limit) {
595   MachineBasicBlock::iterator E = I->getParent()->end();
596   MachineBasicBlock::iterator MBBI = I;
597   MachineInstr *FirstMI = I;
598   ++MBBI;
599
600   unsigned Opc = FirstMI->getOpcode();
601   bool MayLoad = FirstMI->mayLoad();
602   bool IsUnscaled = isUnscaledLdSt(FirstMI);
603   unsigned Reg = getLdStRegOp(FirstMI).getReg();
604   unsigned BaseReg = getLdStBaseOp(FirstMI).getReg();
605   int Offset = getLdStOffsetOp(FirstMI).getImm();
606
607   // Early exit if the first instruction modifies the base register.
608   // e.g., ldr x0, [x0]
609   if (FirstMI->modifiesRegister(BaseReg, TRI))
610     return E;
611
612   // Early exit if the offset if not possible to match. (6 bits of positive
613   // range, plus allow an extra one in case we find a later insn that matches
614   // with Offset-1)
615   int OffsetStride =
616       IsUnscaled && EnableAArch64UnscaledMemOp ? getMemSize(FirstMI) : 1;
617   if (!inBoundsForPair(IsUnscaled, Offset, OffsetStride))
618     return E;
619
620   // Track which registers have been modified and used between the first insn
621   // (inclusive) and the second insn.
622   BitVector ModifiedRegs, UsedRegs;
623   ModifiedRegs.resize(TRI->getNumRegs());
624   UsedRegs.resize(TRI->getNumRegs());
625
626   // Remember any instructions that read/write memory between FirstMI and MI.
627   SmallVector<MachineInstr *, 4> MemInsns;
628
629   for (unsigned Count = 0; MBBI != E && Count < Limit; ++MBBI) {
630     MachineInstr *MI = MBBI;
631     // Skip DBG_VALUE instructions. Otherwise debug info can affect the
632     // optimization by changing how far we scan.
633     if (MI->isDebugValue())
634       continue;
635
636     // Now that we know this is a real instruction, count it.
637     ++Count;
638
639     bool CanMergeOpc = Opc == MI->getOpcode();
640     Flags.setSExtIdx(-1);
641     if (!CanMergeOpc) {
642       bool IsValidLdStrOpc;
643       unsigned NonSExtOpc = getMatchingNonSExtOpcode(Opc, &IsValidLdStrOpc);
644       assert(IsValidLdStrOpc &&
645              "Given Opc should be a Load or Store with an immediate");
646       // Opc will be the first instruction in the pair.
647       Flags.setSExtIdx(NonSExtOpc == (unsigned)Opc ? 1 : 0);
648       CanMergeOpc = NonSExtOpc == getMatchingNonSExtOpcode(MI->getOpcode());
649     }
650
651     if (CanMergeOpc && getLdStOffsetOp(MI).isImm()) {
652       assert(MI->mayLoadOrStore() && "Expected memory operation.");
653       // If we've found another instruction with the same opcode, check to see
654       // if the base and offset are compatible with our starting instruction.
655       // These instructions all have scaled immediate operands, so we just
656       // check for +1/-1. Make sure to check the new instruction offset is
657       // actually an immediate and not a symbolic reference destined for
658       // a relocation.
659       //
660       // Pairwise instructions have a 7-bit signed offset field. Single insns
661       // have a 12-bit unsigned offset field. To be a valid combine, the
662       // final offset must be in range.
663       unsigned MIBaseReg = getLdStBaseOp(MI).getReg();
664       int MIOffset = getLdStOffsetOp(MI).getImm();
665       if (BaseReg == MIBaseReg && ((Offset == MIOffset + OffsetStride) ||
666                                    (Offset + OffsetStride == MIOffset))) {
667         int MinOffset = Offset < MIOffset ? Offset : MIOffset;
668         // If this is a volatile load/store that otherwise matched, stop looking
669         // as something is going on that we don't have enough information to
670         // safely transform. Similarly, stop if we see a hint to avoid pairs.
671         if (MI->hasOrderedMemoryRef() || TII->isLdStPairSuppressed(MI))
672           return E;
673         // If the resultant immediate offset of merging these instructions
674         // is out of range for a pairwise instruction, bail and keep looking.
675         bool MIIsUnscaled = isUnscaledLdSt(MI);
676         if (!inBoundsForPair(MIIsUnscaled, MinOffset, OffsetStride)) {
677           trackRegDefsUses(MI, ModifiedRegs, UsedRegs, TRI);
678           MemInsns.push_back(MI);
679           continue;
680         }
681         // If the alignment requirements of the paired (scaled) instruction
682         // can't express the offset of the unscaled input, bail and keep
683         // looking.
684         if (IsUnscaled && EnableAArch64UnscaledMemOp &&
685             (alignTo(MinOffset, OffsetStride) != MinOffset)) {
686           trackRegDefsUses(MI, ModifiedRegs, UsedRegs, TRI);
687           MemInsns.push_back(MI);
688           continue;
689         }
690         // If the destination register of the loads is the same register, bail
691         // and keep looking. A load-pair instruction with both destination
692         // registers the same is UNPREDICTABLE and will result in an exception.
693         if (MayLoad && Reg == getLdStRegOp(MI).getReg()) {
694           trackRegDefsUses(MI, ModifiedRegs, UsedRegs, TRI);
695           MemInsns.push_back(MI);
696           continue;
697         }
698
699         // If the Rt of the second instruction was not modified or used between
700         // the two instructions and none of the instructions between the second
701         // and first alias with the second, we can combine the second into the
702         // first.
703         if (!ModifiedRegs[getLdStRegOp(MI).getReg()] &&
704             !(MI->mayLoad() && UsedRegs[getLdStRegOp(MI).getReg()]) &&
705             !mayAlias(MI, MemInsns, TII)) {
706           Flags.setMergeForward(false);
707           return MBBI;
708         }
709
710         // Likewise, if the Rt of the first instruction is not modified or used
711         // between the two instructions and none of the instructions between the
712         // first and the second alias with the first, we can combine the first
713         // into the second.
714         if (!ModifiedRegs[getLdStRegOp(FirstMI).getReg()] &&
715             !(MayLoad && UsedRegs[getLdStRegOp(FirstMI).getReg()]) &&
716             !mayAlias(FirstMI, MemInsns, TII)) {
717           Flags.setMergeForward(true);
718           return MBBI;
719         }
720         // Unable to combine these instructions due to interference in between.
721         // Keep looking.
722       }
723     }
724
725     // If the instruction wasn't a matching load or store.  Stop searching if we
726     // encounter a call instruction that might modify memory.
727     if (MI->isCall())
728       return E;
729
730     // Update modified / uses register lists.
731     trackRegDefsUses(MI, ModifiedRegs, UsedRegs, TRI);
732
733     // Otherwise, if the base register is modified, we have no match, so
734     // return early.
735     if (ModifiedRegs[BaseReg])
736       return E;
737
738     // Update list of instructions that read/write memory.
739     if (MI->mayLoadOrStore())
740       MemInsns.push_back(MI);
741   }
742   return E;
743 }
744
745 MachineBasicBlock::iterator
746 AArch64LoadStoreOpt::mergeUpdateInsn(MachineBasicBlock::iterator I,
747                                      MachineBasicBlock::iterator Update,
748                                      bool IsPreIdx) {
749   assert((Update->getOpcode() == AArch64::ADDXri ||
750           Update->getOpcode() == AArch64::SUBXri) &&
751          "Unexpected base register update instruction to merge!");
752   MachineBasicBlock::iterator NextI = I;
753   // Return the instruction following the merged instruction, which is
754   // the instruction following our unmerged load. Unless that's the add/sub
755   // instruction we're merging, in which case it's the one after that.
756   if (++NextI == Update)
757     ++NextI;
758
759   int Value = Update->getOperand(2).getImm();
760   assert(AArch64_AM::getShiftValue(Update->getOperand(3).getImm()) == 0 &&
761          "Can't merge 1 << 12 offset into pre-/post-indexed load / store");
762   if (Update->getOpcode() == AArch64::SUBXri)
763     Value = -Value;
764
765   unsigned NewOpc = IsPreIdx ? getPreIndexedOpcode(I->getOpcode())
766                              : getPostIndexedOpcode(I->getOpcode());
767   MachineInstrBuilder MIB;
768   if (!isPairedLdSt(I)) {
769     // Non-paired instruction.
770     MIB = BuildMI(*I->getParent(), I, I->getDebugLoc(), TII->get(NewOpc))
771               .addOperand(getLdStRegOp(Update))
772               .addOperand(getLdStRegOp(I))
773               .addOperand(getLdStBaseOp(I))
774               .addImm(Value);
775   } else {
776     // Paired instruction.
777     const MachineFunction &MF = *I->getParent()->getParent();
778     int Scale = TII->getRegClass(I->getDesc(), 0, TRI, MF)->getSize();
779     MIB = BuildMI(*I->getParent(), I, I->getDebugLoc(), TII->get(NewOpc))
780               .addOperand(getLdStRegOp(Update))
781               .addOperand(getLdStRegOp(I, 0))
782               .addOperand(getLdStRegOp(I, 1))
783               .addOperand(getLdStBaseOp(I))
784               .addImm(Value / Scale);
785   }
786   (void)MIB;
787
788   if (IsPreIdx)
789     DEBUG(dbgs() << "Creating pre-indexed load/store.");
790   else
791     DEBUG(dbgs() << "Creating post-indexed load/store.");
792   DEBUG(dbgs() << "    Replacing instructions:\n    ");
793   DEBUG(I->print(dbgs()));
794   DEBUG(dbgs() << "    ");
795   DEBUG(Update->print(dbgs()));
796   DEBUG(dbgs() << "  with instruction:\n    ");
797   DEBUG(((MachineInstr *)MIB)->print(dbgs()));
798   DEBUG(dbgs() << "\n");
799
800   // Erase the old instructions for the block.
801   I->eraseFromParent();
802   Update->eraseFromParent();
803
804   return NextI;
805 }
806
807 bool AArch64LoadStoreOpt::isMatchingUpdateInsn(MachineInstr *MemMI,
808                                                MachineInstr *MI,
809                                                unsigned BaseReg, int Offset) {
810   switch (MI->getOpcode()) {
811   default:
812     break;
813   case AArch64::SUBXri:
814     // Negate the offset for a SUB instruction.
815     Offset *= -1;
816   // FALLTHROUGH
817   case AArch64::ADDXri:
818     // Make sure it's a vanilla immediate operand, not a relocation or
819     // anything else we can't handle.
820     if (!MI->getOperand(2).isImm())
821       break;
822     // Watch out for 1 << 12 shifted value.
823     if (AArch64_AM::getShiftValue(MI->getOperand(3).getImm()))
824       break;
825
826     // The update instruction source and destination register must be the
827     // same as the load/store base register.
828     if (MI->getOperand(0).getReg() != BaseReg ||
829         MI->getOperand(1).getReg() != BaseReg)
830       break;
831
832     bool IsPairedInsn = isPairedLdSt(MemMI);
833     int UpdateOffset = MI->getOperand(2).getImm();
834     // For non-paired load/store instructions, the immediate must fit in a
835     // signed 9-bit integer.
836     if (!IsPairedInsn && (UpdateOffset > 255 || UpdateOffset < -256))
837       break;
838
839     // For paired load/store instructions, the immediate must be a multiple of
840     // the scaling factor.  The scaled offset must also fit into a signed 7-bit
841     // integer.
842     if (IsPairedInsn) {
843       const MachineFunction &MF = *MemMI->getParent()->getParent();
844       int Scale = TII->getRegClass(MemMI->getDesc(), 0, TRI, MF)->getSize();
845       if (UpdateOffset % Scale != 0)
846         break;
847
848       int ScaledOffset = UpdateOffset / Scale;
849       if (ScaledOffset > 64 || ScaledOffset < -64)
850         break;
851     }
852
853     // If we have a non-zero Offset, we check that it matches the amount
854     // we're adding to the register.
855     if (!Offset || Offset == MI->getOperand(2).getImm())
856       return true;
857     break;
858   }
859   return false;
860 }
861
862 MachineBasicBlock::iterator AArch64LoadStoreOpt::findMatchingUpdateInsnForward(
863     MachineBasicBlock::iterator I, unsigned Limit, int Value) {
864   MachineBasicBlock::iterator E = I->getParent()->end();
865   MachineInstr *MemMI = I;
866   MachineBasicBlock::iterator MBBI = I;
867   const MachineFunction &MF = *MemMI->getParent()->getParent();
868
869   unsigned BaseReg = getLdStBaseOp(MemMI).getReg();
870   int Offset = getLdStOffsetOp(MemMI).getImm() *
871                TII->getRegClass(MemMI->getDesc(), 0, TRI, MF)->getSize();
872
873   // If the base register overlaps a destination register, we can't
874   // merge the update.
875   bool IsPairedInsn = isPairedLdSt(MemMI);
876   for (unsigned i = 0, e = IsPairedInsn ? 2 : 1; i != e; ++i) {
877     unsigned DestReg = getLdStRegOp(MemMI, i).getReg();
878     if (DestReg == BaseReg || TRI->isSubRegister(BaseReg, DestReg))
879       return E;
880   }
881
882   // Scan forward looking for post-index opportunities.
883   // Updating instructions can't be formed if the memory insn already
884   // has an offset other than the value we're looking for.
885   if (Offset != Value)
886     return E;
887
888   // Track which registers have been modified and used between the first insn
889   // (inclusive) and the second insn.
890   BitVector ModifiedRegs, UsedRegs;
891   ModifiedRegs.resize(TRI->getNumRegs());
892   UsedRegs.resize(TRI->getNumRegs());
893   ++MBBI;
894   for (unsigned Count = 0; MBBI != E; ++MBBI) {
895     MachineInstr *MI = MBBI;
896     // Skip DBG_VALUE instructions. Otherwise debug info can affect the
897     // optimization by changing how far we scan.
898     if (MI->isDebugValue())
899       continue;
900
901     // Now that we know this is a real instruction, count it.
902     ++Count;
903
904     // If we found a match, return it.
905     if (isMatchingUpdateInsn(I, MI, BaseReg, Value))
906       return MBBI;
907
908     // Update the status of what the instruction clobbered and used.
909     trackRegDefsUses(MI, ModifiedRegs, UsedRegs, TRI);
910
911     // Otherwise, if the base register is used or modified, we have no match, so
912     // return early.
913     if (ModifiedRegs[BaseReg] || UsedRegs[BaseReg])
914       return E;
915   }
916   return E;
917 }
918
919 MachineBasicBlock::iterator AArch64LoadStoreOpt::findMatchingUpdateInsnBackward(
920     MachineBasicBlock::iterator I, unsigned Limit) {
921   MachineBasicBlock::iterator B = I->getParent()->begin();
922   MachineBasicBlock::iterator E = I->getParent()->end();
923   MachineInstr *MemMI = I;
924   MachineBasicBlock::iterator MBBI = I;
925   const MachineFunction &MF = *MemMI->getParent()->getParent();
926
927   unsigned BaseReg = getLdStBaseOp(MemMI).getReg();
928   int Offset = getLdStOffsetOp(MemMI).getImm();
929   unsigned RegSize = TII->getRegClass(MemMI->getDesc(), 0, TRI, MF)->getSize();
930
931   // If the load/store is the first instruction in the block, there's obviously
932   // not any matching update. Ditto if the memory offset isn't zero.
933   if (MBBI == B || Offset != 0)
934     return E;
935   // If the base register overlaps a destination register, we can't
936   // merge the update.
937   bool IsPairedInsn = isPairedLdSt(MemMI);
938   for (unsigned i = 0, e = IsPairedInsn ? 2 : 1; i != e; ++i) {
939     unsigned DestReg = getLdStRegOp(MemMI, i).getReg();
940     if (DestReg == BaseReg || TRI->isSubRegister(BaseReg, DestReg))
941       return E;
942   }
943
944   // Track which registers have been modified and used between the first insn
945   // (inclusive) and the second insn.
946   BitVector ModifiedRegs, UsedRegs;
947   ModifiedRegs.resize(TRI->getNumRegs());
948   UsedRegs.resize(TRI->getNumRegs());
949   --MBBI;
950   for (unsigned Count = 0; MBBI != B; --MBBI) {
951     MachineInstr *MI = MBBI;
952     // Skip DBG_VALUE instructions. Otherwise debug info can affect the
953     // optimization by changing how far we scan.
954     if (MI->isDebugValue())
955       continue;
956
957     // Now that we know this is a real instruction, count it.
958     ++Count;
959
960     // If we found a match, return it.
961     if (isMatchingUpdateInsn(I, MI, BaseReg, RegSize))
962       return MBBI;
963
964     // Update the status of what the instruction clobbered and used.
965     trackRegDefsUses(MI, ModifiedRegs, UsedRegs, TRI);
966
967     // Otherwise, if the base register is used or modified, we have no match, so
968     // return early.
969     if (ModifiedRegs[BaseReg] || UsedRegs[BaseReg])
970       return E;
971   }
972   return E;
973 }
974
975 bool AArch64LoadStoreOpt::optimizeBlock(MachineBasicBlock &MBB) {
976   bool Modified = false;
977   // Two tranformations to do here:
978   // 1) Find loads and stores that can be merged into a single load or store
979   //    pair instruction.
980   //      e.g.,
981   //        ldr x0, [x2]
982   //        ldr x1, [x2, #8]
983   //        ; becomes
984   //        ldp x0, x1, [x2]
985   // 2) Find base register updates that can be merged into the load or store
986   //    as a base-reg writeback.
987   //      e.g.,
988   //        ldr x0, [x2]
989   //        add x2, x2, #4
990   //        ; becomes
991   //        ldr x0, [x2], #4
992
993   for (MachineBasicBlock::iterator MBBI = MBB.begin(), E = MBB.end();
994        MBBI != E;) {
995     MachineInstr *MI = MBBI;
996     switch (MI->getOpcode()) {
997     default:
998       // Just move on to the next instruction.
999       ++MBBI;
1000       break;
1001     // Scaled instructions.
1002     case AArch64::STRSui:
1003     case AArch64::STRDui:
1004     case AArch64::STRQui:
1005     case AArch64::STRXui:
1006     case AArch64::STRWui:
1007     case AArch64::LDRSui:
1008     case AArch64::LDRDui:
1009     case AArch64::LDRQui:
1010     case AArch64::LDRXui:
1011     case AArch64::LDRWui:
1012     case AArch64::LDRSWui:
1013     // Unscaled instructions.
1014     case AArch64::STURSi:
1015     case AArch64::STURDi:
1016     case AArch64::STURQi:
1017     case AArch64::STURWi:
1018     case AArch64::STURXi:
1019     case AArch64::LDURSi:
1020     case AArch64::LDURDi:
1021     case AArch64::LDURQi:
1022     case AArch64::LDURWi:
1023     case AArch64::LDURXi:
1024     case AArch64::LDURSWi: {
1025       // If this is a volatile load/store, don't mess with it.
1026       if (MI->hasOrderedMemoryRef()) {
1027         ++MBBI;
1028         break;
1029       }
1030       // Make sure this is a reg+imm (as opposed to an address reloc).
1031       if (!getLdStOffsetOp(MI).isImm()) {
1032         ++MBBI;
1033         break;
1034       }
1035       // Check if this load/store has a hint to avoid pair formation.
1036       // MachineMemOperands hints are set by the AArch64StorePairSuppress pass.
1037       if (TII->isLdStPairSuppressed(MI)) {
1038         ++MBBI;
1039         break;
1040       }
1041       // Look ahead up to ScanLimit instructions for a pairable instruction.
1042       LdStPairFlags Flags;
1043       MachineBasicBlock::iterator Paired =
1044           findMatchingInsn(MBBI, Flags, ScanLimit);
1045       if (Paired != E) {
1046         ++NumPairCreated;
1047         if (isUnscaledLdSt(MI))
1048           ++NumUnscaledPairCreated;
1049
1050         // Merge the loads into a pair. Keeping the iterator straight is a
1051         // pain, so we let the merge routine tell us what the next instruction
1052         // is after it's done mucking about.
1053         MBBI = mergePairedInsns(MBBI, Paired, Flags);
1054         Modified = true;
1055         break;
1056       }
1057       ++MBBI;
1058       break;
1059     }
1060       // FIXME: Do the other instructions.
1061     }
1062   }
1063
1064   for (MachineBasicBlock::iterator MBBI = MBB.begin(), E = MBB.end();
1065        MBBI != E;) {
1066     MachineInstr *MI = MBBI;
1067     // Do update merging. It's simpler to keep this separate from the above
1068     // switch, though not strictly necessary.
1069     unsigned Opc = MI->getOpcode();
1070     switch (Opc) {
1071     default:
1072       // Just move on to the next instruction.
1073       ++MBBI;
1074       break;
1075     // Scaled instructions.
1076     case AArch64::STRSui:
1077     case AArch64::STRDui:
1078     case AArch64::STRQui:
1079     case AArch64::STRXui:
1080     case AArch64::STRWui:
1081     case AArch64::LDRSui:
1082     case AArch64::LDRDui:
1083     case AArch64::LDRQui:
1084     case AArch64::LDRXui:
1085     case AArch64::LDRWui:
1086     // Unscaled instructions.
1087     case AArch64::STURSi:
1088     case AArch64::STURDi:
1089     case AArch64::STURQi:
1090     case AArch64::STURWi:
1091     case AArch64::STURXi:
1092     case AArch64::LDURSi:
1093     case AArch64::LDURDi:
1094     case AArch64::LDURQi:
1095     case AArch64::LDURWi:
1096     case AArch64::LDURXi:
1097     // Paired instructions.
1098     case AArch64::LDPSi:
1099     case AArch64::LDPDi:
1100     case AArch64::LDPQi:
1101     case AArch64::LDPWi:
1102     case AArch64::LDPXi:
1103     case AArch64::STPSi:
1104     case AArch64::STPDi:
1105     case AArch64::STPQi:
1106     case AArch64::STPWi:
1107     case AArch64::STPXi: {
1108       // Make sure this is a reg+imm (as opposed to an address reloc).
1109       if (!getLdStOffsetOp(MI).isImm()) {
1110         ++MBBI;
1111         break;
1112       }
1113       // Look forward to try to form a post-index instruction. For example,
1114       // ldr x0, [x20]
1115       // add x20, x20, #32
1116       //   merged into:
1117       // ldr x0, [x20], #32
1118       MachineBasicBlock::iterator Update =
1119           findMatchingUpdateInsnForward(MBBI, ScanLimit, 0);
1120       if (Update != E) {
1121         // Merge the update into the ld/st.
1122         MBBI = mergeUpdateInsn(MBBI, Update, /*IsPreIdx=*/false);
1123         Modified = true;
1124         ++NumPostFolded;
1125         break;
1126       }
1127       // Don't know how to handle pre/post-index versions, so move to the next
1128       // instruction.
1129       if (isUnscaledLdSt(Opc)) {
1130         ++MBBI;
1131         break;
1132       }
1133
1134       // Look back to try to find a pre-index instruction. For example,
1135       // add x0, x0, #8
1136       // ldr x1, [x0]
1137       //   merged into:
1138       // ldr x1, [x0, #8]!
1139       Update = findMatchingUpdateInsnBackward(MBBI, ScanLimit);
1140       if (Update != E) {
1141         // Merge the update into the ld/st.
1142         MBBI = mergeUpdateInsn(MBBI, Update, /*IsPreIdx=*/true);
1143         Modified = true;
1144         ++NumPreFolded;
1145         break;
1146       }
1147       // The immediate in the load/store is scaled by the size of the register
1148       // being loaded. The immediate in the add we're looking for,
1149       // however, is not, so adjust here.
1150       int Value = MI->getOperand(isPairedLdSt(MI) ? 3 : 2).getImm() *
1151                   TII->getRegClass(MI->getDesc(), 0, TRI, *(MBB.getParent()))
1152                       ->getSize();
1153
1154       // FIXME: The immediate in the load/store should be scaled by the size of
1155       // the memory operation, not the size of the register being loaded/stored.
1156       // This works in general, but does not work for the LDPSW instruction,
1157       // which defines two 64-bit registers, but loads 32-bit values.
1158
1159       // Look forward to try to find a post-index instruction. For example,
1160       // ldr x1, [x0, #64]
1161       // add x0, x0, #64
1162       //   merged into:
1163       // ldr x1, [x0, #64]!
1164       Update = findMatchingUpdateInsnForward(MBBI, ScanLimit, Value);
1165       if (Update != E) {
1166         // Merge the update into the ld/st.
1167         MBBI = mergeUpdateInsn(MBBI, Update, /*IsPreIdx=*/true);
1168         Modified = true;
1169         ++NumPreFolded;
1170         break;
1171       }
1172
1173       // Nothing found. Just move to the next instruction.
1174       ++MBBI;
1175       break;
1176     }
1177       // FIXME: Do the other instructions.
1178     }
1179   }
1180
1181   return Modified;
1182 }
1183
1184 bool AArch64LoadStoreOpt::runOnMachineFunction(MachineFunction &Fn) {
1185   TII = static_cast<const AArch64InstrInfo *>(Fn.getSubtarget().getInstrInfo());
1186   TRI = Fn.getSubtarget().getRegisterInfo();
1187
1188   bool Modified = false;
1189   for (auto &MBB : Fn)
1190     Modified |= optimizeBlock(MBB);
1191
1192   return Modified;
1193 }
1194
1195 // FIXME: Do we need/want a pre-alloc pass like ARM has to try to keep
1196 // loads and stores near one another?
1197
1198 /// createAArch64LoadStoreOptimizationPass - returns an instance of the
1199 /// load / store optimization pass.
1200 FunctionPass *llvm::createAArch64LoadStoreOptimizationPass() {
1201   return new AArch64LoadStoreOpt();
1202 }