LLVM 24.0.0git
ARMLoadStoreOptimizer.cpp
Go to the documentation of this file.
1//===- ARMLoadStoreOptimizer.cpp - ARM load / store opt. pass -------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9/// \file This file contains a pass that performs load / store related peephole
10/// optimizations. This pass should be run after register allocation.
11//
12//===----------------------------------------------------------------------===//
13
14#include "ARM.h"
15#include "ARMBaseInstrInfo.h"
16#include "ARMBaseRegisterInfo.h"
17#include "ARMISelLowering.h"
19#include "ARMSubtarget.h"
22#include "Utils/ARMBaseInfo.h"
23#include "llvm/ADT/ArrayRef.h"
24#include "llvm/ADT/DenseMap.h"
25#include "llvm/ADT/DenseSet.h"
26#include "llvm/ADT/STLExtras.h"
27#include "llvm/ADT/SetVector.h"
29#include "llvm/ADT/SmallSet.h"
31#include "llvm/ADT/Statistic.h"
51#include "llvm/IR/DataLayout.h"
52#include "llvm/IR/DebugLoc.h"
53#include "llvm/IR/Function.h"
54#include "llvm/IR/Type.h"
56#include "llvm/MC/MCInstrDesc.h"
57#include "llvm/Pass.h"
60#include "llvm/Support/Debug.h"
63#include <cassert>
64#include <cstddef>
65#include <cstdlib>
66#include <iterator>
67#include <limits>
68#include <utility>
69
70using namespace llvm;
71
72#define DEBUG_TYPE "arm-ldst-opt"
73
74STATISTIC(NumLDMGened , "Number of ldm instructions generated");
75STATISTIC(NumSTMGened , "Number of stm instructions generated");
76STATISTIC(NumVLDMGened, "Number of vldm instructions generated");
77STATISTIC(NumVSTMGened, "Number of vstm instructions generated");
78STATISTIC(NumLdStMoved, "Number of load / store instructions moved");
79STATISTIC(NumLDRDFormed,"Number of ldrd created before allocation");
80STATISTIC(NumSTRDFormed,"Number of strd created before allocation");
81STATISTIC(NumLDRD2LDM, "Number of ldrd instructions turned back into ldm");
82STATISTIC(NumSTRD2STM, "Number of strd instructions turned back into stm");
83STATISTIC(NumLDRD2LDR, "Number of ldrd instructions turned back into ldr's");
84STATISTIC(NumSTRD2STR, "Number of strd instructions turned back into str's");
85
86/// This switch disables formation of double/multi instructions that could
87/// potentially lead to (new) alignment traps even with CCR.UNALIGN_TRP
88/// disabled. This can be used to create libraries that are robust even when
89/// users provoke undefined behaviour by supplying misaligned pointers.
90/// \see mayCombineMisaligned()
91static cl::opt<bool>
92AssumeMisalignedLoadStores("arm-assume-misaligned-load-store", cl::Hidden,
93 cl::init(false), cl::desc("Be more conservative in ARM load/store opt"));
94
95#define ARM_LOAD_STORE_OPT_NAME "ARM load / store optimization pass"
96
97namespace {
98
99/// Post- register allocation pass the combine load / store instructions to
100/// form ldm / stm instructions.
101struct ARMLoadStoreOpt {
102 const MachineFunction *MF;
103 const TargetInstrInfo *TII;
104 const TargetRegisterInfo *TRI;
105 const ARMSubtarget *STI;
106 const TargetLowering *TL;
107 ARMFunctionInfo *AFI;
109 RegisterClassInfo RegClassInfo;
111 bool LiveRegsValid;
112 bool RegClassInfoValid;
113 bool isThumb1, isThumb2;
114
115 bool runOnMachineFunction(MachineFunction &Fn);
116
117private:
118 /// A set of load/store MachineInstrs with same base register sorted by
119 /// offset.
120 struct MemOpQueueEntry {
122 int Offset; ///< Load/Store offset.
123 unsigned Position; ///< Position as counted from end of basic block.
124
125 MemOpQueueEntry(MachineInstr &MI, int Offset, unsigned Position)
126 : MI(&MI), Offset(Offset), Position(Position) {}
127 };
128 using MemOpQueue = SmallVector<MemOpQueueEntry, 8>;
129
130 /// A set of MachineInstrs that fulfill (nearly all) conditions to get
131 /// merged into a LDM/STM.
132 struct MergeCandidate {
133 /// List of instructions ordered by load/store offset.
135
136 /// Index in Instrs of the instruction being latest in the schedule.
137 unsigned LatestMIIdx;
138
139 /// Index in Instrs of the instruction being earliest in the schedule.
140 unsigned EarliestMIIdx;
141
142 /// Index into the basic block where the merged instruction will be
143 /// inserted. (See MemOpQueueEntry.Position)
144 unsigned InsertPos;
145
146 /// Whether the instructions can be merged into a ldm/stm instruction.
147 bool CanMergeToLSMulti;
148
149 /// Whether the instructions can be merged into a ldrd/strd instruction.
150 bool CanMergeToLSDouble;
151 };
154 SmallVector<MachineInstr *, 4> MergeBaseCandidates;
155
156 void moveLiveRegsBefore(const MachineBasicBlock &MBB,
158 unsigned findFreeReg(const TargetRegisterClass &RegClass);
159 void UpdateBaseRegUses(MachineBasicBlock &MBB,
161 unsigned Base, unsigned WordOffset,
162 ARMCC::CondCodes Pred, unsigned PredReg);
163 MachineInstr *CreateLoadStoreMulti(MachineBasicBlock &MBB,
164 MachineBasicBlock::iterator InsertBefore,
165 int Offset, unsigned Base, bool BaseKill,
166 unsigned Opcode, ARMCC::CondCodes Pred,
167 unsigned PredReg, const DebugLoc &DL,
168 ArrayRef<std::pair<unsigned, bool>> Regs,
170 MachineInstr *CreateLoadStoreDouble(MachineBasicBlock &MBB,
171 MachineBasicBlock::iterator InsertBefore,
172 int Offset, unsigned Base, bool BaseKill,
173 unsigned Opcode, ARMCC::CondCodes Pred,
174 unsigned PredReg, const DebugLoc &DL,
175 ArrayRef<std::pair<unsigned, bool>> Regs,
176 ArrayRef<MachineInstr *> Instrs) const;
177 void FormCandidates(const MemOpQueue &MemOps);
178 MachineInstr *MergeOpsUpdate(const MergeCandidate &Cand);
179 bool FixInvalidRegPairOp(MachineBasicBlock &MBB,
181 bool MergeBaseUpdateLoadStore(MachineInstr *MI);
182 bool MergeBaseUpdateLSMultiple(MachineInstr *MI);
183 bool MergeBaseUpdateLSDouble(MachineInstr &MI) const;
184 bool LoadStoreMultipleOpti(MachineBasicBlock &MBB);
185 bool MergeReturnIntoLDM(MachineBasicBlock &MBB);
186 bool CombineMovBx(MachineBasicBlock &MBB);
187};
188
189struct ARMLoadStoreOptLegacy : public MachineFunctionPass {
190 static char ID;
191
192 ARMLoadStoreOptLegacy() : MachineFunctionPass(ID) {}
193
194 bool runOnMachineFunction(MachineFunction &Fn) override;
195
196 MachineFunctionProperties getRequiredProperties() const override {
197 return MachineFunctionProperties().setNoVRegs();
198 }
199
200 StringRef getPassName() const override { return ARM_LOAD_STORE_OPT_NAME; }
201
202 void getAnalysisUsage(AnalysisUsage &AU) const override {
205 }
206};
207
208char ARMLoadStoreOptLegacy::ID = 0;
209
210} // end anonymous namespace
211
212INITIALIZE_PASS(ARMLoadStoreOptLegacy, "arm-ldst-opt", ARM_LOAD_STORE_OPT_NAME,
213 false, false)
214
215static bool definesCPSR(const MachineInstr &MI) {
216 for (const auto &MO : MI.operands()) {
217 if (!MO.isReg())
218 continue;
219 if (MO.isDef() && MO.getReg() == ARM::CPSR && !MO.isDead())
220 // If the instruction has live CPSR def, then it's not safe to fold it
221 // into load / store.
222 return true;
223 }
224
225 return false;
226}
227
229 unsigned Opcode = MI.getOpcode();
230 bool isAM3 = Opcode == ARM::LDRD || Opcode == ARM::STRD;
231 unsigned NumOperands = MI.getDesc().getNumOperands();
232 unsigned OffField = MI.getOperand(NumOperands - 3).getImm();
233
234 if (Opcode == ARM::t2LDRi12 || Opcode == ARM::t2LDRi8 ||
235 Opcode == ARM::t2STRi12 || Opcode == ARM::t2STRi8 ||
236 Opcode == ARM::t2LDRDi8 || Opcode == ARM::t2STRDi8 ||
237 Opcode == ARM::LDRi12 || Opcode == ARM::STRi12)
238 return OffField;
239
240 // Thumb1 immediate offsets are scaled by 4
241 if (Opcode == ARM::tLDRi || Opcode == ARM::tSTRi ||
242 Opcode == ARM::tLDRspi || Opcode == ARM::tSTRspi)
243 return OffField * 4;
244
245 int Offset = isAM3 ? ARM_AM::getAM3Offset(OffField)
246 : ARM_AM::getAM5Offset(OffField) * 4;
247 ARM_AM::AddrOpc Op = isAM3 ? ARM_AM::getAM3Op(OffField)
248 : ARM_AM::getAM5Op(OffField);
249
250 if (Op == ARM_AM::sub)
251 return -Offset;
252
253 return Offset;
254}
255
257 return MI.getOperand(1);
258}
259
261 return MI.getOperand(0);
262}
263
265 switch (Opcode) {
266 default: llvm_unreachable("Unhandled opcode!");
267 case ARM::LDRi12:
268 ++NumLDMGened;
269 switch (Mode) {
270 default: llvm_unreachable("Unhandled submode!");
271 case ARM_AM::ia: return ARM::LDMIA;
272 case ARM_AM::da: return ARM::LDMDA;
273 case ARM_AM::db: return ARM::LDMDB;
274 case ARM_AM::ib: return ARM::LDMIB;
275 }
276 case ARM::STRi12:
277 ++NumSTMGened;
278 switch (Mode) {
279 default: llvm_unreachable("Unhandled submode!");
280 case ARM_AM::ia: return ARM::STMIA;
281 case ARM_AM::da: return ARM::STMDA;
282 case ARM_AM::db: return ARM::STMDB;
283 case ARM_AM::ib: return ARM::STMIB;
284 }
285 case ARM::tLDRi:
286 case ARM::tLDRspi:
287 // tLDMIA is writeback-only - unless the base register is in the input
288 // reglist.
289 ++NumLDMGened;
290 switch (Mode) {
291 default: llvm_unreachable("Unhandled submode!");
292 case ARM_AM::ia: return ARM::tLDMIA;
293 }
294 case ARM::tSTRi:
295 case ARM::tSTRspi:
296 // There is no non-writeback tSTMIA either.
297 ++NumSTMGened;
298 switch (Mode) {
299 default: llvm_unreachable("Unhandled submode!");
300 case ARM_AM::ia: return ARM::tSTMIA_UPD;
301 }
302 case ARM::t2LDRi8:
303 case ARM::t2LDRi12:
304 ++NumLDMGened;
305 switch (Mode) {
306 default: llvm_unreachable("Unhandled submode!");
307 case ARM_AM::ia: return ARM::t2LDMIA;
308 case ARM_AM::db: return ARM::t2LDMDB;
309 }
310 case ARM::t2STRi8:
311 case ARM::t2STRi12:
312 ++NumSTMGened;
313 switch (Mode) {
314 default: llvm_unreachable("Unhandled submode!");
315 case ARM_AM::ia: return ARM::t2STMIA;
316 case ARM_AM::db: return ARM::t2STMDB;
317 }
318 case ARM::VLDRS:
319 ++NumVLDMGened;
320 switch (Mode) {
321 default: llvm_unreachable("Unhandled submode!");
322 case ARM_AM::ia: return ARM::VLDMSIA;
323 case ARM_AM::db: return 0; // Only VLDMSDB_UPD exists.
324 }
325 case ARM::VSTRS:
326 ++NumVSTMGened;
327 switch (Mode) {
328 default: llvm_unreachable("Unhandled submode!");
329 case ARM_AM::ia: return ARM::VSTMSIA;
330 case ARM_AM::db: return 0; // Only VSTMSDB_UPD exists.
331 }
332 case ARM::VLDRD:
333 ++NumVLDMGened;
334 switch (Mode) {
335 default: llvm_unreachable("Unhandled submode!");
336 case ARM_AM::ia: return ARM::VLDMDIA;
337 case ARM_AM::db: return 0; // Only VLDMDDB_UPD exists.
338 }
339 case ARM::VSTRD:
340 ++NumVSTMGened;
341 switch (Mode) {
342 default: llvm_unreachable("Unhandled submode!");
343 case ARM_AM::ia: return ARM::VSTMDIA;
344 case ARM_AM::db: return 0; // Only VSTMDDB_UPD exists.
345 }
346 }
347}
348
350 switch (Opcode) {
351 default: llvm_unreachable("Unhandled opcode!");
352 case ARM::LDMIA_RET:
353 case ARM::LDMIA:
354 case ARM::LDMIA_UPD:
355 case ARM::STMIA:
356 case ARM::STMIA_UPD:
357 case ARM::tLDMIA:
358 case ARM::tLDMIA_UPD:
359 case ARM::tSTMIA_UPD:
360 case ARM::t2LDMIA_RET:
361 case ARM::t2LDMIA:
362 case ARM::t2LDMIA_UPD:
363 case ARM::t2STMIA:
364 case ARM::t2STMIA_UPD:
365 case ARM::VLDMSIA:
366 case ARM::VLDMSIA_UPD:
367 case ARM::VSTMSIA:
368 case ARM::VSTMSIA_UPD:
369 case ARM::VLDMDIA:
370 case ARM::VLDMDIA_UPD:
371 case ARM::VSTMDIA:
372 case ARM::VSTMDIA_UPD:
373 return ARM_AM::ia;
374
375 case ARM::LDMDA:
376 case ARM::LDMDA_UPD:
377 case ARM::STMDA:
378 case ARM::STMDA_UPD:
379 return ARM_AM::da;
380
381 case ARM::LDMDB:
382 case ARM::LDMDB_UPD:
383 case ARM::STMDB:
384 case ARM::STMDB_UPD:
385 case ARM::t2LDMDB:
386 case ARM::t2LDMDB_UPD:
387 case ARM::t2STMDB:
388 case ARM::t2STMDB_UPD:
389 case ARM::VLDMSDB_UPD:
390 case ARM::VSTMSDB_UPD:
391 case ARM::VLDMDDB_UPD:
392 case ARM::VSTMDDB_UPD:
393 return ARM_AM::db;
394
395 case ARM::LDMIB:
396 case ARM::LDMIB_UPD:
397 case ARM::STMIB:
398 case ARM::STMIB_UPD:
399 return ARM_AM::ib;
400 }
401}
402
403static bool isT1i32Load(unsigned Opc) {
404 return Opc == ARM::tLDRi || Opc == ARM::tLDRspi;
405}
406
407static bool isT2i32Load(unsigned Opc) {
408 return Opc == ARM::t2LDRi12 || Opc == ARM::t2LDRi8;
409}
410
411static bool isi32Load(unsigned Opc) {
412 return Opc == ARM::LDRi12 || isT1i32Load(Opc) || isT2i32Load(Opc) ;
413}
414
415static bool isT1i32Store(unsigned Opc) {
416 return Opc == ARM::tSTRi || Opc == ARM::tSTRspi;
417}
418
419static bool isT2i32Store(unsigned Opc) {
420 return Opc == ARM::t2STRi12 || Opc == ARM::t2STRi8;
421}
422
423static bool isi32Store(unsigned Opc) {
424 return Opc == ARM::STRi12 || isT1i32Store(Opc) || isT2i32Store(Opc);
425}
426
427static bool isLoadSingle(unsigned Opc) {
428 return isi32Load(Opc) || Opc == ARM::VLDRS || Opc == ARM::VLDRD;
429}
430
431static unsigned getImmScale(unsigned Opc) {
432 switch (Opc) {
433 default: llvm_unreachable("Unhandled opcode!");
434 case ARM::tLDRi:
435 case ARM::tSTRi:
436 case ARM::tLDRspi:
437 case ARM::tSTRspi:
438 return 1;
439 case ARM::tLDRHi:
440 case ARM::tSTRHi:
441 return 2;
442 case ARM::tLDRBi:
443 case ARM::tSTRBi:
444 return 4;
445 }
446}
447
449 switch (MI->getOpcode()) {
450 default: return 0;
451 case ARM::LDRi12:
452 case ARM::STRi12:
453 case ARM::tLDRi:
454 case ARM::tSTRi:
455 case ARM::tLDRspi:
456 case ARM::tSTRspi:
457 case ARM::t2LDRi8:
458 case ARM::t2LDRi12:
459 case ARM::t2STRi8:
460 case ARM::t2STRi12:
461 case ARM::VLDRS:
462 case ARM::VSTRS:
463 return 4;
464 case ARM::VLDRD:
465 case ARM::VSTRD:
466 return 8;
467 case ARM::LDMIA:
468 case ARM::LDMDA:
469 case ARM::LDMDB:
470 case ARM::LDMIB:
471 case ARM::STMIA:
472 case ARM::STMDA:
473 case ARM::STMDB:
474 case ARM::STMIB:
475 case ARM::tLDMIA:
476 case ARM::tLDMIA_UPD:
477 case ARM::tSTMIA_UPD:
478 case ARM::t2LDMIA:
479 case ARM::t2LDMDB:
480 case ARM::t2STMIA:
481 case ARM::t2STMDB:
482 case ARM::VLDMSIA:
483 case ARM::VSTMSIA:
484 return (MI->getNumOperands() - MI->getDesc().getNumOperands() + 1) * 4;
485 case ARM::VLDMDIA:
486 case ARM::VSTMDIA:
487 return (MI->getNumOperands() - MI->getDesc().getNumOperands() + 1) * 8;
488 }
489}
490
491/// Update future uses of the base register with the offset introduced
492/// due to writeback. This function only works on Thumb1.
493void ARMLoadStoreOpt::UpdateBaseRegUses(MachineBasicBlock &MBB,
495 const DebugLoc &DL, unsigned Base,
496 unsigned WordOffset,
497 ARMCC::CondCodes Pred,
498 unsigned PredReg) {
499 assert(isThumb1 && "Can only update base register uses for Thumb1!");
500 // Start updating any instructions with immediate offsets. Insert a SUB before
501 // the first non-updateable instruction (if any).
502 for (; MBBI != MBB.end(); ++MBBI) {
503 bool InsertSub = false;
504 unsigned Opc = MBBI->getOpcode();
505
506 if (MBBI->readsRegister(Base, /*TRI=*/nullptr)) {
507 int Offset;
508 bool IsLoad =
509 Opc == ARM::tLDRi || Opc == ARM::tLDRHi || Opc == ARM::tLDRBi;
510 bool IsStore =
511 Opc == ARM::tSTRi || Opc == ARM::tSTRHi || Opc == ARM::tSTRBi;
512
513 if (IsLoad || IsStore) {
514 // Loads and stores with immediate offsets can be updated, but only if
515 // the new offset isn't negative.
516 // The MachineOperand containing the offset immediate is the last one
517 // before predicates.
518 MachineOperand &MO =
519 MBBI->getOperand(MBBI->getDesc().getNumOperands() - 3);
520 // The offsets are scaled by 1, 2 or 4 depending on the Opcode.
521 Offset = MO.getImm() - WordOffset * getImmScale(Opc);
522
523 // If storing the base register, it needs to be reset first.
524 Register InstrSrcReg = getLoadStoreRegOp(*MBBI).getReg();
525
526 if (Offset >= 0 && !(IsStore && InstrSrcReg == Base))
527 MO.setImm(Offset);
528 else
529 InsertSub = true;
530 } else if ((Opc == ARM::tSUBi8 || Opc == ARM::tADDi8) &&
531 !definesCPSR(*MBBI)) {
532 // SUBS/ADDS using this register, with a dead def of the CPSR.
533 // Merge it with the update; if the merged offset is too large,
534 // insert a new sub instead.
535 MachineOperand &MO =
536 MBBI->getOperand(MBBI->getDesc().getNumOperands() - 3);
537 Offset = (Opc == ARM::tSUBi8) ?
538 MO.getImm() + WordOffset * 4 :
539 MO.getImm() - WordOffset * 4 ;
540 if (Offset >= 0 && TL->isLegalAddImmediate(Offset)) {
541 // FIXME: Swap ADDS<->SUBS if Offset < 0, erase instruction if
542 // Offset == 0.
543 MO.setImm(Offset);
544 // The base register has now been reset, so exit early.
545 return;
546 } else {
547 InsertSub = true;
548 }
549 } else {
550 // Can't update the instruction.
551 InsertSub = true;
552 }
553 } else if (definesCPSR(*MBBI) || MBBI->isCall() || MBBI->isBranch()) {
554 // Since SUBS sets the condition flags, we can't place the base reset
555 // after an instruction that has a live CPSR def.
556 // The base register might also contain an argument for a function call.
557 InsertSub = true;
558 }
559
560 if (InsertSub) {
561 // An instruction above couldn't be updated, so insert a sub.
562 BuildMI(MBB, MBBI, DL, TII->get(ARM::tSUBi8), Base)
563 .add(t1CondCodeOp(true))
564 .addReg(Base)
565 .addImm(WordOffset * 4)
566 .addImm(Pred)
567 .addReg(PredReg);
568 return;
569 }
570
571 if (MBBI->killsRegister(Base, /*TRI=*/nullptr) ||
572 MBBI->definesRegister(Base, /*TRI=*/nullptr))
573 // Register got killed. Stop updating.
574 return;
575 }
576
577 // End of block was reached.
578 if (!MBB.succ_empty()) {
579 // FIXME: Because of a bug, live registers are sometimes missing from
580 // the successor blocks' live-in sets. This means we can't trust that
581 // information and *always* have to reset at the end of a block.
582 // See PR21029.
583 if (MBBI != MBB.end()) --MBBI;
584 BuildMI(MBB, MBBI, DL, TII->get(ARM::tSUBi8), Base)
585 .add(t1CondCodeOp(true))
586 .addReg(Base)
587 .addImm(WordOffset * 4)
588 .addImm(Pred)
589 .addReg(PredReg);
590 }
591}
592
593/// Return the first register of class \p RegClass that is not in \p Regs.
594unsigned ARMLoadStoreOpt::findFreeReg(const TargetRegisterClass &RegClass) {
595 if (!RegClassInfoValid) {
596 RegClassInfo.runOnMachineFunction(*MF);
597 RegClassInfoValid = true;
598 }
599
600 for (unsigned Reg : RegClassInfo.getOrder(&RegClass))
601 if (LiveRegs.available(Reg) && !MF->getRegInfo().isReserved(Reg))
602 return Reg;
603 return 0;
604}
605
606/// Compute live registers just before instruction \p Before (in normal schedule
607/// direction). Computes backwards so multiple queries in the same block must
608/// come in reverse order.
609void ARMLoadStoreOpt::moveLiveRegsBefore(const MachineBasicBlock &MBB,
611 // Initialize if we never queried in this block.
612 if (!LiveRegsValid) {
613 LiveRegs.init(*TRI);
614 LiveRegs.addLiveOuts(MBB);
615 LiveRegPos = MBB.end();
616 LiveRegsValid = true;
617 }
618 // Move backward just before the "Before" position.
619 while (LiveRegPos != Before) {
620 --LiveRegPos;
621 if (!LiveRegPos->isDebugInstr())
622 LiveRegs.stepBackward(*LiveRegPos);
623 }
624}
625
626static bool ContainsReg(ArrayRef<std::pair<unsigned, bool>> Regs,
627 unsigned Reg) {
628 for (const std::pair<unsigned, bool> &R : Regs)
629 if (R.first == Reg)
630 return true;
631 return false;
632}
633
634/// Create and insert a LDM or STM with Base as base register and registers in
635/// Regs as the register operands that would be loaded / stored. It returns
636/// true if the transformation is done.
637MachineInstr *ARMLoadStoreOpt::CreateLoadStoreMulti(
638 MachineBasicBlock &MBB, MachineBasicBlock::iterator InsertBefore,
639 int Offset, unsigned Base, bool BaseKill, unsigned Opcode,
640 ARMCC::CondCodes Pred, unsigned PredReg, const DebugLoc &DL,
641 ArrayRef<std::pair<unsigned, bool>> Regs,
643 unsigned NumRegs = Regs.size();
644 assert(NumRegs > 1);
645
646 // For Thumb1 targets, it might be necessary to clobber the CPSR to merge.
647 // Compute liveness information for that register to make the decision.
648 bool SafeToClobberCPSR = !isThumb1 ||
649 (MBB.computeRegisterLiveness(TRI, ARM::CPSR, InsertBefore, 20) ==
651
652 bool Writeback = isThumb1; // Thumb1 LDM/STM have base reg writeback.
653
654 // Exception: If the base register is in the input reglist, Thumb1 LDM is
655 // non-writeback.
656 // It's also not possible to merge an STR of the base register in Thumb1.
657 if (isThumb1 && ContainsReg(Regs, Base)) {
658 assert(Base != ARM::SP && "Thumb1 does not allow SP in register list");
659 if (Opcode == ARM::tLDRi)
660 Writeback = false;
661 else if (Opcode == ARM::tSTRi)
662 return nullptr;
663 }
664
666 // VFP and Thumb2 do not support IB or DA modes. Thumb1 only supports IA.
667 bool isNotVFP = isi32Load(Opcode) || isi32Store(Opcode);
668 bool haveIBAndDA = isNotVFP && !isThumb2 && !isThumb1;
669
670 if (Offset == 4 && haveIBAndDA) {
672 } else if (Offset == -4 * (int)NumRegs + 4 && haveIBAndDA) {
674 } else if (Offset == -4 * (int)NumRegs && isNotVFP && !isThumb1) {
675 // VLDM/VSTM do not support DB mode without also updating the base reg.
677 } else if (Offset != 0 || Opcode == ARM::tLDRspi || Opcode == ARM::tSTRspi) {
678 // Check if this is a supported opcode before inserting instructions to
679 // calculate a new base register.
680 if (!getLoadStoreMultipleOpcode(Opcode, Mode)) return nullptr;
681
682 // If starting offset isn't zero, insert a MI to materialize a new base.
683 // But only do so if it is cost effective, i.e. merging more than two
684 // loads / stores.
685 if (NumRegs <= 2)
686 return nullptr;
687
688 // On Thumb1, it's not worth materializing a new base register without
689 // clobbering the CPSR (i.e. not using ADDS/SUBS).
690 if (!SafeToClobberCPSR)
691 return nullptr;
692
693 unsigned NewBase;
694 if (isi32Load(Opcode)) {
695 // If it is a load, then just use one of the destination registers
696 // as the new base. Will no longer be writeback in Thumb1.
697 NewBase = Regs[NumRegs-1].first;
698 Writeback = false;
699 } else {
700 // Find a free register that we can use as scratch register.
701 moveLiveRegsBefore(MBB, InsertBefore);
702 // The merged instruction does not exist yet but will use several Regs if
703 // it is a Store.
704 if (!isLoadSingle(Opcode))
705 for (const std::pair<unsigned, bool> &R : Regs)
706 LiveRegs.addReg(R.first);
707
708 NewBase = findFreeReg(isThumb1 ? ARM::tGPRRegClass : ARM::GPRRegClass);
709 if (NewBase == 0)
710 return nullptr;
711 }
712
713 int BaseOpc = isThumb2 ? (BaseKill && Base == ARM::SP ? ARM::t2ADDspImm
714 : ARM::t2ADDri)
715 : (isThumb1 && Base == ARM::SP)
716 ? ARM::tADDrSPi
717 : (isThumb1 && Offset < 8)
718 ? ARM::tADDi3
719 : isThumb1 ? ARM::tADDi8 : ARM::ADDri;
720
721 if (Offset < 0) {
722 // FIXME: There are no Thumb1 load/store instructions with negative
723 // offsets. So the Base != ARM::SP might be unnecessary.
724 Offset = -Offset;
725 BaseOpc = isThumb2 ? (BaseKill && Base == ARM::SP ? ARM::t2SUBspImm
726 : ARM::t2SUBri)
727 : (isThumb1 && Offset < 8 && Base != ARM::SP)
728 ? ARM::tSUBi3
729 : isThumb1 ? ARM::tSUBi8 : ARM::SUBri;
730 }
731
732 if (!TL->isLegalAddImmediate(Offset))
733 // FIXME: Try add with register operand?
734 return nullptr; // Probably not worth it then.
735
736 // We can only append a kill flag to the add/sub input if the value is not
737 // used in the register list of the stm as well.
738 bool KillOldBase = BaseKill &&
739 (!isi32Store(Opcode) || !ContainsReg(Regs, Base));
740
741 if (isThumb1) {
742 // Thumb1: depending on immediate size, use either
743 // ADDS NewBase, Base, #imm3
744 // or
745 // MOV NewBase, Base
746 // ADDS NewBase, #imm8.
747 if (Base != NewBase &&
748 (BaseOpc == ARM::tADDi8 || BaseOpc == ARM::tSUBi8)) {
749 // Need to insert a MOV to the new base first.
750 if (isARMLowRegister(NewBase) && isARMLowRegister(Base) &&
751 !STI->hasV6Ops()) {
752 // thumbv4t doesn't have lo->lo copies, and we can't predicate tMOVSr
753 if (Pred != ARMCC::AL)
754 return nullptr;
755 BuildMI(MBB, InsertBefore, DL, TII->get(ARM::tMOVSr), NewBase)
756 .addReg(Base, getKillRegState(KillOldBase));
757 } else
758 BuildMI(MBB, InsertBefore, DL, TII->get(ARM::tMOVr), NewBase)
759 .addReg(Base, getKillRegState(KillOldBase))
760 .add(predOps(Pred, PredReg));
761
762 // The following ADDS/SUBS becomes an update.
763 Base = NewBase;
764 KillOldBase = true;
765 }
766 if (BaseOpc == ARM::tADDrSPi) {
767 assert(Offset % 4 == 0 && "tADDrSPi offset is scaled by 4");
768 BuildMI(MBB, InsertBefore, DL, TII->get(BaseOpc), NewBase)
769 .addReg(Base, getKillRegState(KillOldBase))
770 .addImm(Offset / 4)
771 .add(predOps(Pred, PredReg));
772 } else
773 BuildMI(MBB, InsertBefore, DL, TII->get(BaseOpc), NewBase)
774 .add(t1CondCodeOp(true))
775 .addReg(Base, getKillRegState(KillOldBase))
776 .addImm(Offset)
777 .add(predOps(Pred, PredReg));
778 } else {
779 BuildMI(MBB, InsertBefore, DL, TII->get(BaseOpc), NewBase)
780 .addReg(Base, getKillRegState(KillOldBase))
781 .addImm(Offset)
782 .add(predOps(Pred, PredReg))
783 .add(condCodeOp());
784 }
785 Base = NewBase;
786 BaseKill = true; // New base is always killed straight away.
787 }
788
789 bool isDef = isLoadSingle(Opcode);
790
791 // Get LS multiple opcode. Note that for Thumb1 this might be an opcode with
792 // base register writeback.
793 Opcode = getLoadStoreMultipleOpcode(Opcode, Mode);
794 if (!Opcode)
795 return nullptr;
796
797 // Check if a Thumb1 LDM/STM merge is safe. This is the case if:
798 // - There is no writeback (LDM of base register),
799 // - the base register is killed by the merged instruction,
800 // - or it's safe to overwrite the condition flags, i.e. to insert a SUBS
801 // to reset the base register.
802 // Otherwise, don't merge.
803 // It's safe to return here since the code to materialize a new base register
804 // above is also conditional on SafeToClobberCPSR.
805 if (isThumb1 && !SafeToClobberCPSR && Writeback && !BaseKill)
806 return nullptr;
807
808 MachineInstrBuilder MIB;
809
810 if (Writeback) {
811 assert(isThumb1 && "expected Writeback only inThumb1");
812 if (Opcode == ARM::tLDMIA) {
813 assert(!(ContainsReg(Regs, Base)) && "Thumb1 can't LDM ! with Base in Regs");
814 // Update tLDMIA with writeback if necessary.
815 Opcode = ARM::tLDMIA_UPD;
816 }
817
818 MIB = BuildMI(MBB, InsertBefore, DL, TII->get(Opcode));
819
820 // Thumb1: we might need to set base writeback when building the MI.
821 MIB.addReg(Base, getDefRegState(true))
822 .addReg(Base, getKillRegState(BaseKill));
823
824 // The base isn't dead after a merged instruction with writeback.
825 // Insert a sub instruction after the newly formed instruction to reset.
826 if (!BaseKill)
827 UpdateBaseRegUses(MBB, InsertBefore, DL, Base, NumRegs, Pred, PredReg);
828 } else {
829 // No writeback, simply build the MachineInstr.
830 MIB = BuildMI(MBB, InsertBefore, DL, TII->get(Opcode));
831 MIB.addReg(Base, getKillRegState(BaseKill));
832 }
833
834 MIB.addImm(Pred).addReg(PredReg);
835
836 for (const std::pair<unsigned, bool> &R : Regs)
837 MIB.addReg(R.first, getDefRegState(isDef) | getKillRegState(R.second));
838
839 MIB.cloneMergedMemRefs(Instrs);
840
841 return MIB.getInstr();
842}
843
844MachineInstr *ARMLoadStoreOpt::CreateLoadStoreDouble(
845 MachineBasicBlock &MBB, MachineBasicBlock::iterator InsertBefore,
846 int Offset, unsigned Base, bool BaseKill, unsigned Opcode,
847 ARMCC::CondCodes Pred, unsigned PredReg, const DebugLoc &DL,
848 ArrayRef<std::pair<unsigned, bool>> Regs,
849 ArrayRef<MachineInstr*> Instrs) const {
850 bool IsLoad = isi32Load(Opcode);
851 assert((IsLoad || isi32Store(Opcode)) && "Must have integer load or store");
852 unsigned LoadStoreOpcode = IsLoad ? ARM::t2LDRDi8 : ARM::t2STRDi8;
853
854 assert(Regs.size() == 2);
855 MachineInstrBuilder MIB = BuildMI(MBB, InsertBefore, DL,
856 TII->get(LoadStoreOpcode));
857 if (IsLoad) {
858 MIB.addReg(Regs[0].first, RegState::Define)
859 .addReg(Regs[1].first, RegState::Define);
860 } else {
861 MIB.addReg(Regs[0].first, getKillRegState(Regs[0].second))
862 .addReg(Regs[1].first, getKillRegState(Regs[1].second));
863 }
864 MIB.addReg(Base).addImm(Offset).addImm(Pred).addReg(PredReg);
865 MIB.cloneMergedMemRefs(Instrs);
866 return MIB.getInstr();
867}
868
869/// Call MergeOps and update MemOps and merges accordingly on success.
870MachineInstr *ARMLoadStoreOpt::MergeOpsUpdate(const MergeCandidate &Cand) {
871 const MachineInstr *First = Cand.Instrs.front();
872 unsigned Opcode = First->getOpcode();
873 bool IsLoad = isLoadSingle(Opcode);
875 SmallVector<unsigned, 4> ImpDefs;
876 DenseSet<unsigned> KilledRegs;
877 DenseSet<unsigned> UsedRegs;
878 // Determine list of registers and list of implicit super-register defs.
879 for (const MachineInstr *MI : Cand.Instrs) {
880 const MachineOperand &MO = getLoadStoreRegOp(*MI);
881 Register Reg = MO.getReg();
882 bool IsKill = MO.isKill();
883 if (IsKill)
884 KilledRegs.insert(Reg);
885 Regs.push_back(std::make_pair(Reg, IsKill));
886 UsedRegs.insert(Reg);
887
888 if (IsLoad) {
889 // Collect any implicit defs of super-registers, after merging we can't
890 // be sure anymore that we properly preserved these live ranges and must
891 // removed these implicit operands.
892 for (const MachineOperand &MO : MI->implicit_operands()) {
893 if (!MO.isReg() || !MO.isDef() || MO.isDead())
894 continue;
895 assert(MO.isImplicit());
896 Register DefReg = MO.getReg();
897
898 if (is_contained(ImpDefs, DefReg))
899 continue;
900 // We can ignore cases where the super-reg is read and written.
901 if (MI->readsRegister(DefReg, /*TRI=*/nullptr))
902 continue;
903 ImpDefs.push_back(DefReg);
904 }
905 }
906 }
907
908 // Attempt the merge.
910
911 MachineInstr *LatestMI = Cand.Instrs[Cand.LatestMIIdx];
912 iterator InsertBefore = std::next(iterator(LatestMI));
913 MachineBasicBlock &MBB = *LatestMI->getParent();
914 unsigned Offset = getMemoryOpOffset(*First);
916 bool BaseKill = LatestMI->killsRegister(Base, /*TRI=*/nullptr);
917 Register PredReg;
918 ARMCC::CondCodes Pred = getInstrPredicate(*First, PredReg);
919 DebugLoc DL = First->getDebugLoc();
920 MachineInstr *Merged = nullptr;
921 if (Cand.CanMergeToLSDouble)
922 Merged = CreateLoadStoreDouble(MBB, InsertBefore, Offset, Base, BaseKill,
923 Opcode, Pred, PredReg, DL, Regs,
924 Cand.Instrs);
925 if (!Merged && Cand.CanMergeToLSMulti)
926 Merged = CreateLoadStoreMulti(MBB, InsertBefore, Offset, Base, BaseKill,
927 Opcode, Pred, PredReg, DL, Regs, Cand.Instrs);
928 if (!Merged)
929 return nullptr;
930
931 // Determine earliest instruction that will get removed. We then keep an
932 // iterator just above it so the following erases don't invalidated it.
933 iterator EarliestI(Cand.Instrs[Cand.EarliestMIIdx]);
934 bool EarliestAtBegin = false;
935 if (EarliestI == MBB.begin()) {
936 EarliestAtBegin = true;
937 } else {
938 EarliestI = std::prev(EarliestI);
939 }
940
941 // Remove instructions which have been merged.
942 for (MachineInstr *MI : Cand.Instrs)
943 MBB.erase(MI);
944
945 // Determine range between the earliest removed instruction and the new one.
946 if (EarliestAtBegin)
947 EarliestI = MBB.begin();
948 else
949 EarliestI = std::next(EarliestI);
950 auto FixupRange = make_range(EarliestI, iterator(Merged));
951
952 if (isLoadSingle(Opcode)) {
953 // If the previous loads defined a super-reg, then we have to mark earlier
954 // operands undef; Replicate the super-reg def on the merged instruction.
955 for (MachineInstr &MI : FixupRange) {
956 for (unsigned &ImpDefReg : ImpDefs) {
957 for (MachineOperand &MO : MI.implicit_operands()) {
958 if (!MO.isReg() || MO.getReg() != ImpDefReg)
959 continue;
960 if (MO.readsReg())
961 MO.setIsUndef();
962 else if (MO.isDef())
963 ImpDefReg = 0;
964 }
965 }
966 }
967
968 MachineInstrBuilder MIB(*Merged->getParent()->getParent(), Merged);
969 for (unsigned ImpDef : ImpDefs)
970 MIB.addReg(ImpDef, RegState::ImplicitDefine);
971 } else {
972 // Remove kill flags: We are possibly storing the values later now.
973 assert(isi32Store(Opcode) || Opcode == ARM::VSTRS || Opcode == ARM::VSTRD);
974 for (MachineInstr &MI : FixupRange) {
975 for (MachineOperand &MO : MI.uses()) {
976 if (!MO.isReg() || !MO.isKill())
977 continue;
978 if (UsedRegs.count(MO.getReg()))
979 MO.setIsKill(false);
980 }
981 }
982 assert(ImpDefs.empty());
983 }
984
985 return Merged;
986}
987
989 unsigned Value = abs(Offset);
990 // t2LDRDi8/t2STRDi8 supports an 8 bit immediate which is internally
991 // multiplied by 4.
992 return (Value % 4) == 0 && Value < 1024;
993}
994
995/// Return true for loads/stores that can be combined to a double/multi
996/// operation without increasing the requirements for alignment.
998 const MachineInstr &MI) {
999 // vldr/vstr trap on misaligned pointers anyway, forming vldm makes no
1000 // difference.
1001 unsigned Opcode = MI.getOpcode();
1002 if (!isi32Load(Opcode) && !isi32Store(Opcode))
1003 return true;
1004
1005 // Stack pointer alignment is out of the programmers control so we can trust
1006 // SP-relative loads/stores.
1007 if (getLoadStoreBaseOp(MI).getReg() == ARM::SP &&
1009 return true;
1010 return false;
1011}
1012
1013/// Find candidates for load/store multiple merge in list of MemOpQueueEntries.
1014void ARMLoadStoreOpt::FormCandidates(const MemOpQueue &MemOps) {
1015 const MachineInstr *FirstMI = MemOps[0].MI;
1016 unsigned Opcode = FirstMI->getOpcode();
1017 bool isNotVFP = isi32Load(Opcode) || isi32Store(Opcode);
1018 unsigned Size = getLSMultipleTransferSize(FirstMI);
1019
1020 unsigned SIndex = 0;
1021 unsigned EIndex = MemOps.size();
1022 do {
1023 // Look at the first instruction.
1024 const MachineInstr *MI = MemOps[SIndex].MI;
1025 int Offset = MemOps[SIndex].Offset;
1026 const MachineOperand &PMO = getLoadStoreRegOp(*MI);
1027 Register PReg = PMO.getReg();
1028 unsigned PRegNum = PMO.isUndef() ? std::numeric_limits<unsigned>::max()
1029 : TRI->getEncodingValue(PReg);
1030 unsigned Latest = SIndex;
1031 unsigned Earliest = SIndex;
1032 unsigned Count = 1;
1033 bool CanMergeToLSDouble =
1034 STI->isThumb2() && isNotVFP && isValidLSDoubleOffset(Offset);
1035 // ARM errata 602117: LDRD with base in list may result in incorrect base
1036 // register when interrupted or faulted.
1037 if (STI->isCortexM3() && isi32Load(Opcode) &&
1038 PReg == getLoadStoreBaseOp(*MI).getReg())
1039 CanMergeToLSDouble = false;
1040
1041 bool CanMergeToLSMulti = true;
1042 // On swift vldm/vstm starting with an odd register number as that needs
1043 // more uops than single vldrs.
1044 if (STI->hasSlowOddRegister() && !isNotVFP && (PRegNum % 2) == 1)
1045 CanMergeToLSMulti = false;
1046
1047 // LDRD/STRD do not allow SP/PC. LDM/STM do not support it or have it
1048 // deprecated; LDM to PC is fine but cannot happen here.
1049 if (PReg == ARM::SP || PReg == ARM::PC)
1050 CanMergeToLSMulti = CanMergeToLSDouble = false;
1051
1052 // Should we be conservative?
1054 CanMergeToLSMulti = CanMergeToLSDouble = false;
1055
1056 // vldm / vstm limit are 32 for S variants, 16 for D variants.
1057 unsigned Limit;
1058 switch (Opcode) {
1059 default:
1060 Limit = UINT_MAX;
1061 break;
1062 case ARM::VLDRD:
1063 case ARM::VSTRD:
1064 Limit = 16;
1065 break;
1066 }
1067
1068 // Merge following instructions where possible.
1069 for (unsigned I = SIndex+1; I < EIndex; ++I, ++Count) {
1070 int NewOffset = MemOps[I].Offset;
1071 if (NewOffset != Offset + (int)Size)
1072 break;
1073 const MachineOperand &MO = getLoadStoreRegOp(*MemOps[I].MI);
1074 Register Reg = MO.getReg();
1075 if (Reg == ARM::SP || Reg == ARM::PC)
1076 break;
1077 if (Count == Limit)
1078 break;
1079
1080 // See if the current load/store may be part of a multi load/store.
1081 unsigned RegNum = MO.isUndef() ? std::numeric_limits<unsigned>::max()
1082 : TRI->getEncodingValue(Reg);
1083 bool PartOfLSMulti = CanMergeToLSMulti;
1084 if (PartOfLSMulti) {
1085 // Register numbers must be in ascending order.
1086 if (RegNum <= PRegNum)
1087 PartOfLSMulti = false;
1088 // For VFP / NEON load/store multiples, the registers must be
1089 // consecutive and within the limit on the number of registers per
1090 // instruction.
1091 else if (!isNotVFP && RegNum != PRegNum+1)
1092 PartOfLSMulti = false;
1093 }
1094 // See if the current load/store may be part of a double load/store.
1095 bool PartOfLSDouble = CanMergeToLSDouble && Count <= 1;
1096
1097 if (!PartOfLSMulti && !PartOfLSDouble)
1098 break;
1099 CanMergeToLSMulti &= PartOfLSMulti;
1100 CanMergeToLSDouble &= PartOfLSDouble;
1101 // Track MemOp with latest and earliest position (Positions are
1102 // counted in reverse).
1103 unsigned Position = MemOps[I].Position;
1104 if (Position < MemOps[Latest].Position)
1105 Latest = I;
1106 else if (Position > MemOps[Earliest].Position)
1107 Earliest = I;
1108 // Prepare for next MemOp.
1109 Offset += Size;
1110 PRegNum = RegNum;
1111 }
1112
1113 // Form a candidate from the Ops collected so far.
1114 MergeCandidate *Candidate = new(Allocator.Allocate()) MergeCandidate;
1115 for (unsigned C = SIndex, CE = SIndex + Count; C < CE; ++C)
1116 Candidate->Instrs.push_back(MemOps[C].MI);
1117 Candidate->LatestMIIdx = Latest - SIndex;
1118 Candidate->EarliestMIIdx = Earliest - SIndex;
1119 Candidate->InsertPos = MemOps[Latest].Position;
1120 if (Count == 1)
1121 CanMergeToLSMulti = CanMergeToLSDouble = false;
1122 Candidate->CanMergeToLSMulti = CanMergeToLSMulti;
1123 Candidate->CanMergeToLSDouble = CanMergeToLSDouble;
1124 Candidates.push_back(Candidate);
1125 // Continue after the chain.
1126 SIndex += Count;
1127 } while (SIndex < EIndex);
1128}
1129
1130static unsigned getUpdatingLSMultipleOpcode(unsigned Opc,
1132 switch (Opc) {
1133 default: llvm_unreachable("Unhandled opcode!");
1134 case ARM::LDMIA:
1135 case ARM::LDMDA:
1136 case ARM::LDMDB:
1137 case ARM::LDMIB:
1138 switch (Mode) {
1139 default: llvm_unreachable("Unhandled submode!");
1140 case ARM_AM::ia: return ARM::LDMIA_UPD;
1141 case ARM_AM::ib: return ARM::LDMIB_UPD;
1142 case ARM_AM::da: return ARM::LDMDA_UPD;
1143 case ARM_AM::db: return ARM::LDMDB_UPD;
1144 }
1145 case ARM::STMIA:
1146 case ARM::STMDA:
1147 case ARM::STMDB:
1148 case ARM::STMIB:
1149 switch (Mode) {
1150 default: llvm_unreachable("Unhandled submode!");
1151 case ARM_AM::ia: return ARM::STMIA_UPD;
1152 case ARM_AM::ib: return ARM::STMIB_UPD;
1153 case ARM_AM::da: return ARM::STMDA_UPD;
1154 case ARM_AM::db: return ARM::STMDB_UPD;
1155 }
1156 case ARM::t2LDMIA:
1157 case ARM::t2LDMDB:
1158 switch (Mode) {
1159 default: llvm_unreachable("Unhandled submode!");
1160 case ARM_AM::ia: return ARM::t2LDMIA_UPD;
1161 case ARM_AM::db: return ARM::t2LDMDB_UPD;
1162 }
1163 case ARM::t2STMIA:
1164 case ARM::t2STMDB:
1165 switch (Mode) {
1166 default: llvm_unreachable("Unhandled submode!");
1167 case ARM_AM::ia: return ARM::t2STMIA_UPD;
1168 case ARM_AM::db: return ARM::t2STMDB_UPD;
1169 }
1170 case ARM::VLDMSIA:
1171 switch (Mode) {
1172 default: llvm_unreachable("Unhandled submode!");
1173 case ARM_AM::ia: return ARM::VLDMSIA_UPD;
1174 case ARM_AM::db: return ARM::VLDMSDB_UPD;
1175 }
1176 case ARM::VLDMDIA:
1177 switch (Mode) {
1178 default: llvm_unreachable("Unhandled submode!");
1179 case ARM_AM::ia: return ARM::VLDMDIA_UPD;
1180 case ARM_AM::db: return ARM::VLDMDDB_UPD;
1181 }
1182 case ARM::VSTMSIA:
1183 switch (Mode) {
1184 default: llvm_unreachable("Unhandled submode!");
1185 case ARM_AM::ia: return ARM::VSTMSIA_UPD;
1186 case ARM_AM::db: return ARM::VSTMSDB_UPD;
1187 }
1188 case ARM::VSTMDIA:
1189 switch (Mode) {
1190 default: llvm_unreachable("Unhandled submode!");
1191 case ARM_AM::ia: return ARM::VSTMDIA_UPD;
1192 case ARM_AM::db: return ARM::VSTMDDB_UPD;
1193 }
1194 }
1195}
1196
1197/// Check if the given instruction increments or decrements a register and
1198/// return the amount it is incremented/decremented. Returns 0 if the CPSR flags
1199/// generated by the instruction are possibly read as well.
1201 ARMCC::CondCodes Pred, Register PredReg) {
1202 bool CheckCPSRDef;
1203 int Scale;
1204 switch (MI.getOpcode()) {
1205 case ARM::tADDi8: Scale = 4; CheckCPSRDef = true; break;
1206 case ARM::tSUBi8: Scale = -4; CheckCPSRDef = true; break;
1207 case ARM::t2SUBri:
1208 case ARM::t2SUBspImm:
1209 case ARM::SUBri: Scale = -1; CheckCPSRDef = true; break;
1210 case ARM::t2ADDri:
1211 case ARM::t2ADDspImm:
1212 case ARM::ADDri: Scale = 1; CheckCPSRDef = true; break;
1213 case ARM::tADDspi: Scale = 4; CheckCPSRDef = false; break;
1214 case ARM::tSUBspi: Scale = -4; CheckCPSRDef = false; break;
1215 default: return 0;
1216 }
1217
1218 Register MIPredReg;
1219 if (MI.getOperand(0).getReg() != Reg ||
1220 MI.getOperand(1).getReg() != Reg ||
1221 getInstrPredicate(MI, MIPredReg) != Pred ||
1222 MIPredReg != PredReg)
1223 return 0;
1224
1225 if (CheckCPSRDef && definesCPSR(MI))
1226 return 0;
1227 return MI.getOperand(2).getImm() * Scale;
1228}
1229
1230/// Searches for an increment or decrement of \p Reg before \p MBBI.
1233 ARMCC::CondCodes Pred, Register PredReg, int &Offset) {
1234 Offset = 0;
1235 MachineBasicBlock &MBB = *MBBI->getParent();
1236 MachineBasicBlock::iterator BeginMBBI = MBB.begin();
1237 MachineBasicBlock::iterator EndMBBI = MBB.end();
1238 if (MBBI == BeginMBBI)
1239 return EndMBBI;
1240
1241 // Skip debug values.
1242 MachineBasicBlock::iterator PrevMBBI = std::prev(MBBI);
1243 while (PrevMBBI->isDebugInstr() && PrevMBBI != BeginMBBI)
1244 --PrevMBBI;
1245
1246 Offset = isIncrementOrDecrement(*PrevMBBI, Reg, Pred, PredReg);
1247 return Offset == 0 ? EndMBBI : PrevMBBI;
1248}
1249
1250/// Searches for a increment or decrement of \p Reg after \p MBBI.
1253 ARMCC::CondCodes Pred, Register PredReg, int &Offset,
1254 const TargetRegisterInfo *TRI) {
1255 Offset = 0;
1256 MachineBasicBlock &MBB = *MBBI->getParent();
1257 MachineBasicBlock::iterator EndMBBI = MBB.end();
1258 MachineBasicBlock::iterator NextMBBI = std::next(MBBI);
1259 while (NextMBBI != EndMBBI) {
1260 // Skip debug values.
1261 while (NextMBBI != EndMBBI && NextMBBI->isDebugInstr())
1262 ++NextMBBI;
1263 if (NextMBBI == EndMBBI)
1264 return EndMBBI;
1265
1266 unsigned Off = isIncrementOrDecrement(*NextMBBI, Reg, Pred, PredReg);
1267 if (Off) {
1268 Offset = Off;
1269 return NextMBBI;
1270 }
1271
1272 // SP can only be combined if it is the next instruction after the original
1273 // MBBI, otherwise we may be incrementing the stack pointer (invalidating
1274 // anything below the new pointer) when its frame elements are still in
1275 // use. Other registers can attempt to look further, until a different use
1276 // or def of the register is found.
1277 if (Reg == ARM::SP || NextMBBI->readsRegister(Reg, TRI) ||
1278 NextMBBI->definesRegister(Reg, TRI))
1279 return EndMBBI;
1280
1281 ++NextMBBI;
1282 }
1283 return EndMBBI;
1284}
1285
1286/// Fold proceeding/trailing inc/dec of base register into the
1287/// LDM/STM/VLDM{D|S}/VSTM{D|S} op when possible:
1288///
1289/// stmia rn, <ra, rb, rc>
1290/// rn := rn + 4 * 3;
1291/// =>
1292/// stmia rn!, <ra, rb, rc>
1293///
1294/// rn := rn - 4 * 3;
1295/// ldmia rn, <ra, rb, rc>
1296/// =>
1297/// ldmdb rn!, <ra, rb, rc>
1298bool ARMLoadStoreOpt::MergeBaseUpdateLSMultiple(MachineInstr *MI) {
1299 // Thumb1 is already using updating loads/stores.
1300 if (isThumb1) return false;
1301 LLVM_DEBUG(dbgs() << "Attempting to merge update of: " << *MI);
1302
1303 const MachineOperand &BaseOP = MI->getOperand(0);
1304 Register Base = BaseOP.getReg();
1305 bool BaseKill = BaseOP.isKill();
1306 Register PredReg;
1307 ARMCC::CondCodes Pred = getInstrPredicate(*MI, PredReg);
1308 unsigned Opcode = MI->getOpcode();
1309 DebugLoc DL = MI->getDebugLoc();
1310
1311 // Can't use an updating ld/st if the base register is also a dest
1312 // register. e.g. ldmdb r0!, {r0, r1, r2}. The behavior is undefined.
1313 for (const MachineOperand &MO : llvm::drop_begin(MI->operands(), 2))
1314 if (MO.getReg() == Base)
1315 return false;
1316
1317 int Bytes = getLSMultipleTransferSize(MI);
1318 MachineBasicBlock &MBB = *MI->getParent();
1320 int Offset;
1322 = findIncDecBefore(MBBI, Base, Pred, PredReg, Offset);
1324 if (Mode == ARM_AM::ia && Offset == -Bytes) {
1325 Mode = ARM_AM::db;
1326 } else if (Mode == ARM_AM::ib && Offset == -Bytes) {
1327 Mode = ARM_AM::da;
1328 } else {
1329 MergeInstr = findIncDecAfter(MBBI, Base, Pred, PredReg, Offset, TRI);
1330 if (((Mode != ARM_AM::ia && Mode != ARM_AM::ib) || Offset != Bytes) &&
1331 ((Mode != ARM_AM::da && Mode != ARM_AM::db) || Offset != -Bytes)) {
1332
1333 // We couldn't find an inc/dec to merge. But if the base is dead, we
1334 // can still change to a writeback form as that will save us 2 bytes
1335 // of code size. It can create WAW hazards though, so only do it if
1336 // we're minimizing code size.
1337 if (!STI->hasMinSize() || !BaseKill)
1338 return false;
1339
1340 bool HighRegsUsed = false;
1341 for (const MachineOperand &MO : llvm::drop_begin(MI->operands(), 2))
1342 if (MO.getReg() >= ARM::R8) {
1343 HighRegsUsed = true;
1344 break;
1345 }
1346
1347 if (!HighRegsUsed)
1348 MergeInstr = MBB.end();
1349 else
1350 return false;
1351 }
1352 }
1353 if (MergeInstr != MBB.end()) {
1354 LLVM_DEBUG(dbgs() << " Erasing old increment: " << *MergeInstr);
1355 MBB.erase(MergeInstr);
1356 }
1357
1358 unsigned NewOpc = getUpdatingLSMultipleOpcode(Opcode, Mode);
1359 MachineInstrBuilder MIB = BuildMI(MBB, MBBI, DL, TII->get(NewOpc))
1360 .addReg(Base, getDefRegState(true)) // WB base register
1361 .addReg(Base, getKillRegState(BaseKill))
1362 .addImm(Pred).addReg(PredReg);
1363
1364 // Transfer the rest of operands.
1365 for (const MachineOperand &MO : llvm::drop_begin(MI->operands(), 3))
1366 MIB.add(MO);
1367
1368 // Transfer memoperands.
1369 MIB.setMemRefs(MI->memoperands());
1370
1371 LLVM_DEBUG(dbgs() << " Added new load/store: " << *MIB);
1372 MBB.erase(MBBI);
1373 return true;
1374}
1375
1376static unsigned getPreIndexedLoadStoreOpcode(unsigned Opc,
1378 switch (Opc) {
1379 case ARM::LDRi12:
1380 return ARM::LDR_PRE_IMM;
1381 case ARM::STRi12:
1382 return ARM::STR_PRE_IMM;
1383 case ARM::VLDRS:
1384 return Mode == ARM_AM::add ? ARM::VLDMSIA_UPD : ARM::VLDMSDB_UPD;
1385 case ARM::VLDRD:
1386 return Mode == ARM_AM::add ? ARM::VLDMDIA_UPD : ARM::VLDMDDB_UPD;
1387 case ARM::VSTRS:
1388 return Mode == ARM_AM::add ? ARM::VSTMSIA_UPD : ARM::VSTMSDB_UPD;
1389 case ARM::VSTRD:
1390 return Mode == ARM_AM::add ? ARM::VSTMDIA_UPD : ARM::VSTMDDB_UPD;
1391 case ARM::t2LDRi8:
1392 case ARM::t2LDRi12:
1393 return ARM::t2LDR_PRE;
1394 case ARM::t2STRi8:
1395 case ARM::t2STRi12:
1396 return ARM::t2STR_PRE;
1397 default: llvm_unreachable("Unhandled opcode!");
1398 }
1399}
1400
1401static unsigned getPostIndexedLoadStoreOpcode(unsigned Opc,
1403 switch (Opc) {
1404 case ARM::LDRi12:
1405 return ARM::LDR_POST_IMM;
1406 case ARM::STRi12:
1407 return ARM::STR_POST_IMM;
1408 case ARM::VLDRS:
1409 return Mode == ARM_AM::add ? ARM::VLDMSIA_UPD : ARM::VLDMSDB_UPD;
1410 case ARM::VLDRD:
1411 return Mode == ARM_AM::add ? ARM::VLDMDIA_UPD : ARM::VLDMDDB_UPD;
1412 case ARM::VSTRS:
1413 return Mode == ARM_AM::add ? ARM::VSTMSIA_UPD : ARM::VSTMSDB_UPD;
1414 case ARM::VSTRD:
1415 return Mode == ARM_AM::add ? ARM::VSTMDIA_UPD : ARM::VSTMDDB_UPD;
1416 case ARM::t2LDRi8:
1417 case ARM::t2LDRi12:
1418 return ARM::t2LDR_POST;
1419 case ARM::t2LDRBi8:
1420 case ARM::t2LDRBi12:
1421 return ARM::t2LDRB_POST;
1422 case ARM::t2LDRSBi8:
1423 case ARM::t2LDRSBi12:
1424 return ARM::t2LDRSB_POST;
1425 case ARM::t2LDRHi8:
1426 case ARM::t2LDRHi12:
1427 return ARM::t2LDRH_POST;
1428 case ARM::t2LDRSHi8:
1429 case ARM::t2LDRSHi12:
1430 return ARM::t2LDRSH_POST;
1431 case ARM::t2STRi8:
1432 case ARM::t2STRi12:
1433 return ARM::t2STR_POST;
1434 case ARM::t2STRBi8:
1435 case ARM::t2STRBi12:
1436 return ARM::t2STRB_POST;
1437 case ARM::t2STRHi8:
1438 case ARM::t2STRHi12:
1439 return ARM::t2STRH_POST;
1440
1441 case ARM::MVE_VLDRBS16:
1442 return ARM::MVE_VLDRBS16_post;
1443 case ARM::MVE_VLDRBS32:
1444 return ARM::MVE_VLDRBS32_post;
1445 case ARM::MVE_VLDRBU16:
1446 return ARM::MVE_VLDRBU16_post;
1447 case ARM::MVE_VLDRBU32:
1448 return ARM::MVE_VLDRBU32_post;
1449 case ARM::MVE_VLDRHS32:
1450 return ARM::MVE_VLDRHS32_post;
1451 case ARM::MVE_VLDRHU32:
1452 return ARM::MVE_VLDRHU32_post;
1453 case ARM::MVE_VLDRBU8:
1454 return ARM::MVE_VLDRBU8_post;
1455 case ARM::MVE_VLDRHU16:
1456 return ARM::MVE_VLDRHU16_post;
1457 case ARM::MVE_VLDRWU32:
1458 return ARM::MVE_VLDRWU32_post;
1459 case ARM::MVE_VSTRB16:
1460 return ARM::MVE_VSTRB16_post;
1461 case ARM::MVE_VSTRB32:
1462 return ARM::MVE_VSTRB32_post;
1463 case ARM::MVE_VSTRH32:
1464 return ARM::MVE_VSTRH32_post;
1465 case ARM::MVE_VSTRBU8:
1466 return ARM::MVE_VSTRBU8_post;
1467 case ARM::MVE_VSTRHU16:
1468 return ARM::MVE_VSTRHU16_post;
1469 case ARM::MVE_VSTRWU32:
1470 return ARM::MVE_VSTRWU32_post;
1471
1472 default: llvm_unreachable("Unhandled opcode!");
1473 }
1474}
1475
1476/// Fold proceeding/trailing inc/dec of base register into the
1477/// LDR/STR/FLD{D|S}/FST{D|S} op when possible:
1478bool ARMLoadStoreOpt::MergeBaseUpdateLoadStore(MachineInstr *MI) {
1479 // Thumb1 doesn't have updating LDR/STR.
1480 // FIXME: Use LDM/STM with single register instead.
1481 if (isThumb1) return false;
1482 LLVM_DEBUG(dbgs() << "Attempting to merge update of: " << *MI);
1483
1485 bool BaseKill = getLoadStoreBaseOp(*MI).isKill();
1486 unsigned Opcode = MI->getOpcode();
1487 DebugLoc DL = MI->getDebugLoc();
1488 bool isAM5 = (Opcode == ARM::VLDRD || Opcode == ARM::VLDRS ||
1489 Opcode == ARM::VSTRD || Opcode == ARM::VSTRS);
1490 bool isAM2 = (Opcode == ARM::LDRi12 || Opcode == ARM::STRi12);
1491 if (isi32Load(Opcode) || isi32Store(Opcode))
1492 if (MI->getOperand(2).getImm() != 0)
1493 return false;
1494 if (isAM5 && ARM_AM::getAM5Offset(MI->getOperand(2).getImm()) != 0)
1495 return false;
1496
1497 // Can't do the merge if the destination register is the same as the would-be
1498 // writeback register.
1499 if (MI->getOperand(0).getReg() == Base)
1500 return false;
1501
1502 Register PredReg;
1503 ARMCC::CondCodes Pred = getInstrPredicate(*MI, PredReg);
1504 int Bytes = getLSMultipleTransferSize(MI);
1505 MachineBasicBlock &MBB = *MI->getParent();
1507 int Offset;
1509 = findIncDecBefore(MBBI, Base, Pred, PredReg, Offset);
1510 unsigned NewOpc;
1511 if (!isAM5 && Offset == Bytes) {
1512 NewOpc = getPreIndexedLoadStoreOpcode(Opcode, ARM_AM::add);
1513 } else if (Offset == -Bytes) {
1514 NewOpc = getPreIndexedLoadStoreOpcode(Opcode, ARM_AM::sub);
1515 } else {
1516 MergeInstr = findIncDecAfter(MBBI, Base, Pred, PredReg, Offset, TRI);
1517 if (MergeInstr == MBB.end())
1518 return false;
1519
1521 if ((isAM5 && Offset != Bytes) ||
1522 (!isAM5 && !isLegalAddressImm(NewOpc, Offset, TII))) {
1524 if (isAM5 || !isLegalAddressImm(NewOpc, Offset, TII))
1525 return false;
1526 }
1527 }
1528 LLVM_DEBUG(dbgs() << " Erasing old increment: " << *MergeInstr);
1529 MBB.erase(MergeInstr);
1530
1532
1533 bool isLd = isLoadSingle(Opcode);
1534 if (isAM5) {
1535 // VLDM[SD]_UPD, VSTM[SD]_UPD
1536 // (There are no base-updating versions of VLDR/VSTR instructions, but the
1537 // updating load/store-multiple instructions can be used with only one
1538 // register.)
1539 MachineOperand &MO = MI->getOperand(0);
1540 auto MIB = BuildMI(MBB, MBBI, DL, TII->get(NewOpc))
1541 .addReg(Base, getDefRegState(true)) // WB base register
1542 .addReg(Base, getKillRegState(isLd ? BaseKill : false))
1543 .addImm(Pred)
1544 .addReg(PredReg)
1545 .addReg(MO.getReg(), (isLd ? getDefRegState(true)
1546 : getKillRegState(MO.isKill())))
1547 .cloneMemRefs(*MI);
1548 (void)MIB;
1549 LLVM_DEBUG(dbgs() << " Added new instruction: " << *MIB);
1550 } else if (isLd) {
1551 if (isAM2) {
1552 // LDR_PRE, LDR_POST
1553 if (NewOpc == ARM::LDR_PRE_IMM || NewOpc == ARM::LDRB_PRE_IMM) {
1554 auto MIB =
1555 BuildMI(MBB, MBBI, DL, TII->get(NewOpc), MI->getOperand(0).getReg())
1556 .addReg(Base, RegState::Define)
1557 .addReg(Base)
1558 .addImm(Offset)
1559 .addImm(Pred)
1560 .addReg(PredReg)
1561 .cloneMemRefs(*MI);
1562 (void)MIB;
1563 LLVM_DEBUG(dbgs() << " Added new instruction: " << *MIB);
1564 } else {
1566 auto MIB =
1567 BuildMI(MBB, MBBI, DL, TII->get(NewOpc), MI->getOperand(0).getReg())
1568 .addReg(Base, RegState::Define)
1569 .addReg(Base)
1570 .addReg(0)
1571 .addImm(Imm)
1572 .add(predOps(Pred, PredReg))
1573 .cloneMemRefs(*MI);
1574 (void)MIB;
1575 LLVM_DEBUG(dbgs() << " Added new instruction: " << *MIB);
1576 }
1577 } else {
1578 // t2LDR_PRE, t2LDR_POST
1579 auto MIB =
1580 BuildMI(MBB, MBBI, DL, TII->get(NewOpc), MI->getOperand(0).getReg())
1581 .addReg(Base, RegState::Define)
1582 .addReg(Base)
1583 .addImm(Offset)
1584 .add(predOps(Pred, PredReg))
1585 .cloneMemRefs(*MI);
1586 (void)MIB;
1587 LLVM_DEBUG(dbgs() << " Added new instruction: " << *MIB);
1588 }
1589 } else {
1590 MachineOperand &MO = MI->getOperand(0);
1591 // FIXME: post-indexed stores use am2offset_imm, which still encodes
1592 // the vestigial zero-reg offset register. When that's fixed, this clause
1593 // can be removed entirely.
1594 if (isAM2 && NewOpc == ARM::STR_POST_IMM) {
1596 // STR_PRE, STR_POST
1597 auto MIB = BuildMI(MBB, MBBI, DL, TII->get(NewOpc), Base)
1598 .addReg(MO.getReg(), getKillRegState(MO.isKill()))
1599 .addReg(Base)
1600 .addReg(0)
1601 .addImm(Imm)
1602 .add(predOps(Pred, PredReg))
1603 .cloneMemRefs(*MI);
1604 (void)MIB;
1605 LLVM_DEBUG(dbgs() << " Added new instruction: " << *MIB);
1606 } else {
1607 // t2STR_PRE, t2STR_POST
1608 auto MIB = BuildMI(MBB, MBBI, DL, TII->get(NewOpc), Base)
1609 .addReg(MO.getReg(), getKillRegState(MO.isKill()))
1610 .addReg(Base)
1611 .addImm(Offset)
1612 .add(predOps(Pred, PredReg))
1613 .cloneMemRefs(*MI);
1614 (void)MIB;
1615 LLVM_DEBUG(dbgs() << " Added new instruction: " << *MIB);
1616 }
1617 }
1618 MBB.erase(MBBI);
1619
1620 return true;
1621}
1622
1623bool ARMLoadStoreOpt::MergeBaseUpdateLSDouble(MachineInstr &MI) const {
1624 unsigned Opcode = MI.getOpcode();
1625 assert((Opcode == ARM::t2LDRDi8 || Opcode == ARM::t2STRDi8) &&
1626 "Must have t2STRDi8 or t2LDRDi8");
1627 if (MI.getOperand(3).getImm() != 0)
1628 return false;
1629 LLVM_DEBUG(dbgs() << "Attempting to merge update of: " << MI);
1630
1631 // Behaviour for writeback is undefined if base register is the same as one
1632 // of the others.
1633 const MachineOperand &BaseOp = MI.getOperand(2);
1634 Register Base = BaseOp.getReg();
1635 const MachineOperand &Reg0Op = MI.getOperand(0);
1636 const MachineOperand &Reg1Op = MI.getOperand(1);
1637 if (Reg0Op.getReg() == Base || Reg1Op.getReg() == Base)
1638 return false;
1639
1640 Register PredReg;
1641 ARMCC::CondCodes Pred = getInstrPredicate(MI, PredReg);
1643 MachineBasicBlock &MBB = *MI.getParent();
1644 int Offset;
1646 PredReg, Offset);
1647 unsigned NewOpc;
1648 if (Offset == 8 || Offset == -8) {
1649 NewOpc = Opcode == ARM::t2LDRDi8 ? ARM::t2LDRD_PRE : ARM::t2STRD_PRE;
1650 } else {
1651 MergeInstr = findIncDecAfter(MBBI, Base, Pred, PredReg, Offset, TRI);
1652 if (MergeInstr == MBB.end())
1653 return false;
1654 NewOpc = Opcode == ARM::t2LDRDi8 ? ARM::t2LDRD_POST : ARM::t2STRD_POST;
1655 if (!isLegalAddressImm(NewOpc, Offset, TII))
1656 return false;
1657 }
1658 LLVM_DEBUG(dbgs() << " Erasing old increment: " << *MergeInstr);
1659 MBB.erase(MergeInstr);
1660
1661 DebugLoc DL = MI.getDebugLoc();
1662 MachineInstrBuilder MIB = BuildMI(MBB, MBBI, DL, TII->get(NewOpc));
1663 if (NewOpc == ARM::t2LDRD_PRE || NewOpc == ARM::t2LDRD_POST) {
1664 MIB.add(Reg0Op).add(Reg1Op).addReg(BaseOp.getReg(), RegState::Define);
1665 } else {
1666 assert(NewOpc == ARM::t2STRD_PRE || NewOpc == ARM::t2STRD_POST);
1667 MIB.addReg(BaseOp.getReg(), RegState::Define).add(Reg0Op).add(Reg1Op);
1668 }
1669 MIB.addReg(BaseOp.getReg(), RegState::Kill)
1670 .addImm(Offset).addImm(Pred).addReg(PredReg);
1671 assert(TII->get(Opcode).getNumOperands() == 6 &&
1672 TII->get(NewOpc).getNumOperands() == 7 &&
1673 "Unexpected number of operands in Opcode specification.");
1674
1675 // Transfer implicit operands.
1676 for (const MachineOperand &MO : MI.implicit_operands())
1677 MIB.add(MO);
1678 MIB.cloneMemRefs(MI);
1679
1680 LLVM_DEBUG(dbgs() << " Added new load/store: " << *MIB);
1681 MBB.erase(MBBI);
1682 return true;
1683}
1684
1685/// Returns true if instruction is a memory operation that this pass is capable
1686/// of operating on.
1687static bool isMemoryOp(const MachineInstr &MI) {
1688 unsigned Opcode = MI.getOpcode();
1689 switch (Opcode) {
1690 case ARM::VLDRS:
1691 case ARM::VSTRS:
1692 case ARM::VLDRD:
1693 case ARM::VSTRD:
1694 case ARM::LDRi12:
1695 case ARM::STRi12:
1696 case ARM::tLDRi:
1697 case ARM::tSTRi:
1698 case ARM::tLDRspi:
1699 case ARM::tSTRspi:
1700 case ARM::t2LDRi8:
1701 case ARM::t2LDRi12:
1702 case ARM::t2STRi8:
1703 case ARM::t2STRi12:
1704 break;
1705 default:
1706 return false;
1707 }
1708 if (!MI.getOperand(1).isReg())
1709 return false;
1710
1711 // When no memory operands are present, conservatively assume unaligned,
1712 // volatile, unfoldable.
1713 if (!MI.hasOneMemOperand())
1714 return false;
1715
1716 const MachineMemOperand &MMO = **MI.memoperands_begin();
1717
1718 // Don't touch volatile memory accesses - we may be changing their order.
1719 // TODO: We could allow unordered and monotonic atomics here, but we need to
1720 // make sure the resulting ldm/stm is correctly marked as atomic.
1721 if (MMO.isVolatile() || MMO.isAtomic())
1722 return false;
1723
1724 // Unaligned ldr/str is emulated by some kernels, but unaligned ldm/stm is
1725 // not.
1726 if (MMO.getAlign() < Align(4))
1727 return false;
1728
1729 // str <undef> could probably be eliminated entirely, but for now we just want
1730 // to avoid making a mess of it.
1731 // FIXME: Use str <undef> as a wildcard to enable better stm folding.
1732 if (MI.getOperand(0).isReg() && MI.getOperand(0).isUndef())
1733 return false;
1734
1735 // Likewise don't mess with references to undefined addresses.
1736 if (MI.getOperand(1).isUndef())
1737 return false;
1738
1739 return true;
1740}
1741
1744 bool isDef, unsigned NewOpc, unsigned Reg,
1745 bool RegDeadKill, bool RegUndef, unsigned BaseReg,
1746 bool BaseKill, bool BaseUndef, ARMCC::CondCodes Pred,
1747 unsigned PredReg, const TargetInstrInfo *TII,
1748 MachineInstr *MI) {
1749 if (isDef) {
1750 MachineInstrBuilder MIB = BuildMI(MBB, MBBI, MBBI->getDebugLoc(),
1751 TII->get(NewOpc))
1752 .addReg(Reg, getDefRegState(true) | getDeadRegState(RegDeadKill))
1753 .addReg(BaseReg, getKillRegState(BaseKill)|getUndefRegState(BaseUndef));
1754 MIB.addImm(Offset).addImm(Pred).addReg(PredReg);
1755 // FIXME: This is overly conservative; the new instruction accesses 4
1756 // bytes, not 8.
1757 MIB.cloneMemRefs(*MI);
1758 } else {
1759 MachineInstrBuilder MIB = BuildMI(MBB, MBBI, MBBI->getDebugLoc(),
1760 TII->get(NewOpc))
1761 .addReg(Reg, getKillRegState(RegDeadKill) | getUndefRegState(RegUndef))
1762 .addReg(BaseReg, getKillRegState(BaseKill)|getUndefRegState(BaseUndef));
1763 MIB.addImm(Offset).addImm(Pred).addReg(PredReg);
1764 // FIXME: This is overly conservative; the new instruction accesses 4
1765 // bytes, not 8.
1766 MIB.cloneMemRefs(*MI);
1767 }
1768}
1769
1770bool ARMLoadStoreOpt::FixInvalidRegPairOp(MachineBasicBlock &MBB,
1772 MachineInstr *MI = &*MBBI;
1773 unsigned Opcode = MI->getOpcode();
1774 // FIXME: Code/comments below check Opcode == t2STRDi8, but this check returns
1775 // if we see this opcode.
1776 if (Opcode != ARM::LDRD && Opcode != ARM::STRD && Opcode != ARM::t2LDRDi8)
1777 return false;
1778
1779 const MachineOperand &BaseOp = MI->getOperand(2);
1780 Register BaseReg = BaseOp.getReg();
1781 Register EvenReg = MI->getOperand(0).getReg();
1782 Register OddReg = MI->getOperand(1).getReg();
1783 unsigned EvenRegNum = TRI->getDwarfRegNum(EvenReg, false);
1784 unsigned OddRegNum = TRI->getDwarfRegNum(OddReg, false);
1785
1786 // ARM errata 602117: LDRD with base in list may result in incorrect base
1787 // register when interrupted or faulted.
1788 bool Errata602117 = EvenReg == BaseReg &&
1789 (Opcode == ARM::LDRD || Opcode == ARM::t2LDRDi8) && STI->isCortexM3();
1790 // ARM LDRD/STRD needs consecutive registers.
1791 bool NonConsecutiveRegs = (Opcode == ARM::LDRD || Opcode == ARM::STRD) &&
1792 (EvenRegNum % 2 != 0 || EvenRegNum + 1 != OddRegNum);
1793
1794 if (!Errata602117 && !NonConsecutiveRegs)
1795 return false;
1796
1797 bool isT2 = Opcode == ARM::t2LDRDi8 || Opcode == ARM::t2STRDi8;
1798 bool isLd = Opcode == ARM::LDRD || Opcode == ARM::t2LDRDi8;
1799 bool EvenDeadKill = isLd ?
1800 MI->getOperand(0).isDead() : MI->getOperand(0).isKill();
1801 bool EvenUndef = MI->getOperand(0).isUndef();
1802 bool OddDeadKill = isLd ?
1803 MI->getOperand(1).isDead() : MI->getOperand(1).isKill();
1804 bool OddUndef = MI->getOperand(1).isUndef();
1805 bool BaseKill = BaseOp.isKill();
1806 bool BaseUndef = BaseOp.isUndef();
1807 assert((isT2 || MI->getOperand(3).getReg() == ARM::NoRegister) &&
1808 "register offset not handled below");
1809 int OffImm = getMemoryOpOffset(*MI);
1810 Register PredReg;
1811 ARMCC::CondCodes Pred = getInstrPredicate(*MI, PredReg);
1812
1813 if (OddRegNum > EvenRegNum && OffImm == 0) {
1814 // Ascending register numbers and no offset. It's safe to change it to a
1815 // ldm or stm.
1816 unsigned NewOpc = (isLd)
1817 ? (isT2 ? ARM::t2LDMIA : ARM::LDMIA)
1818 : (isT2 ? ARM::t2STMIA : ARM::STMIA);
1819 if (isLd) {
1820 BuildMI(MBB, MBBI, MBBI->getDebugLoc(), TII->get(NewOpc))
1821 .add(BaseOp)
1822 .addImm(Pred)
1823 .addReg(PredReg)
1824 .addReg(EvenReg, getDefRegState(isLd) | getDeadRegState(EvenDeadKill))
1825 .addReg(OddReg, getDefRegState(isLd) | getDeadRegState(OddDeadKill))
1826 .cloneMemRefs(*MI);
1827 ++NumLDRD2LDM;
1828 } else {
1829 BuildMI(MBB, MBBI, MBBI->getDebugLoc(), TII->get(NewOpc))
1830 .add(BaseOp)
1831 .addImm(Pred)
1832 .addReg(PredReg)
1833 .addReg(EvenReg,
1834 getKillRegState(EvenDeadKill) | getUndefRegState(EvenUndef))
1835 .addReg(OddReg,
1836 getKillRegState(OddDeadKill) | getUndefRegState(OddUndef))
1837 .cloneMemRefs(*MI);
1838 ++NumSTRD2STM;
1839 }
1840 } else {
1841 // Split into two instructions.
1842 unsigned NewOpc = (isLd)
1843 ? (isT2 ? (OffImm < 0 ? ARM::t2LDRi8 : ARM::t2LDRi12) : ARM::LDRi12)
1844 : (isT2 ? (OffImm < 0 ? ARM::t2STRi8 : ARM::t2STRi12) : ARM::STRi12);
1845 // Be extra careful for thumb2. t2LDRi8 can't reference a zero offset,
1846 // so adjust and use t2LDRi12 here for that.
1847 unsigned NewOpc2 = (isLd)
1848 ? (isT2 ? (OffImm+4 < 0 ? ARM::t2LDRi8 : ARM::t2LDRi12) : ARM::LDRi12)
1849 : (isT2 ? (OffImm+4 < 0 ? ARM::t2STRi8 : ARM::t2STRi12) : ARM::STRi12);
1850 // If this is a load, make sure the first load does not clobber the base
1851 // register before the second load reads it.
1852 if (isLd && TRI->regsOverlap(EvenReg, BaseReg)) {
1853 assert(!TRI->regsOverlap(OddReg, BaseReg));
1854 InsertLDR_STR(MBB, MBBI, OffImm + 4, isLd, NewOpc2, OddReg, OddDeadKill,
1855 false, BaseReg, false, BaseUndef, Pred, PredReg, TII, MI);
1856 InsertLDR_STR(MBB, MBBI, OffImm, isLd, NewOpc, EvenReg, EvenDeadKill,
1857 false, BaseReg, BaseKill, BaseUndef, Pred, PredReg, TII,
1858 MI);
1859 } else {
1860 if (OddReg == EvenReg && EvenDeadKill) {
1861 // If the two source operands are the same, the kill marker is
1862 // probably on the first one. e.g.
1863 // t2STRDi8 killed %r5, %r5, killed %r9, 0, 14, %reg0
1864 EvenDeadKill = false;
1865 OddDeadKill = true;
1866 }
1867 // Never kill the base register in the first instruction.
1868 if (EvenReg == BaseReg)
1869 EvenDeadKill = false;
1870 InsertLDR_STR(MBB, MBBI, OffImm, isLd, NewOpc, EvenReg, EvenDeadKill,
1871 EvenUndef, BaseReg, false, BaseUndef, Pred, PredReg, TII,
1872 MI);
1873 InsertLDR_STR(MBB, MBBI, OffImm + 4, isLd, NewOpc2, OddReg, OddDeadKill,
1874 OddUndef, BaseReg, BaseKill, BaseUndef, Pred, PredReg, TII,
1875 MI);
1876 }
1877 if (isLd)
1878 ++NumLDRD2LDR;
1879 else
1880 ++NumSTRD2STR;
1881 }
1882
1883 MBBI = MBB.erase(MBBI);
1884 return true;
1885}
1886
1887/// An optimization pass to turn multiple LDR / STR ops of the same base and
1888/// incrementing offset into LDM / STM ops.
1889bool ARMLoadStoreOpt::LoadStoreMultipleOpti(MachineBasicBlock &MBB) {
1890 MemOpQueue MemOps;
1891 unsigned CurrBase = 0;
1892 unsigned CurrOpc = ~0u;
1893 ARMCC::CondCodes CurrPred = ARMCC::AL;
1894 unsigned Position = 0;
1895 assert(Candidates.size() == 0);
1896 assert(MergeBaseCandidates.size() == 0);
1897 LiveRegsValid = false;
1898
1900 I = MBBI) {
1901 // The instruction in front of the iterator is the one we look at.
1902 MBBI = std::prev(I);
1903 if (FixInvalidRegPairOp(MBB, MBBI))
1904 continue;
1905 ++Position;
1906
1907 if (isMemoryOp(*MBBI)) {
1908 unsigned Opcode = MBBI->getOpcode();
1909 const MachineOperand &MO = MBBI->getOperand(0);
1910 Register Reg = MO.getReg();
1912 Register PredReg;
1913 ARMCC::CondCodes Pred = getInstrPredicate(*MBBI, PredReg);
1915 if (CurrBase == 0) {
1916 // Start of a new chain.
1917 CurrBase = Base;
1918 CurrOpc = Opcode;
1919 CurrPred = Pred;
1920 MemOps.push_back(MemOpQueueEntry(*MBBI, Offset, Position));
1921 continue;
1922 }
1923 // Note: No need to match PredReg in the next if.
1924 if (CurrOpc == Opcode && CurrBase == Base && CurrPred == Pred) {
1925 // Watch out for:
1926 // r4 := ldr [r0, #8]
1927 // r4 := ldr [r0, #4]
1928 // or
1929 // r0 := ldr [r0]
1930 // If a load overrides the base register or a register loaded by
1931 // another load in our chain, we cannot take this instruction.
1932 bool Overlap = false;
1933 if (isLoadSingle(Opcode)) {
1934 Overlap = (Base == Reg);
1935 if (!Overlap) {
1936 for (const MemOpQueueEntry &E : MemOps) {
1937 if (TRI->regsOverlap(Reg, E.MI->getOperand(0).getReg())) {
1938 Overlap = true;
1939 break;
1940 }
1941 }
1942 }
1943 }
1944
1945 if (!Overlap) {
1946 // Check offset and sort memory operation into the current chain.
1947 if (Offset > MemOps.back().Offset) {
1948 MemOps.push_back(MemOpQueueEntry(*MBBI, Offset, Position));
1949 continue;
1950 } else {
1951 MemOpQueue::iterator MI, ME;
1952 for (MI = MemOps.begin(), ME = MemOps.end(); MI != ME; ++MI) {
1953 if (Offset < MI->Offset) {
1954 // Found a place to insert.
1955 break;
1956 }
1957 if (Offset == MI->Offset) {
1958 // Collision, abort.
1959 MI = ME;
1960 break;
1961 }
1962 }
1963 if (MI != MemOps.end()) {
1964 MemOps.insert(MI, MemOpQueueEntry(*MBBI, Offset, Position));
1965 continue;
1966 }
1967 }
1968 }
1969 }
1970
1971 // Don't advance the iterator; The op will start a new chain next.
1972 MBBI = I;
1973 --Position;
1974 // Fallthrough to look into existing chain.
1975 } else if (MBBI->isDebugInstr()) {
1976 continue;
1977 } else if (MBBI->getOpcode() == ARM::t2LDRDi8 ||
1978 MBBI->getOpcode() == ARM::t2STRDi8) {
1979 // ARMPreAllocLoadStoreOpt has already formed some LDRD/STRD instructions
1980 // remember them because we may still be able to merge add/sub into them.
1981 MergeBaseCandidates.push_back(&*MBBI);
1982 }
1983
1984 // If we are here then the chain is broken; Extract candidates for a merge.
1985 if (MemOps.size() > 0) {
1986 FormCandidates(MemOps);
1987 // Reset for the next chain.
1988 CurrBase = 0;
1989 CurrOpc = ~0u;
1990 CurrPred = ARMCC::AL;
1991 MemOps.clear();
1992 }
1993 }
1994 if (MemOps.size() > 0)
1995 FormCandidates(MemOps);
1996
1997 // Sort candidates so they get processed from end to begin of the basic
1998 // block later; This is necessary for liveness calculation.
1999 auto LessThan = [](const MergeCandidate* M0, const MergeCandidate *M1) {
2000 return M0->InsertPos < M1->InsertPos;
2001 };
2002 llvm::sort(Candidates, LessThan);
2003
2004 // Go through list of candidates and merge.
2005 bool Changed = false;
2006 for (const MergeCandidate *Candidate : Candidates) {
2007 if (Candidate->CanMergeToLSMulti || Candidate->CanMergeToLSDouble) {
2008 MachineInstr *Merged = MergeOpsUpdate(*Candidate);
2009 // Merge preceding/trailing base inc/dec into the merged op.
2010 if (Merged) {
2011 Changed = true;
2012 unsigned Opcode = Merged->getOpcode();
2013 if (Opcode == ARM::t2STRDi8 || Opcode == ARM::t2LDRDi8)
2014 MergeBaseUpdateLSDouble(*Merged);
2015 else
2016 MergeBaseUpdateLSMultiple(Merged);
2017 } else {
2018 for (MachineInstr *MI : Candidate->Instrs) {
2019 if (MergeBaseUpdateLoadStore(MI))
2020 Changed = true;
2021 }
2022 }
2023 } else {
2024 assert(Candidate->Instrs.size() == 1);
2025 if (MergeBaseUpdateLoadStore(Candidate->Instrs.front()))
2026 Changed = true;
2027 }
2028 }
2029 Candidates.clear();
2030 // Try to fold add/sub into the LDRD/STRD formed by ARMPreAllocLoadStoreOpt.
2031 for (MachineInstr *MI : MergeBaseCandidates)
2032 MergeBaseUpdateLSDouble(*MI);
2033 MergeBaseCandidates.clear();
2034
2035 return Changed;
2036}
2037
2038/// If this is a exit BB, try merging the return ops ("bx lr" and "mov pc, lr")
2039/// into the preceding stack restore so it directly restore the value of LR
2040/// into pc.
2041/// ldmfd sp!, {..., lr}
2042/// bx lr
2043/// or
2044/// ldmfd sp!, {..., lr}
2045/// mov pc, lr
2046/// =>
2047/// ldmfd sp!, {..., pc}
2048bool ARMLoadStoreOpt::MergeReturnIntoLDM(MachineBasicBlock &MBB) {
2049 // Thumb1 LDM doesn't allow high registers.
2050 if (isThumb1) return false;
2051 if (MBB.empty()) return false;
2052
2054 if (MBBI != MBB.begin() && MBBI != MBB.end() &&
2055 (MBBI->getOpcode() == ARM::BX_RET ||
2056 MBBI->getOpcode() == ARM::tBX_RET ||
2057 MBBI->getOpcode() == ARM::MOVPCLR)) {
2058 MachineBasicBlock::iterator PrevI = std::prev(MBBI);
2059 // Ignore any debug instructions.
2060 while (PrevI->isDebugInstr() && PrevI != MBB.begin())
2061 --PrevI;
2062 MachineInstr &PrevMI = *PrevI;
2063 unsigned Opcode = PrevMI.getOpcode();
2064 if (Opcode == ARM::LDMIA_UPD || Opcode == ARM::LDMDA_UPD ||
2065 Opcode == ARM::LDMDB_UPD || Opcode == ARM::LDMIB_UPD ||
2066 Opcode == ARM::t2LDMIA_UPD || Opcode == ARM::t2LDMDB_UPD) {
2067 MachineOperand &MO = PrevMI.getOperand(PrevMI.getNumOperands() - 1);
2068 if (MO.getReg() != ARM::LR)
2069 return false;
2070 unsigned NewOpc = (isThumb2 ? ARM::t2LDMIA_RET : ARM::LDMIA_RET);
2071 assert(((isThumb2 && Opcode == ARM::t2LDMIA_UPD) ||
2072 Opcode == ARM::LDMIA_UPD) && "Unsupported multiple load-return!");
2073 PrevMI.setDesc(TII->get(NewOpc));
2074 MO.setReg(ARM::PC);
2075 PrevMI.copyImplicitOps(*MBB.getParent(), *MBBI);
2076 MBB.erase(MBBI);
2077 return true;
2078 }
2079 }
2080 return false;
2081}
2082
2083bool ARMLoadStoreOpt::CombineMovBx(MachineBasicBlock &MBB) {
2085 if (MBBI == MBB.begin() || MBBI == MBB.end() ||
2086 MBBI->getOpcode() != ARM::tBX_RET)
2087 return false;
2088
2090 --Prev;
2091 if (Prev->getOpcode() != ARM::tMOVr ||
2092 !Prev->definesRegister(ARM::LR, /*TRI=*/nullptr))
2093 return false;
2094
2095 for (auto Use : Prev->uses())
2096 if (Use.isKill()) {
2097 assert(STI->hasV4TOps());
2098 BuildMI(MBB, MBBI, MBBI->getDebugLoc(), TII->get(ARM::tBX))
2099 .addReg(Use.getReg(), RegState::Kill)
2102 MBB.erase(MBBI);
2103 MBB.erase(Prev);
2104 return true;
2105 }
2106
2107 llvm_unreachable("tMOVr doesn't kill a reg before tBX_RET?");
2108}
2109
2110bool ARMLoadStoreOpt::runOnMachineFunction(MachineFunction &Fn) {
2111 MF = &Fn;
2112 STI = &Fn.getSubtarget<ARMSubtarget>();
2113 TL = STI->getTargetLowering();
2114 AFI = Fn.getInfo<ARMFunctionInfo>();
2115 TII = STI->getInstrInfo();
2116 TRI = STI->getRegisterInfo();
2117
2118 RegClassInfoValid = false;
2119 isThumb2 = AFI->isThumb2Function();
2120 isThumb1 = AFI->isThumbFunction() && !isThumb2;
2121
2122 bool Modified = false, ModifiedLDMReturn = false;
2123 for (MachineBasicBlock &MBB : Fn) {
2124 Modified |= LoadStoreMultipleOpti(MBB);
2125 if (STI->hasV5TOps() && !AFI->shouldSignReturnAddress())
2126 ModifiedLDMReturn |= MergeReturnIntoLDM(MBB);
2127 if (isThumb1)
2128 Modified |= CombineMovBx(MBB);
2129 }
2130 Modified |= ModifiedLDMReturn;
2131
2132 // If we merged a BX instruction into an LDM, we need to re-calculate whether
2133 // LR is restored. This check needs to consider the whole function, not just
2134 // the instruction(s) we changed, because there may be other BX returns which
2135 // still need LR to be restored.
2136 if (ModifiedLDMReturn)
2138
2139 Allocator.DestroyAll();
2140 return Modified;
2141}
2142
2143bool ARMLoadStoreOptLegacy::runOnMachineFunction(MachineFunction &MF) {
2144 if (skipFunction(MF.getFunction()))
2145 return false;
2146 ARMLoadStoreOpt Impl;
2147 return Impl.runOnMachineFunction(MF);
2148}
2149
2150#define ARM_PREALLOC_LOAD_STORE_OPT_NAME \
2151 "ARM pre- register allocation load / store optimization pass"
2152
2153namespace {
2154
2155/// Pre- register allocation pass that move load / stores from consecutive
2156/// locations close to make it more likely they will be combined later.
2157struct ARMPreAllocLoadStoreOpt {
2159 const DataLayout *TD;
2160 const TargetInstrInfo *TII;
2161 const TargetRegisterInfo *TRI;
2162 const ARMSubtarget *STI;
2165 MachineFunction *MF;
2166
2167 bool runOnMachineFunction(MachineFunction &Fn, AliasAnalysis *AA,
2169
2170private:
2171 bool CanFormLdStDWord(MachineInstr *Op0, MachineInstr *Op1, DebugLoc &dl,
2172 unsigned &NewOpc, Register &EvenReg, Register &OddReg,
2173 Register &BaseReg, int &Offset, Register &PredReg,
2174 ARMCC::CondCodes &Pred, bool &isT2);
2175 bool RescheduleOps(
2177 unsigned Base, bool isLd, DenseMap<MachineInstr *, unsigned> &MI2LocMap,
2179 bool RescheduleLoadStoreInstrs(MachineBasicBlock *MBB);
2180 bool DistributeIncrements();
2181 bool DistributeIncrements(Register Base);
2182};
2183
2184struct ARMPreAllocLoadStoreOptLegacy : public MachineFunctionPass {
2185 static char ID;
2186
2187 ARMPreAllocLoadStoreOptLegacy() : MachineFunctionPass(ID) {}
2188
2189 bool runOnMachineFunction(MachineFunction &Fn) override;
2190
2191 StringRef getPassName() const override {
2193 }
2194
2195 void getAnalysisUsage(AnalysisUsage &AU) const override {
2201 }
2202};
2203
2204char ARMPreAllocLoadStoreOptLegacy::ID = 0;
2205
2206} // end anonymous namespace
2207
2208INITIALIZE_PASS_BEGIN(ARMPreAllocLoadStoreOptLegacy, "arm-prera-ldst-opt",
2211INITIALIZE_PASS_END(ARMPreAllocLoadStoreOptLegacy, "arm-prera-ldst-opt",
2213
2214// Limit the number of instructions to be rescheduled.
2215// FIXME: tune this limit, and/or come up with some better heuristics.
2216static cl::opt<unsigned> InstReorderLimit("arm-prera-ldst-opt-reorder-limit",
2217 cl::init(8), cl::Hidden);
2218
2219bool ARMPreAllocLoadStoreOpt::runOnMachineFunction(MachineFunction &Fn,
2220 AliasAnalysis *AAIn,
2221 MachineDominatorTree *DTIn) {
2223 return false;
2224
2225 AA = AAIn;
2226 DT = DTIn;
2227 TD = &Fn.getDataLayout();
2228 STI = &Fn.getSubtarget<ARMSubtarget>();
2229 TII = STI->getInstrInfo();
2230 TRI = STI->getRegisterInfo();
2231 MRI = &Fn.getRegInfo();
2232 MF = &Fn;
2233
2234 bool Modified = DistributeIncrements();
2235 for (MachineBasicBlock &MFI : Fn)
2236 Modified |= RescheduleLoadStoreInstrs(&MFI);
2237
2238 return Modified;
2239}
2240
2241bool ARMPreAllocLoadStoreOptLegacy::runOnMachineFunction(MachineFunction &Fn) {
2242 if (skipFunction(Fn.getFunction()))
2243 return false;
2244
2245 ARMPreAllocLoadStoreOpt Impl;
2246 AliasAnalysis *AA = &getAnalysis<AAResultsWrapperPass>().getAAResults();
2247 MachineDominatorTree *DT =
2248 &getAnalysis<MachineDominatorTreeWrapperPass>().getDomTree();
2249 return Impl.runOnMachineFunction(Fn, AA, DT);
2250}
2251
2252static bool IsSafeAndProfitableToMove(bool isLd, unsigned Base,
2256 SmallSet<unsigned, 4> &MemRegs,
2257 const TargetRegisterInfo *TRI,
2258 AliasAnalysis *AA) {
2259 // Are there stores / loads / calls between them?
2260 SmallSet<unsigned, 4> AddedRegPressure;
2261 while (++I != E) {
2262 if (I->isDebugInstr() || MemOps.count(&*I))
2263 continue;
2264 if (I->isCall() || I->isTerminator() || I->hasUnmodeledSideEffects())
2265 return false;
2266 if (I->mayStore() || (!isLd && I->mayLoad()))
2267 for (MachineInstr *MemOp : MemOps)
2268 if (I->mayAlias(AA, *MemOp, /*UseTBAA*/ false))
2269 return false;
2270 for (unsigned j = 0, NumOps = I->getNumOperands(); j != NumOps; ++j) {
2271 MachineOperand &MO = I->getOperand(j);
2272 if (!MO.isReg())
2273 continue;
2274 Register Reg = MO.getReg();
2275 if (MO.isDef() && TRI->regsOverlap(Reg, Base))
2276 return false;
2277 if (Reg != Base && !MemRegs.count(Reg))
2278 AddedRegPressure.insert(Reg);
2279 }
2280 }
2281
2282 // Estimate register pressure increase due to the transformation.
2283 if (MemRegs.size() <= 4)
2284 // Ok if we are moving small number of instructions.
2285 return true;
2286 return AddedRegPressure.size() <= MemRegs.size() * 2;
2287}
2288
2289bool ARMPreAllocLoadStoreOpt::CanFormLdStDWord(
2290 MachineInstr *Op0, MachineInstr *Op1, DebugLoc &dl, unsigned &NewOpc,
2291 Register &FirstReg, Register &SecondReg, Register &BaseReg, int &Offset,
2292 Register &PredReg, ARMCC::CondCodes &Pred, bool &isT2) {
2293 // Make sure we're allowed to generate LDRD/STRD.
2294 if (!STI->hasV5TEOps())
2295 return false;
2296
2297 // FIXME: VLDRS / VSTRS -> VLDRD / VSTRD
2298 unsigned Scale = 1;
2299 unsigned Opcode = Op0->getOpcode();
2300 if (Opcode == ARM::LDRi12) {
2301 NewOpc = ARM::LDRD;
2302 } else if (Opcode == ARM::STRi12) {
2303 NewOpc = ARM::STRD;
2304 } else if (Opcode == ARM::t2LDRi8 || Opcode == ARM::t2LDRi12) {
2305 NewOpc = ARM::t2LDRDi8;
2306 Scale = 4;
2307 isT2 = true;
2308 } else if (Opcode == ARM::t2STRi8 || Opcode == ARM::t2STRi12) {
2309 NewOpc = ARM::t2STRDi8;
2310 Scale = 4;
2311 isT2 = true;
2312 } else {
2313 return false;
2314 }
2315
2316 // Make sure the base address satisfies i64 ld / st alignment requirement.
2317 // At the moment, we ignore the memoryoperand's value.
2318 // If we want to use AliasAnalysis, we should check it accordingly.
2319 if (!Op0->hasOneMemOperand() ||
2320 (*Op0->memoperands_begin())->isVolatile() ||
2321 (*Op0->memoperands_begin())->isAtomic())
2322 return false;
2323
2324 Align Alignment = (*Op0->memoperands_begin())->getAlign();
2325 Align ReqAlign = STI->getDualLoadStoreAlignment();
2326 if (Alignment < ReqAlign)
2327 return false;
2328
2329 // Then make sure the immediate offset fits.
2330 int OffImm = getMemoryOpOffset(*Op0);
2331 if (isT2) {
2332 int Limit = (1 << 8) * Scale;
2333 if (OffImm >= Limit || (OffImm <= -Limit) || (OffImm & (Scale-1)))
2334 return false;
2335 Offset = OffImm;
2336 } else {
2338 if (OffImm < 0) {
2340 OffImm = - OffImm;
2341 }
2342 int Limit = (1 << 8) * Scale;
2343 if (OffImm >= Limit || (OffImm & (Scale-1)))
2344 return false;
2345 Offset = ARM_AM::getAM3Opc(AddSub, OffImm);
2346 }
2347 FirstReg = Op0->getOperand(0).getReg();
2348 SecondReg = Op1->getOperand(0).getReg();
2349 if (FirstReg == SecondReg)
2350 return false;
2351 BaseReg = Op0->getOperand(1).getReg();
2352 Pred = getInstrPredicate(*Op0, PredReg);
2353 dl = Op0->getDebugLoc();
2354 return true;
2355}
2356
2357bool ARMPreAllocLoadStoreOpt::RescheduleOps(
2358 MachineBasicBlock *MBB, SmallVectorImpl<MachineInstr *> &Ops, unsigned Base,
2359 bool isLd, DenseMap<MachineInstr *, unsigned> &MI2LocMap,
2360 SmallDenseMap<Register, SmallVector<MachineInstr *>, 8> &RegisterMap) {
2361 bool RetVal = false;
2362
2363 // Sort by offset (in reverse order).
2364 llvm::sort(Ops, [](const MachineInstr *LHS, const MachineInstr *RHS) {
2365 int LOffset = getMemoryOpOffset(*LHS);
2366 int ROffset = getMemoryOpOffset(*RHS);
2367 assert(LHS == RHS || LOffset != ROffset);
2368 return LOffset > ROffset;
2369 });
2370
2371 // The loads / stores of the same base are in order. Scan them from first to
2372 // last and check for the following:
2373 // 1. Any def of base.
2374 // 2. Any gaps.
2375 while (Ops.size() > 1) {
2376 unsigned FirstLoc = ~0U;
2377 unsigned LastLoc = 0;
2378 MachineInstr *FirstOp = nullptr;
2379 MachineInstr *LastOp = nullptr;
2380 int LastOffset = 0;
2381 unsigned LastOpcode = 0;
2382 unsigned LastBytes = 0;
2383 unsigned NumMove = 0;
2384 for (MachineInstr *Op : llvm::reverse(Ops)) {
2385 // Make sure each operation has the same kind.
2386 unsigned LSMOpcode
2387 = getLoadStoreMultipleOpcode(Op->getOpcode(), ARM_AM::ia);
2388 if (LastOpcode && LSMOpcode != LastOpcode)
2389 break;
2390
2391 // Check that we have a continuous set of offsets.
2392 int Offset = getMemoryOpOffset(*Op);
2393 unsigned Bytes = getLSMultipleTransferSize(Op);
2394 if (LastBytes) {
2395 if (Bytes != LastBytes || Offset != (LastOffset + (int)Bytes))
2396 break;
2397 }
2398
2399 // Don't try to reschedule too many instructions.
2400 if (NumMove == InstReorderLimit)
2401 break;
2402
2403 // Found a mergeable instruction; save information about it.
2404 ++NumMove;
2405 LastOffset = Offset;
2406 LastBytes = Bytes;
2407 LastOpcode = LSMOpcode;
2408
2409 unsigned Loc = MI2LocMap[Op];
2410 if (Loc <= FirstLoc) {
2411 FirstLoc = Loc;
2412 FirstOp = Op;
2413 }
2414 if (Loc >= LastLoc) {
2415 LastLoc = Loc;
2416 LastOp = Op;
2417 }
2418 }
2419
2420 if (NumMove <= 1)
2421 Ops.pop_back();
2422 else {
2423 SmallPtrSet<MachineInstr*, 4> MemOps;
2424 SmallSet<unsigned, 4> MemRegs;
2425 for (size_t i = Ops.size() - NumMove, e = Ops.size(); i != e; ++i) {
2426 MemOps.insert(Ops[i]);
2427 MemRegs.insert(Ops[i]->getOperand(0).getReg());
2428 }
2429
2430 // Be conservative, if the instructions are too far apart, don't
2431 // move them. We want to limit the increase of register pressure.
2432 bool DoMove = (LastLoc - FirstLoc) <= NumMove*4; // FIXME: Tune this.
2433 if (DoMove)
2434 DoMove = IsSafeAndProfitableToMove(isLd, Base, FirstOp, LastOp,
2435 MemOps, MemRegs, TRI, AA);
2436 if (!DoMove) {
2437 for (unsigned i = 0; i != NumMove; ++i)
2438 Ops.pop_back();
2439 } else {
2440 // This is the new location for the loads / stores.
2441 MachineBasicBlock::iterator InsertPos = isLd ? FirstOp : LastOp;
2442 while (InsertPos != MBB->end() &&
2443 (MemOps.count(&*InsertPos) || InsertPos->isDebugInstr()))
2444 ++InsertPos;
2445
2446 // If we are moving a pair of loads / stores, see if it makes sense
2447 // to try to allocate a pair of registers that can form register pairs.
2448 MachineInstr *Op0 = Ops.back();
2449 MachineInstr *Op1 = Ops[Ops.size()-2];
2450 Register FirstReg, SecondReg;
2451 Register BaseReg, PredReg;
2453 bool isT2 = false;
2454 unsigned NewOpc = 0;
2455 int Offset = 0;
2456 DebugLoc dl;
2457 if (NumMove == 2 && CanFormLdStDWord(Op0, Op1, dl, NewOpc,
2458 FirstReg, SecondReg, BaseReg,
2459 Offset, PredReg, Pred, isT2)) {
2460 Ops.pop_back();
2461 Ops.pop_back();
2462
2463 const MCInstrDesc &MCID = TII->get(NewOpc);
2464 const TargetRegisterClass *TRC = TII->getRegClass(MCID, 0);
2465 MRI->constrainRegClass(FirstReg, TRC);
2466 MRI->constrainRegClass(SecondReg, TRC);
2467
2468 // Form the pair instruction.
2469 if (isLd) {
2470 MachineInstrBuilder MIB = BuildMI(*MBB, InsertPos, dl, MCID)
2471 .addReg(FirstReg, RegState::Define)
2472 .addReg(SecondReg, RegState::Define)
2473 .addReg(BaseReg);
2474 // FIXME: We're converting from LDRi12 to an insn that still
2475 // uses addrmode2, so we need an explicit offset reg. It should
2476 // always by reg0 since we're transforming LDRi12s.
2477 if (!isT2)
2478 MIB.addReg(0);
2479 MIB.addImm(Offset).addImm(Pred).addReg(PredReg);
2480 MIB.cloneMergedMemRefs({Op0, Op1});
2481 LLVM_DEBUG(dbgs() << "Formed " << *MIB << "\n");
2482 ++NumLDRDFormed;
2483 } else {
2484 MachineInstrBuilder MIB = BuildMI(*MBB, InsertPos, dl, MCID)
2485 .addReg(FirstReg)
2486 .addReg(SecondReg)
2487 .addReg(BaseReg);
2488 // FIXME: We're converting from LDRi12 to an insn that still
2489 // uses addrmode2, so we need an explicit offset reg. It should
2490 // always by reg0 since we're transforming STRi12s.
2491 if (!isT2)
2492 MIB.addReg(0);
2493 MIB.addImm(Offset).addImm(Pred).addReg(PredReg);
2494 MIB.cloneMergedMemRefs({Op0, Op1});
2495 LLVM_DEBUG(dbgs() << "Formed " << *MIB << "\n");
2496 ++NumSTRDFormed;
2497 }
2498 MBB->erase(Op0);
2499 MBB->erase(Op1);
2500
2501 if (!isT2) {
2502 // Add register allocation hints to form register pairs.
2503 MRI->setRegAllocationHint(FirstReg, ARMRI::RegPairEven, SecondReg);
2504 MRI->setRegAllocationHint(SecondReg, ARMRI::RegPairOdd, FirstReg);
2505 }
2506 } else {
2507 for (unsigned i = 0; i != NumMove; ++i) {
2508 MachineInstr *Op = Ops.pop_back_val();
2509 if (isLd) {
2510 // Populate RegisterMap with all Registers defined by loads.
2511 Register Reg = Op->getOperand(0).getReg();
2512 RegisterMap[Reg];
2513 }
2514
2515 MBB->splice(InsertPos, MBB, Op);
2516 }
2517 }
2518
2519 NumLdStMoved += NumMove;
2520 RetVal = true;
2521 }
2522 }
2523 }
2524
2525 return RetVal;
2526}
2527
2529 std::function<void(MachineOperand &)> Fn) {
2530 if (MI->isNonListDebugValue()) {
2531 auto &Op = MI->getOperand(0);
2532 if (Op.isReg())
2533 Fn(Op);
2534 } else {
2535 for (unsigned I = 2; I < MI->getNumOperands(); I++) {
2536 auto &Op = MI->getOperand(I);
2537 if (Op.isReg())
2538 Fn(Op);
2539 }
2540 }
2541}
2542
2543// Update the RegisterMap with the instruction that was moved because a
2544// DBG_VALUE_LIST may need to be moved again.
2547 MachineInstr *DbgValueListInstr, MachineInstr *InstrToReplace) {
2548
2549 forEachDbgRegOperand(DbgValueListInstr, [&](MachineOperand &Op) {
2550 auto RegIt = RegisterMap.find(Op.getReg());
2551 if (RegIt == RegisterMap.end())
2552 return;
2553 auto &InstrVec = RegIt->getSecond();
2554 llvm::replace(InstrVec, InstrToReplace, DbgValueListInstr);
2555 });
2556}
2557
2559 auto DbgVar = DebugVariable(MI->getDebugVariable(), MI->getDebugExpression(),
2560 MI->getDebugLoc()->getInlinedAt());
2561 return DbgVar;
2562}
2563
2564bool
2565ARMPreAllocLoadStoreOpt::RescheduleLoadStoreInstrs(MachineBasicBlock *MBB) {
2566 bool RetVal = false;
2567
2568 DenseMap<MachineInstr *, unsigned> MI2LocMap;
2569 using Base2InstMap = DenseMap<unsigned, SmallVector<MachineInstr *, 4>>;
2570 using BaseVec = SmallVector<unsigned, 4>;
2571 Base2InstMap Base2LdsMap;
2572 Base2InstMap Base2StsMap;
2573 BaseVec LdBases;
2574 BaseVec StBases;
2575 // This map is used to track the relationship between the virtual
2576 // register that is the result of a load that is moved and the DBG_VALUE
2577 // MachineInstr pointer that uses that virtual register.
2578 SmallDenseMap<Register, SmallVector<MachineInstr *>, 8> RegisterMap;
2579
2580 unsigned Loc = 0;
2583 while (MBBI != E) {
2584 for (; MBBI != E; ++MBBI) {
2585 MachineInstr &MI = *MBBI;
2586 if (MI.isCall() || MI.isTerminator()) {
2587 // Stop at barriers.
2588 ++MBBI;
2589 break;
2590 }
2591
2592 if (!MI.isDebugInstr())
2593 MI2LocMap[&MI] = ++Loc;
2594
2595 if (!isMemoryOp(MI))
2596 continue;
2597 Register PredReg;
2598 if (getInstrPredicate(MI, PredReg) != ARMCC::AL)
2599 continue;
2600
2601 int Opc = MI.getOpcode();
2602 bool isLd = isLoadSingle(Opc);
2603 Register Base = MI.getOperand(1).getReg();
2605 bool StopHere = false;
2606 auto FindBases = [&](Base2InstMap &Base2Ops, BaseVec &Bases) {
2607 auto [BI, Inserted] = Base2Ops.try_emplace(Base);
2608 if (Inserted) {
2609 BI->second.push_back(&MI);
2610 Bases.push_back(Base);
2611 return;
2612 }
2613 for (const MachineInstr *MI : BI->second) {
2614 if (Offset == getMemoryOpOffset(*MI)) {
2615 StopHere = true;
2616 break;
2617 }
2618 }
2619 if (!StopHere)
2620 BI->second.push_back(&MI);
2621 };
2622
2623 if (isLd)
2624 FindBases(Base2LdsMap, LdBases);
2625 else
2626 FindBases(Base2StsMap, StBases);
2627
2628 if (StopHere) {
2629 // Found a duplicate (a base+offset combination that's seen earlier).
2630 // Backtrack.
2631 --Loc;
2632 break;
2633 }
2634 }
2635
2636 // Re-schedule loads.
2637 for (unsigned Base : LdBases) {
2638 SmallVectorImpl<MachineInstr *> &Lds = Base2LdsMap[Base];
2639 if (Lds.size() > 1)
2640 RetVal |= RescheduleOps(MBB, Lds, Base, true, MI2LocMap, RegisterMap);
2641 }
2642
2643 // Re-schedule stores.
2644 for (unsigned Base : StBases) {
2645 SmallVectorImpl<MachineInstr *> &Sts = Base2StsMap[Base];
2646 if (Sts.size() > 1)
2647 RetVal |= RescheduleOps(MBB, Sts, Base, false, MI2LocMap, RegisterMap);
2648 }
2649
2650 if (MBBI != E) {
2651 Base2LdsMap.clear();
2652 Base2StsMap.clear();
2653 LdBases.clear();
2654 StBases.clear();
2655 }
2656 }
2657
2658 // Reschedule DBG_VALUEs to match any loads that were moved. When a load is
2659 // sunk beyond a DBG_VALUE that is referring to it, the DBG_VALUE becomes a
2660 // use-before-def, resulting in a loss of debug info.
2661
2662 // Example:
2663 // Before the Pre Register Allocation Load Store Pass
2664 // inst_a
2665 // %2 = ld ...
2666 // inst_b
2667 // DBG_VALUE %2, "x", ...
2668 // %3 = ld ...
2669
2670 // After the Pass:
2671 // inst_a
2672 // inst_b
2673 // DBG_VALUE %2, "x", ...
2674 // %2 = ld ...
2675 // %3 = ld ...
2676
2677 // The code below addresses this by moving the DBG_VALUE to the position
2678 // immediately after the load.
2679
2680 // Example:
2681 // After the code below:
2682 // inst_a
2683 // inst_b
2684 // %2 = ld ...
2685 // DBG_VALUE %2, "x", ...
2686 // %3 = ld ...
2687
2688 // The algorithm works in two phases: First RescheduleOps() populates the
2689 // RegisterMap with registers that were moved as keys, there is no value
2690 // inserted. In the next phase, every MachineInstr in a basic block is
2691 // iterated over. If it is a valid DBG_VALUE or DBG_VALUE_LIST and it uses one
2692 // or more registers in the RegisterMap, the RegisterMap and InstrMap are
2693 // populated with the MachineInstr. If the DBG_VALUE or DBG_VALUE_LIST
2694 // describes debug information for a variable that already exists in the
2695 // DbgValueSinkCandidates, the MachineInstr in the DbgValueSinkCandidates must
2696 // be set to undef. If the current MachineInstr is a load that was moved,
2697 // undef the corresponding DBG_VALUE or DBG_VALUE_LIST and clone it to below
2698 // the load.
2699
2700 // To illustrate the above algorithm visually let's take this example.
2701
2702 // Before the Pre Register Allocation Load Store Pass:
2703 // %2 = ld ...
2704 // DBG_VALUE %2, A, .... # X
2705 // DBG_VALUE 0, A, ... # Y
2706 // %3 = ld ...
2707 // DBG_VALUE %3, A, ..., # Z
2708 // %4 = ld ...
2709
2710 // After Pre Register Allocation Load Store Pass:
2711 // DBG_VALUE %2, A, .... # X
2712 // DBG_VALUE 0, A, ... # Y
2713 // DBG_VALUE %3, A, ..., # Z
2714 // %2 = ld ...
2715 // %3 = ld ...
2716 // %4 = ld ...
2717
2718 // The algorithm below does the following:
2719
2720 // In the beginning, the RegisterMap will have been populated with the virtual
2721 // registers %2, and %3, the DbgValueSinkCandidates and the InstrMap will be
2722 // empty. DbgValueSinkCandidates = {}, RegisterMap = {2 -> {}, 3 -> {}},
2723 // InstrMap {}
2724 // -> DBG_VALUE %2, A, .... # X
2725 // DBG_VALUE 0, A, ... # Y
2726 // DBG_VALUE %3, A, ..., # Z
2727 // %2 = ld ...
2728 // %3 = ld ...
2729 // %4 = ld ...
2730
2731 // After the first DBG_VALUE (denoted with an X) is processed, the
2732 // DbgValueSinkCandidates and InstrMap will be populated and the RegisterMap
2733 // entry for %2 will be populated as well. DbgValueSinkCandidates = {A -> X},
2734 // RegisterMap = {2 -> {X}, 3 -> {}}, InstrMap {X -> 2}
2735 // DBG_VALUE %2, A, .... # X
2736 // -> DBG_VALUE 0, A, ... # Y
2737 // DBG_VALUE %3, A, ..., # Z
2738 // %2 = ld ...
2739 // %3 = ld ...
2740 // %4 = ld ...
2741
2742 // After the DBG_VALUE Y is processed, the DbgValueSinkCandidates is updated
2743 // to now hold Y for A and the RegisterMap is also updated to remove X from
2744 // %2, this is because both X and Y describe the same debug variable A. X is
2745 // also updated to have a $noreg as the first operand.
2746 // DbgValueSinkCandidates = {A -> {Y}}, RegisterMap = {2 -> {}, 3 -> {}},
2747 // InstrMap = {X-> 2}
2748 // DBG_VALUE $noreg, A, .... # X
2749 // DBG_VALUE 0, A, ... # Y
2750 // -> DBG_VALUE %3, A, ..., # Z
2751 // %2 = ld ...
2752 // %3 = ld ...
2753 // %4 = ld ...
2754
2755 // After DBG_VALUE Z is processed, the DbgValueSinkCandidates is updated to
2756 // hold Z fr A, the RegisterMap is updated to hold Z for %3, and the InstrMap
2757 // is updated to have Z mapped to %3. This is again because Z describes the
2758 // debug variable A, Y is not updated to have $noreg as first operand because
2759 // its first operand is an immediate, not a register.
2760 // DbgValueSinkCandidates = {A -> {Z}}, RegisterMap = {2 -> {}, 3 -> {Z}},
2761 // InstrMap = {X -> 2, Z -> 3}
2762 // DBG_VALUE $noreg, A, .... # X
2763 // DBG_VALUE 0, A, ... # Y
2764 // DBG_VALUE %3, A, ..., # Z
2765 // -> %2 = ld ...
2766 // %3 = ld ...
2767 // %4 = ld ...
2768
2769 // Nothing happens here since the RegisterMap for %2 contains no value.
2770 // DbgValueSinkCandidates = {A -> {Z}}, RegisterMap = {2 -> {}, 3 -> {Z}},
2771 // InstrMap = {X -> 2, Z -> 3}
2772 // DBG_VALUE $noreg, A, .... # X
2773 // DBG_VALUE 0, A, ... # Y
2774 // DBG_VALUE %3, A, ..., # Z
2775 // %2 = ld ...
2776 // -> %3 = ld ...
2777 // %4 = ld ...
2778
2779 // Since the RegisterMap contains Z as a value for %3, the MachineInstr
2780 // pointer Z is copied to come after the load for %3 and the old Z's first
2781 // operand is changed to $noreg the Basic Block iterator is moved to after the
2782 // DBG_VALUE Z's new position.
2783 // DbgValueSinkCandidates = {A -> {Z}}, RegisterMap = {2 -> {}, 3 -> {Z}},
2784 // InstrMap = {X -> 2, Z -> 3}
2785 // DBG_VALUE $noreg, A, .... # X
2786 // DBG_VALUE 0, A, ... # Y
2787 // DBG_VALUE $noreg, A, ..., # Old Z
2788 // %2 = ld ...
2789 // %3 = ld ...
2790 // DBG_VALUE %3, A, ..., # Z
2791 // -> %4 = ld ...
2792
2793 // Nothing happens for %4 and the algorithm exits having processed the entire
2794 // Basic Block.
2795 // DbgValueSinkCandidates = {A -> {Z}}, RegisterMap = {2 -> {}, 3 -> {Z}},
2796 // InstrMap = {X -> 2, Z -> 3}
2797 // DBG_VALUE $noreg, A, .... # X
2798 // DBG_VALUE 0, A, ... # Y
2799 // DBG_VALUE $noreg, A, ..., # Old Z
2800 // %2 = ld ...
2801 // %3 = ld ...
2802 // DBG_VALUE %3, A, ..., # Z
2803 // %4 = ld ...
2804
2805 // This map is used to track the relationship between
2806 // a Debug Variable and the DBG_VALUE MachineInstr pointer that describes the
2807 // debug information for that Debug Variable.
2808 SmallDenseMap<DebugVariable, MachineInstr *, 8> DbgValueSinkCandidates;
2809 // This map is used to track the relationship between a DBG_VALUE or
2810 // DBG_VALUE_LIST MachineInstr pointer and Registers that it uses.
2811 SmallDenseMap<MachineInstr *, SmallVector<Register>, 8> InstrMap;
2812 for (MBBI = MBB->begin(), E = MBB->end(); MBBI != E; ++MBBI) {
2813 MachineInstr &MI = *MBBI;
2814
2815 auto PopulateRegisterAndInstrMapForDebugInstr = [&](Register Reg) {
2816 auto RegIt = RegisterMap.find(Reg);
2817 if (RegIt == RegisterMap.end())
2818 return;
2819 auto &InstrVec = RegIt->getSecond();
2820 InstrVec.push_back(&MI);
2821 InstrMap[&MI].push_back(Reg);
2822 };
2823
2824 if (MI.isDebugValue()) {
2825 assert(MI.getDebugVariable() &&
2826 "DBG_VALUE or DBG_VALUE_LIST must contain a DILocalVariable");
2827
2829 // If the first operand is a register and it exists in the RegisterMap, we
2830 // know this is a DBG_VALUE that uses the result of a load that was moved,
2831 // and is therefore a candidate to also be moved, add it to the
2832 // RegisterMap and InstrMap.
2833 forEachDbgRegOperand(&MI, [&](MachineOperand &Op) {
2834 PopulateRegisterAndInstrMapForDebugInstr(Op.getReg());
2835 });
2836
2837 // If the current DBG_VALUE describes the same variable as one of the
2838 // in-flight DBG_VALUEs, remove the candidate from the list and set it to
2839 // undef. Moving one DBG_VALUE past another would result in the variable's
2840 // value going back in time when stepping through the block in the
2841 // debugger.
2842 auto InstrIt = DbgValueSinkCandidates.find(DbgVar);
2843 if (InstrIt != DbgValueSinkCandidates.end()) {
2844 auto *Instr = InstrIt->getSecond();
2845 auto RegIt = InstrMap.find(Instr);
2846 if (RegIt != InstrMap.end()) {
2847 const auto &RegVec = RegIt->getSecond();
2848 // For every Register in the RegVec, remove the MachineInstr in the
2849 // RegisterMap that describes the DbgVar.
2850 for (auto &Reg : RegVec) {
2851 auto RegIt = RegisterMap.find(Reg);
2852 if (RegIt == RegisterMap.end())
2853 continue;
2854 auto &InstrVec = RegIt->getSecond();
2855 auto IsDbgVar = [&](MachineInstr *I) -> bool {
2857 return Var == DbgVar;
2858 };
2859
2860 llvm::erase_if(InstrVec, IsDbgVar);
2861 }
2863 [&](MachineOperand &Op) { Op.setReg(0); });
2864 }
2865 }
2866 DbgValueSinkCandidates[DbgVar] = &MI;
2867 } else {
2868 // If the first operand of a load matches with a DBG_VALUE in RegisterMap,
2869 // then move that DBG_VALUE to below the load.
2870 auto Opc = MI.getOpcode();
2871 if (!isLoadSingle(Opc))
2872 continue;
2873 auto Reg = MI.getOperand(0).getReg();
2874 auto RegIt = RegisterMap.find(Reg);
2875 if (RegIt == RegisterMap.end())
2876 continue;
2877 auto &DbgInstrVec = RegIt->getSecond();
2878 if (!DbgInstrVec.size())
2879 continue;
2880 for (auto *DbgInstr : DbgInstrVec) {
2881 MachineBasicBlock::iterator InsertPos = std::next(MBBI);
2882 auto *ClonedMI = MI.getMF()->CloneMachineInstr(DbgInstr);
2883 MBB->insert(InsertPos, ClonedMI);
2884 MBBI++;
2885 // Erase the entry into the DbgValueSinkCandidates for the DBG_VALUE
2886 // that was moved.
2887 auto DbgVar = createDebugVariableFromMachineInstr(DbgInstr);
2888 // Erase DbgVar from DbgValueSinkCandidates if still present. If the
2889 // instruction is a DBG_VALUE_LIST, it may have already been erased from
2890 // DbgValueSinkCandidates.
2891 DbgValueSinkCandidates.erase(DbgVar);
2892 // Zero out original dbg instr
2893 forEachDbgRegOperand(DbgInstr,
2894 [&](MachineOperand &Op) { Op.setReg(0); });
2895 // Update RegisterMap with ClonedMI because it might have to be moved
2896 // again.
2897 if (DbgInstr->isDebugValueList())
2898 updateRegisterMapForDbgValueListAfterMove(RegisterMap, ClonedMI,
2899 DbgInstr);
2900 }
2901 }
2902 }
2903 return RetVal;
2904}
2905
2906// Get the Base register operand index from the memory access MachineInst if we
2907// should attempt to distribute postinc on it. Return -1 if not of a valid
2908// instruction type. If it returns an index, it is assumed that instruction is a
2909// r+i indexing mode, and getBaseOperandIndex() + 1 is the Offset index.
2911 switch (MI.getOpcode()) {
2912 case ARM::MVE_VLDRBS16:
2913 case ARM::MVE_VLDRBS32:
2914 case ARM::MVE_VLDRBU16:
2915 case ARM::MVE_VLDRBU32:
2916 case ARM::MVE_VLDRHS32:
2917 case ARM::MVE_VLDRHU32:
2918 case ARM::MVE_VLDRBU8:
2919 case ARM::MVE_VLDRHU16:
2920 case ARM::MVE_VLDRWU32:
2921 case ARM::MVE_VSTRB16:
2922 case ARM::MVE_VSTRB32:
2923 case ARM::MVE_VSTRH32:
2924 case ARM::MVE_VSTRBU8:
2925 case ARM::MVE_VSTRHU16:
2926 case ARM::MVE_VSTRWU32:
2927 case ARM::t2LDRHi8:
2928 case ARM::t2LDRHi12:
2929 case ARM::t2LDRSHi8:
2930 case ARM::t2LDRSHi12:
2931 case ARM::t2LDRBi8:
2932 case ARM::t2LDRBi12:
2933 case ARM::t2LDRSBi8:
2934 case ARM::t2LDRSBi12:
2935 case ARM::t2STRBi8:
2936 case ARM::t2STRBi12:
2937 case ARM::t2STRHi8:
2938 case ARM::t2STRHi12:
2939 return 1;
2940 case ARM::MVE_VLDRBS16_post:
2941 case ARM::MVE_VLDRBS32_post:
2942 case ARM::MVE_VLDRBU16_post:
2943 case ARM::MVE_VLDRBU32_post:
2944 case ARM::MVE_VLDRHS32_post:
2945 case ARM::MVE_VLDRHU32_post:
2946 case ARM::MVE_VLDRBU8_post:
2947 case ARM::MVE_VLDRHU16_post:
2948 case ARM::MVE_VLDRWU32_post:
2949 case ARM::MVE_VSTRB16_post:
2950 case ARM::MVE_VSTRB32_post:
2951 case ARM::MVE_VSTRH32_post:
2952 case ARM::MVE_VSTRBU8_post:
2953 case ARM::MVE_VSTRHU16_post:
2954 case ARM::MVE_VSTRWU32_post:
2955 case ARM::MVE_VLDRBS16_pre:
2956 case ARM::MVE_VLDRBS32_pre:
2957 case ARM::MVE_VLDRBU16_pre:
2958 case ARM::MVE_VLDRBU32_pre:
2959 case ARM::MVE_VLDRHS32_pre:
2960 case ARM::MVE_VLDRHU32_pre:
2961 case ARM::MVE_VLDRBU8_pre:
2962 case ARM::MVE_VLDRHU16_pre:
2963 case ARM::MVE_VLDRWU32_pre:
2964 case ARM::MVE_VSTRB16_pre:
2965 case ARM::MVE_VSTRB32_pre:
2966 case ARM::MVE_VSTRH32_pre:
2967 case ARM::MVE_VSTRBU8_pre:
2968 case ARM::MVE_VSTRHU16_pre:
2969 case ARM::MVE_VSTRWU32_pre:
2970 return 2;
2971 }
2972 return -1;
2973}
2974
2976 switch (MI.getOpcode()) {
2977 case ARM::MVE_VLDRBS16_post:
2978 case ARM::MVE_VLDRBS32_post:
2979 case ARM::MVE_VLDRBU16_post:
2980 case ARM::MVE_VLDRBU32_post:
2981 case ARM::MVE_VLDRHS32_post:
2982 case ARM::MVE_VLDRHU32_post:
2983 case ARM::MVE_VLDRBU8_post:
2984 case ARM::MVE_VLDRHU16_post:
2985 case ARM::MVE_VLDRWU32_post:
2986 case ARM::MVE_VSTRB16_post:
2987 case ARM::MVE_VSTRB32_post:
2988 case ARM::MVE_VSTRH32_post:
2989 case ARM::MVE_VSTRBU8_post:
2990 case ARM::MVE_VSTRHU16_post:
2991 case ARM::MVE_VSTRWU32_post:
2992 return true;
2993 }
2994 return false;
2995}
2996
2998 switch (MI.getOpcode()) {
2999 case ARM::MVE_VLDRBS16_pre:
3000 case ARM::MVE_VLDRBS32_pre:
3001 case ARM::MVE_VLDRBU16_pre:
3002 case ARM::MVE_VLDRBU32_pre:
3003 case ARM::MVE_VLDRHS32_pre:
3004 case ARM::MVE_VLDRHU32_pre:
3005 case ARM::MVE_VLDRBU8_pre:
3006 case ARM::MVE_VLDRHU16_pre:
3007 case ARM::MVE_VLDRWU32_pre:
3008 case ARM::MVE_VSTRB16_pre:
3009 case ARM::MVE_VSTRB32_pre:
3010 case ARM::MVE_VSTRH32_pre:
3011 case ARM::MVE_VSTRBU8_pre:
3012 case ARM::MVE_VSTRHU16_pre:
3013 case ARM::MVE_VSTRWU32_pre:
3014 return true;
3015 }
3016 return false;
3017}
3018
3019// Given a memory access Opcode, check that the give Imm would be a valid Offset
3020// for this instruction (same as isLegalAddressImm), Or if the instruction
3021// could be easily converted to one where that was valid. For example converting
3022// t2LDRi12 to t2LDRi8 for negative offsets. Works in conjunction with
3023// AdjustBaseAndOffset below.
3024static bool isLegalOrConvertibleAddressImm(unsigned Opcode, int Imm,
3025 const TargetInstrInfo *TII,
3026 int &CodesizeEstimate) {
3027 if (isLegalAddressImm(Opcode, Imm, TII))
3028 return true;
3029
3030 // We can convert AddrModeT2_i12 to AddrModeT2_i8neg.
3031 const MCInstrDesc &Desc = TII->get(Opcode);
3032 unsigned AddrMode = (Desc.TSFlags & ARMII::AddrModeMask);
3033 switch (AddrMode) {
3035 CodesizeEstimate += 1;
3036 return Imm < 0 && -Imm < ((1 << 8) * 1);
3037 }
3038 return false;
3039}
3040
3041// Given an MI adjust its address BaseReg to use NewBaseReg and address offset
3042// by -Offset. This can either happen in-place or be a replacement as MI is
3043// converted to another instruction type.
3045 int Offset, const TargetInstrInfo *TII,
3046 const TargetRegisterInfo *TRI) {
3047 // Set the Base reg
3048 unsigned BaseOp = getBaseOperandIndex(*MI);
3049 MI->getOperand(BaseOp).setReg(NewBaseReg);
3050 // and constrain the reg class to that required by the instruction.
3051 MachineFunction *MF = MI->getMF();
3052 MachineRegisterInfo &MRI = MF->getRegInfo();
3053 const MCInstrDesc &MCID = TII->get(MI->getOpcode());
3054 const TargetRegisterClass *TRC = TII->getRegClass(MCID, BaseOp);
3055 MRI.constrainRegClass(NewBaseReg, TRC);
3056
3057 int OldOffset = MI->getOperand(BaseOp + 1).getImm();
3058 if (isLegalAddressImm(MI->getOpcode(), OldOffset - Offset, TII))
3059 MI->getOperand(BaseOp + 1).setImm(OldOffset - Offset);
3060 else {
3061 unsigned ConvOpcode;
3062 switch (MI->getOpcode()) {
3063 case ARM::t2LDRHi12:
3064 ConvOpcode = ARM::t2LDRHi8;
3065 break;
3066 case ARM::t2LDRSHi12:
3067 ConvOpcode = ARM::t2LDRSHi8;
3068 break;
3069 case ARM::t2LDRBi12:
3070 ConvOpcode = ARM::t2LDRBi8;
3071 break;
3072 case ARM::t2LDRSBi12:
3073 ConvOpcode = ARM::t2LDRSBi8;
3074 break;
3075 case ARM::t2STRHi12:
3076 ConvOpcode = ARM::t2STRHi8;
3077 break;
3078 case ARM::t2STRBi12:
3079 ConvOpcode = ARM::t2STRBi8;
3080 break;
3081 default:
3082 llvm_unreachable("Unhandled convertible opcode");
3083 }
3084 assert(isLegalAddressImm(ConvOpcode, OldOffset - Offset, TII) &&
3085 "Illegal Address Immediate after convert!");
3086
3087 const MCInstrDesc &MCID = TII->get(ConvOpcode);
3088 BuildMI(*MI->getParent(), MI, MI->getDebugLoc(), MCID)
3089 .add(MI->getOperand(0))
3090 .add(MI->getOperand(1))
3091 .addImm(OldOffset - Offset)
3092 .add(MI->getOperand(3))
3093 .add(MI->getOperand(4))
3094 .cloneMemRefs(*MI);
3095 MI->eraseFromParent();
3096 }
3097}
3098
3100 Register NewReg,
3101 const TargetInstrInfo *TII,
3102 const TargetRegisterInfo *TRI) {
3103 MachineFunction *MF = MI->getMF();
3104 MachineRegisterInfo &MRI = MF->getRegInfo();
3105
3106 unsigned NewOpcode = getPostIndexedLoadStoreOpcode(
3107 MI->getOpcode(), Offset > 0 ? ARM_AM::add : ARM_AM::sub);
3108
3109 const MCInstrDesc &MCID = TII->get(NewOpcode);
3110 // Constrain the def register class
3111 const TargetRegisterClass *TRC = TII->getRegClass(MCID, 0);
3112 MRI.constrainRegClass(NewReg, TRC);
3113 // And do the same for the base operand
3114 TRC = TII->getRegClass(MCID, 2);
3115 MRI.constrainRegClass(MI->getOperand(1).getReg(), TRC);
3116
3117 unsigned AddrMode = (MCID.TSFlags & ARMII::AddrModeMask);
3118 switch (AddrMode) {
3122 // Any MVE load/store
3123 return BuildMI(*MI->getParent(), MI, MI->getDebugLoc(), MCID)
3124 .addReg(NewReg, RegState::Define)
3125 .add(MI->getOperand(0))
3126 .add(MI->getOperand(1))
3127 .addImm(Offset)
3128 .add(MI->getOperand(3))
3129 .add(MI->getOperand(4))
3130 .add(MI->getOperand(5))
3131 .cloneMemRefs(*MI);
3133 if (MI->mayLoad()) {
3134 return BuildMI(*MI->getParent(), MI, MI->getDebugLoc(), MCID)
3135 .add(MI->getOperand(0))
3136 .addReg(NewReg, RegState::Define)
3137 .add(MI->getOperand(1))
3138 .addImm(Offset)
3139 .add(MI->getOperand(3))
3140 .add(MI->getOperand(4))
3141 .cloneMemRefs(*MI);
3142 } else {
3143 return BuildMI(*MI->getParent(), MI, MI->getDebugLoc(), MCID)
3144 .addReg(NewReg, RegState::Define)
3145 .add(MI->getOperand(0))
3146 .add(MI->getOperand(1))
3147 .addImm(Offset)
3148 .add(MI->getOperand(3))
3149 .add(MI->getOperand(4))
3150 .cloneMemRefs(*MI);
3151 }
3152 default:
3153 llvm_unreachable("Unhandled createPostIncLoadStore");
3154 }
3155}
3156
3157// Given a Base Register, optimise the load/store uses to attempt to create more
3158// post-inc accesses and less register moves. We do this by taking zero offset
3159// loads/stores with an add, and convert them to a postinc load/store of the
3160// same type. Any subsequent accesses will be adjusted to use and account for
3161// the post-inc value.
3162// For example:
3163// LDR #0 LDR_POSTINC #16
3164// LDR #4 LDR #-12
3165// LDR #8 LDR #-8
3166// LDR #12 LDR #-4
3167// ADD #16
3168//
3169// At the same time if we do not find an increment but do find an existing
3170// pre/post inc instruction, we can still adjust the offsets of subsequent
3171// instructions to save the register move that would otherwise be needed for the
3172// in-place increment.
3173bool ARMPreAllocLoadStoreOpt::DistributeIncrements(Register Base) {
3174 // We are looking for:
3175 // One zero offset load/store that can become postinc
3176 MachineInstr *BaseAccess = nullptr;
3177 MachineInstr *PrePostInc = nullptr;
3178 // An increment that can be folded in
3179 MachineInstr *Increment = nullptr;
3180 // Other accesses after BaseAccess that will need to be updated to use the
3181 // postinc value.
3182 SmallPtrSet<MachineInstr *, 8> OtherAccesses;
3183 for (auto &Use : MRI->use_nodbg_instructions(Base)) {
3184 if (!Increment && getAddSubImmediate(Use) != 0) {
3185 Increment = &Use;
3186 continue;
3187 }
3188
3189 int BaseOp = getBaseOperandIndex(Use);
3190 if (BaseOp == -1)
3191 return false;
3192
3193 if (!Use.getOperand(BaseOp).isReg() ||
3194 Use.getOperand(BaseOp).getReg() != Base)
3195 return false;
3196 if (isPreIndex(Use) || isPostIndex(Use))
3197 PrePostInc = &Use;
3198 else if (Use.getOperand(BaseOp + 1).getImm() == 0)
3199 BaseAccess = &Use;
3200 else
3201 OtherAccesses.insert(&Use);
3202 }
3203
3204 int IncrementOffset;
3205 Register NewBaseReg;
3206 if (BaseAccess && Increment) {
3207 if (PrePostInc || BaseAccess->getParent() != Increment->getParent())
3208 return false;
3209 Register PredReg;
3210 if (Increment->definesRegister(ARM::CPSR, /*TRI=*/nullptr) ||
3212 return false;
3213
3214 LLVM_DEBUG(dbgs() << "\nAttempting to distribute increments on VirtualReg "
3215 << Base.virtRegIndex() << "\n");
3216
3217 // Make sure that Increment has no uses before BaseAccess that are not PHI
3218 // uses.
3219 for (MachineInstr &Use :
3220 MRI->use_nodbg_instructions(Increment->getOperand(0).getReg())) {
3221 if (&Use == BaseAccess || (Use.getOpcode() != TargetOpcode::PHI &&
3222 !DT->dominates(BaseAccess, &Use))) {
3223 LLVM_DEBUG(dbgs() << " BaseAccess doesn't dominate use of increment\n");
3224 return false;
3225 }
3226 }
3227
3228 // Make sure that Increment can be folded into Base
3229 IncrementOffset = getAddSubImmediate(*Increment);
3230 unsigned NewPostIncOpcode = getPostIndexedLoadStoreOpcode(
3231 BaseAccess->getOpcode(), IncrementOffset > 0 ? ARM_AM::add : ARM_AM::sub);
3232 if (!isLegalAddressImm(NewPostIncOpcode, IncrementOffset, TII)) {
3233 LLVM_DEBUG(dbgs() << " Illegal addressing mode immediate on postinc\n");
3234 return false;
3235 }
3236 }
3237 else if (PrePostInc) {
3238 // If we already have a pre/post index load/store then set BaseAccess,
3239 // IncrementOffset and NewBaseReg to the values it already produces,
3240 // allowing us to update and subsequent uses of BaseOp reg with the
3241 // incremented value.
3242 if (Increment)
3243 return false;
3244
3245 LLVM_DEBUG(dbgs() << "\nAttempting to distribute increments on already "
3246 << "indexed VirtualReg " << Base.virtRegIndex() << "\n");
3247 int BaseOp = getBaseOperandIndex(*PrePostInc);
3248 IncrementOffset = PrePostInc->getOperand(BaseOp+1).getImm();
3249 BaseAccess = PrePostInc;
3250 NewBaseReg = PrePostInc->getOperand(0).getReg();
3251 }
3252 else
3253 return false;
3254
3255 // And make sure that the negative value of increment can be added to all
3256 // other offsets after the BaseAccess. We rely on either
3257 // dominates(BaseAccess, OtherAccess) or dominates(OtherAccess, BaseAccess)
3258 // to keep things simple.
3259 // This also adds a simple codesize metric, to detect if an instruction (like
3260 // t2LDRBi12) which can often be shrunk to a thumb1 instruction (tLDRBi)
3261 // cannot because it is converted to something else (t2LDRBi8). We start this
3262 // at -1 for the gain from removing the increment.
3263 SmallPtrSet<MachineInstr *, 4> SuccessorAccesses;
3264 int CodesizeEstimate = -1;
3265 for (auto *Use : OtherAccesses) {
3266 if (DT->dominates(BaseAccess, Use)) {
3267 SuccessorAccesses.insert(Use);
3268 unsigned BaseOp = getBaseOperandIndex(*Use);
3269 if (!isLegalOrConvertibleAddressImm(Use->getOpcode(),
3270 Use->getOperand(BaseOp + 1).getImm() -
3271 IncrementOffset,
3272 TII, CodesizeEstimate)) {
3273 LLVM_DEBUG(dbgs() << " Illegal addressing mode immediate on use\n");
3274 return false;
3275 }
3276 } else if (!DT->dominates(Use, BaseAccess)) {
3277 LLVM_DEBUG(
3278 dbgs() << " Unknown dominance relation between Base and Use\n");
3279 return false;
3280 }
3281 }
3282 if (STI->hasMinSize() && CodesizeEstimate > 0) {
3283 LLVM_DEBUG(dbgs() << " Expected to grow instructions under minsize\n");
3284 return false;
3285 }
3286
3287 if (!PrePostInc) {
3288 // Replace BaseAccess with a post inc
3289 LLVM_DEBUG(dbgs() << "Changing: "; BaseAccess->dump());
3290 LLVM_DEBUG(dbgs() << " And : "; Increment->dump());
3291 NewBaseReg = Increment->getOperand(0).getReg();
3292 MachineInstr *BaseAccessPost =
3293 createPostIncLoadStore(BaseAccess, IncrementOffset, NewBaseReg, TII, TRI);
3294 BaseAccess->eraseFromParent();
3295 Increment->eraseFromParent();
3296 (void)BaseAccessPost;
3297 LLVM_DEBUG(dbgs() << " To : "; BaseAccessPost->dump());
3298 }
3299
3300 for (auto *Use : SuccessorAccesses) {
3301 LLVM_DEBUG(dbgs() << "Changing: "; Use->dump());
3302 AdjustBaseAndOffset(Use, NewBaseReg, IncrementOffset, TII, TRI);
3303 LLVM_DEBUG(dbgs() << " To : "; Use->dump());
3304 }
3305
3306 // Remove the kill flag from all uses of NewBaseReg, in case any old uses
3307 // remain.
3308 for (MachineOperand &Op : MRI->use_nodbg_operands(NewBaseReg))
3309 Op.setIsKill(false);
3310 return true;
3311}
3312
3313bool ARMPreAllocLoadStoreOpt::DistributeIncrements() {
3314 bool Changed = false;
3315 SmallSetVector<Register, 4> Visited;
3316 for (auto &MBB : *MF) {
3317 for (auto &MI : MBB) {
3318 int BaseOp = getBaseOperandIndex(MI);
3319 if (BaseOp == -1 || !MI.getOperand(BaseOp).isReg())
3320 continue;
3321
3322 Register Base = MI.getOperand(BaseOp).getReg();
3323 if (!Base.isVirtual())
3324 continue;
3325
3326 Visited.insert(Base);
3327 }
3328 }
3329
3330 for (auto Base : Visited)
3331 Changed |= DistributeIncrements(Base);
3332
3333 return Changed;
3334}
3335
3336/// Returns an instance of the load / store optimization pass.
3338 if (PreAlloc)
3339 return new ARMPreAllocLoadStoreOptLegacy();
3340 return new ARMLoadStoreOptLegacy();
3341}
3342
3346 ARMLoadStoreOpt Impl;
3347 bool Changed = Impl.runOnMachineFunction(MF);
3348 if (!Changed)
3349 return PreservedAnalyses::all();
3352 return PA;
3353}
3354
3358 ARMPreAllocLoadStoreOpt Impl;
3359 AliasAnalysis *AA =
3361 .getManager()
3362 .getResult<AAManager>(MF.getFunction());
3364 bool Changed = Impl.runOnMachineFunction(MF, AA, DT);
3365 if (!Changed)
3366 return PreservedAnalyses::all();
3369 return PA;
3370}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
aarch64 promote const
static bool isLoadSingle(unsigned Opc)
static int getMemoryOpOffset(const MachineInstr &MI)
static unsigned getPostIndexedLoadStoreOpcode(unsigned Opc, ARM_AM::AddrOpc Mode)
static bool IsSafeAndProfitableToMove(bool isLd, unsigned Base, MachineBasicBlock::iterator I, MachineBasicBlock::iterator E, SmallPtrSetImpl< MachineInstr * > &MemOps, SmallSet< unsigned, 4 > &MemRegs, const TargetRegisterInfo *TRI, AliasAnalysis *AA)
static bool ContainsReg(ArrayRef< std::pair< unsigned, bool > > Regs, unsigned Reg)
static bool isPreIndex(MachineInstr &MI)
static void forEachDbgRegOperand(MachineInstr *MI, std::function< void(MachineOperand &)> Fn)
static bool isPostIndex(MachineInstr &MI)
static int getLoadStoreMultipleOpcode(unsigned Opcode, ARM_AM::AMSubMode Mode)
static unsigned getLSMultipleTransferSize(const MachineInstr *MI)
static bool isLegalOrConvertibleAddressImm(unsigned Opcode, int Imm, const TargetInstrInfo *TII, int &CodesizeEstimate)
static ARM_AM::AMSubMode getLoadStoreMultipleSubMode(unsigned Opcode)
static bool isT1i32Load(unsigned Opc)
static void AdjustBaseAndOffset(MachineInstr *MI, Register NewBaseReg, int Offset, const TargetInstrInfo *TII, const TargetRegisterInfo *TRI)
static unsigned getPreIndexedLoadStoreOpcode(unsigned Opc, ARM_AM::AddrOpc Mode)
static MachineInstr * createPostIncLoadStore(MachineInstr *MI, int Offset, Register NewReg, const TargetInstrInfo *TII, const TargetRegisterInfo *TRI)
static bool isi32Store(unsigned Opc)
static MachineBasicBlock::iterator findIncDecAfter(MachineBasicBlock::iterator MBBI, Register Reg, ARMCC::CondCodes Pred, Register PredReg, int &Offset, const TargetRegisterInfo *TRI)
Searches for a increment or decrement of Reg after MBBI.
static MachineBasicBlock::iterator findIncDecBefore(MachineBasicBlock::iterator MBBI, Register Reg, ARMCC::CondCodes Pred, Register PredReg, int &Offset)
Searches for an increment or decrement of Reg before MBBI.
static const MachineOperand & getLoadStoreBaseOp(const MachineInstr &MI)
static void updateRegisterMapForDbgValueListAfterMove(SmallDenseMap< Register, SmallVector< MachineInstr * >, 8 > &RegisterMap, MachineInstr *DbgValueListInstr, MachineInstr *InstrToReplace)
arm prera ldst static false cl::opt< unsigned > InstReorderLimit("arm-prera-ldst-opt-reorder-limit", cl::init(8), cl::Hidden)
static void InsertLDR_STR(MachineBasicBlock &MBB, MachineBasicBlock::iterator &MBBI, int Offset, bool isDef, unsigned NewOpc, unsigned Reg, bool RegDeadKill, bool RegUndef, unsigned BaseReg, bool BaseKill, bool BaseUndef, ARMCC::CondCodes Pred, unsigned PredReg, const TargetInstrInfo *TII, MachineInstr *MI)
static int isIncrementOrDecrement(const MachineInstr &MI, Register Reg, ARMCC::CondCodes Pred, Register PredReg)
Check if the given instruction increments or decrements a register and return the amount it is increm...
static bool isT2i32Store(unsigned Opc)
static bool mayCombineMisaligned(const TargetSubtargetInfo &STI, const MachineInstr &MI)
Return true for loads/stores that can be combined to a double/multi operation without increasing the ...
static int getBaseOperandIndex(MachineInstr &MI)
static bool isT2i32Load(unsigned Opc)
static bool isi32Load(unsigned Opc)
static unsigned getImmScale(unsigned Opc)
static bool isT1i32Store(unsigned Opc)
#define ARM_PREALLOC_LOAD_STORE_OPT_NAME
#define ARM_LOAD_STORE_OPT_NAME
static unsigned getUpdatingLSMultipleOpcode(unsigned Opc, ARM_AM::AMSubMode Mode)
static bool isMemoryOp(const MachineInstr &MI)
Returns true if instruction is a memory operation that this pass is capable of operating on.
static const MachineOperand & getLoadStoreRegOp(const MachineInstr &MI)
static bool isValidLSDoubleOffset(int Offset)
static DebugVariable createDebugVariableFromMachineInstr(MachineInstr *MI)
static cl::opt< bool > AssumeMisalignedLoadStores("arm-assume-misaligned-load-store", cl::Hidden, cl::init(false), cl::desc("Be more conservative in ARM load/store opt"))
This switch disables formation of double/multi instructions that could potentially lead to (new) alig...
MachineBasicBlock & MBB
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
MachineBasicBlock MachineBasicBlock::iterator MBBI
This file defines the BumpPtrAllocator interface.
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
This file defines the DenseMap class.
This file defines the DenseSet and SmallDenseSet classes.
const HexagonInstrInfo * TII
IRTranslator LLVM IR MI
const size_t AbstractManglingParser< Derived, Alloc >::NumOps
const AbstractManglingParser< Derived, Alloc >::OperatorInfo AbstractManglingParser< Derived, Alloc >::Ops[]
A set of register units.
#define I(x, y, z)
Definition MD5.cpp:57
Register Reg
Register const TargetRegisterInfo * TRI
Promote Memory to Register
Definition Mem2Reg.cpp:110
static MCRegister getReg(const MCDisassembler *D, unsigned RC, unsigned RegNo)
if(PassOpts->AAPipeline)
#define INITIALIZE_PASS_DEPENDENCY(depName)
Definition PassSupport.h:42
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
Definition PassSupport.h:44
#define INITIALIZE_PASS_BEGIN(passName, arg, name, cfg, analysis)
Definition PassSupport.h:39
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
Definition PassSupport.h:56
Basic Register Allocator
static cl::opt< RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode > Mode("regalloc-enable-advisor", cl::Hidden, cl::init(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Default), cl::desc("Enable regalloc advisor mode"), cl::values(clEnumValN(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Default, "default", "Default"), clEnumValN(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Release, "release", "precompiled"), clEnumValN(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Development, "development", "for training")))
This file contains some templates that are useful if you are working with the STL at all.
This file implements a set that has insertion order iteration characteristics.
This file defines the SmallPtrSet class.
This file defines the SmallSet class.
This file defines the SmallVector class.
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
Definition Statistic.h:171
#define LLVM_DEBUG(...)
Definition Debug.h:119
This file describes how to lower LLVM code to machine code.
Value * RHS
Value * LHS
A manager for alias analyses.
A wrapper pass to provide the legacy pass manager access to a suitably prepared AAResults object.
static void updateLRRestored(MachineFunction &MF)
Update the IsRestored flag on LR if it is spilled, based on the return instructions.
ARMFunctionInfo - This class is derived from MachineFunctionInfo and contains private ARM-specific in...
PreservedAnalyses run(MachineFunction &MF, MachineFunctionAnalysisManager &MFAM)
PreservedAnalyses run(MachineFunction &MF, MachineFunctionAnalysisManager &MFAM)
const ARMBaseInstrInfo * getInstrInfo() const override
bool isThumb2() const
const ARMTargetLowering * getTargetLowering() const override
const ARMBaseRegisterInfo * getRegisterInfo() const override
bool hasMinSize() const
bool isCortexM3() const
Align getDualLoadStoreAlignment() const
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
Represent the analysis usage information of a pass.
AnalysisUsage & addRequired()
AnalysisUsage & addPreserved()
Add the specified Pass class to the set of analyses preserved by this pass.
Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition ArrayRef.h:40
Represents analyses that only rely on functions' control flow.
Definition Analysis.h:73
A parsed version of the target data layout string in and methods for querying it.
Definition DataLayout.h:64
A debug info location.
Definition DebugLoc.h:126
Identifies a unique instance of a variable.
iterator find(const_arg_type_t< KeyT > Val)
Definition DenseMap.h:223
bool erase(const KeyT &Val)
Definition DenseMap.h:377
iterator end()
Definition DenseMap.h:141
FunctionPass class - This class is used to implement most global optimizations.
Definition Pass.h:314
A set of register units used to track register liveness.
bool available(MCRegister Reg) const
Returns true if no part of physical register Reg is live.
void init(const TargetRegisterInfo &TRI)
Initialize and clear the set.
void addReg(MCRegister Reg)
Adds register units covered by physical register Reg.
LLVM_ABI void stepBackward(const MachineInstr &MI)
Updates liveness when stepping backwards over the instruction MI.
LLVM_ABI void addLiveOuts(const MachineBasicBlock &MBB)
Adds registers living out of block MBB.
Describe properties that are true of each instruction in the target description file.
MachineInstrBundleIterator< const MachineInstr > const_iterator
LLVM_ABI instr_iterator insert(instr_iterator I, MachineInstr *M)
Insert MI into the instruction list before I, possibly inside a bundle.
LLVM_ABI LivenessQueryResult computeRegisterLiveness(const TargetRegisterInfo *TRI, MCRegister Reg, const_iterator Before, unsigned Neighborhood=10) const
Return whether (physical) register Reg has been defined and not killed as of just before Before.
LLVM_ABI iterator getFirstTerminator()
Returns an iterator to the first terminator instruction of this basic block.
LLVM_ABI iterator getLastNonDebugInstr(bool SkipPseudoOp=true)
Returns an iterator to the last non-debug instruction in the basic block, or end().
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
LLVM_ABI instr_iterator erase(instr_iterator I)
Remove an instruction from the instruction list and delete it.
void splice(iterator Where, MachineBasicBlock *Other, iterator From)
Take an instruction from MBB 'Other' at the position From, and insert it into this MBB right before '...
MachineInstrBundleIterator< MachineInstr > iterator
@ LQR_Dead
Register is known to be fully dead.
Analysis pass which computes a MachineDominatorTree.
Analysis pass which computes a MachineDominatorTree.
DominatorTree Class - Concrete subclass of DominatorTreeBase that is used to compute a normal dominat...
bool dominates(const MachineInstr *A, const MachineInstr *B) const
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
Properties which a MachineFunction may have at a given point in time.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
Function & getFunction()
Return the LLVM function that this machine code represents.
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
const MachineInstrBuilder & cloneMergedMemRefs(ArrayRef< const MachineInstr * > OtherMIs) const
const MachineInstrBuilder & setMemRefs(ArrayRef< MachineMemOperand * > MMOs) const
const MachineInstrBuilder & addReg(Register RegNo, RegState Flags={}, unsigned SubReg=0) const
Add a new virtual register operand.
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
const MachineInstrBuilder & add(const MachineOperand &MO) const
const MachineInstrBuilder & cloneMemRefs(const MachineInstr &OtherMI) const
const MachineInstrBuilder & copyImplicitOps(const MachineInstr &OtherMI) const
Copy all the implicit operands from OtherMI onto this one.
MachineInstr * getInstr() const
If conversion operators fail, use this method to get the MachineInstr explicitly.
Representation of each machine instruction.
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
const MachineBasicBlock * getParent() const
unsigned getNumOperands() const
Retuns the total number of operands.
LLVM_ABI void copyImplicitOps(MachineFunction &MF, const MachineInstr &MI)
Copy implicit register operands from specified instruction to this instruction.
bool killsRegister(Register Reg, const TargetRegisterInfo *TRI) const
Return true if the MachineInstr kills the specified register.
LLVM_ABI void setDesc(const MCInstrDesc &TID)
Replace the instruction descriptor (thus opcode) of the current instruction with a new one.
bool hasOneMemOperand() const
Return true if this instruction has exactly one MachineMemOperand.
mmo_iterator memoperands_begin() const
Access to memory operands of the instruction.
const DebugLoc & getDebugLoc() const
Returns the debug location id of this MachineInstr.
LLVM_ABI void dump() const
const MachineOperand & getOperand(unsigned i) const
LLVM_ABI MachineInstrBundleIterator< MachineInstr > eraseFromParent()
Unlink 'this' from the containing basic block and delete it.
A description of a memory reference used in the backend.
bool isAtomic() const
Returns true if this operation has an atomic ordering requirement of unordered or higher,...
LLVM_ABI Align getAlign() const
Return the minimum known alignment in bytes of the actual memory reference.
MachineOperand class - Representation of each machine instruction operand.
void setImm(int64_t immVal)
int64_t getImm() const
bool readsReg() const
readsReg - Returns true if this operand reads the previous value of its register.
bool isReg() const
isReg - Tests if this is a MO_Register operand.
LLVM_ABI void setReg(Register Reg)
Change the register this operand corresponds to.
void setIsKill(bool Val=true)
void setIsUndef(bool Val=true)
Register getReg() const
getReg - Returns the register number.
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
iterator_range< use_nodbg_iterator > use_nodbg_operands(Register Reg) const
bool isReserved(MCRegister PhysReg) const
isReserved - Returns true when PhysReg is a reserved register.
iterator_range< use_instr_nodbg_iterator > use_nodbg_instructions(Register Reg) const
void setRegAllocationHint(Register VReg, unsigned Type, Register PrefReg)
setRegAllocationHint - Specify a register allocation hint for the specified virtual register.
LLVM_ABI const TargetRegisterClass * constrainRegClass(Register Reg, const TargetRegisterClass *RC, unsigned MinNumRegs=0)
constrainRegClass - Constrain the register class of the specified virtual register to be a common sub...
A set of analyses that are preserved following a run of a transformation pass.
Definition Analysis.h:112
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
Definition Analysis.h:118
PreservedAnalyses & preserveSet()
Mark an analysis set as preserved.
Definition Analysis.h:151
LLVM_ABI void runOnMachineFunction(const MachineFunction &MF, bool Rev=false)
runOnFunction - Prepare to answer questions about MF.
ArrayRef< MCPhysReg > getOrder(const TargetRegisterClass *RC) const
getOrder - Returns the preferred allocation order for RC.
Wrapper class representing virtual and physical registers.
Definition Register.h:20
bool insert(const value_type &X)
Insert a new element into the SetVector.
Definition SetVector.h:151
A templated base class for SmallPtrSet which provides the typesafe interface that is common across al...
size_type count(ConstPtrType Ptr) const
count - Return 1 if the specified pointer is in the set, 0 otherwise.
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
SmallSet - This maintains a set of unique values, optimizing for the case when the set is small (less...
Definition SmallSet.h:134
size_type count(const T &V) const
count - Return 1 if the element is in the set, 0 otherwise.
Definition SmallSet.h:176
std::pair< const_iterator, bool > insert(const T &V)
insert - Insert an element into the set if it isn't already there.
Definition SmallSet.h:184
size_type size() const
Definition SmallSet.h:171
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
A BumpPtrAllocator that allows only elements of a specific type to be allocated.
Definition Allocator.h:397
Represent a constant reference to a string, i.e.
Definition StringRef.h:56
Align getTransientStackAlign() const
getTransientStackAlignment - This method returns the number of bytes to which the stack pointer must ...
TargetInstrInfo - Interface to description of machine instruction set.
virtual bool isLegalAddImmediate(int64_t) const
Return true if the specified immediate is legal add immediate, that is the target has add instruction...
This class defines information used to lower LLVM code to legal SelectionDAG operators that the targe...
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
TargetSubtargetInfo - Generic base class for all target subtargets.
virtual const TargetFrameLowering * getFrameLowering() const
LLVM Value Representation.
Definition Value.h:75
std::pair< iterator, bool > insert(const ValueT &V)
Definition DenseSet.h:209
size_type count(const_arg_type_t< ValueT > V) const
Return 1 if the specified key is in the set, 0 otherwise.
Definition DenseSet.h:187
Changed
This provides a very simple, boring adaptor for a begin and end iterator into a range type.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Abstract Attribute helper functions.
Definition Attributor.h:165
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
unsigned char getAM3Offset(unsigned AM3Opc)
unsigned getAM2Opc(AddrOpc Opc, unsigned Imm12, ShiftOpc SO, unsigned IdxMode=0)
AddrOpc getAM5Op(unsigned AM5Opc)
unsigned getAM3Opc(AddrOpc Opc, unsigned char Offset, unsigned IdxMode=0)
getAM3Opc - This function encodes the addrmode3 opc field.
unsigned char getAM5Offset(unsigned AM5Opc)
AddrOpc getAM3Op(unsigned AM3Opc)
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
Definition CallingConv.h:24
@ C
The default llvm calling convention, compatible with C.
Definition CallingConv.h:34
@ ARM
Windows AXP64.
Definition MCAsmInfo.h:50
@ CE
Windows NT (Windows on ARM)
Definition MCAsmInfo.h:51
This namespace contains all of the command line option processing machinery.
Definition MCSchedule.h:35
initializer< Ty > init(const Ty &Val)
NodeAddr< InstrNode * > Instr
Definition RDFGraph.h:389
NodeAddr< UseNode * > Use
Definition RDFGraph.h:385
BBIterator iterator
Definition BasicBlock.h:87
BaseReg
Stack frame base register. Bit 0 of FREInfo.Info.
Definition SFrame.h:77
This is an optimization pass for GlobalISel generic memory operations.
auto drop_begin(T &&RangeOrContainer, size_t N=1)
Return a range covering RangeOrContainer with the first N elements excluded.
Definition STLExtras.h:315
@ Offset
Definition DWP.cpp:578
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
@ Define
Register definition.
constexpr RegState getKillRegState(bool B)
static bool isARMLowRegister(MCRegister Reg)
isARMLowRegister - Returns true if the register is a low register (r0-r7).
APFloat abs(APFloat X)
Returns the absolute value of the argument.
Definition APFloat.h:1703
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
bool isLegalAddressImm(unsigned Opcode, int Imm, const TargetInstrInfo *TII)
AnalysisManager< MachineFunction > MachineFunctionAnalysisManager
constexpr RegState getDeadRegState(bool B)
static std::array< MachineOperand, 2 > predOps(ARMCC::CondCodes Pred, unsigned PredReg=0)
Get the operands corresponding to the given Pred value.
Op::Description Desc
unsigned M1(unsigned Val)
Definition VE.h:377
LLVM_ABI PreservedAnalyses getMachineFunctionPassPreservedAnalyses()
Returns the minimum set of Analyses that all machine function passes must preserve.
auto reverse(ContainerTy &&C)
Definition STLExtras.h:407
void sort(IteratorTy Start, IteratorTy End)
Definition STLExtras.h:1636
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition Debug.cpp:209
constexpr RegState getDefRegState(bool B)
FunctionPass * createARMLoadStoreOptLegacyPass(bool PreAlloc=false)
Returns an instance of the load / store optimization pass.
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
@ First
Helpers to iterate all locations in the MemoryEffectsBase class.
Definition ModRef.h:74
void replace(R &&Range, const T &OldValue, const T &NewValue)
Provide wrappers to std::replace which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1910
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Count
Definition InstrProf.h:145
ARMCC::CondCodes getInstrPredicate(const MachineInstr &MI, Register &PredReg)
getInstrPredicate - If instruction is predicated, returns its predicate condition,...
DWARFExpression::Operation Op
unsigned M0(unsigned Val)
Definition VE.h:376
ArrayRef(const T &OneElt) -> ArrayRef< T >
static MachineOperand t1CondCodeOp(bool isDead=false)
Get the operand corresponding to the conditional code result for Thumb1.
void erase_if(Container &C, UnaryPredicate P)
Provide a container algorithm similar to C++ Library Fundamentals v2's erase_if which is equivalent t...
Definition STLExtras.h:2192
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.
Definition STLExtras.h:1947
static MachineOperand condCodeOp(unsigned CCReg=0)
Get the operand corresponding to the conditional code result.
@ Increment
Incrementally increasing token ID.
Definition AllocToken.h:26
int getAddSubImmediate(MachineInstr &MI)
AAResults AliasAnalysis
Temporary typedef for legacy code that uses a generic AliasAnalysis pointer or reference.
constexpr RegState getUndefRegState(bool B)
MCRegisterClass TargetRegisterClass
Definition FastISel.h:58
This struct is a compact representation of a valid (non-zero power of two) alignment.
Definition Alignment.h:39