LLVM 24.0.0git
ARMBaseInstrInfo.cpp
Go to the documentation of this file.
1//===-- ARMBaseInstrInfo.cpp - ARM Instruction Information ----------------===//
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// This file contains the Base ARM implementation of the TargetInstrInfo class.
10//
11//===----------------------------------------------------------------------===//
12
13#include "ARMBaseInstrInfo.h"
14#include "ARMBaseRegisterInfo.h"
16#include "ARMFeatures.h"
17#include "ARMHazardRecognizer.h"
19#include "ARMSubtarget.h"
22#include "MVETailPredUtils.h"
23#include "llvm/ADT/DenseMap.h"
24#include "llvm/ADT/STLExtras.h"
25#include "llvm/ADT/SmallSet.h"
48#include "llvm/IR/Attributes.h"
49#include "llvm/IR/DebugLoc.h"
50#include "llvm/IR/Function.h"
51#include "llvm/IR/GlobalValue.h"
52#include "llvm/IR/Module.h"
53#include "llvm/MC/MCAsmInfo.h"
54#include "llvm/MC/MCInstrDesc.h"
59#include "llvm/Support/Debug.h"
63#include <algorithm>
64#include <cassert>
65#include <cstdint>
66#include <iterator>
67#include <new>
68#include <utility>
69#include <vector>
70
71using namespace llvm;
72
73#define DEBUG_TYPE "arm-instrinfo"
74
75#define GET_INSTRINFO_CTOR_DTOR
76#include "ARMGenInstrInfo.inc"
77
78/// ARM_MLxEntry - Record information about MLA / MLS instructions.
80 uint16_t MLxOpc; // MLA / MLS opcode
81 uint16_t MulOpc; // Expanded multiplication opcode
82 uint16_t AddSubOpc; // Expanded add / sub opcode
83 bool NegAcc; // True if the acc is negated before the add / sub.
84 bool HasLane; // True if instruction has an extra "lane" operand.
85};
86
87static const ARM_MLxEntry ARM_MLxTable[] = {
88 // MLxOpc, MulOpc, AddSubOpc, NegAcc, HasLane
89 // fp scalar ops
90 { ARM::VMLAS, ARM::VMULS, ARM::VADDS, false, false },
91 { ARM::VMLSS, ARM::VMULS, ARM::VSUBS, false, false },
92 { ARM::VMLAD, ARM::VMULD, ARM::VADDD, false, false },
93 { ARM::VMLSD, ARM::VMULD, ARM::VSUBD, false, false },
94 { ARM::VNMLAS, ARM::VNMULS, ARM::VSUBS, true, false },
95 { ARM::VNMLSS, ARM::VMULS, ARM::VSUBS, true, false },
96 { ARM::VNMLAD, ARM::VNMULD, ARM::VSUBD, true, false },
97 { ARM::VNMLSD, ARM::VMULD, ARM::VSUBD, true, false },
98
99 // fp SIMD ops
100 { ARM::VMLAfd, ARM::VMULfd, ARM::VADDfd, false, false },
101 { ARM::VMLSfd, ARM::VMULfd, ARM::VSUBfd, false, false },
102 { ARM::VMLAfq, ARM::VMULfq, ARM::VADDfq, false, false },
103 { ARM::VMLSfq, ARM::VMULfq, ARM::VSUBfq, false, false },
104 { ARM::VMLAslfd, ARM::VMULslfd, ARM::VADDfd, false, true },
105 { ARM::VMLSslfd, ARM::VMULslfd, ARM::VSUBfd, false, true },
106 { ARM::VMLAslfq, ARM::VMULslfq, ARM::VADDfq, false, true },
107 { ARM::VMLSslfq, ARM::VMULslfq, ARM::VSUBfq, false, true },
108};
109
112 : ARMGenInstrInfo(STI, TRI, ARM::ADJCALLSTACKDOWN, ARM::ADJCALLSTACKUP),
113 Subtarget(STI) {
114 for (unsigned i = 0, e = std::size(ARM_MLxTable); i != e; ++i) {
115 if (!MLxEntryMap.insert(std::make_pair(ARM_MLxTable[i].MLxOpc, i)).second)
116 llvm_unreachable("Duplicated entries?");
117 MLxHazardOpcodes.insert(ARM_MLxTable[i].AddSubOpc);
118 MLxHazardOpcodes.insert(ARM_MLxTable[i].MulOpc);
119 }
120}
121
122// Use a ScoreboardHazardRecognizer for prepass ARM scheduling. TargetInstrImpl
123// currently defaults to no prepass hazard recognizer.
126 const ScheduleDAG *DAG) const {
127 if (usePreRAHazardRecognizer()) {
128 const InstrItineraryData *II =
129 static_cast<const ARMSubtarget *>(STI)->getInstrItineraryData();
130 return new ScoreboardHazardRecognizer(II, DAG, "pre-RA-sched");
131 }
133}
134
135// Called during:
136// - pre-RA scheduling
137// - post-RA scheduling when FeatureUseMISched is set
139 const InstrItineraryData *II, const ScheduleDAGMI *DAG) const {
141
142 // We would like to restrict this hazard recognizer to only
143 // post-RA scheduling; we can tell that we're post-RA because we don't
144 // track VRegLiveness.
145 // Cortex-M7: TRM indicates that there is a single ITCM bank and two DTCM
146 // banks banked on bit 2. Assume that TCMs are in use.
147 if (Subtarget.isCortexM7() && !DAG->hasVRegLiveness())
149 std::make_unique<ARMBankConflictHazardRecognizer>(DAG, 0x4, true));
150
151 // Not inserting ARMHazardRecognizerFPMLx because that would change
152 // legacy behavior
153
155 MHR->AddHazardRecognizer(std::unique_ptr<ScheduleHazardRecognizer>(BHR));
156 return MHR;
157}
158
159// Called during post-RA scheduling when FeatureUseMISched is not set
162 const ScheduleDAG *DAG) const {
164
165 if (Subtarget.isThumb2() || Subtarget.hasVFP2Base())
166 MHR->AddHazardRecognizer(std::make_unique<ARMHazardRecognizerFPMLx>());
167
169 if (BHR)
170 MHR->AddHazardRecognizer(std::unique_ptr<ScheduleHazardRecognizer>(BHR));
171 return MHR;
172}
173
174// Branch analysis.
175// Cond vector output format:
176// 0 elements indicates an unconditional branch
177// 2 elements indicates a conditional branch; the elements are
178// the condition to check and the CPSR.
179// 3 elements indicates a hardware loop end; the elements
180// are the opcode, the operand value to test, and a dummy
181// operand used to pad out to 3 operands.
184 MachineBasicBlock *&FBB,
186 bool AllowModify) const {
187 TBB = nullptr;
188 FBB = nullptr;
189
191 if (I == MBB.instr_begin())
192 return false; // Empty blocks are easy.
193 --I;
194
195 // Walk backwards from the end of the basic block until the branch is
196 // analyzed or we give up.
197 while (isPredicated(*I) || I->isTerminator() || I->isDebugValue()) {
198 // Flag to be raised on unanalyzeable instructions. This is useful in cases
199 // where we want to clean up on the end of the basic block before we bail
200 // out.
201 bool CantAnalyze = false;
202
203 // Skip over DEBUG values, predicated nonterminators and speculation
204 // barrier terminators.
205 while (I->isDebugInstr() || !I->isTerminator() ||
206 isSpeculationBarrierEndBBOpcode(I->getOpcode()) ||
207 I->getOpcode() == ARM::t2DoLoopStartTP){
208 if (I == MBB.instr_begin())
209 return false;
210 --I;
211 }
212
213 if (isIndirectBranchOpcode(I->getOpcode()) ||
214 isJumpTableBranchOpcode(I->getOpcode())) {
215 // Indirect branches and jump tables can't be analyzed, but we still want
216 // to clean up any instructions at the tail of the basic block.
217 CantAnalyze = true;
218 } else if (isUncondBranchOpcode(I->getOpcode())) {
219 TBB = I->getOperand(0).getMBB();
220 } else if (isCondBranchOpcode(I->getOpcode())) {
221 // Bail out if we encounter multiple conditional branches.
222 if (!Cond.empty())
223 return true;
224
225 assert(!FBB && "FBB should have been null.");
226 FBB = TBB;
227 TBB = I->getOperand(0).getMBB();
228 Cond.push_back(I->getOperand(1));
229 Cond.push_back(I->getOperand(2));
230 } else if (I->isReturn()) {
231 // Returns can't be analyzed, but we should run cleanup.
232 CantAnalyze = true;
233 } else if (I->getOpcode() == ARM::t2LoopEnd &&
234 MBB.getParent()
235 ->getSubtarget<ARMSubtarget>()
237 if (!Cond.empty())
238 return true;
239 FBB = TBB;
240 TBB = I->getOperand(1).getMBB();
241 Cond.push_back(MachineOperand::CreateImm(I->getOpcode()));
242 Cond.push_back(I->getOperand(0));
243 Cond.push_back(MachineOperand::CreateImm(0));
244 } else {
245 // We encountered other unrecognized terminator. Bail out immediately.
246 return true;
247 }
248
249 // Cleanup code - to be run for unpredicated unconditional branches and
250 // returns.
251 if (!isPredicated(*I) &&
252 (isUncondBranchOpcode(I->getOpcode()) ||
253 isIndirectBranchOpcode(I->getOpcode()) ||
254 isJumpTableBranchOpcode(I->getOpcode()) ||
255 I->isReturn())) {
256 // Forget any previous condition branch information - it no longer applies.
257 Cond.clear();
258 FBB = nullptr;
259
260 // If we can modify the function, delete everything below this
261 // unconditional branch.
262 if (AllowModify) {
263 MachineBasicBlock::iterator DI = std::next(I);
264 while (DI != MBB.instr_end()) {
265 MachineInstr &InstToDelete = *DI;
266 ++DI;
267 // Speculation barriers must not be deleted.
268 if (isSpeculationBarrierEndBBOpcode(InstToDelete.getOpcode()))
269 continue;
270 InstToDelete.eraseFromParent();
271 }
272 }
273 }
274
275 if (CantAnalyze) {
276 // We may not be able to analyze the block, but we could still have
277 // an unconditional branch as the last instruction in the block, which
278 // just branches to layout successor. If this is the case, then just
279 // remove it if we're allowed to make modifications.
280 if (AllowModify && !isPredicated(MBB.back()) &&
281 isUncondBranchOpcode(MBB.back().getOpcode()) &&
282 TBB && MBB.isLayoutSuccessor(TBB))
284 return true;
285 }
286
287 if (I == MBB.instr_begin())
288 return false;
289
290 --I;
291 }
292
293 // We made it past the terminators without bailing out - we must have
294 // analyzed this branch successfully.
295 return false;
296}
297
299 int *BytesRemoved) const {
300 assert(!BytesRemoved && "code size not handled");
301
302 MachineBasicBlock::iterator I = MBB.getLastNonDebugInstr();
303 if (I == MBB.end())
304 return 0;
305
306 if (!isUncondBranchOpcode(I->getOpcode()) &&
307 !isCondBranchOpcode(I->getOpcode()) && I->getOpcode() != ARM::t2LoopEnd)
308 return 0;
309
310 // Remove the branch.
311 I->eraseFromParent();
312
313 I = MBB.end();
314
315 if (I == MBB.begin()) return 1;
316 --I;
317 if (!isCondBranchOpcode(I->getOpcode()) && I->getOpcode() != ARM::t2LoopEnd)
318 return 1;
319
320 // Remove the branch.
321 I->eraseFromParent();
322 return 2;
323}
324
329 const DebugLoc &DL,
330 int *BytesAdded) const {
331 assert(!BytesAdded && "code size not handled");
332 ARMFunctionInfo *AFI = MBB.getParent()->getInfo<ARMFunctionInfo>();
333 int BOpc = !AFI->isThumbFunction()
334 ? ARM::B : (AFI->isThumb2Function() ? ARM::t2B : ARM::tB);
335 int BccOpc = !AFI->isThumbFunction()
336 ? ARM::Bcc : (AFI->isThumb2Function() ? ARM::t2Bcc : ARM::tBcc);
337 bool isThumb = AFI->isThumbFunction() || AFI->isThumb2Function();
338
339 // Shouldn't be a fall through.
340 assert(TBB && "insertBranch must not be told to insert a fallthrough");
341 assert((Cond.size() == 2 || Cond.size() == 0 || Cond.size() == 3) &&
342 "ARM branch conditions have two or three components!");
343
344 // For conditional branches, we use addOperand to preserve CPSR flags.
345
346 if (!FBB) {
347 if (Cond.empty()) { // Unconditional branch?
348 if (isThumb)
350 else
351 BuildMI(&MBB, DL, get(BOpc)).addMBB(TBB);
352 } else if (Cond.size() == 2) {
353 BuildMI(&MBB, DL, get(BccOpc))
354 .addMBB(TBB)
355 .addImm(Cond[0].getImm())
356 .add(Cond[1]);
357 } else
358 BuildMI(&MBB, DL, get(Cond[0].getImm())).add(Cond[1]).addMBB(TBB);
359 return 1;
360 }
361
362 // Two-way conditional branch.
363 if (Cond.size() == 2)
364 BuildMI(&MBB, DL, get(BccOpc))
365 .addMBB(TBB)
366 .addImm(Cond[0].getImm())
367 .add(Cond[1]);
368 else if (Cond.size() == 3)
369 BuildMI(&MBB, DL, get(Cond[0].getImm())).add(Cond[1]).addMBB(TBB);
370 if (isThumb)
371 BuildMI(&MBB, DL, get(BOpc)).addMBB(FBB).add(predOps(ARMCC::AL));
372 else
373 BuildMI(&MBB, DL, get(BOpc)).addMBB(FBB);
374 return 2;
375}
376
379 if (Cond.size() == 2) {
380 ARMCC::CondCodes CC = (ARMCC::CondCodes)(int)Cond[0].getImm();
381 Cond[0].setImm(ARMCC::getOppositeCondition(CC));
382 return false;
383 }
384 return true;
385}
386
388 if (MI.isBundle()) {
390 MachineBasicBlock::const_instr_iterator E = MI.getParent()->instr_end();
391 while (++I != E && I->isInsideBundle()) {
392 int PIdx = I->findFirstPredOperandIdx();
393 if (PIdx != -1 && I->getOperand(PIdx).getImm() != ARMCC::AL)
394 return true;
395 }
396 return false;
397 }
398
399 int PIdx = MI.findFirstPredOperandIdx();
400 return PIdx != -1 && MI.getOperand(PIdx).getImm() != ARMCC::AL;
401}
402
404 const MachineInstr &MI, const MachineOperand &Op, unsigned OpIdx,
405 const TargetRegisterInfo *TRI) const {
406
407 // First, let's see if there is a generic comment for this operand
408 std::string GenericComment =
410 if (!GenericComment.empty())
411 return GenericComment;
412
413 // If not, check if we have an immediate operand.
414 if (!Op.isImm())
415 return std::string();
416
417 // And print its corresponding condition code if the immediate is a
418 // predicate.
419 int FirstPredOp = MI.findFirstPredOperandIdx();
420 if (FirstPredOp != (int) OpIdx)
421 return std::string();
422
423 std::string CC = "CC::";
424 CC += ARMCondCodeToString((ARMCC::CondCodes)Op.getImm());
425 return CC;
426}
427
430 unsigned Opc = MI.getOpcode();
433 MachineInstrBuilder(*MI.getParent()->getParent(), MI)
434 .addImm(Pred[0].getImm())
435 .addReg(Pred[1].getReg());
436 return true;
437 }
438
439 int PIdx = MI.findFirstPredOperandIdx();
440 if (PIdx != -1) {
441 MachineOperand &PMO = MI.getOperand(PIdx);
442 PMO.setImm(Pred[0].getImm());
443 MI.getOperand(PIdx+1).setReg(Pred[1].getReg());
444
445 // Thumb 1 arithmetic instructions do not set CPSR when executed inside an
446 // IT block. This affects how they are printed.
447 const MCInstrDesc &MCID = MI.getDesc();
448 if (MCID.TSFlags & ARMII::ThumbArithFlagSetting) {
449 assert(MCID.operands()[1].isOptionalDef() &&
450 "CPSR def isn't expected operand");
451 assert((MI.getOperand(1).isDead() ||
452 MI.getOperand(1).getReg() != ARM::CPSR) &&
453 "if conversion tried to stop defining used CPSR");
454 MI.getOperand(1).setReg(ARM::NoRegister);
455 }
456
457 return true;
458 }
459 return false;
460}
461
463 ArrayRef<MachineOperand> Pred2) const {
464 if (Pred1.size() > 2 || Pred2.size() > 2)
465 return false;
466
467 ARMCC::CondCodes CC1 = (ARMCC::CondCodes)Pred1[0].getImm();
468 ARMCC::CondCodes CC2 = (ARMCC::CondCodes)Pred2[0].getImm();
469 if (CC1 == CC2)
470 return true;
471
472 switch (CC1) {
473 default:
474 return false;
475 case ARMCC::AL:
476 return true;
477 case ARMCC::HS:
478 return CC2 == ARMCC::HI;
479 case ARMCC::LS:
480 return CC2 == ARMCC::LO || CC2 == ARMCC::EQ;
481 case ARMCC::GE:
482 return CC2 == ARMCC::GT;
483 case ARMCC::LE:
484 return CC2 == ARMCC::LT;
485 }
486}
487
489 std::vector<MachineOperand> &Pred,
490 bool SkipDead) const {
491 bool Found = false;
492 for (const MachineOperand &MO : MI.operands()) {
493 bool ClobbersCPSR = MO.isRegMask() && MO.clobbersPhysReg(ARM::CPSR);
494 bool IsCPSR = MO.isReg() && MO.isDef() && MO.getReg() == ARM::CPSR;
495 if (ClobbersCPSR || IsCPSR) {
496
497 // Filter out T1 instructions that have a dead CPSR,
498 // allowing IT blocks to be generated containing T1 instructions
499 const MCInstrDesc &MCID = MI.getDesc();
500 if (MCID.TSFlags & ARMII::ThumbArithFlagSetting && MO.isDead() &&
501 SkipDead)
502 continue;
503
504 Pred.push_back(MO);
505 Found = true;
506 }
507 }
508
509 return Found;
510}
511
513 for (const auto &MO : MI.operands())
514 if (MO.isReg() && MO.getReg() == ARM::CPSR && MO.isDef() && !MO.isDead())
515 return true;
516 return false;
517}
518
520 switch (MI->getOpcode()) {
521 default: return true;
522 case ARM::tADC: // ADC (register) T1
523 case ARM::tADDi3: // ADD (immediate) T1
524 case ARM::tADDi8: // ADD (immediate) T2
525 case ARM::tADDrr: // ADD (register) T1
526 case ARM::tAND: // AND (register) T1
527 case ARM::tASRri: // ASR (immediate) T1
528 case ARM::tASRrr: // ASR (register) T1
529 case ARM::tBIC: // BIC (register) T1
530 case ARM::tEOR: // EOR (register) T1
531 case ARM::tLSLri: // LSL (immediate) T1
532 case ARM::tLSLrr: // LSL (register) T1
533 case ARM::tLSRri: // LSR (immediate) T1
534 case ARM::tLSRrr: // LSR (register) T1
535 case ARM::tMUL: // MUL T1
536 case ARM::tMVN: // MVN (register) T1
537 case ARM::tORR: // ORR (register) T1
538 case ARM::tROR: // ROR (register) T1
539 case ARM::tRSB: // RSB (immediate) T1
540 case ARM::tSBC: // SBC (register) T1
541 case ARM::tSUBi3: // SUB (immediate) T1
542 case ARM::tSUBi8: // SUB (immediate) T2
543 case ARM::tSUBrr: // SUB (register) T1
545 }
546}
547
548/// isPredicable - Return true if the specified instruction can be predicated.
549/// By default, this returns true for every instruction with a
550/// PredicateOperand.
552 if (!MI.isPredicable())
553 return false;
554
555 if (MI.isBundle())
556 return false;
557
559 return false;
560
561 const MachineFunction *MF = MI.getParent()->getParent();
562 const ARMFunctionInfo *AFI =
564
565 // Neon instructions in Thumb2 IT blocks are deprecated, see ARMARM.
566 // In their ARM encoding, they can't be encoded in a conditional form.
567 if ((MI.getDesc().TSFlags & ARMII::DomainMask) == ARMII::DomainNEON)
568 return false;
569
570 // Make indirect control flow changes unpredictable when SLS mitigation is
571 // enabled.
572 const ARMSubtarget &ST = MF->getSubtarget<ARMSubtarget>();
573 if (ST.hardenSlsRetBr() && isIndirectControlFlowNotComingBack(MI))
574 return false;
575 if (ST.hardenSlsBlr() && isIndirectCall(MI))
576 return false;
577
578 if (AFI->isThumb2Function()) {
579 if (getSubtarget().restrictIT())
580 return isV8EligibleForIT(&MI);
581 }
582
583 return true;
584}
585
586namespace llvm {
587
588template <> bool IsCPSRDead<MachineInstr>(const MachineInstr *MI) {
589 for (const MachineOperand &MO : MI->operands()) {
590 if (!MO.isReg() || MO.isUndef() || MO.isUse())
591 continue;
592 if (MO.getReg() != ARM::CPSR)
593 continue;
594 if (!MO.isDead())
595 return false;
596 }
597 // all definitions of CPSR are dead
598 return true;
599}
600
601} // end namespace llvm
602
603/// GetInstSize - Return the size of the specified MachineInstr.
604///
606 const MachineBasicBlock &MBB = *MI.getParent();
607 const MachineFunction *MF = MBB.getParent();
608 const MCAsmInfo &MAI = MF->getTarget().getMCAsmInfo();
609
610 const MCInstrDesc &MCID = MI.getDesc();
611
612 switch (MI.getOpcode()) {
613 default:
614 // Return the size specified in .td file. If there's none, return 0, as we
615 // can't define a default size (Thumb1 instructions are 2 bytes, Thumb2
616 // instructions are 2-4 bytes, and ARM instructions are 4 bytes), in
617 // contrast to AArch64 instructions which have a default size of 4 bytes for
618 // example.
619 return MCID.getSize();
620 case TargetOpcode::BUNDLE:
621 return getInstBundleSize(MI);
622 case TargetOpcode::COPY:
624 return 4;
625 else
626 return 2;
627 case TargetOpcode::PATCHABLE_FUNCTION_ENTER:
628 case TargetOpcode::PATCHABLE_FUNCTION_EXIT:
629 case TargetOpcode::PATCHABLE_TAIL_CALL:
630 // Size of xray sled: Branch + 6 nops.
631 return 28;
632 case ARM::CONSTPOOL_ENTRY:
633 case ARM::JUMPTABLE_INSTS:
634 case ARM::JUMPTABLE_ADDRS:
635 case ARM::JUMPTABLE_TBB:
636 case ARM::JUMPTABLE_TBH:
637 // If this machine instr is a constant pool entry, its size is recorded as
638 // operand #2.
639 return MI.getOperand(2).getImm();
640 case ARM::SPACE:
641 return MI.getOperand(1).getImm();
642 case ARM::INLINEASM:
643 case ARM::INLINEASM_BR: {
644 // If this machine instr is an inline asm, measure it.
645 unsigned Size = getInlineAsmLength(MI.getOperand(0).getSymbolName(), MAI);
647 Size = alignTo(Size, 4);
648 return Size;
649 }
650 }
651}
652
655 MCRegister DestReg, bool KillSrc,
656 const ARMSubtarget &Subtarget) const {
657 unsigned Opc = Subtarget.isThumb()
658 ? (Subtarget.isMClass() ? ARM::t2MRS_M : ARM::t2MRS_AR)
659 : ARM::MRS;
660
662 BuildMI(MBB, I, I->getDebugLoc(), get(Opc), DestReg);
663
664 // There is only 1 A/R class MRS instruction, and it always refers to
665 // APSR. However, there are lots of other possibilities on M-class cores.
666 if (Subtarget.isMClass())
667 MIB.addImm(0x800);
668
669 MIB.add(predOps(ARMCC::AL))
670 .addReg(ARM::CPSR, RegState::Implicit | getKillRegState(KillSrc));
671}
672
675 MCRegister SrcReg, bool KillSrc,
676 const ARMSubtarget &Subtarget) const {
677 unsigned Opc = Subtarget.isThumb()
678 ? (Subtarget.isMClass() ? ARM::t2MSR_M : ARM::t2MSR_AR)
679 : ARM::MSR;
680
681 MachineInstrBuilder MIB = BuildMI(MBB, I, I->getDebugLoc(), get(Opc));
682
683 if (Subtarget.isMClass())
684 MIB.addImm(0x800);
685 else
686 MIB.addImm(8);
687
688 MIB.addReg(SrcReg, getKillRegState(KillSrc))
691}
692
694 MIB.addImm(ARMVCC::None);
695 MIB.addReg(0);
696 MIB.addReg(0); // tp_reg
697}
698
704
706 MIB.addImm(Cond);
707 MIB.addReg(ARM::VPR, RegState::Implicit);
708 MIB.addReg(0); // tp_reg
709}
710
712 unsigned Cond, unsigned Inactive) {
714 MIB.addReg(Inactive);
715}
716
719 const DebugLoc &DL, Register DestReg,
720 Register SrcReg, bool KillSrc,
721 bool RenamableDest,
722 bool RenamableSrc) const {
723 bool GPRDest = ARM::GPRRegClass.contains(DestReg);
724 bool GPRSrc = ARM::GPRRegClass.contains(SrcReg);
725
726 if (GPRDest && GPRSrc) {
727 BuildMI(MBB, I, DL, get(ARM::MOVr), DestReg)
728 .addReg(SrcReg, getKillRegState(KillSrc))
730 .add(condCodeOp());
731 return;
732 }
733
734 bool SPRDest = ARM::SPRRegClass.contains(DestReg);
735 bool SPRSrc = ARM::SPRRegClass.contains(SrcReg);
736
737 unsigned Opc = 0;
738 if (SPRDest && SPRSrc)
739 Opc = ARM::VMOVS;
740 else if (GPRDest && SPRSrc)
741 Opc = ARM::VMOVRS;
742 else if (SPRDest && GPRSrc)
743 Opc = ARM::VMOVSR;
744 else if (ARM::DPRRegClass.contains(DestReg, SrcReg) && Subtarget.hasFP64())
745 Opc = ARM::VMOVD;
746 else if (ARM::QPRRegClass.contains(DestReg, SrcReg))
747 Opc = Subtarget.hasNEON() ? ARM::VORRq : ARM::MQPRCopy;
748
749 if (Opc) {
750 MachineInstrBuilder MIB = BuildMI(MBB, I, DL, get(Opc), DestReg);
751 MIB.addReg(SrcReg, getKillRegState(KillSrc));
752 if (Opc == ARM::VORRq || Opc == ARM::MVE_VORR)
753 MIB.addReg(SrcReg, getKillRegState(KillSrc));
754 if (Opc == ARM::MVE_VORR)
755 addUnpredicatedMveVpredROp(MIB, DestReg);
756 else if (Opc != ARM::MQPRCopy)
757 MIB.add(predOps(ARMCC::AL));
758 return;
759 }
760
761 // Handle register classes that require multiple instructions.
762 unsigned BeginIdx = 0;
763 unsigned SubRegs = 0;
764 int Spacing = 1;
765
766 // Use VORRq when possible.
767 if (ARM::QQPRRegClass.contains(DestReg, SrcReg)) {
768 Opc = Subtarget.hasNEON() ? ARM::VORRq : ARM::MVE_VORR;
769 BeginIdx = ARM::qsub_0;
770 SubRegs = 2;
771 } else if (ARM::QQQQPRRegClass.contains(DestReg, SrcReg)) {
772 Opc = Subtarget.hasNEON() ? ARM::VORRq : ARM::MVE_VORR;
773 BeginIdx = ARM::qsub_0;
774 SubRegs = 4;
775 // Fall back to VMOVD.
776 } else if (ARM::DPairRegClass.contains(DestReg, SrcReg)) {
777 Opc = ARM::VMOVD;
778 BeginIdx = ARM::dsub_0;
779 SubRegs = 2;
780 } else if (ARM::DTripleRegClass.contains(DestReg, SrcReg)) {
781 Opc = ARM::VMOVD;
782 BeginIdx = ARM::dsub_0;
783 SubRegs = 3;
784 } else if (ARM::DQuadRegClass.contains(DestReg, SrcReg)) {
785 Opc = ARM::VMOVD;
786 BeginIdx = ARM::dsub_0;
787 SubRegs = 4;
788 } else if (ARM::GPRPairRegClass.contains(DestReg, SrcReg)) {
789 Opc = Subtarget.isThumb2() ? ARM::tMOVr : ARM::MOVr;
790 BeginIdx = ARM::gsub_0;
791 SubRegs = 2;
792 } else if (ARM::DPairSpcRegClass.contains(DestReg, SrcReg)) {
793 Opc = ARM::VMOVD;
794 BeginIdx = ARM::dsub_0;
795 SubRegs = 2;
796 Spacing = 2;
797 } else if (ARM::DTripleSpcRegClass.contains(DestReg, SrcReg)) {
798 Opc = ARM::VMOVD;
799 BeginIdx = ARM::dsub_0;
800 SubRegs = 3;
801 Spacing = 2;
802 } else if (ARM::DQuadSpcRegClass.contains(DestReg, SrcReg)) {
803 Opc = ARM::VMOVD;
804 BeginIdx = ARM::dsub_0;
805 SubRegs = 4;
806 Spacing = 2;
807 } else if (ARM::DPRRegClass.contains(DestReg, SrcReg) &&
808 !Subtarget.hasFP64()) {
809 Opc = ARM::VMOVS;
810 BeginIdx = ARM::ssub_0;
811 SubRegs = 2;
812 } else if (SrcReg == ARM::CPSR) {
813 copyFromCPSR(MBB, I, DestReg, KillSrc, Subtarget);
814 return;
815 } else if (DestReg == ARM::CPSR) {
816 copyToCPSR(MBB, I, SrcReg, KillSrc, Subtarget);
817 return;
818 } else if (DestReg == ARM::VPR) {
819 assert(ARM::GPRRegClass.contains(SrcReg));
820 BuildMI(MBB, I, I->getDebugLoc(), get(ARM::VMSR_P0), DestReg)
821 .addReg(SrcReg, getKillRegState(KillSrc))
823 return;
824 } else if (SrcReg == ARM::VPR) {
825 assert(ARM::GPRRegClass.contains(DestReg));
826 BuildMI(MBB, I, I->getDebugLoc(), get(ARM::VMRS_P0), DestReg)
827 .addReg(SrcReg, getKillRegState(KillSrc))
829 return;
830 } else if (DestReg == ARM::FPSCR_NZCV) {
831 assert(ARM::GPRRegClass.contains(SrcReg));
832 BuildMI(MBB, I, I->getDebugLoc(), get(ARM::VMSR_FPSCR_NZCVQC), DestReg)
833 .addReg(SrcReg, getKillRegState(KillSrc))
835 return;
836 } else if (SrcReg == ARM::FPSCR_NZCV) {
837 assert(ARM::GPRRegClass.contains(DestReg));
838 BuildMI(MBB, I, I->getDebugLoc(), get(ARM::VMRS_FPSCR_NZCVQC), DestReg)
839 .addReg(SrcReg, getKillRegState(KillSrc))
841 return;
842 }
843
844 assert(Opc && "Impossible reg-to-reg copy");
845
848
849 // Copy register tuples backward when the first Dest reg overlaps with SrcReg.
850 if (TRI->regsOverlap(SrcReg, TRI->getSubReg(DestReg, BeginIdx))) {
851 BeginIdx = BeginIdx + ((SubRegs - 1) * Spacing);
852 Spacing = -Spacing;
853 }
854#ifndef NDEBUG
855 SmallSet<unsigned, 4> DstRegs;
856#endif
857 for (unsigned i = 0; i != SubRegs; ++i) {
858 Register Dst = TRI->getSubReg(DestReg, BeginIdx + i * Spacing);
859 Register Src = TRI->getSubReg(SrcReg, BeginIdx + i * Spacing);
860 assert(Dst && Src && "Bad sub-register");
861#ifndef NDEBUG
862 assert(!DstRegs.count(Src) && "destructive vector copy");
863 DstRegs.insert(Dst);
864#endif
865 Mov = BuildMI(MBB, I, I->getDebugLoc(), get(Opc), Dst).addReg(Src);
866 // VORR (NEON or MVE) takes two source operands.
867 if (Opc == ARM::VORRq || Opc == ARM::MVE_VORR) {
868 Mov.addReg(Src);
869 }
870 // MVE VORR takes predicate operands in place of an ordinary condition.
871 if (Opc == ARM::MVE_VORR)
873 else
874 Mov = Mov.add(predOps(ARMCC::AL));
875 // MOVr can set CC.
876 if (Opc == ARM::MOVr)
877 Mov = Mov.add(condCodeOp());
878 }
879 // Add implicit super-register defs and kills to the last instruction.
880 Mov->addRegisterDefined(DestReg, TRI);
881 if (KillSrc)
882 Mov->addRegisterKilled(SrcReg, TRI);
883}
884
885std::optional<DestSourcePair>
887 // VMOVRRD is also a copy instruction but it requires
888 // special way of handling. It is more complex copy version
889 // and since that we are not considering it. For recognition
890 // of such instruction isExtractSubregLike MI interface function
891 // could be used.
892 // VORRq is considered as a move only if two inputs are
893 // the same register.
894 if (!MI.isMoveReg() ||
895 (MI.getOpcode() == ARM::VORRq &&
896 MI.getOperand(1).getReg() != MI.getOperand(2).getReg()))
897 return std::nullopt;
898 return DestSourcePair{MI.getOperand(0), MI.getOperand(1)};
899}
900
901std::optional<ParamLoadedValue>
903 Register Reg) const {
904 if (auto DstSrcPair = isCopyInstrImpl(MI)) {
905 Register DstReg = DstSrcPair->Destination->getReg();
906
907 // TODO: We don't handle cases where the forwarding reg is narrower/wider
908 // than the copy registers. Consider for example:
909 //
910 // s16 = VMOVS s0
911 // s17 = VMOVS s1
912 // call @callee(d0)
913 //
914 // We'd like to describe the call site value of d0 as d8, but this requires
915 // gathering and merging the descriptions for the two VMOVS instructions.
916 //
917 // We also don't handle the reverse situation, where the forwarding reg is
918 // narrower than the copy destination:
919 //
920 // d8 = VMOVD d0
921 // call @callee(s1)
922 //
923 // We need to produce a fragment description (the call site value of s1 is
924 // /not/ just d8).
925 if (DstReg != Reg)
926 return std::nullopt;
927 }
929}
930
932 unsigned Reg,
933 unsigned SubIdx,
934 RegState State) const {
935 if (!SubIdx)
936 return MIB.addReg(Reg, State);
937
939 return MIB.addReg(getRegisterInfo().getSubReg(Reg, SubIdx), State);
940 return MIB.addReg(Reg, State, SubIdx);
941}
942
945 Register SrcReg, bool isKill, int FI,
946 const TargetRegisterClass *RC,
947 Register VReg,
948 MachineInstr::MIFlag Flags) const {
949 MachineFunction &MF = *MBB.getParent();
950 MachineFrameInfo &MFI = MF.getFrameInfo();
951 Align Alignment = MFI.getObjectAlign(FI);
953
956 MFI.getObjectSize(FI), Alignment);
957
958 switch (TRI.getSpillSize(*RC)) {
959 case 2:
960 if (ARM::HPRRegClass.hasSubClassEq(RC)) {
961 BuildMI(MBB, I, DebugLoc(), get(ARM::VSTRH))
962 .addReg(SrcReg, getKillRegState(isKill))
963 .addFrameIndex(FI)
964 .addImm(0)
965 .addMemOperand(MMO)
967 } else
968 llvm_unreachable("Unknown reg class!");
969 break;
970 case 4:
971 if (ARM::GPRRegClass.hasSubClassEq(RC)) {
972 BuildMI(MBB, I, DebugLoc(), get(ARM::STRi12))
973 .addReg(SrcReg, getKillRegState(isKill))
974 .addFrameIndex(FI)
975 .addImm(0)
976 .addMemOperand(MMO)
978 } else if (ARM::SPRRegClass.hasSubClassEq(RC)) {
979 BuildMI(MBB, I, DebugLoc(), get(ARM::VSTRS))
980 .addReg(SrcReg, getKillRegState(isKill))
981 .addFrameIndex(FI)
982 .addImm(0)
983 .addMemOperand(MMO)
985 } else if (ARM::VCCRRegClass.hasSubClassEq(RC)) {
986 BuildMI(MBB, I, DebugLoc(), get(ARM::VSTR_P0_off))
987 .addReg(SrcReg, getKillRegState(isKill))
988 .addFrameIndex(FI)
989 .addImm(0)
990 .addMemOperand(MMO)
992 } else if (ARM::cl_FPSCR_NZCVRegClass.hasSubClassEq(RC)) {
993 BuildMI(MBB, I, DebugLoc(), get(ARM::VSTR_FPSCR_NZCVQC_off))
994 .addReg(SrcReg, getKillRegState(isKill))
995 .addFrameIndex(FI)
996 .addImm(0)
997 .addMemOperand(MMO)
999 } else
1000 llvm_unreachable("Unknown reg class!");
1001 break;
1002 case 8:
1003 if (ARM::DPRRegClass.hasSubClassEq(RC)) {
1004 BuildMI(MBB, I, DebugLoc(), get(ARM::VSTRD))
1005 .addReg(SrcReg, getKillRegState(isKill))
1006 .addFrameIndex(FI)
1007 .addImm(0)
1008 .addMemOperand(MMO)
1010 } else if (ARM::GPRPairRegClass.hasSubClassEq(RC)) {
1011 if (Subtarget.hasV5TEOps()) {
1012 MachineInstrBuilder MIB = BuildMI(MBB, I, DebugLoc(), get(ARM::STRD));
1013 AddDReg(MIB, SrcReg, ARM::gsub_0, getKillRegState(isKill));
1014 AddDReg(MIB, SrcReg, ARM::gsub_1, {});
1015 MIB.addFrameIndex(FI).addReg(0).addImm(0).addMemOperand(MMO)
1017 } else {
1018 // Fallback to STM instruction, which has existed since the dawn of
1019 // time.
1020 MachineInstrBuilder MIB = BuildMI(MBB, I, DebugLoc(), get(ARM::STMIA))
1021 .addFrameIndex(FI)
1022 .addMemOperand(MMO)
1024 AddDReg(MIB, SrcReg, ARM::gsub_0, getKillRegState(isKill));
1025 AddDReg(MIB, SrcReg, ARM::gsub_1, {});
1026 }
1027 } else
1028 llvm_unreachable("Unknown reg class!");
1029 break;
1030 case 16:
1031 if (ARM::DPairRegClass.hasSubClassEq(RC) && Subtarget.hasNEON()) {
1032 // Use aligned spills if the stack can be realigned.
1033 if (Alignment >= 16 && getRegisterInfo().canRealignStack(MF)) {
1034 BuildMI(MBB, I, DebugLoc(), get(ARM::VST1q64))
1035 .addFrameIndex(FI)
1036 .addImm(16)
1037 .addReg(SrcReg, getKillRegState(isKill))
1038 .addMemOperand(MMO)
1040 } else {
1041 BuildMI(MBB, I, DebugLoc(), get(ARM::VSTMQIA))
1042 .addReg(SrcReg, getKillRegState(isKill))
1043 .addFrameIndex(FI)
1044 .addMemOperand(MMO)
1046 }
1047 } else if (ARM::QPRRegClass.hasSubClassEq(RC) &&
1048 Subtarget.hasMVEIntegerOps()) {
1049 auto MIB = BuildMI(MBB, I, DebugLoc(), get(ARM::MVE_VSTRWU32));
1050 MIB.addReg(SrcReg, getKillRegState(isKill))
1051 .addFrameIndex(FI)
1052 .addImm(0)
1053 .addMemOperand(MMO);
1055 } else
1056 llvm_unreachable("Unknown reg class!");
1057 break;
1058 case 24:
1059 if (ARM::DTripleRegClass.hasSubClassEq(RC)) {
1060 // Use aligned spills if the stack can be realigned.
1061 if (Alignment >= 16 && getRegisterInfo().canRealignStack(MF) &&
1062 Subtarget.hasNEON()) {
1063 BuildMI(MBB, I, DebugLoc(), get(ARM::VST1d64TPseudo))
1064 .addFrameIndex(FI)
1065 .addImm(16)
1066 .addReg(SrcReg, getKillRegState(isKill))
1067 .addMemOperand(MMO)
1069 } else {
1071 get(ARM::VSTMDIA))
1072 .addFrameIndex(FI)
1074 .addMemOperand(MMO);
1075 MIB = AddDReg(MIB, SrcReg, ARM::dsub_0, getKillRegState(isKill));
1076 MIB = AddDReg(MIB, SrcReg, ARM::dsub_1, {});
1077 AddDReg(MIB, SrcReg, ARM::dsub_2, {});
1078 }
1079 } else
1080 llvm_unreachable("Unknown reg class!");
1081 break;
1082 case 32:
1083 if (ARM::QQPRRegClass.hasSubClassEq(RC) ||
1084 ARM::MQQPRRegClass.hasSubClassEq(RC) ||
1085 ARM::DQuadRegClass.hasSubClassEq(RC)) {
1086 if (Alignment >= 16 && getRegisterInfo().canRealignStack(MF) &&
1087 Subtarget.hasNEON()) {
1088 // FIXME: It's possible to only store part of the QQ register if the
1089 // spilled def has a sub-register index.
1090 BuildMI(MBB, I, DebugLoc(), get(ARM::VST1d64QPseudo))
1091 .addFrameIndex(FI)
1092 .addImm(16)
1093 .addReg(SrcReg, getKillRegState(isKill))
1094 .addMemOperand(MMO)
1096 } else if (Subtarget.hasMVEIntegerOps()) {
1097 BuildMI(MBB, I, DebugLoc(), get(ARM::MQQPRStore))
1098 .addReg(SrcReg, getKillRegState(isKill))
1099 .addFrameIndex(FI)
1100 .addMemOperand(MMO);
1101 } else {
1103 get(ARM::VSTMDIA))
1104 .addFrameIndex(FI)
1106 .addMemOperand(MMO);
1107 MIB = AddDReg(MIB, SrcReg, ARM::dsub_0, getKillRegState(isKill));
1108 MIB = AddDReg(MIB, SrcReg, ARM::dsub_1, {});
1109 MIB = AddDReg(MIB, SrcReg, ARM::dsub_2, {});
1110 AddDReg(MIB, SrcReg, ARM::dsub_3, {});
1111 }
1112 } else
1113 llvm_unreachable("Unknown reg class!");
1114 break;
1115 case 64:
1116 if (ARM::MQQQQPRRegClass.hasSubClassEq(RC) &&
1117 Subtarget.hasMVEIntegerOps()) {
1118 BuildMI(MBB, I, DebugLoc(), get(ARM::MQQQQPRStore))
1119 .addReg(SrcReg, getKillRegState(isKill))
1120 .addFrameIndex(FI)
1121 .addMemOperand(MMO);
1122 } else if (ARM::QQQQPRRegClass.hasSubClassEq(RC)) {
1123 MachineInstrBuilder MIB = BuildMI(MBB, I, DebugLoc(), get(ARM::VSTMDIA))
1124 .addFrameIndex(FI)
1126 .addMemOperand(MMO);
1127 MIB = AddDReg(MIB, SrcReg, ARM::dsub_0, getKillRegState(isKill));
1128 MIB = AddDReg(MIB, SrcReg, ARM::dsub_1, {});
1129 MIB = AddDReg(MIB, SrcReg, ARM::dsub_2, {});
1130 MIB = AddDReg(MIB, SrcReg, ARM::dsub_3, {});
1131 MIB = AddDReg(MIB, SrcReg, ARM::dsub_4, {});
1132 MIB = AddDReg(MIB, SrcReg, ARM::dsub_5, {});
1133 MIB = AddDReg(MIB, SrcReg, ARM::dsub_6, {});
1134 AddDReg(MIB, SrcReg, ARM::dsub_7, {});
1135 } else
1136 llvm_unreachable("Unknown reg class!");
1137 break;
1138 default:
1139 llvm_unreachable("Unknown reg class!");
1140 }
1141}
1142
1144 int &FrameIndex) const {
1145 switch (MI.getOpcode()) {
1146 default: break;
1147 case ARM::STRrs:
1148 case ARM::t2STRs: // FIXME: don't use t2STRs to access frame.
1149 if (MI.getOperand(1).isFI() && MI.getOperand(2).isReg() &&
1150 MI.getOperand(3).isImm() && MI.getOperand(2).getReg() == 0 &&
1151 MI.getOperand(3).getImm() == 0) {
1152 FrameIndex = MI.getOperand(1).getIndex();
1153 return MI.getOperand(0).getReg();
1154 }
1155 break;
1156 case ARM::STRi12:
1157 case ARM::t2STRi12:
1158 case ARM::tSTRspi:
1159 case ARM::VSTRD:
1160 case ARM::VSTRS:
1161 case ARM::VSTRH:
1162 case ARM::VSTR_P0_off:
1163 case ARM::VSTR_FPSCR_NZCVQC_off:
1164 case ARM::MVE_VSTRWU32:
1165 if (MI.getOperand(1).isFI() && MI.getOperand(2).isImm() &&
1166 MI.getOperand(2).getImm() == 0) {
1167 FrameIndex = MI.getOperand(1).getIndex();
1168 return MI.getOperand(0).getReg();
1169 }
1170 break;
1171 case ARM::VST1q64:
1172 case ARM::VST1d64TPseudo:
1173 case ARM::VST1d64QPseudo:
1174 if (MI.getOperand(0).isFI() && MI.getOperand(2).getSubReg() == 0) {
1175 FrameIndex = MI.getOperand(0).getIndex();
1176 return MI.getOperand(2).getReg();
1177 }
1178 break;
1179 case ARM::VSTMQIA:
1180 if (MI.getOperand(1).isFI() && MI.getOperand(0).getSubReg() == 0) {
1181 FrameIndex = MI.getOperand(1).getIndex();
1182 return MI.getOperand(0).getReg();
1183 }
1184 break;
1185 case ARM::MQQPRStore:
1186 case ARM::MQQQQPRStore:
1187 if (MI.getOperand(1).isFI()) {
1188 FrameIndex = MI.getOperand(1).getIndex();
1189 return MI.getOperand(0).getReg();
1190 }
1191 break;
1192 }
1193
1194 return 0;
1195}
1196
1198 int &FrameIndex) const {
1200 if (MI.mayStore() && hasStoreToStackSlot(MI, Accesses) &&
1201 Accesses.size() == 1) {
1202 FrameIndex =
1203 cast<FixedStackPseudoSourceValue>(Accesses.front()->getPseudoValue())
1204 ->getFrameIndex();
1205 return true;
1206 }
1207 return false;
1208}
1209
1212 Register DestReg, int FI,
1213 const TargetRegisterClass *RC,
1214 Register VReg, unsigned SubReg,
1215 MachineInstr::MIFlag Flags) const {
1216 DebugLoc DL;
1217 if (I != MBB.end()) DL = I->getDebugLoc();
1218 MachineFunction &MF = *MBB.getParent();
1219 MachineFrameInfo &MFI = MF.getFrameInfo();
1220 const Align Alignment = MFI.getObjectAlign(FI);
1223 MFI.getObjectSize(FI), Alignment);
1224
1226 switch (TRI.getSpillSize(*RC)) {
1227 case 2:
1228 if (ARM::HPRRegClass.hasSubClassEq(RC)) {
1229 BuildMI(MBB, I, DL, get(ARM::VLDRH), DestReg)
1230 .addFrameIndex(FI)
1231 .addImm(0)
1232 .addMemOperand(MMO)
1234 } else
1235 llvm_unreachable("Unknown reg class!");
1236 break;
1237 case 4:
1238 if (ARM::GPRRegClass.hasSubClassEq(RC)) {
1239 BuildMI(MBB, I, DL, get(ARM::LDRi12), DestReg)
1240 .addFrameIndex(FI)
1241 .addImm(0)
1242 .addMemOperand(MMO)
1244 } else if (ARM::SPRRegClass.hasSubClassEq(RC)) {
1245 BuildMI(MBB, I, DL, get(ARM::VLDRS), DestReg)
1246 .addFrameIndex(FI)
1247 .addImm(0)
1248 .addMemOperand(MMO)
1250 } else if (ARM::VCCRRegClass.hasSubClassEq(RC)) {
1251 BuildMI(MBB, I, DL, get(ARM::VLDR_P0_off), DestReg)
1252 .addFrameIndex(FI)
1253 .addImm(0)
1254 .addMemOperand(MMO)
1256 } else if (ARM::cl_FPSCR_NZCVRegClass.hasSubClassEq(RC)) {
1257 BuildMI(MBB, I, DL, get(ARM::VLDR_FPSCR_NZCVQC_off), DestReg)
1258 .addFrameIndex(FI)
1259 .addImm(0)
1260 .addMemOperand(MMO)
1262 } else
1263 llvm_unreachable("Unknown reg class!");
1264 break;
1265 case 8:
1266 if (ARM::DPRRegClass.hasSubClassEq(RC)) {
1267 BuildMI(MBB, I, DL, get(ARM::VLDRD), DestReg)
1268 .addFrameIndex(FI)
1269 .addImm(0)
1270 .addMemOperand(MMO)
1272 } else if (ARM::GPRPairRegClass.hasSubClassEq(RC)) {
1274
1275 if (Subtarget.hasV5TEOps()) {
1276 MIB = BuildMI(MBB, I, DL, get(ARM::LDRD));
1277 AddDReg(MIB, DestReg, ARM::gsub_0, RegState::DefineNoRead);
1278 AddDReg(MIB, DestReg, ARM::gsub_1, RegState::DefineNoRead);
1279 MIB.addFrameIndex(FI).addReg(0).addImm(0).addMemOperand(MMO)
1281 } else {
1282 // Fallback to LDM instruction, which has existed since the dawn of
1283 // time.
1284 MIB = BuildMI(MBB, I, DL, get(ARM::LDMIA))
1285 .addFrameIndex(FI)
1286 .addMemOperand(MMO)
1288 MIB = AddDReg(MIB, DestReg, ARM::gsub_0, RegState::DefineNoRead);
1289 MIB = AddDReg(MIB, DestReg, ARM::gsub_1, RegState::DefineNoRead);
1290 }
1291
1292 if (DestReg.isPhysical())
1293 MIB.addReg(DestReg, RegState::ImplicitDefine);
1294 } else
1295 llvm_unreachable("Unknown reg class!");
1296 break;
1297 case 16:
1298 if (ARM::DPairRegClass.hasSubClassEq(RC) && Subtarget.hasNEON()) {
1299 if (Alignment >= 16 && getRegisterInfo().canRealignStack(MF)) {
1300 BuildMI(MBB, I, DL, get(ARM::VLD1q64), DestReg)
1301 .addFrameIndex(FI)
1302 .addImm(16)
1303 .addMemOperand(MMO)
1305 } else {
1306 BuildMI(MBB, I, DL, get(ARM::VLDMQIA), DestReg)
1307 .addFrameIndex(FI)
1308 .addMemOperand(MMO)
1310 }
1311 } else if (ARM::QPRRegClass.hasSubClassEq(RC) &&
1312 Subtarget.hasMVEIntegerOps()) {
1313 auto MIB = BuildMI(MBB, I, DL, get(ARM::MVE_VLDRWU32), DestReg);
1314 MIB.addFrameIndex(FI)
1315 .addImm(0)
1316 .addMemOperand(MMO);
1318 } else
1319 llvm_unreachable("Unknown reg class!");
1320 break;
1321 case 24:
1322 if (ARM::DTripleRegClass.hasSubClassEq(RC)) {
1323 if (Alignment >= 16 && getRegisterInfo().canRealignStack(MF) &&
1324 Subtarget.hasNEON()) {
1325 BuildMI(MBB, I, DL, get(ARM::VLD1d64TPseudo), DestReg)
1326 .addFrameIndex(FI)
1327 .addImm(16)
1328 .addMemOperand(MMO)
1330 } else {
1331 MachineInstrBuilder MIB = BuildMI(MBB, I, DL, get(ARM::VLDMDIA))
1332 .addFrameIndex(FI)
1333 .addMemOperand(MMO)
1335 MIB = AddDReg(MIB, DestReg, ARM::dsub_0, RegState::DefineNoRead);
1336 MIB = AddDReg(MIB, DestReg, ARM::dsub_1, RegState::DefineNoRead);
1337 MIB = AddDReg(MIB, DestReg, ARM::dsub_2, RegState::DefineNoRead);
1338 if (DestReg.isPhysical())
1339 MIB.addReg(DestReg, RegState::ImplicitDefine);
1340 }
1341 } else
1342 llvm_unreachable("Unknown reg class!");
1343 break;
1344 case 32:
1345 if (ARM::QQPRRegClass.hasSubClassEq(RC) ||
1346 ARM::MQQPRRegClass.hasSubClassEq(RC) ||
1347 ARM::DQuadRegClass.hasSubClassEq(RC)) {
1348 if (Alignment >= 16 && getRegisterInfo().canRealignStack(MF) &&
1349 Subtarget.hasNEON()) {
1350 BuildMI(MBB, I, DL, get(ARM::VLD1d64QPseudo), DestReg)
1351 .addFrameIndex(FI)
1352 .addImm(16)
1353 .addMemOperand(MMO)
1355 } else if (Subtarget.hasMVEIntegerOps()) {
1356 BuildMI(MBB, I, DL, get(ARM::MQQPRLoad), DestReg)
1357 .addFrameIndex(FI)
1358 .addMemOperand(MMO);
1359 } else {
1360 MachineInstrBuilder MIB = BuildMI(MBB, I, DL, get(ARM::VLDMDIA))
1361 .addFrameIndex(FI)
1363 .addMemOperand(MMO);
1364 MIB = AddDReg(MIB, DestReg, ARM::dsub_0, RegState::DefineNoRead);
1365 MIB = AddDReg(MIB, DestReg, ARM::dsub_1, RegState::DefineNoRead);
1366 MIB = AddDReg(MIB, DestReg, ARM::dsub_2, RegState::DefineNoRead);
1367 MIB = AddDReg(MIB, DestReg, ARM::dsub_3, RegState::DefineNoRead);
1368 if (DestReg.isPhysical())
1369 MIB.addReg(DestReg, RegState::ImplicitDefine);
1370 }
1371 } else
1372 llvm_unreachable("Unknown reg class!");
1373 break;
1374 case 64:
1375 if (ARM::MQQQQPRRegClass.hasSubClassEq(RC) &&
1376 Subtarget.hasMVEIntegerOps()) {
1377 BuildMI(MBB, I, DL, get(ARM::MQQQQPRLoad), DestReg)
1378 .addFrameIndex(FI)
1379 .addMemOperand(MMO);
1380 } else if (ARM::QQQQPRRegClass.hasSubClassEq(RC)) {
1381 MachineInstrBuilder MIB = BuildMI(MBB, I, DL, get(ARM::VLDMDIA))
1382 .addFrameIndex(FI)
1384 .addMemOperand(MMO);
1385 MIB = AddDReg(MIB, DestReg, ARM::dsub_0, RegState::DefineNoRead);
1386 MIB = AddDReg(MIB, DestReg, ARM::dsub_1, RegState::DefineNoRead);
1387 MIB = AddDReg(MIB, DestReg, ARM::dsub_2, RegState::DefineNoRead);
1388 MIB = AddDReg(MIB, DestReg, ARM::dsub_3, RegState::DefineNoRead);
1389 MIB = AddDReg(MIB, DestReg, ARM::dsub_4, RegState::DefineNoRead);
1390 MIB = AddDReg(MIB, DestReg, ARM::dsub_5, RegState::DefineNoRead);
1391 MIB = AddDReg(MIB, DestReg, ARM::dsub_6, RegState::DefineNoRead);
1392 MIB = AddDReg(MIB, DestReg, ARM::dsub_7, RegState::DefineNoRead);
1393 if (DestReg.isPhysical())
1394 MIB.addReg(DestReg, RegState::ImplicitDefine);
1395 } else
1396 llvm_unreachable("Unknown reg class!");
1397 break;
1398 default:
1399 llvm_unreachable("Unknown regclass!");
1400 }
1401}
1402
1404 int &FrameIndex) const {
1405 switch (MI.getOpcode()) {
1406 default: break;
1407 case ARM::LDRrs:
1408 case ARM::t2LDRs: // FIXME: don't use t2LDRs to access frame.
1409 if (MI.getOperand(1).isFI() && MI.getOperand(2).isReg() &&
1410 MI.getOperand(3).isImm() && MI.getOperand(2).getReg() == 0 &&
1411 MI.getOperand(3).getImm() == 0) {
1412 FrameIndex = MI.getOperand(1).getIndex();
1413 return MI.getOperand(0).getReg();
1414 }
1415 break;
1416 case ARM::LDRi12:
1417 case ARM::t2LDRi12:
1418 case ARM::tLDRspi:
1419 case ARM::VLDRD:
1420 case ARM::VLDRS:
1421 case ARM::VLDRH:
1422 case ARM::VLDR_P0_off:
1423 case ARM::VLDR_FPSCR_NZCVQC_off:
1424 case ARM::MVE_VLDRWU32:
1425 if (MI.getOperand(1).isFI() && MI.getOperand(2).isImm() &&
1426 MI.getOperand(2).getImm() == 0) {
1427 FrameIndex = MI.getOperand(1).getIndex();
1428 return MI.getOperand(0).getReg();
1429 }
1430 break;
1431 case ARM::VLD1q64:
1432 case ARM::VLD1d8TPseudo:
1433 case ARM::VLD1d16TPseudo:
1434 case ARM::VLD1d32TPseudo:
1435 case ARM::VLD1d64TPseudo:
1436 case ARM::VLD1d8QPseudo:
1437 case ARM::VLD1d16QPseudo:
1438 case ARM::VLD1d32QPseudo:
1439 case ARM::VLD1d64QPseudo:
1440 if (MI.getOperand(1).isFI() && MI.getOperand(0).getSubReg() == 0) {
1441 FrameIndex = MI.getOperand(1).getIndex();
1442 return MI.getOperand(0).getReg();
1443 }
1444 break;
1445 case ARM::VLDMQIA:
1446 if (MI.getOperand(1).isFI() && MI.getOperand(0).getSubReg() == 0) {
1447 FrameIndex = MI.getOperand(1).getIndex();
1448 return MI.getOperand(0).getReg();
1449 }
1450 break;
1451 case ARM::MQQPRLoad:
1452 case ARM::MQQQQPRLoad:
1453 if (MI.getOperand(1).isFI()) {
1454 FrameIndex = MI.getOperand(1).getIndex();
1455 return MI.getOperand(0).getReg();
1456 }
1457 break;
1458 }
1459
1460 return 0;
1461}
1462
1464 int &FrameIndex) const {
1466 if (MI.mayLoad() && hasLoadFromStackSlot(MI, Accesses) &&
1467 Accesses.size() == 1) {
1468 FrameIndex =
1469 cast<FixedStackPseudoSourceValue>(Accesses.front()->getPseudoValue())
1470 ->getFrameIndex();
1471 return true;
1472 }
1473 return false;
1474}
1475
1476/// Expands MEMCPY to either LDMIA/STMIA or LDMIA_UPD/STMID_UPD
1477/// depending on whether the result is used.
1478void ARMBaseInstrInfo::expandMEMCPY(MachineBasicBlock::iterator MI) const {
1479 bool isThumb1 = Subtarget.isThumb1Only();
1480 bool isThumb2 = Subtarget.isThumb2();
1481 const ARMBaseInstrInfo *TII = Subtarget.getInstrInfo();
1482
1483 DebugLoc dl = MI->getDebugLoc();
1484 MachineBasicBlock *BB = MI->getParent();
1485
1486 MachineInstrBuilder LDM, STM;
1487 if (isThumb1 || !MI->getOperand(1).isDead()) {
1488 MachineOperand LDWb(MI->getOperand(1));
1489 LDM = BuildMI(*BB, MI, dl, TII->get(isThumb2 ? ARM::t2LDMIA_UPD
1490 : isThumb1 ? ARM::tLDMIA_UPD
1491 : ARM::LDMIA_UPD))
1492 .add(LDWb);
1493 } else {
1494 LDM = BuildMI(*BB, MI, dl, TII->get(isThumb2 ? ARM::t2LDMIA : ARM::LDMIA));
1495 }
1496
1497 if (isThumb1 || !MI->getOperand(0).isDead()) {
1498 MachineOperand STWb(MI->getOperand(0));
1499 STM = BuildMI(*BB, MI, dl, TII->get(isThumb2 ? ARM::t2STMIA_UPD
1500 : isThumb1 ? ARM::tSTMIA_UPD
1501 : ARM::STMIA_UPD))
1502 .add(STWb);
1503 } else {
1504 STM = BuildMI(*BB, MI, dl, TII->get(isThumb2 ? ARM::t2STMIA : ARM::STMIA));
1505 }
1506
1507 MachineOperand LDBase(MI->getOperand(3));
1508 LDM.add(LDBase).add(predOps(ARMCC::AL));
1509
1510 MachineOperand STBase(MI->getOperand(2));
1511 STM.add(STBase).add(predOps(ARMCC::AL));
1512
1513 // Sort the scratch registers into ascending order.
1514 const TargetRegisterInfo &TRI = getRegisterInfo();
1515 SmallVector<unsigned, 6> ScratchRegs;
1516 for (MachineOperand &MO : llvm::drop_begin(MI->operands(), 5))
1517 ScratchRegs.push_back(MO.getReg());
1518 llvm::sort(ScratchRegs,
1519 [&TRI](const unsigned &Reg1, const unsigned &Reg2) -> bool {
1520 return TRI.getEncodingValue(Reg1) <
1521 TRI.getEncodingValue(Reg2);
1522 });
1523
1524 for (const auto &Reg : ScratchRegs) {
1527 }
1528
1529 BB->erase(MI);
1530}
1531
1533 if (MI.getOpcode() == TargetOpcode::LOAD_STACK_GUARD) {
1534 expandLoadStackGuard(MI);
1535 MI.getParent()->erase(MI);
1536 return true;
1537 }
1538
1539 if (MI.getOpcode() == ARM::MEMCPY) {
1540 expandMEMCPY(MI);
1541 return true;
1542 }
1543
1544 // This hook gets to expand COPY instructions before they become
1545 // copyPhysReg() calls. Look for VMOVS instructions that can legally be
1546 // widened to VMOVD. We prefer the VMOVD when possible because it may be
1547 // changed into a VORR that can go down the NEON pipeline.
1548 if (!MI.isCopy() || Subtarget.dontWidenVMOVS() || !Subtarget.hasFP64())
1549 return false;
1550
1551 // Look for a copy between even S-registers. That is where we keep floats
1552 // when using NEON v2f32 instructions for f32 arithmetic.
1553 Register DstRegS = MI.getOperand(0).getReg();
1554 Register SrcRegS = MI.getOperand(1).getReg();
1555 if (!ARM::SPRRegClass.contains(DstRegS, SrcRegS))
1556 return false;
1557
1559 MCRegister DstRegD =
1560 TRI->getMatchingSuperReg(DstRegS, ARM::ssub_0, &ARM::DPRRegClass);
1561 MCRegister SrcRegD =
1562 TRI->getMatchingSuperReg(SrcRegS, ARM::ssub_0, &ARM::DPRRegClass);
1563 if (!DstRegD || !SrcRegD)
1564 return false;
1565
1566 // We want to widen this into a DstRegD = VMOVD SrcRegD copy. This is only
1567 // legal if the COPY already defines the full DstRegD, and it isn't a
1568 // sub-register insertion.
1569 if (!MI.definesRegister(DstRegD, TRI) || MI.readsRegister(DstRegD, TRI))
1570 return false;
1571
1572 // A dead copy shouldn't show up here, but reject it just in case.
1573 if (MI.getOperand(0).isDead())
1574 return false;
1575
1576 // All clear, widen the COPY.
1577 LLVM_DEBUG(dbgs() << "widening: " << MI);
1578 MachineInstrBuilder MIB(*MI.getParent()->getParent(), MI);
1579
1580 // Get rid of the old implicit-def of DstRegD. Leave it if it defines a Q-reg
1581 // or some other super-register.
1582 int ImpDefIdx = MI.findRegisterDefOperandIdx(DstRegD, /*TRI=*/nullptr);
1583 if (ImpDefIdx != -1)
1584 MI.removeOperand(ImpDefIdx);
1585
1586 // Change the opcode and operands.
1587 MI.setDesc(get(ARM::VMOVD));
1588 MI.getOperand(0).setReg(DstRegD);
1589 MI.getOperand(1).setReg(SrcRegD);
1590 MIB.add(predOps(ARMCC::AL));
1591
1592 // We are now reading SrcRegD instead of SrcRegS. This may upset the
1593 // register scavenger and machine verifier, so we need to indicate that we
1594 // are reading an undefined value from SrcRegD, but a proper value from
1595 // SrcRegS.
1596 MI.getOperand(1).setIsUndef();
1597 MIB.addReg(SrcRegS, RegState::Implicit);
1598
1599 // SrcRegD may actually contain an unrelated value in the ssub_1
1600 // sub-register. Don't kill it. Only kill the ssub_0 sub-register.
1601 if (MI.getOperand(1).isKill()) {
1602 MI.getOperand(1).setIsKill(false);
1603 MI.addRegisterKilled(SrcRegS, TRI, true);
1604 }
1605
1606 LLVM_DEBUG(dbgs() << "replaced by: " << MI);
1607 return true;
1608}
1609
1610/// Create a copy of a const pool value. Update CPI to the new index and return
1611/// the label UID.
1612static unsigned duplicateCPV(MachineFunction &MF, unsigned &CPI) {
1615
1616 const MachineConstantPoolEntry &MCPE = MCP->getConstants()[CPI];
1617 assert(MCPE.isMachineConstantPoolEntry() &&
1618 "Expecting a machine constantpool entry!");
1619 ARMConstantPoolValue *ACPV =
1620 static_cast<ARMConstantPoolValue*>(MCPE.Val.MachineCPVal);
1621
1622 unsigned PCLabelId = AFI->createPICLabelUId();
1623 ARMConstantPoolValue *NewCPV = nullptr;
1624
1625 // FIXME: The below assumes PIC relocation model and that the function
1626 // is Thumb mode (t1 or t2). PCAdjustment would be 8 for ARM mode PIC, and
1627 // zero for non-PIC in ARM or Thumb. The callers are all of thumb LDR
1628 // instructions, so that's probably OK, but is PIC always correct when
1629 // we get here?
1630 if (ACPV->isGlobalValue())
1632 cast<ARMConstantPoolConstant>(ACPV)->getGV(), PCLabelId, ARMCP::CPValue,
1633 4, ACPV->getModifier(), ACPV->mustAddCurrentAddress());
1634 else if (ACPV->isExtSymbol())
1637 cast<ARMConstantPoolSymbol>(ACPV)->getSymbol(), PCLabelId, 4);
1638 else if (ACPV->isBlockAddress())
1640 Create(cast<ARMConstantPoolConstant>(ACPV)->getBlockAddress(), PCLabelId,
1642 else if (ACPV->isLSDA())
1643 NewCPV = ARMConstantPoolConstant::Create(&MF.getFunction(), PCLabelId,
1644 ARMCP::CPLSDA, 4);
1645 else if (ACPV->isMachineBasicBlock())
1646 NewCPV = ARMConstantPoolMBB::
1648 cast<ARMConstantPoolMBB>(ACPV)->getMBB(), PCLabelId, 4);
1649 else
1650 llvm_unreachable("Unexpected ARM constantpool value type!!");
1651 CPI = MCP->getConstantPoolIndex(NewCPV, MCPE.getAlign());
1652 return PCLabelId;
1653}
1654
1657 Register DestReg, unsigned SubIdx,
1658 const MachineInstr &Orig,
1659 LaneBitmask UsedLanes) const {
1660 unsigned Opcode = Orig.getOpcode();
1661 switch (Opcode) {
1662 default: {
1663 MachineInstr *MI = MBB.getParent()->CloneMachineInstr(&Orig);
1664 MI->substituteRegister(Orig.getOperand(0).getReg(), DestReg, SubIdx, TRI);
1665 MBB.insert(I, MI);
1666 break;
1667 }
1668 case ARM::tLDRpci_pic:
1669 case ARM::t2LDRpci_pic: {
1670 MachineFunction &MF = *MBB.getParent();
1671 unsigned CPI = Orig.getOperand(1).getIndex();
1672 unsigned PCLabelId = duplicateCPV(MF, CPI);
1673 BuildMI(MBB, I, Orig.getDebugLoc(), get(Opcode), DestReg)
1675 .addImm(PCLabelId)
1676 .cloneMemRefs(Orig);
1677 break;
1678 }
1679 }
1680}
1681
1684 MachineBasicBlock::iterator InsertBefore,
1685 const MachineInstr &Orig) const {
1686 MachineInstr &Cloned = TargetInstrInfo::duplicate(MBB, InsertBefore, Orig);
1688 for (;;) {
1689 switch (I->getOpcode()) {
1690 case ARM::tLDRpci_pic:
1691 case ARM::t2LDRpci_pic: {
1692 MachineFunction &MF = *MBB.getParent();
1693 unsigned CPI = I->getOperand(1).getIndex();
1694 unsigned PCLabelId = duplicateCPV(MF, CPI);
1695 I->getOperand(1).setIndex(CPI);
1696 I->getOperand(2).setImm(PCLabelId);
1697 break;
1698 }
1699 }
1700 if (!I->isBundledWithSucc())
1701 break;
1702 ++I;
1703 }
1704 return Cloned;
1705}
1706
1708 const MachineInstr &MI1,
1709 const MachineRegisterInfo *MRI) const {
1710 unsigned Opcode = MI0.getOpcode();
1711 if (Opcode == ARM::t2LDRpci || Opcode == ARM::t2LDRpci_pic ||
1712 Opcode == ARM::tLDRpci || Opcode == ARM::tLDRpci_pic ||
1713 Opcode == ARM::LDRLIT_ga_pcrel || Opcode == ARM::LDRLIT_ga_pcrel_ldr ||
1714 Opcode == ARM::tLDRLIT_ga_pcrel || Opcode == ARM::t2LDRLIT_ga_pcrel ||
1715 Opcode == ARM::MOV_ga_pcrel || Opcode == ARM::MOV_ga_pcrel_ldr ||
1716 Opcode == ARM::t2MOV_ga_pcrel) {
1717 if (MI1.getOpcode() != Opcode)
1718 return false;
1719 if (MI0.getNumOperands() != MI1.getNumOperands())
1720 return false;
1721
1722 const MachineOperand &MO0 = MI0.getOperand(1);
1723 const MachineOperand &MO1 = MI1.getOperand(1);
1724 if (MO0.getOffset() != MO1.getOffset())
1725 return false;
1726
1727 if (Opcode == ARM::LDRLIT_ga_pcrel || Opcode == ARM::LDRLIT_ga_pcrel_ldr ||
1728 Opcode == ARM::tLDRLIT_ga_pcrel || Opcode == ARM::t2LDRLIT_ga_pcrel ||
1729 Opcode == ARM::MOV_ga_pcrel || Opcode == ARM::MOV_ga_pcrel_ldr ||
1730 Opcode == ARM::t2MOV_ga_pcrel)
1731 // Ignore the PC labels.
1732 return MO0.getGlobal() == MO1.getGlobal();
1733
1734 const MachineFunction *MF = MI0.getParent()->getParent();
1735 const MachineConstantPool *MCP = MF->getConstantPool();
1736 int CPI0 = MO0.getIndex();
1737 int CPI1 = MO1.getIndex();
1738 const MachineConstantPoolEntry &MCPE0 = MCP->getConstants()[CPI0];
1739 const MachineConstantPoolEntry &MCPE1 = MCP->getConstants()[CPI1];
1740 bool isARMCP0 = MCPE0.isMachineConstantPoolEntry();
1741 bool isARMCP1 = MCPE1.isMachineConstantPoolEntry();
1742 if (isARMCP0 && isARMCP1) {
1743 ARMConstantPoolValue *ACPV0 =
1744 static_cast<ARMConstantPoolValue*>(MCPE0.Val.MachineCPVal);
1745 ARMConstantPoolValue *ACPV1 =
1746 static_cast<ARMConstantPoolValue*>(MCPE1.Val.MachineCPVal);
1747 return ACPV0->hasSameValue(ACPV1);
1748 } else if (!isARMCP0 && !isARMCP1) {
1749 return MCPE0.Val.ConstVal == MCPE1.Val.ConstVal;
1750 }
1751 return false;
1752 } else if (Opcode == ARM::PICLDR) {
1753 if (MI1.getOpcode() != Opcode)
1754 return false;
1755 if (MI0.getNumOperands() != MI1.getNumOperands())
1756 return false;
1757
1758 Register Addr0 = MI0.getOperand(1).getReg();
1759 Register Addr1 = MI1.getOperand(1).getReg();
1760 if (Addr0 != Addr1) {
1761 if (!MRI || !Addr0.isVirtual() || !Addr1.isVirtual())
1762 return false;
1763
1764 // This assumes SSA form.
1765 MachineInstr *Def0 = MRI->getVRegDef(Addr0);
1766 MachineInstr *Def1 = MRI->getVRegDef(Addr1);
1767 // Check if the loaded value, e.g. a constantpool of a global address, are
1768 // the same.
1769 if (!produceSameValue(*Def0, *Def1, MRI))
1770 return false;
1771 }
1772
1773 for (unsigned i = 3, e = MI0.getNumOperands(); i != e; ++i) {
1774 // %12 = PICLDR %11, 0, 14, %noreg
1775 const MachineOperand &MO0 = MI0.getOperand(i);
1776 const MachineOperand &MO1 = MI1.getOperand(i);
1777 if (!MO0.isIdenticalTo(MO1))
1778 return false;
1779 }
1780 return true;
1781 }
1782
1784}
1785
1786/// areLoadsFromSameBasePtr - This is used by the pre-regalloc scheduler to
1787/// determine if two loads are loading from the same base address. It should
1788/// only return true if the base pointers are the same and the only differences
1789/// between the two addresses is the offset. It also returns the offsets by
1790/// reference.
1791///
1792/// FIXME: remove this in favor of the MachineInstr interface once pre-RA-sched
1793/// is permanently disabled.
1795 int64_t &Offset1,
1796 int64_t &Offset2) const {
1797 // Don't worry about Thumb: just ARM and Thumb2.
1798 if (Subtarget.isThumb1Only()) return false;
1799
1800 if (!Load1->isMachineOpcode() || !Load2->isMachineOpcode())
1801 return false;
1802
1803 auto IsLoadOpcode = [&](unsigned Opcode) {
1804 switch (Opcode) {
1805 default:
1806 return false;
1807 case ARM::LDRi12:
1808 case ARM::LDRBi12:
1809 case ARM::LDRD:
1810 case ARM::LDRH:
1811 case ARM::LDRSB:
1812 case ARM::LDRSH:
1813 case ARM::VLDRD:
1814 case ARM::VLDRS:
1815 case ARM::t2LDRi8:
1816 case ARM::t2LDRBi8:
1817 case ARM::t2LDRDi8:
1818 case ARM::t2LDRSHi8:
1819 case ARM::t2LDRi12:
1820 case ARM::t2LDRBi12:
1821 case ARM::t2LDRSHi12:
1822 return true;
1823 }
1824 };
1825
1826 if (!IsLoadOpcode(Load1->getMachineOpcode()) ||
1827 !IsLoadOpcode(Load2->getMachineOpcode()))
1828 return false;
1829
1830 // Check if base addresses and chain operands match.
1831 if (Load1->getOperand(0) != Load2->getOperand(0) ||
1832 Load1->getOperand(4) != Load2->getOperand(4))
1833 return false;
1834
1835 // Index should be Reg0.
1836 if (Load1->getOperand(3) != Load2->getOperand(3))
1837 return false;
1838
1839 // Determine the offsets.
1840 if (isa<ConstantSDNode>(Load1->getOperand(1)) &&
1841 isa<ConstantSDNode>(Load2->getOperand(1))) {
1842 Offset1 = cast<ConstantSDNode>(Load1->getOperand(1))->getSExtValue();
1843 Offset2 = cast<ConstantSDNode>(Load2->getOperand(1))->getSExtValue();
1844 return true;
1845 }
1846
1847 return false;
1848}
1849
1850/// shouldScheduleLoadsNear - This is a used by the pre-regalloc scheduler to
1851/// determine (in conjunction with areLoadsFromSameBasePtr) if two loads should
1852/// be scheduled together. On some targets if two loads are loading from
1853/// addresses in the same cache line, it's better if they are scheduled
1854/// together. This function takes two integers that represent the load offsets
1855/// from the common base address. It returns true if it decides it's desirable
1856/// to schedule the two loads together. "NumLoads" is the number of loads that
1857/// have already been scheduled after Load1.
1858///
1859/// FIXME: remove this in favor of the MachineInstr interface once pre-RA-sched
1860/// is permanently disabled.
1862 int64_t Offset1, int64_t Offset2,
1863 unsigned NumLoads) const {
1864 // Don't worry about Thumb: just ARM and Thumb2.
1865 if (Subtarget.isThumb1Only()) return false;
1866
1867 assert(Offset2 > Offset1);
1868
1869 if ((Offset2 - Offset1) / 8 > 64)
1870 return false;
1871
1872 // Check if the machine opcodes are different. If they are different
1873 // then we consider them to not be of the same base address,
1874 // EXCEPT in the case of Thumb2 byte loads where one is LDRBi8 and the other LDRBi12.
1875 // In this case, they are considered to be the same because they are different
1876 // encoding forms of the same basic instruction.
1877 if ((Load1->getMachineOpcode() != Load2->getMachineOpcode()) &&
1878 !((Load1->getMachineOpcode() == ARM::t2LDRBi8 &&
1879 Load2->getMachineOpcode() == ARM::t2LDRBi12) ||
1880 (Load1->getMachineOpcode() == ARM::t2LDRBi12 &&
1881 Load2->getMachineOpcode() == ARM::t2LDRBi8)))
1882 return false; // FIXME: overly conservative?
1883
1884 // Four loads in a row should be sufficient.
1885 if (NumLoads >= 3)
1886 return false;
1887
1888 return true;
1889}
1890
1892 const MachineBasicBlock *MBB,
1893 const MachineFunction &MF) const {
1894 // Debug info is never a scheduling boundary. It's necessary to be explicit
1895 // due to the special treatment of IT instructions below, otherwise a
1896 // dbg_value followed by an IT will result in the IT instruction being
1897 // considered a scheduling hazard, which is wrong. It should be the actual
1898 // instruction preceding the dbg_value instruction(s), just like it is
1899 // when debug info is not present.
1900 if (MI.isDebugInstr())
1901 return false;
1902
1903 // Terminators and labels can't be scheduled around.
1904 if (MI.isTerminator() || MI.isPosition())
1905 return true;
1906
1907 // INLINEASM_BR can jump to another block
1908 if (MI.getOpcode() == TargetOpcode::INLINEASM_BR)
1909 return true;
1910
1911 if (isSEHInstruction(MI))
1912 return true;
1913
1914 // Treat the start of the IT block as a scheduling boundary, but schedule
1915 // t2IT along with all instructions following it.
1916 // FIXME: This is a big hammer. But the alternative is to add all potential
1917 // true and anti dependencies to IT block instructions as implicit operands
1918 // to the t2IT instruction. The added compile time and complexity does not
1919 // seem worth it.
1921 // Make sure to skip any debug instructions
1922 while (++I != MBB->end() && I->isDebugInstr())
1923 ;
1924 if (I != MBB->end() && I->getOpcode() == ARM::t2IT)
1925 return true;
1926
1927 // Don't attempt to schedule around any instruction that defines
1928 // a stack-oriented pointer, as it's unlikely to be profitable. This
1929 // saves compile time, because it doesn't require every single
1930 // stack slot reference to depend on the instruction that does the
1931 // modification.
1932 // Calls don't actually change the stack pointer, even if they have imp-defs.
1933 // No ARM calling conventions change the stack pointer. (X86 calling
1934 // conventions sometimes do).
1935 if (!MI.isCall() && MI.definesRegister(ARM::SP, /*TRI=*/nullptr))
1936 return true;
1937
1938 return false;
1939}
1940
1943 unsigned NumCycles, unsigned ExtraPredCycles,
1944 BranchProbability Probability) const {
1945 if (!NumCycles)
1946 return false;
1947
1948 // If we are optimizing for size, see if the branch in the predecessor can be
1949 // lowered to cbn?z by the constant island lowering pass, and return false if
1950 // so. This results in a shorter instruction sequence.
1951 if (MBB.getParent()->getFunction().hasOptSize()) {
1952 MachineBasicBlock *Pred = *MBB.pred_begin();
1953 if (!Pred->empty()) {
1954 MachineInstr *LastMI = &*Pred->rbegin();
1955 if (LastMI->getOpcode() == ARM::t2Bcc) {
1957 MachineInstr *CmpMI = findCMPToFoldIntoCBZ(LastMI, TRI);
1958 if (CmpMI)
1959 return false;
1960 }
1961 }
1962 }
1963 return isProfitableToIfCvt(MBB, NumCycles, ExtraPredCycles,
1964 MBB, 0, 0, Probability);
1965}
1966
1969 unsigned TCycles, unsigned TExtra,
1970 MachineBasicBlock &FBB,
1971 unsigned FCycles, unsigned FExtra,
1972 BranchProbability Probability) const {
1973 if (!TCycles)
1974 return false;
1975
1976 // In thumb code we often end up trading one branch for a IT block, and
1977 // if we are cloning the instruction can increase code size. Prevent
1978 // blocks with multiple predecessors from being ifcvted to prevent this
1979 // cloning.
1980 if (Subtarget.isThumb2() && TBB.getParent()->getFunction().hasMinSize()) {
1981 if (TBB.pred_size() != 1 || FBB.pred_size() != 1)
1982 return false;
1983 }
1984
1985 // Attempt to estimate the relative costs of predication versus branching.
1986 // Here we scale up each component of UnpredCost to avoid precision issue when
1987 // scaling TCycles/FCycles by Probability.
1988 const unsigned ScalingUpFactor = 1024;
1989
1990 unsigned PredCost = (TCycles + FCycles + TExtra + FExtra) * ScalingUpFactor;
1991 unsigned UnpredCost;
1992 if (!Subtarget.hasBranchPredictor()) {
1993 // When we don't have a branch predictor it's always cheaper to not take a
1994 // branch than take it, so we have to take that into account.
1995 unsigned NotTakenBranchCost = 1;
1996 unsigned TakenBranchCost = Subtarget.getMispredictionPenalty();
1997 unsigned TUnpredCycles, FUnpredCycles;
1998 if (!FCycles) {
1999 // Triangle: TBB is the fallthrough
2000 TUnpredCycles = TCycles + NotTakenBranchCost;
2001 FUnpredCycles = TakenBranchCost;
2002 } else {
2003 // Diamond: TBB is the block that is branched to, FBB is the fallthrough
2004 TUnpredCycles = TCycles + TakenBranchCost;
2005 FUnpredCycles = FCycles + NotTakenBranchCost;
2006 // The branch at the end of FBB will disappear when it's predicated, so
2007 // discount it from PredCost.
2008 PredCost -= 1 * ScalingUpFactor;
2009 }
2010 // The total cost is the cost of each path scaled by their probabilities
2011 unsigned TUnpredCost = Probability.scale(TUnpredCycles * ScalingUpFactor);
2012 unsigned FUnpredCost = Probability.getCompl().scale(FUnpredCycles * ScalingUpFactor);
2013 UnpredCost = TUnpredCost + FUnpredCost;
2014 // When predicating assume that the first IT can be folded away but later
2015 // ones cost one cycle each
2016 if (Subtarget.isThumb2() && TCycles + FCycles > 4) {
2017 PredCost += ((TCycles + FCycles - 4) / 4) * ScalingUpFactor;
2018 }
2019 } else {
2020 unsigned TUnpredCost = Probability.scale(TCycles * ScalingUpFactor);
2021 unsigned FUnpredCost =
2022 Probability.getCompl().scale(FCycles * ScalingUpFactor);
2023 UnpredCost = TUnpredCost + FUnpredCost;
2024 UnpredCost += 1 * ScalingUpFactor; // The branch itself
2025 UnpredCost += Subtarget.getMispredictionPenalty() * ScalingUpFactor / 10;
2026 }
2027
2028 return PredCost <= UnpredCost;
2029}
2030
2031unsigned
2033 unsigned NumInsts) const {
2034 // Thumb2 needs a 2-byte IT instruction to predicate up to 4 instructions.
2035 // ARM has a condition code field in every predicable instruction, using it
2036 // doesn't change code size.
2037 if (!Subtarget.isThumb2())
2038 return 0;
2039
2040 // It's possible that the size of the IT is restricted to a single block.
2041 unsigned MaxInsts = Subtarget.restrictIT() ? 1 : 4;
2042 return divideCeil(NumInsts, MaxInsts) * 2;
2043}
2044
2045unsigned
2047 // If this branch is likely to be folded into the comparison to form a
2048 // CB(N)Z, then removing it won't reduce code size at all, because that will
2049 // just replace the CB(N)Z with a CMP.
2050 if (MI.getOpcode() == ARM::t2Bcc &&
2052 return 0;
2053
2054 unsigned Size = getInstSizeInBytes(MI);
2055
2056 // For Thumb2, all branches are 32-bit instructions during the if conversion
2057 // pass, but may be replaced with 16-bit instructions during size reduction.
2058 // Since the branches considered by if conversion tend to be forward branches
2059 // over small basic blocks, they are very likely to be in range for the
2060 // narrow instructions, so we assume the final code size will be half what it
2061 // currently is.
2062 if (Subtarget.isThumb2())
2063 Size /= 2;
2064
2065 return Size;
2066}
2067
2068bool
2070 MachineBasicBlock &FMBB) const {
2071 // Reduce false anti-dependencies to let the target's out-of-order execution
2072 // engine do its thing.
2073 return Subtarget.isProfitableToUnpredicate();
2074}
2075
2076/// getInstrPredicate - If instruction is predicated, returns its predicate
2077/// condition, otherwise returns AL. It also returns the condition code
2078/// register by reference.
2080 Register &PredReg) {
2081 int PIdx = MI.findFirstPredOperandIdx();
2082 if (PIdx == -1) {
2083 PredReg = 0;
2084 return ARMCC::AL;
2085 }
2086
2087 PredReg = MI.getOperand(PIdx+1).getReg();
2088 return (ARMCC::CondCodes)MI.getOperand(PIdx).getImm();
2089}
2090
2092 if (Opc == ARM::B)
2093 return ARM::Bcc;
2094 if (Opc == ARM::tB)
2095 return ARM::tBcc;
2096 if (Opc == ARM::t2B)
2097 return ARM::t2Bcc;
2098
2099 llvm_unreachable("Unknown unconditional branch opcode!");
2100}
2101
2103 bool NewMI,
2104 unsigned OpIdx1,
2105 unsigned OpIdx2) const {
2106 switch (MI.getOpcode()) {
2107 case ARM::MOVCCr:
2108 case ARM::t2MOVCCr: {
2109 // MOVCC can be commuted by inverting the condition.
2110 Register PredReg;
2111 ARMCC::CondCodes CC = getInstrPredicate(MI, PredReg);
2112 // MOVCC AL can't be inverted. Shouldn't happen.
2113 if (CC == ARMCC::AL || PredReg != ARM::CPSR)
2114 return nullptr;
2115 MachineInstr *CommutedMI =
2116 TargetInstrInfo::commuteInstructionImpl(MI, NewMI, OpIdx1, OpIdx2);
2117 if (!CommutedMI)
2118 return nullptr;
2119 // After swapping the MOVCC operands, also invert the condition.
2120 CommutedMI->getOperand(CommutedMI->findFirstPredOperandIdx())
2122 return CommutedMI;
2123 }
2124 }
2125 return TargetInstrInfo::commuteInstructionImpl(MI, NewMI, OpIdx1, OpIdx2);
2126}
2127
2128/// Identify instructions that can be folded into a MOVCC instruction, and
2129/// return the defining instruction.
2131ARMBaseInstrInfo::canFoldIntoMOVCC(Register Reg, const MachineRegisterInfo &MRI,
2132 const TargetInstrInfo *TII) const {
2133 if (!Reg.isVirtual())
2134 return nullptr;
2135 if (!MRI.hasOneNonDBGUse(Reg))
2136 return nullptr;
2137 MachineInstr *MI = MRI.getVRegDef(Reg);
2138 if (!MI)
2139 return nullptr;
2140 // Check if MI can be predicated and folded into the MOVCC.
2141 if (!isPredicable(*MI))
2142 return nullptr;
2143 // Check if MI has any non-dead defs or physreg uses. This also detects
2144 // predicated instructions which will be reading CPSR.
2145 for (const MachineOperand &MO : llvm::drop_begin(MI->operands(), 1)) {
2146 // Reject frame index operands, PEI can't handle the predicated pseudos.
2147 if (MO.isFI() || MO.isCPI() || MO.isJTI())
2148 return nullptr;
2149 if (!MO.isReg())
2150 continue;
2151 // MI can't have any tied operands, that would conflict with predication.
2152 if (MO.isTied())
2153 return nullptr;
2154 if (MO.getReg().isPhysical())
2155 return nullptr;
2156 if (MO.isDef() && !MO.isDead())
2157 return nullptr;
2158 }
2159 bool DontMoveAcrossStores = true;
2160 if (!MI->isSafeToMove(DontMoveAcrossStores))
2161 return nullptr;
2162 return MI;
2163}
2164
2168 bool PreferFalse) const {
2169 assert((MI.getOpcode() == ARM::MOVCCr || MI.getOpcode() == ARM::t2MOVCCr) &&
2170 "Unknown select instruction");
2171 MachineRegisterInfo &MRI = MI.getParent()->getParent()->getRegInfo();
2172 MachineInstr *DefMI = canFoldIntoMOVCC(MI.getOperand(2).getReg(), MRI, this);
2173 bool Invert = !DefMI;
2174 if (!DefMI)
2175 DefMI = canFoldIntoMOVCC(MI.getOperand(1).getReg(), MRI, this);
2176 if (!DefMI)
2177 return nullptr;
2178
2179 // Find new register class to use.
2180 MachineOperand FalseReg = MI.getOperand(Invert ? 2 : 1);
2181 MachineOperand TrueReg = MI.getOperand(Invert ? 1 : 2);
2182 Register DestReg = MI.getOperand(0).getReg();
2183 const TargetRegisterClass *FalseClass = MRI.getRegClass(FalseReg.getReg());
2184 const TargetRegisterClass *TrueClass = MRI.getRegClass(TrueReg.getReg());
2185 if (!MRI.constrainRegClass(DestReg, FalseClass))
2186 return nullptr;
2187 if (!MRI.constrainRegClass(DestReg, TrueClass))
2188 return nullptr;
2189
2190 // Create a new predicated version of DefMI.
2191 // Rfalse is the first use.
2192 MachineInstrBuilder NewMI =
2193 BuildMI(*MI.getParent(), MI, MI.getDebugLoc(), DefMI->getDesc(), DestReg);
2194
2195 // Copy all the DefMI operands, excluding its (null) predicate.
2196 const MCInstrDesc &DefDesc = DefMI->getDesc();
2197 for (unsigned i = 1, e = DefDesc.getNumOperands();
2198 i != e && !DefDesc.operands()[i].isPredicate(); ++i)
2199 NewMI.add(DefMI->getOperand(i));
2200
2201 unsigned CondCode = MI.getOperand(3).getImm();
2202 if (Invert)
2204 else
2205 NewMI.addImm(CondCode);
2206 NewMI.add(MI.getOperand(4));
2207
2208 // DefMI is not the -S version that sets CPSR, so add an optional %noreg.
2209 if (NewMI->hasOptionalDef())
2210 NewMI.add(condCodeOp());
2211
2212 // The output register value when the predicate is false is an implicit
2213 // register operand tied to the first def.
2214 // The tie makes the register allocator ensure the FalseReg is allocated the
2215 // same register as operand 0.
2216 FalseReg.setImplicit();
2217 NewMI.add(FalseReg);
2218 NewMI->tieOperands(0, NewMI->getNumOperands() - 1);
2219
2220 // Update SeenMIs set: register newly created MI and erase removed DefMI.
2221 SeenMIs.insert(NewMI);
2222 SeenMIs.erase(DefMI);
2223
2224 // If MI is inside a loop, and DefMI is outside the loop, then kill flags on
2225 // DefMI would be invalid when transferred inside the loop. Checking for a
2226 // loop is expensive, but at least remove kill flags if they are in different
2227 // BBs.
2228 if (DefMI->getParent() != MI.getParent())
2229 NewMI->clearKillInfo();
2230
2231 // The caller will erase MI, but not DefMI.
2232 DefMI->eraseFromParent();
2233 return NewMI;
2234}
2235
2236/// Map pseudo instructions that imply an 'S' bit onto real opcodes. Whether the
2237/// instruction is encoded with an 'S' bit is determined by the optional CPSR
2238/// def operand.
2239///
2240/// This will go away once we can teach tblgen how to set the optional CPSR def
2241/// operand itself.
2243 uint16_t PseudoOpc;
2244 uint16_t MachineOpc;
2245};
2246
2248 {ARM::ADDSri, ARM::ADDri},
2249 {ARM::ADDSrr, ARM::ADDrr},
2250 {ARM::ADDSrsi, ARM::ADDrsi},
2251 {ARM::ADDSrsr, ARM::ADDrsr},
2252
2253 {ARM::SUBSri, ARM::SUBri},
2254 {ARM::SUBSrr, ARM::SUBrr},
2255 {ARM::SUBSrsi, ARM::SUBrsi},
2256 {ARM::SUBSrsr, ARM::SUBrsr},
2257
2258 {ARM::RSBSri, ARM::RSBri},
2259 {ARM::RSBSrsi, ARM::RSBrsi},
2260 {ARM::RSBSrsr, ARM::RSBrsr},
2261
2262 {ARM::tADDSi3, ARM::tADDi3},
2263 {ARM::tADDSi8, ARM::tADDi8},
2264 {ARM::tADDSrr, ARM::tADDrr},
2265 {ARM::tADCS, ARM::tADC},
2266
2267 {ARM::tSUBSi3, ARM::tSUBi3},
2268 {ARM::tSUBSi8, ARM::tSUBi8},
2269 {ARM::tSUBSrr, ARM::tSUBrr},
2270 {ARM::tSBCS, ARM::tSBC},
2271 {ARM::tRSBS, ARM::tRSB},
2272 {ARM::tLSLSri, ARM::tLSLri},
2273
2274 {ARM::t2ADDSri, ARM::t2ADDri},
2275 {ARM::t2ADDSrr, ARM::t2ADDrr},
2276 {ARM::t2ADDSrs, ARM::t2ADDrs},
2277
2278 {ARM::t2SUBSri, ARM::t2SUBri},
2279 {ARM::t2SUBSrr, ARM::t2SUBrr},
2280 {ARM::t2SUBSrs, ARM::t2SUBrs},
2281
2282 {ARM::t2RSBSri, ARM::t2RSBri},
2283 {ARM::t2RSBSrs, ARM::t2RSBrs},
2284};
2285
2286unsigned llvm::convertAddSubFlagsOpcode(unsigned OldOpc) {
2287 for (const auto &Entry : AddSubFlagsOpcodeMap)
2288 if (OldOpc == Entry.PseudoOpc)
2289 return Entry.MachineOpc;
2290 return 0;
2291}
2292
2295 const DebugLoc &dl, Register DestReg,
2296 Register BaseReg, int NumBytes,
2297 ARMCC::CondCodes Pred, Register PredReg,
2298 const ARMBaseInstrInfo &TII,
2299 unsigned MIFlags) {
2300 if (NumBytes == 0 && DestReg != BaseReg) {
2301 BuildMI(MBB, MBBI, dl, TII.get(ARM::MOVr), DestReg)
2302 .addReg(BaseReg, RegState::Kill)
2303 .add(predOps(Pred, PredReg))
2304 .add(condCodeOp())
2305 .setMIFlags(MIFlags);
2306 return;
2307 }
2308
2309 bool isSub = NumBytes < 0;
2310 if (isSub) NumBytes = -NumBytes;
2311
2312 while (NumBytes) {
2313 unsigned RotAmt = ARM_AM::getSOImmValRotate(NumBytes);
2314 unsigned ThisVal = NumBytes & llvm::rotr<uint32_t>(0xFF, RotAmt);
2315 assert(ThisVal && "Didn't extract field correctly");
2316
2317 // We will handle these bits from offset, clear them.
2318 NumBytes &= ~ThisVal;
2319
2320 assert(ARM_AM::getSOImmVal(ThisVal) != -1 && "Bit extraction didn't work?");
2321
2322 // Build the new ADD / SUB.
2323 unsigned Opc = isSub ? ARM::SUBri : ARM::ADDri;
2324 BuildMI(MBB, MBBI, dl, TII.get(Opc), DestReg)
2325 .addReg(BaseReg, RegState::Kill)
2326 .addImm(ThisVal)
2327 .add(predOps(Pred, PredReg))
2328 .add(condCodeOp())
2329 .setMIFlags(MIFlags);
2330 BaseReg = DestReg;
2331 }
2332}
2333
2336 unsigned NumBytes) {
2337 // This optimisation potentially adds lots of load and store
2338 // micro-operations, it's only really a great benefit to code-size.
2339 if (!Subtarget.hasMinSize())
2340 return false;
2341
2342 // If only one register is pushed/popped, LLVM can use an LDR/STR
2343 // instead. We can't modify those so make sure we're dealing with an
2344 // instruction we understand.
2345 bool IsPop = isPopOpcode(MI->getOpcode());
2346 bool IsPush = isPushOpcode(MI->getOpcode());
2347 if (!IsPush && !IsPop)
2348 return false;
2349
2350 bool IsVFPPushPop = MI->getOpcode() == ARM::VSTMDDB_UPD ||
2351 MI->getOpcode() == ARM::VLDMDIA_UPD;
2352 bool IsT1PushPop = MI->getOpcode() == ARM::tPUSH ||
2353 MI->getOpcode() == ARM::tPOP ||
2354 MI->getOpcode() == ARM::tPOP_RET;
2355
2356 assert((IsT1PushPop || (MI->getOperand(0).getReg() == ARM::SP &&
2357 MI->getOperand(1).getReg() == ARM::SP)) &&
2358 "trying to fold sp update into non-sp-updating push/pop");
2359
2360 // The VFP push & pop act on D-registers, so we can only fold an adjustment
2361 // by a multiple of 8 bytes in correctly. Similarly rN is 4-bytes. Don't try
2362 // if this is violated.
2363 if (NumBytes % (IsVFPPushPop ? 8 : 4) != 0)
2364 return false;
2365
2366 // ARM and Thumb2 push/pop insts have explicit "sp, sp" operands (+
2367 // pred) so the list starts at 4. Thumb1 starts after the predicate.
2368 int RegListIdx = IsT1PushPop ? 2 : 4;
2369
2370 // Calculate the space we'll need in terms of registers.
2371 unsigned RegsNeeded;
2372 const TargetRegisterClass *RegClass;
2373 if (IsVFPPushPop) {
2374 RegsNeeded = NumBytes / 8;
2375 RegClass = &ARM::DPRRegClass;
2376 } else {
2377 RegsNeeded = NumBytes / 4;
2378 RegClass = &ARM::GPRRegClass;
2379 }
2380
2381 // We're going to have to strip all list operands off before
2382 // re-adding them since the order matters, so save the existing ones
2383 // for later.
2385
2386 // We're also going to need the first register transferred by this
2387 // instruction, which won't necessarily be the first register in the list.
2388 unsigned FirstRegEnc = -1;
2389
2391 for (int i = MI->getNumOperands() - 1; i >= RegListIdx; --i) {
2392 MachineOperand &MO = MI->getOperand(i);
2393 RegList.push_back(MO);
2394
2395 if (MO.isReg() && !MO.isImplicit() &&
2396 TRI->getEncodingValue(MO.getReg()) < FirstRegEnc)
2397 FirstRegEnc = TRI->getEncodingValue(MO.getReg());
2398 }
2399
2400 const MCPhysReg *CSRegs = TRI->getCalleeSavedRegs(&MF);
2401
2402 // Now try to find enough space in the reglist to allocate NumBytes.
2403 for (int CurRegEnc = FirstRegEnc - 1; CurRegEnc >= 0 && RegsNeeded;
2404 --CurRegEnc) {
2405 MCRegister CurReg = RegClass->getRegister(CurRegEnc);
2406 if (IsT1PushPop && CurRegEnc > TRI->getEncodingValue(ARM::R7))
2407 continue;
2408 if (!IsPop) {
2409 // Pushing any register is completely harmless, mark the register involved
2410 // as undef since we don't care about its value and must not restore it
2411 // during stack unwinding.
2412 RegList.push_back(MachineOperand::CreateReg(CurReg, false, false,
2413 false, false, true));
2414 --RegsNeeded;
2415 continue;
2416 }
2417
2418 // However, we can only pop an extra register if it's not live. For
2419 // registers live within the function we might clobber a return value
2420 // register; the other way a register can be live here is if it's
2421 // callee-saved.
2422 if (isCalleeSavedRegister(CurReg, CSRegs) ||
2423 MI->getParent()->computeRegisterLiveness(TRI, CurReg, MI) !=
2425 // VFP pops don't allow holes in the register list, so any skip is fatal
2426 // for our transformation. GPR pops do, so we should just keep looking.
2427 if (IsVFPPushPop)
2428 return false;
2429 else
2430 continue;
2431 }
2432
2433 // Mark the unimportant registers as <def,dead> in the POP.
2434 RegList.push_back(MachineOperand::CreateReg(CurReg, true, false, false,
2435 true));
2436 --RegsNeeded;
2437 }
2438
2439 if (RegsNeeded > 0)
2440 return false;
2441
2442 // Finally we know we can profitably perform the optimisation so go
2443 // ahead: strip all existing registers off and add them back again
2444 // in the right order.
2445 for (int i = MI->getNumOperands() - 1; i >= RegListIdx; --i)
2446 MI->removeOperand(i);
2447
2448 // Add the complete list back in.
2449 MachineInstrBuilder MIB(MF, &*MI);
2450 for (const MachineOperand &MO : llvm::reverse(RegList))
2451 MIB.add(MO);
2452
2453 return true;
2454}
2455
2456bool llvm::rewriteARMFrameIndex(MachineInstr &MI, unsigned FrameRegIdx,
2457 Register FrameReg, int &Offset,
2458 const ARMBaseInstrInfo &TII) {
2459 unsigned Opcode = MI.getOpcode();
2460 const MCInstrDesc &Desc = MI.getDesc();
2461 unsigned AddrMode = (Desc.TSFlags & ARMII::AddrModeMask);
2462 bool isSub = false;
2463
2464 // Memory operands in inline assembly always use AddrMode2.
2465 if (Opcode == ARM::INLINEASM || Opcode == ARM::INLINEASM_BR)
2467
2468 if (Opcode == ARM::ADDri) {
2469 Offset += MI.getOperand(FrameRegIdx+1).getImm();
2470 if (Offset == 0) {
2471 // Turn it into a move.
2472 MI.setDesc(TII.get(ARM::MOVr));
2473 MI.getOperand(FrameRegIdx).ChangeToRegister(FrameReg, false);
2474 MI.removeOperand(FrameRegIdx+1);
2475 Offset = 0;
2476 return true;
2477 } else if (Offset < 0) {
2478 Offset = -Offset;
2479 isSub = true;
2480 MI.setDesc(TII.get(ARM::SUBri));
2481 }
2482
2483 // Common case: small offset, fits into instruction.
2484 if (ARM_AM::getSOImmVal(Offset) != -1) {
2485 // Replace the FrameIndex with sp / fp
2486 MI.getOperand(FrameRegIdx).ChangeToRegister(FrameReg, false);
2487 MI.getOperand(FrameRegIdx+1).ChangeToImmediate(Offset);
2488 Offset = 0;
2489 return true;
2490 }
2491
2492 // Otherwise, pull as much of the immediate into this ADDri/SUBri
2493 // as possible.
2494 unsigned RotAmt = ARM_AM::getSOImmValRotate(Offset);
2495 unsigned ThisImmVal = Offset & llvm::rotr<uint32_t>(0xFF, RotAmt);
2496
2497 // We will handle these bits from offset, clear them.
2498 Offset &= ~ThisImmVal;
2499
2500 // Get the properly encoded SOImmVal field.
2501 assert(ARM_AM::getSOImmVal(ThisImmVal) != -1 &&
2502 "Bit extraction didn't work?");
2503 MI.getOperand(FrameRegIdx+1).ChangeToImmediate(ThisImmVal);
2504 } else {
2505 unsigned ImmIdx = 0;
2506 int InstrOffs = 0;
2507 unsigned NumBits = 0;
2508 unsigned Scale = 1;
2509 switch (AddrMode) {
2511 ImmIdx = FrameRegIdx + 1;
2512 InstrOffs = MI.getOperand(ImmIdx).getImm();
2513 NumBits = 12;
2514 break;
2515 case ARMII::AddrMode2:
2516 ImmIdx = FrameRegIdx+2;
2517 InstrOffs = ARM_AM::getAM2Offset(MI.getOperand(ImmIdx).getImm());
2518 if (ARM_AM::getAM2Op(MI.getOperand(ImmIdx).getImm()) == ARM_AM::sub)
2519 InstrOffs *= -1;
2520 NumBits = 12;
2521 break;
2522 case ARMII::AddrMode3:
2523 ImmIdx = FrameRegIdx+2;
2524 InstrOffs = ARM_AM::getAM3Offset(MI.getOperand(ImmIdx).getImm());
2525 if (ARM_AM::getAM3Op(MI.getOperand(ImmIdx).getImm()) == ARM_AM::sub)
2526 InstrOffs *= -1;
2527 NumBits = 8;
2528 break;
2529 case ARMII::AddrMode4:
2530 case ARMII::AddrMode6:
2531 // Can't fold any offset even if it's zero.
2532 return false;
2533 case ARMII::AddrMode5:
2534 ImmIdx = FrameRegIdx+1;
2535 InstrOffs = ARM_AM::getAM5Offset(MI.getOperand(ImmIdx).getImm());
2536 if (ARM_AM::getAM5Op(MI.getOperand(ImmIdx).getImm()) == ARM_AM::sub)
2537 InstrOffs *= -1;
2538 NumBits = 8;
2539 Scale = 4;
2540 break;
2542 ImmIdx = FrameRegIdx+1;
2543 InstrOffs = ARM_AM::getAM5Offset(MI.getOperand(ImmIdx).getImm());
2544 if (ARM_AM::getAM5Op(MI.getOperand(ImmIdx).getImm()) == ARM_AM::sub)
2545 InstrOffs *= -1;
2546 NumBits = 8;
2547 Scale = 2;
2548 break;
2552 ImmIdx = FrameRegIdx+1;
2553 InstrOffs = MI.getOperand(ImmIdx).getImm();
2554 NumBits = 7;
2555 Scale = (AddrMode == ARMII::AddrModeT2_i7s2 ? 2 :
2556 AddrMode == ARMII::AddrModeT2_i7s4 ? 4 : 1);
2557 break;
2558 default:
2559 llvm_unreachable("Unsupported addressing mode!");
2560 }
2561
2562 Offset += InstrOffs * Scale;
2563 assert((Offset & (Scale-1)) == 0 && "Can't encode this offset!");
2564 if (Offset < 0) {
2565 Offset = -Offset;
2566 isSub = true;
2567 }
2568
2569 // Attempt to fold address comp. if opcode has offset bits
2570 if (NumBits > 0) {
2571 // Common case: small offset, fits into instruction.
2572 MachineOperand &ImmOp = MI.getOperand(ImmIdx);
2573 int ImmedOffset = Offset / Scale;
2574 unsigned Mask = (1 << NumBits) - 1;
2575 if ((unsigned)Offset <= Mask * Scale) {
2576 // Replace the FrameIndex with sp
2577 MI.getOperand(FrameRegIdx).ChangeToRegister(FrameReg, false);
2578 // FIXME: When addrmode2 goes away, this will simplify (like the
2579 // T2 version), as the LDR.i12 versions don't need the encoding
2580 // tricks for the offset value.
2581 if (isSub) {
2583 ImmedOffset = -ImmedOffset;
2584 else
2585 ImmedOffset |= 1 << NumBits;
2586 }
2587 ImmOp.ChangeToImmediate(ImmedOffset);
2588 Offset = 0;
2589 return true;
2590 }
2591
2592 // Otherwise, it didn't fit. Pull in what we can to simplify the immed.
2593 ImmedOffset = ImmedOffset & Mask;
2594 if (isSub) {
2596 ImmedOffset = -ImmedOffset;
2597 else
2598 ImmedOffset |= 1 << NumBits;
2599 }
2600 ImmOp.ChangeToImmediate(ImmedOffset);
2601 Offset &= ~(Mask*Scale);
2602 }
2603 }
2604
2605 Offset = (isSub) ? -Offset : Offset;
2606 return Offset == 0;
2607}
2608
2609/// analyzeCompare - For a comparison instruction, return the source registers
2610/// in SrcReg and SrcReg2 if having two register operands, and the value it
2611/// compares against in CmpValue. Return true if the comparison instruction
2612/// can be analyzed.
2614 Register &SrcReg2, int64_t &CmpMask,
2615 int64_t &CmpValue) const {
2616 switch (MI.getOpcode()) {
2617 default: break;
2618 case ARM::CMPri:
2619 case ARM::t2CMPri:
2620 case ARM::tCMPi8:
2621 SrcReg = MI.getOperand(0).getReg();
2622 SrcReg2 = 0;
2623 CmpMask = ~0;
2624 CmpValue = MI.getOperand(1).getImm();
2625 return true;
2626 case ARM::CMPrr:
2627 case ARM::t2CMPrr:
2628 case ARM::tCMPr:
2629 SrcReg = MI.getOperand(0).getReg();
2630 SrcReg2 = MI.getOperand(1).getReg();
2631 CmpMask = ~0;
2632 CmpValue = 0;
2633 return true;
2634 case ARM::TSTri:
2635 case ARM::t2TSTri:
2636 SrcReg = MI.getOperand(0).getReg();
2637 SrcReg2 = 0;
2638 CmpMask = MI.getOperand(1).getImm();
2639 CmpValue = 0;
2640 return true;
2641 }
2642
2643 return false;
2644}
2645
2646/// isSuitableForMask - Identify a suitable 'and' instruction that
2647/// operates on the given source register and applies the same mask
2648/// as a 'tst' instruction. Provide a limited look-through for copies.
2649/// When successful, MI will hold the found instruction.
2651 int CmpMask, bool CommonUse) {
2652 switch (MI->getOpcode()) {
2653 case ARM::ANDri:
2654 case ARM::t2ANDri:
2655 if (CmpMask != MI->getOperand(2).getImm())
2656 return false;
2657 if (SrcReg == MI->getOperand(CommonUse ? 1 : 0).getReg())
2658 return true;
2659 break;
2660 }
2661
2662 return false;
2663}
2664
2665/// getCmpToAddCondition - assume the flags are set by CMP(a,b), return
2666/// the condition code if we modify the instructions such that flags are
2667/// set by ADD(a,b,X).
2669 switch (CC) {
2670 default: return ARMCC::AL;
2671 case ARMCC::HS: return ARMCC::LO;
2672 case ARMCC::LO: return ARMCC::HS;
2673 case ARMCC::VS: return ARMCC::VS;
2674 case ARMCC::VC: return ARMCC::VC;
2675 }
2676}
2677
2678/// isRedundantFlagInstr - check whether the first instruction, whose only
2679/// purpose is to update flags, can be made redundant.
2680/// CMPrr can be made redundant by SUBrr if the operands are the same.
2681/// CMPri can be made redundant by SUBri if the operands are the same.
2682/// CMPrr(r0, r1) can be made redundant by ADDr[ri](r0, r1, X).
2683/// This function can be extended later on.
2684inline static bool isRedundantFlagInstr(const MachineInstr *CmpI,
2685 Register SrcReg, Register SrcReg2,
2686 int64_t ImmValue,
2687 const MachineInstr *OI,
2688 bool &IsThumb1) {
2689 if ((CmpI->getOpcode() == ARM::CMPrr || CmpI->getOpcode() == ARM::t2CMPrr) &&
2690 (OI->getOpcode() == ARM::SUBrr || OI->getOpcode() == ARM::t2SUBrr) &&
2691 ((OI->getOperand(1).getReg() == SrcReg &&
2692 OI->getOperand(2).getReg() == SrcReg2) ||
2693 (OI->getOperand(1).getReg() == SrcReg2 &&
2694 OI->getOperand(2).getReg() == SrcReg))) {
2695 IsThumb1 = false;
2696 return true;
2697 }
2698
2699 if (CmpI->getOpcode() == ARM::tCMPr && OI->getOpcode() == ARM::tSUBrr &&
2700 ((OI->getOperand(2).getReg() == SrcReg &&
2701 OI->getOperand(3).getReg() == SrcReg2) ||
2702 (OI->getOperand(2).getReg() == SrcReg2 &&
2703 OI->getOperand(3).getReg() == SrcReg))) {
2704 IsThumb1 = true;
2705 return true;
2706 }
2707
2708 if ((CmpI->getOpcode() == ARM::CMPri || CmpI->getOpcode() == ARM::t2CMPri) &&
2709 (OI->getOpcode() == ARM::SUBri || OI->getOpcode() == ARM::t2SUBri) &&
2710 OI->getOperand(1).getReg() == SrcReg &&
2711 OI->getOperand(2).getImm() == ImmValue) {
2712 IsThumb1 = false;
2713 return true;
2714 }
2715
2716 if (CmpI->getOpcode() == ARM::tCMPi8 &&
2717 (OI->getOpcode() == ARM::tSUBi8 || OI->getOpcode() == ARM::tSUBi3) &&
2718 OI->getOperand(2).getReg() == SrcReg &&
2719 OI->getOperand(3).getImm() == ImmValue) {
2720 IsThumb1 = true;
2721 return true;
2722 }
2723
2724 if ((CmpI->getOpcode() == ARM::CMPrr || CmpI->getOpcode() == ARM::t2CMPrr) &&
2725 (OI->getOpcode() == ARM::ADDrr || OI->getOpcode() == ARM::t2ADDrr ||
2726 OI->getOpcode() == ARM::ADDri || OI->getOpcode() == ARM::t2ADDri) &&
2727 OI->getOperand(0).isReg() && OI->getOperand(1).isReg() &&
2728 OI->getOperand(0).getReg() == SrcReg &&
2729 OI->getOperand(1).getReg() == SrcReg2) {
2730 IsThumb1 = false;
2731 return true;
2732 }
2733
2734 if (CmpI->getOpcode() == ARM::tCMPr &&
2735 (OI->getOpcode() == ARM::tADDi3 || OI->getOpcode() == ARM::tADDi8 ||
2736 OI->getOpcode() == ARM::tADDrr) &&
2737 OI->getOperand(0).getReg() == SrcReg &&
2738 OI->getOperand(2).getReg() == SrcReg2) {
2739 IsThumb1 = true;
2740 return true;
2741 }
2742
2743 return false;
2744}
2745
2746static bool isOptimizeCompareCandidate(MachineInstr *MI, bool &IsThumb1) {
2747 switch (MI->getOpcode()) {
2748 default: return false;
2749 case ARM::tLSLri:
2750 case ARM::tLSRri:
2751 case ARM::tLSLrr:
2752 case ARM::tLSRrr:
2753 case ARM::tSUBrr:
2754 case ARM::tADDrr:
2755 case ARM::tADDi3:
2756 case ARM::tADDi8:
2757 case ARM::tSUBi3:
2758 case ARM::tSUBi8:
2759 case ARM::tMUL:
2760 case ARM::tADC:
2761 case ARM::tSBC:
2762 case ARM::tRSB:
2763 case ARM::tAND:
2764 case ARM::tORR:
2765 case ARM::tEOR:
2766 case ARM::tBIC:
2767 case ARM::tMVN:
2768 case ARM::tASRri:
2769 case ARM::tASRrr:
2770 case ARM::tROR:
2771 IsThumb1 = true;
2772 [[fallthrough]];
2773 case ARM::RSBrr:
2774 case ARM::RSBri:
2775 case ARM::RSCrr:
2776 case ARM::RSCri:
2777 case ARM::ADDrr:
2778 case ARM::ADDri:
2779 case ARM::ADCrr:
2780 case ARM::ADCri:
2781 case ARM::SUBrr:
2782 case ARM::SUBri:
2783 case ARM::SBCrr:
2784 case ARM::SBCri:
2785 case ARM::t2RSBri:
2786 case ARM::t2ADDrr:
2787 case ARM::t2ADDri:
2788 case ARM::t2ADCrr:
2789 case ARM::t2ADCri:
2790 case ARM::t2SUBrr:
2791 case ARM::t2SUBri:
2792 case ARM::t2SBCrr:
2793 case ARM::t2SBCri:
2794 case ARM::ANDrr:
2795 case ARM::ANDri:
2796 case ARM::ANDrsr:
2797 case ARM::ANDrsi:
2798 case ARM::t2ANDrr:
2799 case ARM::t2ANDri:
2800 case ARM::t2ANDrs:
2801 case ARM::ORRrr:
2802 case ARM::ORRri:
2803 case ARM::ORRrsr:
2804 case ARM::ORRrsi:
2805 case ARM::t2ORRrr:
2806 case ARM::t2ORRri:
2807 case ARM::t2ORRrs:
2808 case ARM::EORrr:
2809 case ARM::EORri:
2810 case ARM::EORrsr:
2811 case ARM::EORrsi:
2812 case ARM::t2EORrr:
2813 case ARM::t2EORri:
2814 case ARM::t2EORrs:
2815 case ARM::BICri:
2816 case ARM::BICrr:
2817 case ARM::BICrsi:
2818 case ARM::BICrsr:
2819 case ARM::t2BICri:
2820 case ARM::t2BICrr:
2821 case ARM::t2BICrs:
2822 case ARM::t2LSRri:
2823 case ARM::t2LSRrr:
2824 case ARM::t2LSLri:
2825 case ARM::t2LSLrr:
2826 case ARM::MOVsr:
2827 case ARM::MOVsi:
2828 return true;
2829 }
2830}
2831
2832/// optimizeCompareInstr - Convert the instruction supplying the argument to the
2833/// comparison into one that sets the zero bit in the flags register;
2834/// Remove a redundant Compare instruction if an earlier instruction can set the
2835/// flags in the same way as Compare.
2836/// E.g. SUBrr(r1,r2) and CMPrr(r1,r2). We also handle the case where two
2837/// operands are swapped: SUBrr(r1,r2) and CMPrr(r2,r1), by updating the
2838/// condition code of instructions which use the flags.
2840 MachineInstr &CmpInstr, Register SrcReg, Register SrcReg2, int64_t CmpMask,
2841 int64_t CmpValue, const MachineRegisterInfo *MRI) const {
2842 // Get the unique definition of SrcReg.
2843 MachineInstr *MI = MRI->getUniqueVRegDef(SrcReg);
2844 if (!MI) return false;
2845
2846 // Masked compares sometimes use the same register as the corresponding 'and'.
2847 if (CmpMask != ~0) {
2848 if (!isSuitableForMask(MI, SrcReg, CmpMask, false) || isPredicated(*MI)) {
2849 MI = nullptr;
2851 UI = MRI->use_instr_begin(SrcReg), UE = MRI->use_instr_end();
2852 UI != UE; ++UI) {
2853 if (UI->getParent() != CmpInstr.getParent())
2854 continue;
2855 MachineInstr *PotentialAND = &*UI;
2856 if (!isSuitableForMask(PotentialAND, SrcReg, CmpMask, true) ||
2857 isPredicated(*PotentialAND))
2858 continue;
2859 MI = PotentialAND;
2860 break;
2861 }
2862 if (!MI) return false;
2863 }
2864 }
2865
2866 // Get ready to iterate backward from CmpInstr.
2867 MachineBasicBlock::iterator I = CmpInstr, E = MI,
2868 B = CmpInstr.getParent()->begin();
2869
2870 // Early exit if CmpInstr is at the beginning of the BB.
2871 if (I == B) return false;
2872
2873 // There are two possible candidates which can be changed to set CPSR:
2874 // One is MI, the other is a SUB or ADD instruction.
2875 // For CMPrr(r1,r2), we are looking for SUB(r1,r2), SUB(r2,r1), or
2876 // ADDr[ri](r1, r2, X).
2877 // For CMPri(r1, CmpValue), we are looking for SUBri(r1, CmpValue).
2878 MachineInstr *SubAdd = nullptr;
2879 if (SrcReg2 != 0)
2880 // MI is not a candidate for CMPrr.
2881 MI = nullptr;
2882 else if (MI->getParent() != CmpInstr.getParent() || CmpValue != 0) {
2883 // Conservatively refuse to convert an instruction which isn't in the same
2884 // BB as the comparison.
2885 // For CMPri w/ CmpValue != 0, a SubAdd may still be a candidate.
2886 // Thus we cannot return here.
2887 if (CmpInstr.getOpcode() == ARM::CMPri ||
2888 CmpInstr.getOpcode() == ARM::t2CMPri ||
2889 CmpInstr.getOpcode() == ARM::tCMPi8)
2890 MI = nullptr;
2891 else
2892 return false;
2893 }
2894
2895 bool IsThumb1 = false;
2896 if (MI && !isOptimizeCompareCandidate(MI, IsThumb1))
2897 return false;
2898
2899 // We also want to do this peephole for cases like this: if (a*b == 0),
2900 // and optimise away the CMP instruction from the generated code sequence:
2901 // MULS, MOVS, MOVS, CMP. Here the MOVS instructions load the boolean values
2902 // resulting from the select instruction, but these MOVS instructions for
2903 // Thumb1 (V6M) are flag setting and are thus preventing this optimisation.
2904 // However, if we only have MOVS instructions in between the CMP and the
2905 // other instruction (the MULS in this example), then the CPSR is dead so we
2906 // can safely reorder the sequence into: MOVS, MOVS, MULS, CMP. We do this
2907 // reordering and then continue the analysis hoping we can eliminate the
2908 // CMP. This peephole works on the vregs, so is still in SSA form. As a
2909 // consequence, the movs won't redefine/kill the MUL operands which would
2910 // make this reordering illegal.
2912 if (MI && IsThumb1) {
2913 --I;
2914 if (I != E && !MI->readsRegister(ARM::CPSR, TRI)) {
2915 bool CanReorder = true;
2916 for (; I != E; --I) {
2917 if (I->getOpcode() != ARM::tMOVi8) {
2918 CanReorder = false;
2919 break;
2920 }
2921 }
2922 if (CanReorder) {
2923 MI = MI->removeFromParent();
2924 E = CmpInstr;
2925 CmpInstr.getParent()->insert(E, MI);
2926 }
2927 }
2928 I = CmpInstr;
2929 E = MI;
2930 }
2931
2932 // Check that CPSR isn't set between the comparison instruction and the one we
2933 // want to change. At the same time, search for SubAdd.
2934 bool SubAddIsThumb1 = false;
2935 do {
2936 const MachineInstr &Instr = *--I;
2937
2938 // Check whether CmpInstr can be made redundant by the current instruction.
2939 if (isRedundantFlagInstr(&CmpInstr, SrcReg, SrcReg2, CmpValue, &Instr,
2940 SubAddIsThumb1)) {
2941 SubAdd = &*I;
2942 break;
2943 }
2944
2945 // Allow E (which was initially MI) to be SubAdd but do not search before E.
2946 if (I == E)
2947 break;
2948
2949 if (Instr.modifiesRegister(ARM::CPSR, TRI) ||
2950 Instr.readsRegister(ARM::CPSR, TRI))
2951 // This instruction modifies or uses CPSR after the one we want to
2952 // change. We can't do this transformation.
2953 return false;
2954
2955 if (I == B) {
2956 // In some cases, we scan the use-list of an instruction for an AND;
2957 // that AND is in the same BB, but may not be scheduled before the
2958 // corresponding TST. In that case, bail out.
2959 //
2960 // FIXME: We could try to reschedule the AND.
2961 return false;
2962 }
2963 } while (true);
2964
2965 // Return false if no candidates exist.
2966 if (!MI && !SubAdd)
2967 return false;
2968
2969 // If we found a SubAdd, use it as it will be closer to the CMP
2970 if (SubAdd) {
2971 MI = SubAdd;
2972 IsThumb1 = SubAddIsThumb1;
2973 }
2974
2975 // We can't use a predicated instruction - it doesn't always write the flags.
2976 if (isPredicated(*MI))
2977 return false;
2978
2979 // Scan forward for the use of CPSR
2980 // When checking against MI: if it's a conditional code that requires
2981 // checking of the V bit or C bit, then this is not safe to do.
2982 // It is safe to remove CmpInstr if CPSR is redefined or killed.
2983 // If we are done with the basic block, we need to check whether CPSR is
2984 // live-out.
2986 OperandsToUpdate;
2987 bool isSafe = false;
2988 I = CmpInstr;
2989 E = CmpInstr.getParent()->end();
2990 while (!isSafe && ++I != E) {
2991 const MachineInstr &Instr = *I;
2992 for (unsigned IO = 0, EO = Instr.getNumOperands();
2993 !isSafe && IO != EO; ++IO) {
2994 const MachineOperand &MO = Instr.getOperand(IO);
2995 if (MO.isRegMask() && MO.clobbersPhysReg(ARM::CPSR)) {
2996 isSafe = true;
2997 break;
2998 }
2999 if (!MO.isReg() || MO.getReg() != ARM::CPSR)
3000 continue;
3001 if (MO.isDef()) {
3002 isSafe = true;
3003 break;
3004 }
3005 // Condition code is after the operand before CPSR except for VSELs.
3007 bool IsInstrVSel = true;
3008 switch (Instr.getOpcode()) {
3009 default:
3010 IsInstrVSel = false;
3011 CC = (ARMCC::CondCodes)Instr.getOperand(IO - 1).getImm();
3012 break;
3013 case ARM::VSELEQD:
3014 case ARM::VSELEQS:
3015 case ARM::VSELEQH:
3016 CC = ARMCC::EQ;
3017 break;
3018 case ARM::VSELGTD:
3019 case ARM::VSELGTS:
3020 case ARM::VSELGTH:
3021 CC = ARMCC::GT;
3022 break;
3023 case ARM::VSELGED:
3024 case ARM::VSELGES:
3025 case ARM::VSELGEH:
3026 CC = ARMCC::GE;
3027 break;
3028 case ARM::VSELVSD:
3029 case ARM::VSELVSS:
3030 case ARM::VSELVSH:
3031 CC = ARMCC::VS;
3032 break;
3033 }
3034
3035 if (SubAdd) {
3036 // If we have SUB(r1, r2) and CMP(r2, r1), the condition code based
3037 // on CMP needs to be updated to be based on SUB.
3038 // If we have ADD(r1, r2, X) and CMP(r1, r2), the condition code also
3039 // needs to be modified.
3040 // Push the condition code operands to OperandsToUpdate.
3041 // If it is safe to remove CmpInstr, the condition code of these
3042 // operands will be modified.
3043 unsigned Opc = SubAdd->getOpcode();
3044 bool IsSub = Opc == ARM::SUBrr || Opc == ARM::t2SUBrr ||
3045 Opc == ARM::SUBri || Opc == ARM::t2SUBri ||
3046 Opc == ARM::tSUBrr || Opc == ARM::tSUBi3 ||
3047 Opc == ARM::tSUBi8;
3048 unsigned OpI = Opc != ARM::tSUBrr ? 1 : 2;
3049 if (!IsSub ||
3050 (SrcReg2 != 0 && SubAdd->getOperand(OpI).getReg() == SrcReg2 &&
3051 SubAdd->getOperand(OpI + 1).getReg() == SrcReg)) {
3052 // VSel doesn't support condition code update.
3053 if (IsInstrVSel)
3054 return false;
3055 // Ensure we can swap the condition.
3056 ARMCC::CondCodes NewCC = (IsSub ? getSwappedCondition(CC) : getCmpToAddCondition(CC));
3057 if (NewCC == ARMCC::AL)
3058 return false;
3059 OperandsToUpdate.push_back(
3060 std::make_pair(&((*I).getOperand(IO - 1)), NewCC));
3061 }
3062 } else {
3063 // No SubAdd, so this is x = <op> y, z; cmp x, 0.
3064 switch (CC) {
3065 case ARMCC::EQ: // Z
3066 case ARMCC::NE: // Z
3067 case ARMCC::MI: // N
3068 case ARMCC::PL: // N
3069 case ARMCC::AL: // none
3070 // CPSR can be used multiple times, we should continue.
3071 break;
3072 case ARMCC::HS: // C
3073 case ARMCC::LO: // C
3074 case ARMCC::VS: // V
3075 case ARMCC::VC: // V
3076 case ARMCC::HI: // C Z
3077 case ARMCC::LS: // C Z
3078 case ARMCC::GE: // N V
3079 case ARMCC::LT: // N V
3080 case ARMCC::GT: // Z N V
3081 case ARMCC::LE: // Z N V
3082 // The instruction uses the V bit or C bit which is not safe.
3083 return false;
3084 }
3085 }
3086 }
3087 }
3088
3089 // If CPSR is not killed nor re-defined, we should check whether it is
3090 // live-out. If it is live-out, do not optimize.
3091 if (!isSafe) {
3092 MachineBasicBlock *MBB = CmpInstr.getParent();
3093 for (MachineBasicBlock *Succ : MBB->successors())
3094 if (Succ->isLiveIn(ARM::CPSR))
3095 return false;
3096 }
3097
3098 // Toggle the optional operand to CPSR (if it exists - in Thumb1 we always
3099 // set CPSR so this is represented as an explicit output)
3100 if (!IsThumb1) {
3101 unsigned CPSRRegNum = MI->getNumExplicitOperands() - 1;
3102 MI->getOperand(CPSRRegNum).setReg(ARM::CPSR);
3103 MI->getOperand(CPSRRegNum).setIsDef(true);
3104 }
3105 assert(!isPredicated(*MI) && "Can't use flags from predicated instruction");
3106 CmpInstr.eraseFromParent();
3107
3108 // Modify the condition code of operands in OperandsToUpdate.
3109 // Since we have SUB(r1, r2) and CMP(r2, r1), the condition code needs to
3110 // be changed from r2 > r1 to r1 < r2, from r2 < r1 to r1 > r2, etc.
3111 for (auto &[MO, Cond] : OperandsToUpdate)
3112 MO->setImm(Cond);
3113
3114 MI->clearRegisterDeads(ARM::CPSR);
3115
3116 return true;
3117}
3118
3120 // Do not sink MI if it might be used to optimize a redundant compare.
3121 // We heuristically only look at the instruction immediately following MI to
3122 // avoid potentially searching the entire basic block.
3123 if (isPredicated(MI))
3124 return true;
3126 ++Next;
3127 Register SrcReg, SrcReg2;
3128 int64_t CmpMask, CmpValue;
3129 bool IsThumb1;
3130 if (Next != MI.getParent()->end() &&
3131 analyzeCompare(*Next, SrcReg, SrcReg2, CmpMask, CmpValue) &&
3132 isRedundantFlagInstr(&*Next, SrcReg, SrcReg2, CmpValue, &MI, IsThumb1))
3133 return false;
3134 return true;
3135}
3136
3138 Register Reg,
3139 MachineRegisterInfo *MRI) const {
3140 // Fold large immediates into add, sub, or, xor.
3141 unsigned DefOpc = DefMI.getOpcode();
3142 if (DefOpc != ARM::t2MOVi32imm && DefOpc != ARM::MOVi32imm &&
3143 DefOpc != ARM::tMOVi32imm)
3144 return false;
3145 if (!DefMI.getOperand(1).isImm())
3146 // Could be t2MOVi32imm @xx
3147 return false;
3148
3149 if (!MRI->hasOneNonDBGUse(Reg))
3150 return false;
3151
3152 const MCInstrDesc &DefMCID = DefMI.getDesc();
3153 if (DefMCID.hasOptionalDef()) {
3154 unsigned NumOps = DefMCID.getNumOperands();
3155 const MachineOperand &MO = DefMI.getOperand(NumOps - 1);
3156 if (MO.getReg() == ARM::CPSR && !MO.isDead())
3157 // If DefMI defines CPSR and it is not dead, it's obviously not safe
3158 // to delete DefMI.
3159 return false;
3160 }
3161
3162 const MCInstrDesc &UseMCID = UseMI.getDesc();
3163 if (UseMCID.hasOptionalDef()) {
3164 unsigned NumOps = UseMCID.getNumOperands();
3165 if (UseMI.getOperand(NumOps - 1).getReg() == ARM::CPSR)
3166 // If the instruction sets the flag, do not attempt this optimization
3167 // since it may change the semantics of the code.
3168 return false;
3169 }
3170
3171 unsigned UseOpc = UseMI.getOpcode();
3172 unsigned NewUseOpc = 0;
3173 uint32_t ImmVal = (uint32_t)DefMI.getOperand(1).getImm();
3174 uint32_t SOImmValV1 = 0, SOImmValV2 = 0;
3175 bool Commute = false;
3176 switch (UseOpc) {
3177 default: return false;
3178 case ARM::SUBrr:
3179 case ARM::ADDrr:
3180 case ARM::ORRrr:
3181 case ARM::EORrr:
3182 case ARM::t2SUBrr:
3183 case ARM::t2ADDrr:
3184 case ARM::t2ORRrr:
3185 case ARM::t2EORrr: {
3186 Commute = UseMI.getOperand(2).getReg() != Reg;
3187 switch (UseOpc) {
3188 default: break;
3189 case ARM::ADDrr:
3190 case ARM::SUBrr:
3191 if (UseOpc == ARM::SUBrr && Commute)
3192 return false;
3193
3194 // ADD/SUB are special because they're essentially the same operation, so
3195 // we can handle a larger range of immediates.
3196 if (ARM_AM::isSOImmTwoPartVal(ImmVal))
3197 NewUseOpc = UseOpc == ARM::ADDrr ? ARM::ADDri : ARM::SUBri;
3198 else if (ARM_AM::isSOImmTwoPartVal(-ImmVal)) {
3199 ImmVal = -ImmVal;
3200 NewUseOpc = UseOpc == ARM::ADDrr ? ARM::SUBri : ARM::ADDri;
3201 } else
3202 return false;
3203 SOImmValV1 = (uint32_t)ARM_AM::getSOImmTwoPartFirst(ImmVal);
3204 SOImmValV2 = (uint32_t)ARM_AM::getSOImmTwoPartSecond(ImmVal);
3205 break;
3206 case ARM::ORRrr:
3207 case ARM::EORrr:
3208 if (!ARM_AM::isSOImmTwoPartVal(ImmVal))
3209 return false;
3210 SOImmValV1 = (uint32_t)ARM_AM::getSOImmTwoPartFirst(ImmVal);
3211 SOImmValV2 = (uint32_t)ARM_AM::getSOImmTwoPartSecond(ImmVal);
3212 switch (UseOpc) {
3213 default: break;
3214 case ARM::ORRrr: NewUseOpc = ARM::ORRri; break;
3215 case ARM::EORrr: NewUseOpc = ARM::EORri; break;
3216 }
3217 break;
3218 case ARM::t2ADDrr:
3219 case ARM::t2SUBrr: {
3220 if (UseOpc == ARM::t2SUBrr && Commute)
3221 return false;
3222
3223 // ADD/SUB are special because they're essentially the same operation, so
3224 // we can handle a larger range of immediates.
3225 const bool ToSP = DefMI.getOperand(0).getReg() == ARM::SP;
3226 const unsigned t2ADD = ToSP ? ARM::t2ADDspImm : ARM::t2ADDri;
3227 const unsigned t2SUB = ToSP ? ARM::t2SUBspImm : ARM::t2SUBri;
3228 if (ARM_AM::isT2SOImmTwoPartVal(ImmVal))
3229 NewUseOpc = UseOpc == ARM::t2ADDrr ? t2ADD : t2SUB;
3230 else if (ARM_AM::isT2SOImmTwoPartVal(-ImmVal)) {
3231 ImmVal = -ImmVal;
3232 NewUseOpc = UseOpc == ARM::t2ADDrr ? t2SUB : t2ADD;
3233 } else
3234 return false;
3235 SOImmValV1 = (uint32_t)ARM_AM::getT2SOImmTwoPartFirst(ImmVal);
3236 SOImmValV2 = (uint32_t)ARM_AM::getT2SOImmTwoPartSecond(ImmVal);
3237 break;
3238 }
3239 case ARM::t2ORRrr:
3240 case ARM::t2EORrr:
3241 if (!ARM_AM::isT2SOImmTwoPartVal(ImmVal))
3242 return false;
3243 SOImmValV1 = (uint32_t)ARM_AM::getT2SOImmTwoPartFirst(ImmVal);
3244 SOImmValV2 = (uint32_t)ARM_AM::getT2SOImmTwoPartSecond(ImmVal);
3245 switch (UseOpc) {
3246 default: break;
3247 case ARM::t2ORRrr: NewUseOpc = ARM::t2ORRri; break;
3248 case ARM::t2EORrr: NewUseOpc = ARM::t2EORri; break;
3249 }
3250 break;
3251 }
3252 }
3253 }
3254
3255 unsigned OpIdx = Commute ? 2 : 1;
3256 Register Reg1 = UseMI.getOperand(OpIdx).getReg();
3257 bool isKill = UseMI.getOperand(OpIdx).isKill();
3258 const TargetRegisterClass *TRC = MRI->getRegClass(Reg);
3259 Register NewReg = MRI->createVirtualRegister(TRC);
3260 BuildMI(*UseMI.getParent(), UseMI, UseMI.getDebugLoc(), get(NewUseOpc),
3261 NewReg)
3262 .addReg(Reg1, getKillRegState(isKill))
3263 .addImm(SOImmValV1)
3265 .add(condCodeOp());
3266 UseMI.setDesc(get(NewUseOpc));
3267 UseMI.getOperand(1).setReg(NewReg);
3268 UseMI.getOperand(1).setIsKill();
3269 UseMI.getOperand(2).ChangeToImmediate(SOImmValV2);
3270 DefMI.eraseFromParent();
3271 // FIXME: t2ADDrr should be split, as different rulles apply when writing to SP.
3272 // Just as t2ADDri, that was split to [t2ADDri, t2ADDspImm].
3273 // Then the below code will not be needed, as the input/output register
3274 // classes will be rgpr or gprSP.
3275 // For now, we fix the UseMI operand explicitly here:
3276 switch(NewUseOpc){
3277 case ARM::t2ADDspImm:
3278 case ARM::t2SUBspImm:
3279 case ARM::t2ADDri:
3280 case ARM::t2SUBri:
3281 MRI->constrainRegClass(UseMI.getOperand(0).getReg(), TRC);
3282 }
3283 return true;
3284}
3285
3286static unsigned getNumMicroOpsSwiftLdSt(const InstrItineraryData *ItinData,
3287 const MachineInstr &MI) {
3288 switch (MI.getOpcode()) {
3289 default: {
3290 const MCInstrDesc &Desc = MI.getDesc();
3291 int UOps = ItinData->getNumMicroOps(Desc.getSchedClass());
3292 assert(UOps >= 0 && "bad # UOps");
3293 return UOps;
3294 }
3295
3296 case ARM::LDRrs:
3297 case ARM::LDRBrs:
3298 case ARM::STRrs:
3299 case ARM::STRBrs: {
3300 unsigned ShOpVal = MI.getOperand(3).getImm();
3301 bool isSub = ARM_AM::getAM2Op(ShOpVal) == ARM_AM::sub;
3302 unsigned ShImm = ARM_AM::getAM2Offset(ShOpVal);
3303 if (!isSub &&
3304 (ShImm == 0 ||
3305 ((ShImm == 1 || ShImm == 2 || ShImm == 3) &&
3306 ARM_AM::getAM2ShiftOpc(ShOpVal) == ARM_AM::lsl)))
3307 return 1;
3308 return 2;
3309 }
3310
3311 case ARM::LDRH:
3312 case ARM::STRH: {
3313 if (!MI.getOperand(2).getReg())
3314 return 1;
3315
3316 unsigned ShOpVal = MI.getOperand(3).getImm();
3317 bool isSub = ARM_AM::getAM2Op(ShOpVal) == ARM_AM::sub;
3318 unsigned ShImm = ARM_AM::getAM2Offset(ShOpVal);
3319 if (!isSub &&
3320 (ShImm == 0 ||
3321 ((ShImm == 1 || ShImm == 2 || ShImm == 3) &&
3322 ARM_AM::getAM2ShiftOpc(ShOpVal) == ARM_AM::lsl)))
3323 return 1;
3324 return 2;
3325 }
3326
3327 case ARM::LDRSB:
3328 case ARM::LDRSH:
3329 return (ARM_AM::getAM3Op(MI.getOperand(3).getImm()) == ARM_AM::sub) ? 3 : 2;
3330
3331 case ARM::LDRSB_POST:
3332 case ARM::LDRSH_POST: {
3333 Register Rt = MI.getOperand(0).getReg();
3334 Register Rm = MI.getOperand(3).getReg();
3335 return (Rt == Rm) ? 4 : 3;
3336 }
3337
3338 case ARM::LDR_PRE_REG:
3339 case ARM::LDRB_PRE_REG: {
3340 Register Rt = MI.getOperand(0).getReg();
3341 Register Rm = MI.getOperand(3).getReg();
3342 if (Rt == Rm)
3343 return 3;
3344 unsigned ShOpVal = MI.getOperand(4).getImm();
3345 bool isSub = ARM_AM::getAM2Op(ShOpVal) == ARM_AM::sub;
3346 unsigned ShImm = ARM_AM::getAM2Offset(ShOpVal);
3347 if (!isSub &&
3348 (ShImm == 0 ||
3349 ((ShImm == 1 || ShImm == 2 || ShImm == 3) &&
3350 ARM_AM::getAM2ShiftOpc(ShOpVal) == ARM_AM::lsl)))
3351 return 2;
3352 return 3;
3353 }
3354
3355 case ARM::STR_PRE_REG:
3356 case ARM::STRB_PRE_REG: {
3357 unsigned ShOpVal = MI.getOperand(4).getImm();
3358 bool isSub = ARM_AM::getAM2Op(ShOpVal) == ARM_AM::sub;
3359 unsigned ShImm = ARM_AM::getAM2Offset(ShOpVal);
3360 if (!isSub &&
3361 (ShImm == 0 ||
3362 ((ShImm == 1 || ShImm == 2 || ShImm == 3) &&
3363 ARM_AM::getAM2ShiftOpc(ShOpVal) == ARM_AM::lsl)))
3364 return 2;
3365 return 3;
3366 }
3367
3368 case ARM::LDRH_PRE:
3369 case ARM::STRH_PRE: {
3370 Register Rt = MI.getOperand(0).getReg();
3371 Register Rm = MI.getOperand(3).getReg();
3372 if (!Rm)
3373 return 2;
3374 if (Rt == Rm)
3375 return 3;
3376 return (ARM_AM::getAM3Op(MI.getOperand(4).getImm()) == ARM_AM::sub) ? 3 : 2;
3377 }
3378
3379 case ARM::LDR_POST_REG:
3380 case ARM::LDRB_POST_REG:
3381 case ARM::LDRH_POST: {
3382 Register Rt = MI.getOperand(0).getReg();
3383 Register Rm = MI.getOperand(3).getReg();
3384 return (Rt == Rm) ? 3 : 2;
3385 }
3386
3387 case ARM::LDR_PRE_IMM:
3388 case ARM::LDRB_PRE_IMM:
3389 case ARM::LDR_POST_IMM:
3390 case ARM::LDRB_POST_IMM:
3391 case ARM::STRB_POST_IMM:
3392 case ARM::STRB_POST_REG:
3393 case ARM::STRB_PRE_IMM:
3394 case ARM::STRH_POST:
3395 case ARM::STR_POST_IMM:
3396 case ARM::STR_POST_REG:
3397 case ARM::STR_PRE_IMM:
3398 return 2;
3399
3400 case ARM::LDRSB_PRE:
3401 case ARM::LDRSH_PRE: {
3402 Register Rm = MI.getOperand(3).getReg();
3403 if (Rm == 0)
3404 return 3;
3405 Register Rt = MI.getOperand(0).getReg();
3406 if (Rt == Rm)
3407 return 4;
3408 unsigned ShOpVal = MI.getOperand(4).getImm();
3409 bool isSub = ARM_AM::getAM2Op(ShOpVal) == ARM_AM::sub;
3410 unsigned ShImm = ARM_AM::getAM2Offset(ShOpVal);
3411 if (!isSub &&
3412 (ShImm == 0 ||
3413 ((ShImm == 1 || ShImm == 2 || ShImm == 3) &&
3414 ARM_AM::getAM2ShiftOpc(ShOpVal) == ARM_AM::lsl)))
3415 return 3;
3416 return 4;
3417 }
3418
3419 case ARM::LDRD: {
3420 Register Rt = MI.getOperand(0).getReg();
3421 Register Rn = MI.getOperand(2).getReg();
3422 Register Rm = MI.getOperand(3).getReg();
3423 if (Rm)
3424 return (ARM_AM::getAM3Op(MI.getOperand(4).getImm()) == ARM_AM::sub) ? 4
3425 : 3;
3426 return (Rt == Rn) ? 3 : 2;
3427 }
3428
3429 case ARM::STRD: {
3430 Register Rm = MI.getOperand(3).getReg();
3431 if (Rm)
3432 return (ARM_AM::getAM3Op(MI.getOperand(4).getImm()) == ARM_AM::sub) ? 4
3433 : 3;
3434 return 2;
3435 }
3436
3437 case ARM::LDRD_POST:
3438 case ARM::t2LDRD_POST:
3439 return 3;
3440
3441 case ARM::STRD_POST:
3442 case ARM::t2STRD_POST:
3443 return 4;
3444
3445 case ARM::LDRD_PRE: {
3446 Register Rt = MI.getOperand(0).getReg();
3447 Register Rn = MI.getOperand(3).getReg();
3448 Register Rm = MI.getOperand(4).getReg();
3449 if (Rm)
3450 return (ARM_AM::getAM3Op(MI.getOperand(5).getImm()) == ARM_AM::sub) ? 5
3451 : 4;
3452 return (Rt == Rn) ? 4 : 3;
3453 }
3454
3455 case ARM::t2LDRD_PRE: {
3456 Register Rt = MI.getOperand(0).getReg();
3457 Register Rn = MI.getOperand(3).getReg();
3458 return (Rt == Rn) ? 4 : 3;
3459 }
3460
3461 case ARM::STRD_PRE: {
3462 Register Rm = MI.getOperand(4).getReg();
3463 if (Rm)
3464 return (ARM_AM::getAM3Op(MI.getOperand(5).getImm()) == ARM_AM::sub) ? 5
3465 : 4;
3466 return 3;
3467 }
3468
3469 case ARM::t2STRD_PRE:
3470 return 3;
3471
3472 case ARM::t2LDR_POST:
3473 case ARM::t2LDRB_POST:
3474 case ARM::t2LDRB_PRE:
3475 case ARM::t2LDRSBi12:
3476 case ARM::t2LDRSBi8:
3477 case ARM::t2LDRSBpci:
3478 case ARM::t2LDRSBs:
3479 case ARM::t2LDRH_POST:
3480 case ARM::t2LDRH_PRE:
3481 case ARM::t2LDRSBT:
3482 case ARM::t2LDRSB_POST:
3483 case ARM::t2LDRSB_PRE:
3484 case ARM::t2LDRSH_POST:
3485 case ARM::t2LDRSH_PRE:
3486 case ARM::t2LDRSHi12:
3487 case ARM::t2LDRSHi8:
3488 case ARM::t2LDRSHpci:
3489 case ARM::t2LDRSHs:
3490 return 2;
3491
3492 case ARM::t2LDRDi8: {
3493 Register Rt = MI.getOperand(0).getReg();
3494 Register Rn = MI.getOperand(2).getReg();
3495 return (Rt == Rn) ? 3 : 2;
3496 }
3497
3498 case ARM::t2STRB_POST:
3499 case ARM::t2STRB_PRE:
3500 case ARM::t2STRBs:
3501 case ARM::t2STRDi8:
3502 case ARM::t2STRH_POST:
3503 case ARM::t2STRH_PRE:
3504 case ARM::t2STRHs:
3505 case ARM::t2STR_POST:
3506 case ARM::t2STR_PRE:
3507 case ARM::t2STRs:
3508 return 2;
3509 }
3510}
3511
3512// Return the number of 32-bit words loaded by LDM or stored by STM. If this
3513// can't be easily determined return 0 (missing MachineMemOperand).
3514//
3515// FIXME: The current MachineInstr design does not support relying on machine
3516// mem operands to determine the width of a memory access. Instead, we expect
3517// the target to provide this information based on the instruction opcode and
3518// operands. However, using MachineMemOperand is the best solution now for
3519// two reasons:
3520//
3521// 1) getNumMicroOps tries to infer LDM memory width from the total number of MI
3522// operands. This is much more dangerous than using the MachineMemOperand
3523// sizes because CodeGen passes can insert/remove optional machine operands. In
3524// fact, it's totally incorrect for preRA passes and appears to be wrong for
3525// postRA passes as well.
3526//
3527// 2) getNumLDMAddresses is only used by the scheduling machine model and any
3528// machine model that calls this should handle the unknown (zero size) case.
3529//
3530// Long term, we should require a target hook that verifies MachineMemOperand
3531// sizes during MC lowering. That target hook should be local to MC lowering
3532// because we can't ensure that it is aware of other MI forms. Doing this will
3533// ensure that MachineMemOperands are correctly propagated through all passes.
3535 unsigned Size = 0;
3536 for (MachineInstr::mmo_iterator I = MI.memoperands_begin(),
3537 E = MI.memoperands_end();
3538 I != E; ++I) {
3539 Size += (*I)->getSize().getValue();
3540 }
3541 // FIXME: The scheduler currently can't handle values larger than 16. But
3542 // the values can actually go up to 32 for floating-point load/store
3543 // multiple (VLDMIA etc.). Also, the way this code is reasoning about memory
3544 // operations isn't right; we could end up with "extra" memory operands for
3545 // various reasons, like tail merge merging two memory operations.
3546 return std::min(Size / 4, 16U);
3547}
3548
3550 unsigned NumRegs) {
3551 unsigned UOps = 1 + NumRegs; // 1 for address computation.
3552 switch (Opc) {
3553 default:
3554 break;
3555 case ARM::VLDMDIA_UPD:
3556 case ARM::VLDMDDB_UPD:
3557 case ARM::VLDMSIA_UPD:
3558 case ARM::VLDMSDB_UPD:
3559 case ARM::VSTMDIA_UPD:
3560 case ARM::VSTMDDB_UPD:
3561 case ARM::VSTMSIA_UPD:
3562 case ARM::VSTMSDB_UPD:
3563 case ARM::LDMIA_UPD:
3564 case ARM::LDMDA_UPD:
3565 case ARM::LDMDB_UPD:
3566 case ARM::LDMIB_UPD:
3567 case ARM::STMIA_UPD:
3568 case ARM::STMDA_UPD:
3569 case ARM::STMDB_UPD:
3570 case ARM::STMIB_UPD:
3571 case ARM::tLDMIA_UPD:
3572 case ARM::tSTMIA_UPD:
3573 case ARM::t2LDMIA_UPD:
3574 case ARM::t2LDMDB_UPD:
3575 case ARM::t2STMIA_UPD:
3576 case ARM::t2STMDB_UPD:
3577 ++UOps; // One for base register writeback.
3578 break;
3579 case ARM::LDMIA_RET:
3580 case ARM::tPOP_RET:
3581 case ARM::t2LDMIA_RET:
3582 UOps += 2; // One for base reg wb, one for write to pc.
3583 break;
3584 }
3585 return UOps;
3586}
3587
3589 const MachineInstr &MI) const {
3590 if (!ItinData || ItinData->isEmpty())
3591 return 1;
3592
3593 const MCInstrDesc &Desc = MI.getDesc();
3594 unsigned Class = Desc.getSchedClass();
3595 int ItinUOps = ItinData->getNumMicroOps(Class);
3596 if (ItinUOps >= 0) {
3597 if (Subtarget.isSwift() && (Desc.mayLoad() || Desc.mayStore()))
3598 return getNumMicroOpsSwiftLdSt(ItinData, MI);
3599
3600 return ItinUOps;
3601 }
3602
3603 unsigned Opc = MI.getOpcode();
3604 switch (Opc) {
3605 default:
3606 llvm_unreachable("Unexpected multi-uops instruction!");
3607 case ARM::VLDMQIA:
3608 case ARM::VSTMQIA:
3609 return 2;
3610
3611 // The number of uOps for load / store multiple are determined by the number
3612 // registers.
3613 //
3614 // On Cortex-A8, each pair of register loads / stores can be scheduled on the
3615 // same cycle. The scheduling for the first load / store must be done
3616 // separately by assuming the address is not 64-bit aligned.
3617 //
3618 // On Cortex-A9, the formula is simply (#reg / 2) + (#reg % 2). If the address
3619 // is not 64-bit aligned, then AGU would take an extra cycle. For VFP / NEON
3620 // load / store multiple, the formula is (#reg / 2) + (#reg % 2) + 1.
3621 case ARM::VLDMDIA:
3622 case ARM::VLDMDIA_UPD:
3623 case ARM::VLDMDDB_UPD:
3624 case ARM::VLDMSIA:
3625 case ARM::VLDMSIA_UPD:
3626 case ARM::VLDMSDB_UPD:
3627 case ARM::VSTMDIA:
3628 case ARM::VSTMDIA_UPD:
3629 case ARM::VSTMDDB_UPD:
3630 case ARM::VSTMSIA:
3631 case ARM::VSTMSIA_UPD:
3632 case ARM::VSTMSDB_UPD: {
3633 unsigned NumRegs = MI.getNumOperands() - Desc.getNumOperands();
3634 return (NumRegs / 2) + (NumRegs % 2) + 1;
3635 }
3636
3637 case ARM::LDMIA_RET:
3638 case ARM::LDMIA:
3639 case ARM::LDMDA:
3640 case ARM::LDMDB:
3641 case ARM::LDMIB:
3642 case ARM::LDMIA_UPD:
3643 case ARM::LDMDA_UPD:
3644 case ARM::LDMDB_UPD:
3645 case ARM::LDMIB_UPD:
3646 case ARM::STMIA:
3647 case ARM::STMDA:
3648 case ARM::STMDB:
3649 case ARM::STMIB:
3650 case ARM::STMIA_UPD:
3651 case ARM::STMDA_UPD:
3652 case ARM::STMDB_UPD:
3653 case ARM::STMIB_UPD:
3654 case ARM::tLDMIA:
3655 case ARM::tLDMIA_UPD:
3656 case ARM::tSTMIA_UPD:
3657 case ARM::tPOP_RET:
3658 case ARM::tPOP:
3659 case ARM::tPUSH:
3660 case ARM::t2LDMIA_RET:
3661 case ARM::t2LDMIA:
3662 case ARM::t2LDMDB:
3663 case ARM::t2LDMIA_UPD:
3664 case ARM::t2LDMDB_UPD:
3665 case ARM::t2STMIA:
3666 case ARM::t2STMDB:
3667 case ARM::t2STMIA_UPD:
3668 case ARM::t2STMDB_UPD: {
3669 unsigned NumRegs = MI.getNumOperands() - Desc.getNumOperands() + 1;
3670 switch (Subtarget.getLdStMultipleTiming()) {
3674 // Assume the worst.
3675 return NumRegs;
3677 if (NumRegs < 4)
3678 return 2;
3679 // 4 registers would be issued: 2, 2.
3680 // 5 registers would be issued: 2, 2, 1.
3681 unsigned UOps = (NumRegs / 2);
3682 if (NumRegs % 2)
3683 ++UOps;
3684 return UOps;
3685 }
3687 unsigned UOps = (NumRegs / 2);
3688 // If there are odd number of registers or if it's not 64-bit aligned,
3689 // then it takes an extra AGU (Address Generation Unit) cycle.
3690 if ((NumRegs % 2) || !MI.hasOneMemOperand() ||
3691 (*MI.memoperands_begin())->getAlign() < Align(8))
3692 ++UOps;
3693 return UOps;
3694 }
3695 }
3696 }
3697 }
3698 llvm_unreachable("Didn't find the number of microops");
3699}
3700
3701std::optional<unsigned>
3702ARMBaseInstrInfo::getVLDMDefCycle(const InstrItineraryData *ItinData,
3703 const MCInstrDesc &DefMCID, unsigned DefClass,
3704 unsigned DefIdx, unsigned DefAlign) const {
3705 int RegNo = (int)(DefIdx+1) - DefMCID.getNumOperands() + 1;
3706 if (RegNo <= 0)
3707 // Def is the address writeback.
3708 return ItinData->getOperandCycle(DefClass, DefIdx);
3709
3710 unsigned DefCycle;
3711 if (Subtarget.isCortexA8() || Subtarget.isCortexA7()) {
3712 // (regno / 2) + (regno % 2) + 1
3713 DefCycle = RegNo / 2 + 1;
3714 if (RegNo % 2)
3715 ++DefCycle;
3716 } else if (Subtarget.isLikeA9() || Subtarget.isSwift()) {
3717 DefCycle = RegNo;
3718 bool isSLoad = false;
3719
3720 switch (DefMCID.getOpcode()) {
3721 default: break;
3722 case ARM::VLDMSIA:
3723 case ARM::VLDMSIA_UPD:
3724 case ARM::VLDMSDB_UPD:
3725 isSLoad = true;
3726 break;
3727 }
3728
3729 // If there are odd number of 'S' registers or if it's not 64-bit aligned,
3730 // then it takes an extra cycle.
3731 if ((isSLoad && (RegNo % 2)) || DefAlign < 8)
3732 ++DefCycle;
3733 } else {
3734 // Assume the worst.
3735 DefCycle = RegNo + 2;
3736 }
3737
3738 return DefCycle;
3739}
3740
3741std::optional<unsigned>
3742ARMBaseInstrInfo::getLDMDefCycle(const InstrItineraryData *ItinData,
3743 const MCInstrDesc &DefMCID, unsigned DefClass,
3744 unsigned DefIdx, unsigned DefAlign) const {
3745 int RegNo = (int)(DefIdx+1) - DefMCID.getNumOperands() + 1;
3746 if (RegNo <= 0)
3747 // Def is the address writeback.
3748 return ItinData->getOperandCycle(DefClass, DefIdx);
3749
3750 unsigned DefCycle;
3751 if (Subtarget.isCortexA8() || Subtarget.isCortexA7()) {
3752 // 4 registers would be issued: 1, 2, 1.
3753 // 5 registers would be issued: 1, 2, 2.
3754 DefCycle = RegNo / 2;
3755 if (DefCycle < 1)
3756 DefCycle = 1;
3757 // Result latency is issue cycle + 2: E2.
3758 DefCycle += 2;
3759 } else if (Subtarget.isLikeA9() || Subtarget.isSwift()) {
3760 DefCycle = (RegNo / 2);
3761 // If there are odd number of registers or if it's not 64-bit aligned,
3762 // then it takes an extra AGU (Address Generation Unit) cycle.
3763 if ((RegNo % 2) || DefAlign < 8)
3764 ++DefCycle;
3765 // Result latency is AGU cycles + 2.
3766 DefCycle += 2;
3767 } else {
3768 // Assume the worst.
3769 DefCycle = RegNo + 2;
3770 }
3771
3772 return DefCycle;
3773}
3774
3775std::optional<unsigned>
3776ARMBaseInstrInfo::getVSTMUseCycle(const InstrItineraryData *ItinData,
3777 const MCInstrDesc &UseMCID, unsigned UseClass,
3778 unsigned UseIdx, unsigned UseAlign) const {
3779 int RegNo = (int)(UseIdx+1) - UseMCID.getNumOperands() + 1;
3780 if (RegNo <= 0)
3781 return ItinData->getOperandCycle(UseClass, UseIdx);
3782
3783 unsigned UseCycle;
3784 if (Subtarget.isCortexA8() || Subtarget.isCortexA7()) {
3785 // (regno / 2) + (regno % 2) + 1
3786 UseCycle = RegNo / 2 + 1;
3787 if (RegNo % 2)
3788 ++UseCycle;
3789 } else if (Subtarget.isLikeA9() || Subtarget.isSwift()) {
3790 UseCycle = RegNo;
3791 bool isSStore = false;
3792
3793 switch (UseMCID.getOpcode()) {
3794 default: break;
3795 case ARM::VSTMSIA:
3796 case ARM::VSTMSIA_UPD:
3797 case ARM::VSTMSDB_UPD:
3798 isSStore = true;
3799 break;
3800 }
3801
3802 // If there are odd number of 'S' registers or if it's not 64-bit aligned,
3803 // then it takes an extra cycle.
3804 if ((isSStore && (RegNo % 2)) || UseAlign < 8)
3805 ++UseCycle;
3806 } else {
3807 // Assume the worst.
3808 UseCycle = RegNo + 2;
3809 }
3810
3811 return UseCycle;
3812}
3813
3814std::optional<unsigned>
3815ARMBaseInstrInfo::getSTMUseCycle(const InstrItineraryData *ItinData,
3816 const MCInstrDesc &UseMCID, unsigned UseClass,
3817 unsigned UseIdx, unsigned UseAlign) const {
3818 int RegNo = (int)(UseIdx+1) - UseMCID.getNumOperands() + 1;
3819 if (RegNo <= 0)
3820 return ItinData->getOperandCycle(UseClass, UseIdx);
3821
3822 unsigned UseCycle;
3823 if (Subtarget.isCortexA8() || Subtarget.isCortexA7()) {
3824 UseCycle = RegNo / 2;
3825 if (UseCycle < 2)
3826 UseCycle = 2;
3827 // Read in E3.
3828 UseCycle += 2;
3829 } else if (Subtarget.isLikeA9() || Subtarget.isSwift()) {
3830 UseCycle = (RegNo / 2);
3831 // If there are odd number of registers or if it's not 64-bit aligned,
3832 // then it takes an extra AGU (Address Generation Unit) cycle.
3833 if ((RegNo % 2) || UseAlign < 8)
3834 ++UseCycle;
3835 } else {
3836 // Assume the worst.
3837 UseCycle = 1;
3838 }
3839 return UseCycle;
3840}
3841
3842std::optional<unsigned> ARMBaseInstrInfo::getOperandLatency(
3843 const InstrItineraryData *ItinData, const MCInstrDesc &DefMCID,
3844 unsigned DefIdx, unsigned DefAlign, const MCInstrDesc &UseMCID,
3845 unsigned UseIdx, unsigned UseAlign) const {
3846 unsigned DefClass = DefMCID.getSchedClass();
3847 unsigned UseClass = UseMCID.getSchedClass();
3848
3849 if (DefIdx < DefMCID.getNumDefs() && UseIdx < UseMCID.getNumOperands())
3850 return ItinData->getOperandLatency(DefClass, DefIdx, UseClass, UseIdx);
3851
3852 // This may be a def / use of a variable_ops instruction, the operand
3853 // latency might be determinable dynamically. Let the target try to
3854 // figure it out.
3855 std::optional<unsigned> DefCycle;
3856 bool LdmBypass = false;
3857 switch (DefMCID.getOpcode()) {
3858 default:
3859 DefCycle = ItinData->getOperandCycle(DefClass, DefIdx);
3860 break;
3861
3862 case ARM::VLDMDIA:
3863 case ARM::VLDMDIA_UPD:
3864 case ARM::VLDMDDB_UPD:
3865 case ARM::VLDMSIA:
3866 case ARM::VLDMSIA_UPD:
3867 case ARM::VLDMSDB_UPD:
3868 DefCycle = getVLDMDefCycle(ItinData, DefMCID, DefClass, DefIdx, DefAlign);
3869 break;
3870
3871 case ARM::LDMIA_RET:
3872 case ARM::LDMIA:
3873 case ARM::LDMDA:
3874 case ARM::LDMDB:
3875 case ARM::LDMIB:
3876 case ARM::LDMIA_UPD:
3877 case ARM::LDMDA_UPD:
3878 case ARM::LDMDB_UPD:
3879 case ARM::LDMIB_UPD:
3880 case ARM::tLDMIA:
3881 case ARM::tLDMIA_UPD:
3882 case ARM::tPUSH:
3883 case ARM::t2LDMIA_RET:
3884 case ARM::t2LDMIA:
3885 case ARM::t2LDMDB:
3886 case ARM::t2LDMIA_UPD:
3887 case ARM::t2LDMDB_UPD:
3888 LdmBypass = true;
3889 DefCycle = getLDMDefCycle(ItinData, DefMCID, DefClass, DefIdx, DefAlign);
3890 break;
3891 }
3892
3893 if (!DefCycle)
3894 // We can't seem to determine the result latency of the def, assume it's 2.
3895 DefCycle = 2;
3896
3897 std::optional<unsigned> UseCycle;
3898 switch (UseMCID.getOpcode()) {
3899 default:
3900 UseCycle = ItinData->getOperandCycle(UseClass, UseIdx);
3901 break;
3902
3903 case ARM::VSTMDIA:
3904 case ARM::VSTMDIA_UPD:
3905 case ARM::VSTMDDB_UPD:
3906 case ARM::VSTMSIA:
3907 case ARM::VSTMSIA_UPD:
3908 case ARM::VSTMSDB_UPD:
3909 UseCycle = getVSTMUseCycle(ItinData, UseMCID, UseClass, UseIdx, UseAlign);
3910 break;
3911
3912 case ARM::STMIA:
3913 case ARM::STMDA:
3914 case ARM::STMDB:
3915 case ARM::STMIB:
3916 case ARM::STMIA_UPD:
3917 case ARM::STMDA_UPD:
3918 case ARM::STMDB_UPD:
3919 case ARM::STMIB_UPD:
3920 case ARM::tSTMIA_UPD:
3921 case ARM::tPOP_RET:
3922 case ARM::tPOP:
3923 case ARM::t2STMIA:
3924 case ARM::t2STMDB:
3925 case ARM::t2STMIA_UPD:
3926 case ARM::t2STMDB_UPD:
3927 UseCycle = getSTMUseCycle(ItinData, UseMCID, UseClass, UseIdx, UseAlign);
3928 break;
3929 }
3930
3931 if (!UseCycle)
3932 // Assume it's read in the first stage.
3933 UseCycle = 1;
3934
3935 if (UseCycle > *DefCycle + 1)
3936 return std::nullopt;
3937
3938 UseCycle = *DefCycle - *UseCycle + 1;
3939 if (UseCycle > 0u) {
3940 if (LdmBypass) {
3941 // It's a variable_ops instruction so we can't use DefIdx here. Just use
3942 // first def operand.
3943 if (ItinData->hasPipelineForwarding(DefClass, DefMCID.getNumOperands()-1,
3944 UseClass, UseIdx))
3945 UseCycle = *UseCycle - 1;
3946 } else if (ItinData->hasPipelineForwarding(DefClass, DefIdx,
3947 UseClass, UseIdx)) {
3948 UseCycle = *UseCycle - 1;
3949 }
3950 }
3951
3952 return UseCycle;
3953}
3954
3956 const MachineInstr *MI, unsigned Reg,
3957 unsigned &DefIdx, unsigned &Dist) {
3958 Dist = 0;
3959
3961 MachineBasicBlock::const_instr_iterator II = std::prev(I.getInstrIterator());
3962 assert(II->isInsideBundle() && "Empty bundle?");
3963
3964 int Idx = -1;
3965 while (II->isInsideBundle()) {
3966 Idx = II->findRegisterDefOperandIdx(Reg, TRI, false, true);
3967 if (Idx != -1)
3968 break;
3969 --II;
3970 ++Dist;
3971 }
3972
3973 assert(Idx != -1 && "Cannot find bundled definition!");
3974 DefIdx = Idx;
3975 return &*II;
3976}
3977
3979 const MachineInstr &MI, unsigned Reg,
3980 unsigned &UseIdx, unsigned &Dist) {
3981 Dist = 0;
3982
3984 assert(II->isInsideBundle() && "Empty bundle?");
3985 MachineBasicBlock::const_instr_iterator E = MI.getParent()->instr_end();
3986
3987 // FIXME: This doesn't properly handle multiple uses.
3988 int Idx = -1;
3989 while (II != E && II->isInsideBundle()) {
3990 Idx = II->findRegisterUseOperandIdx(Reg, TRI, false);
3991 if (Idx != -1)
3992 break;
3993 if (II->getOpcode() != ARM::t2IT)
3994 ++Dist;
3995 ++II;
3996 }
3997
3998 if (Idx == -1) {
3999 Dist = 0;
4000 return nullptr;
4001 }
4002
4003 UseIdx = Idx;
4004 return &*II;
4005}
4006
4007/// Return the number of cycles to add to (or subtract from) the static
4008/// itinerary based on the def opcode and alignment. The caller will ensure that
4009/// adjusted latency is at least one cycle.
4010static int adjustDefLatency(const ARMSubtarget &Subtarget,
4011 const MachineInstr &DefMI,
4012 const MCInstrDesc &DefMCID, unsigned DefAlign) {
4013 int Adjust = 0;
4014 if (Subtarget.isCortexA8() || Subtarget.isLikeA9() || Subtarget.isCortexA7()) {
4015 // FIXME: Shifter op hack: no shift (i.e. [r +/- r]) or [r + r << 2]
4016 // variants are one cycle cheaper.
4017 switch (DefMCID.getOpcode()) {
4018 default: break;
4019 case ARM::LDRrs:
4020 case ARM::LDRBrs: {
4021 unsigned ShOpVal = DefMI.getOperand(3).getImm();
4022 unsigned ShImm = ARM_AM::getAM2Offset(ShOpVal);
4023 if (ShImm == 0 ||
4024 (ShImm == 2 && ARM_AM::getAM2ShiftOpc(ShOpVal) == ARM_AM::lsl))
4025 --Adjust;
4026 break;
4027 }
4028 case ARM::t2LDRs:
4029 case ARM::t2LDRBs:
4030 case ARM::t2LDRHs:
4031 case ARM::t2LDRSHs: {
4032 // Thumb2 mode: lsl only.
4033 unsigned ShAmt = DefMI.getOperand(3).getImm();
4034 if (ShAmt == 0 || ShAmt == 2)
4035 --Adjust;
4036 break;
4037 }
4038 }
4039 } else if (Subtarget.isSwift()) {
4040 // FIXME: Properly handle all of the latency adjustments for address
4041 // writeback.
4042 switch (DefMCID.getOpcode()) {
4043 default: break;
4044 case ARM::LDRrs:
4045 case ARM::LDRBrs: {
4046 unsigned ShOpVal = DefMI.getOperand(3).getImm();
4047 bool isSub = ARM_AM::getAM2Op(ShOpVal) == ARM_AM::sub;
4048 unsigned ShImm = ARM_AM::getAM2Offset(ShOpVal);
4049 if (!isSub &&
4050 (ShImm == 0 ||
4051 ((ShImm == 1 || ShImm == 2 || ShImm == 3) &&
4052 ARM_AM::getAM2ShiftOpc(ShOpVal) == ARM_AM::lsl)))
4053 Adjust -= 2;
4054 else if (!isSub &&
4055 ShImm == 1 && ARM_AM::getAM2ShiftOpc(ShOpVal) == ARM_AM::lsr)
4056 --Adjust;
4057 break;
4058 }
4059 case ARM::t2LDRs:
4060 case ARM::t2LDRBs:
4061 case ARM::t2LDRHs:
4062 case ARM::t2LDRSHs: {
4063 // Thumb2 mode: lsl only.
4064 unsigned ShAmt = DefMI.getOperand(3).getImm();
4065 if (ShAmt == 0 || ShAmt == 1 || ShAmt == 2 || ShAmt == 3)
4066 Adjust -= 2;
4067 break;
4068 }
4069 }
4070 }
4071
4072 if (DefAlign < 8 && Subtarget.checkVLDnAccessAlignment()) {
4073 switch (DefMCID.getOpcode()) {
4074 default: break;
4075 case ARM::VLD1q8:
4076 case ARM::VLD1q16:
4077 case ARM::VLD1q32:
4078 case ARM::VLD1q64:
4079 case ARM::VLD1q8wb_fixed:
4080 case ARM::VLD1q16wb_fixed:
4081 case ARM::VLD1q32wb_fixed:
4082 case ARM::VLD1q64wb_fixed:
4083 case ARM::VLD1q8wb_register:
4084 case ARM::VLD1q16wb_register:
4085 case ARM::VLD1q32wb_register:
4086 case ARM::VLD1q64wb_register:
4087 case ARM::VLD2d8:
4088 case ARM::VLD2d16:
4089 case ARM::VLD2d32:
4090 case ARM::VLD2q8:
4091 case ARM::VLD2q16:
4092 case ARM::VLD2q32:
4093 case ARM::VLD2d8wb_fixed:
4094 case ARM::VLD2d16wb_fixed:
4095 case ARM::VLD2d32wb_fixed:
4096 case ARM::VLD2q8wb_fixed:
4097 case ARM::VLD2q16wb_fixed:
4098 case ARM::VLD2q32wb_fixed:
4099 case ARM::VLD2d8wb_register:
4100 case ARM::VLD2d16wb_register:
4101 case ARM::VLD2d32wb_register:
4102 case ARM::VLD2q8wb_register:
4103 case ARM::VLD2q16wb_register:
4104 case ARM::VLD2q32wb_register:
4105 case ARM::VLD3d8:
4106 case ARM::VLD3d16:
4107 case ARM::VLD3d32:
4108 case ARM::VLD1d64T:
4109 case ARM::VLD3d8_UPD:
4110 case ARM::VLD3d16_UPD:
4111 case ARM::VLD3d32_UPD:
4112 case ARM::VLD1d64Twb_fixed:
4113 case ARM::VLD1d64Twb_register:
4114 case ARM::VLD3q8_UPD:
4115 case ARM::VLD3q16_UPD:
4116 case ARM::VLD3q32_UPD:
4117 case ARM::VLD4d8:
4118 case ARM::VLD4d16:
4119 case ARM::VLD4d32:
4120 case ARM::VLD1d64Q:
4121 case ARM::VLD4d8_UPD:
4122 case ARM::VLD4d16_UPD:
4123 case ARM::VLD4d32_UPD:
4124 case ARM::VLD1d64Qwb_fixed:
4125 case ARM::VLD1d64Qwb_register:
4126 case ARM::VLD4q8_UPD:
4127 case ARM::VLD4q16_UPD:
4128 case ARM::VLD4q32_UPD:
4129 case ARM::VLD1DUPq8:
4130 case ARM::VLD1DUPq16:
4131 case ARM::VLD1DUPq32:
4132 case ARM::VLD1DUPq8wb_fixed:
4133 case ARM::VLD1DUPq16wb_fixed:
4134 case ARM::VLD1DUPq32wb_fixed:
4135 case ARM::VLD1DUPq8wb_register:
4136 case ARM::VLD1DUPq16wb_register:
4137 case ARM::VLD1DUPq32wb_register:
4138 case ARM::VLD2DUPd8:
4139 case ARM::VLD2DUPd16:
4140 case ARM::VLD2DUPd32:
4141 case ARM::VLD2DUPd8wb_fixed:
4142 case ARM::VLD2DUPd16wb_fixed:
4143 case ARM::VLD2DUPd32wb_fixed:
4144 case ARM::VLD2DUPd8wb_register:
4145 case ARM::VLD2DUPd16wb_register:
4146 case ARM::VLD2DUPd32wb_register:
4147 case ARM::VLD4DUPd8:
4148 case ARM::VLD4DUPd16:
4149 case ARM::VLD4DUPd32:
4150 case ARM::VLD4DUPd8_UPD:
4151 case ARM::VLD4DUPd16_UPD:
4152 case ARM::VLD4DUPd32_UPD:
4153 case ARM::VLD1LNd8:
4154 case ARM::VLD1LNd16:
4155 case ARM::VLD1LNd32:
4156 case ARM::VLD1LNd8_UPD:
4157 case ARM::VLD1LNd16_UPD:
4158 case ARM::VLD1LNd32_UPD:
4159 case ARM::VLD2LNd8:
4160 case ARM::VLD2LNd16:
4161 case ARM::VLD2LNd32:
4162 case ARM::VLD2LNq16:
4163 case ARM::VLD2LNq32:
4164 case ARM::VLD2LNd8_UPD:
4165 case ARM::VLD2LNd16_UPD:
4166 case ARM::VLD2LNd32_UPD:
4167 case ARM::VLD2LNq16_UPD:
4168 case ARM::VLD2LNq32_UPD:
4169 case ARM::VLD4LNd8:
4170 case ARM::VLD4LNd16:
4171 case ARM::VLD4LNd32:
4172 case ARM::VLD4LNq16:
4173 case ARM::VLD4LNq32:
4174 case ARM::VLD4LNd8_UPD:
4175 case ARM::VLD4LNd16_UPD:
4176 case ARM::VLD4LNd32_UPD:
4177 case ARM::VLD4LNq16_UPD:
4178 case ARM::VLD4LNq32_UPD:
4179 // If the address is not 64-bit aligned, the latencies of these
4180 // instructions increases by one.
4181 ++Adjust;
4182 break;
4183 }
4184 }
4185 return Adjust;
4186}
4187
4189 const InstrItineraryData *ItinData, const MachineInstr &DefMI,
4190 unsigned DefIdx, const MachineInstr &UseMI, unsigned UseIdx) const {
4191 // No operand latency. The caller may fall back to getInstrLatency.
4192 if (!ItinData || ItinData->isEmpty())
4193 return std::nullopt;
4194
4195 const MachineOperand &DefMO = DefMI.getOperand(DefIdx);
4196 Register Reg = DefMO.getReg();
4197
4198 const MachineInstr *ResolvedDefMI = &DefMI;
4199 unsigned DefAdj = 0;
4200 if (DefMI.isBundle())
4201 ResolvedDefMI =
4202 getBundledDefMI(&getRegisterInfo(), &DefMI, Reg, DefIdx, DefAdj);
4203 if (ResolvedDefMI->isCopyLike() || ResolvedDefMI->isInsertSubreg() ||
4204 ResolvedDefMI->isRegSequence() || ResolvedDefMI->isImplicitDef()) {
4205 return 1;
4206 }
4207
4208 const MachineInstr *ResolvedUseMI = &UseMI;
4209 unsigned UseAdj = 0;
4210 if (UseMI.isBundle()) {
4211 ResolvedUseMI =
4212 getBundledUseMI(&getRegisterInfo(), UseMI, Reg, UseIdx, UseAdj);
4213 if (!ResolvedUseMI)
4214 return std::nullopt;
4215 }
4216
4217 return getOperandLatencyImpl(
4218 ItinData, *ResolvedDefMI, DefIdx, ResolvedDefMI->getDesc(), DefAdj, DefMO,
4219 Reg, *ResolvedUseMI, UseIdx, ResolvedUseMI->getDesc(), UseAdj);
4220}
4221
4222std::optional<unsigned> ARMBaseInstrInfo::getOperandLatencyImpl(
4223 const InstrItineraryData *ItinData, const MachineInstr &DefMI,
4224 unsigned DefIdx, const MCInstrDesc &DefMCID, unsigned DefAdj,
4225 const MachineOperand &DefMO, unsigned Reg, const MachineInstr &UseMI,
4226 unsigned UseIdx, const MCInstrDesc &UseMCID, unsigned UseAdj) const {
4227 if (Reg == ARM::CPSR) {
4228 if (DefMI.getOpcode() == ARM::FMSTAT) {
4229 // fpscr -> cpsr stalls over 20 cycles on A8 (and earlier?)
4230 return Subtarget.isLikeA9() ? 1 : 20;
4231 }
4232
4233 // CPSR set and branch can be paired in the same cycle.
4234 if (UseMI.isBranch())
4235 return 0;
4236
4237 // Otherwise it takes the instruction latency (generally one).
4238 unsigned Latency = getInstrLatency(ItinData, DefMI);
4239
4240 // For Thumb2 and -Os, prefer scheduling CPSR setting instruction close to
4241 // its uses. Instructions which are otherwise scheduled between them may
4242 // incur a code size penalty (not able to use the CPSR setting 16-bit
4243 // instructions).
4244 if (Latency > 0 && Subtarget.isThumb2()) {
4245 const MachineFunction *MF = DefMI.getParent()->getParent();
4246 if (MF->getFunction().hasOptSize())
4247 --Latency;
4248 }
4249 return Latency;
4250 }
4251
4252 if (DefMO.isImplicit() || UseMI.getOperand(UseIdx).isImplicit())
4253 return std::nullopt;
4254
4255 unsigned DefAlign = DefMI.hasOneMemOperand()
4256 ? (*DefMI.memoperands_begin())->getAlign().value()
4257 : 0;
4258 unsigned UseAlign = UseMI.hasOneMemOperand()
4259 ? (*UseMI.memoperands_begin())->getAlign().value()
4260 : 0;
4261
4262 // Get the itinerary's latency if possible, and handle variable_ops.
4263 std::optional<unsigned> Latency = getOperandLatency(
4264 ItinData, DefMCID, DefIdx, DefAlign, UseMCID, UseIdx, UseAlign);
4265 // Unable to find operand latency. The caller may resort to getInstrLatency.
4266 if (!Latency)
4267 return std::nullopt;
4268
4269 // Adjust for IT block position.
4270 int Adj = DefAdj + UseAdj;
4271
4272 // Adjust for dynamic def-side opcode variants not captured by the itinerary.
4273 Adj += adjustDefLatency(Subtarget, DefMI, DefMCID, DefAlign);
4274 if (Adj >= 0 || (int)*Latency > -Adj) {
4275 return *Latency + Adj;
4276 }
4277 // Return the itinerary latency, which may be zero but not less than zero.
4278 return Latency;
4279}
4280
4281std::optional<unsigned>
4283 SDNode *DefNode, unsigned DefIdx,
4284 SDNode *UseNode, unsigned UseIdx) const {
4285 if (!DefNode->isMachineOpcode())
4286 return 1;
4287
4288 const MCInstrDesc &DefMCID = get(DefNode->getMachineOpcode());
4289
4290 if (isZeroCost(DefMCID.Opcode))
4291 return 0;
4292
4293 if (!ItinData || ItinData->isEmpty())
4294 return DefMCID.mayLoad() ? 3 : 1;
4295
4296 if (!UseNode->isMachineOpcode()) {
4297 std::optional<unsigned> Latency =
4298 ItinData->getOperandCycle(DefMCID.getSchedClass(), DefIdx);
4299 int Adj = Subtarget.getPreISelOperandLatencyAdjustment();
4300 int Threshold = 1 + Adj;
4301 return !Latency || Latency <= (unsigned)Threshold ? 1 : *Latency - Adj;
4302 }
4303
4304 const MCInstrDesc &UseMCID = get(UseNode->getMachineOpcode());
4305 auto *DefMN = cast<MachineSDNode>(DefNode);
4306 unsigned DefAlign = !DefMN->memoperands_empty()
4307 ? (*DefMN->memoperands_begin())->getAlign().value()
4308 : 0;
4309 auto *UseMN = cast<MachineSDNode>(UseNode);
4310 unsigned UseAlign = !UseMN->memoperands_empty()
4311 ? (*UseMN->memoperands_begin())->getAlign().value()
4312 : 0;
4313 std::optional<unsigned> Latency = getOperandLatency(
4314 ItinData, DefMCID, DefIdx, DefAlign, UseMCID, UseIdx, UseAlign);
4315 if (!Latency)
4316 return std::nullopt;
4317
4318 if (Latency > 1U &&
4319 (Subtarget.isCortexA8() || Subtarget.isLikeA9() ||
4320 Subtarget.isCortexA7())) {
4321 // FIXME: Shifter op hack: no shift (i.e. [r +/- r]) or [r + r << 2]
4322 // variants are one cycle cheaper.
4323 switch (DefMCID.getOpcode()) {
4324 default: break;
4325 case ARM::LDRrs:
4326 case ARM::LDRBrs: {
4327 unsigned ShOpVal = DefNode->getConstantOperandVal(2);
4328 unsigned ShImm = ARM_AM::getAM2Offset(ShOpVal);
4329 if (ShImm == 0 ||
4330 (ShImm == 2 && ARM_AM::getAM2ShiftOpc(ShOpVal) == ARM_AM::lsl))
4331 Latency = *Latency - 1;
4332 break;
4333 }
4334 case ARM::t2LDRs:
4335 case ARM::t2LDRBs:
4336 case ARM::t2LDRHs:
4337 case ARM::t2LDRSHs: {
4338 // Thumb2 mode: lsl only.
4339 unsigned ShAmt = DefNode->getConstantOperandVal(2);
4340 if (ShAmt == 0 || ShAmt == 2)
4341 Latency = *Latency - 1;
4342 break;
4343 }
4344 }
4345 } else if (DefIdx == 0 && Latency > 2U && Subtarget.isSwift()) {
4346 // FIXME: Properly handle all of the latency adjustments for address
4347 // writeback.
4348 switch (DefMCID.getOpcode()) {
4349 default: break;
4350 case ARM::LDRrs:
4351 case ARM::LDRBrs: {
4352 unsigned ShOpVal = DefNode->getConstantOperandVal(2);
4353 unsigned ShImm = ARM_AM::getAM2Offset(ShOpVal);
4354 if (ShImm == 0 ||
4355 ((ShImm == 1 || ShImm == 2 || ShImm == 3) &&
4357 Latency = *Latency - 2;
4358 else if (ShImm == 1 && ARM_AM::getAM2ShiftOpc(ShOpVal) == ARM_AM::lsr)
4359 Latency = *Latency - 1;
4360 break;
4361 }
4362 case ARM::t2LDRs:
4363 case ARM::t2LDRBs:
4364 case ARM::t2LDRHs:
4365 case ARM::t2LDRSHs:
4366 // Thumb2 mode: lsl 0-3 only.
4367 Latency = *Latency - 2;
4368 break;
4369 }
4370 }
4371
4372 if (DefAlign < 8 && Subtarget.checkVLDnAccessAlignment())
4373 switch (DefMCID.getOpcode()) {
4374 default: break;
4375 case ARM::VLD1q8:
4376 case ARM::VLD1q16:
4377 case ARM::VLD1q32:
4378 case ARM::VLD1q64:
4379 case ARM::VLD1q8wb_register:
4380 case ARM::VLD1q16wb_register:
4381 case ARM::VLD1q32wb_register:
4382 case ARM::VLD1q64wb_register:
4383 case ARM::VLD1q8wb_fixed:
4384 case ARM::VLD1q16wb_fixed:
4385 case ARM::VLD1q32wb_fixed:
4386 case ARM::VLD1q64wb_fixed:
4387 case ARM::VLD2d8:
4388 case ARM::VLD2d16:
4389 case ARM::VLD2d32:
4390 case ARM::VLD2q8Pseudo:
4391 case ARM::VLD2q16Pseudo:
4392 case ARM::VLD2q32Pseudo:
4393 case ARM::VLD2d8wb_fixed:
4394 case ARM::VLD2d16wb_fixed:
4395 case ARM::VLD2d32wb_fixed:
4396 case ARM::VLD2q8PseudoWB_fixed:
4397 case ARM::VLD2q16PseudoWB_fixed:
4398 case ARM::VLD2q32PseudoWB_fixed:
4399 case ARM::VLD2d8wb_register:
4400 case ARM::VLD2d16wb_register:
4401 case ARM::VLD2d32wb_register:
4402 case ARM::VLD2q8PseudoWB_register:
4403 case ARM::VLD2q16PseudoWB_register:
4404 case ARM::VLD2q32PseudoWB_register:
4405 case ARM::VLD3d8Pseudo:
4406 case ARM::VLD3d16Pseudo:
4407 case ARM::VLD3d32Pseudo:
4408 case ARM::VLD1d8TPseudo:
4409 case ARM::VLD1d16TPseudo:
4410 case ARM::VLD1d32TPseudo:
4411 case ARM::VLD1d64TPseudo:
4412 case ARM::VLD1d64TPseudoWB_fixed:
4413 case ARM::VLD1d64TPseudoWB_register:
4414 case ARM::VLD3d8Pseudo_UPD:
4415 case ARM::VLD3d16Pseudo_UPD:
4416 case ARM::VLD3d32Pseudo_UPD:
4417 case ARM::VLD3q8Pseudo_UPD:
4418 case ARM::VLD3q16Pseudo_UPD:
4419 case ARM::VLD3q32Pseudo_UPD:
4420 case ARM::VLD3q8oddPseudo:
4421 case ARM::VLD3q16oddPseudo:
4422 case ARM::VLD3q32oddPseudo:
4423 case ARM::VLD3q8oddPseudo_UPD:
4424 case ARM::VLD3q16oddPseudo_UPD:
4425 case ARM::VLD3q32oddPseudo_UPD:
4426 case ARM::VLD4d8Pseudo:
4427 case ARM::VLD4d16Pseudo:
4428 case ARM::VLD4d32Pseudo:
4429 case ARM::VLD1d8QPseudo:
4430 case ARM::VLD1d16QPseudo:
4431 case ARM::VLD1d32QPseudo:
4432 case ARM::VLD1d64QPseudo:
4433 case ARM::VLD1d64QPseudoWB_fixed:
4434 case ARM::VLD1d64QPseudoWB_register:
4435 case ARM::VLD1q8HighQPseudo:
4436 case ARM::VLD1q8LowQPseudo_UPD:
4437 case ARM::VLD1q8HighTPseudo:
4438 case ARM::VLD1q8LowTPseudo_UPD:
4439 case ARM::VLD1q16HighQPseudo:
4440 case ARM::VLD1q16LowQPseudo_UPD:
4441 case ARM::VLD1q16HighTPseudo:
4442 case ARM::VLD1q16LowTPseudo_UPD:
4443 case ARM::VLD1q32HighQPseudo:
4444 case ARM::VLD1q32LowQPseudo_UPD:
4445 case ARM::VLD1q32HighTPseudo:
4446 case ARM::VLD1q32LowTPseudo_UPD:
4447 case ARM::VLD1q64HighQPseudo:
4448 case ARM::VLD1q64LowQPseudo_UPD:
4449 case ARM::VLD1q64HighTPseudo:
4450 case ARM::VLD1q64LowTPseudo_UPD:
4451 case ARM::VLD4d8Pseudo_UPD:
4452 case ARM::VLD4d16Pseudo_UPD:
4453 case ARM::VLD4d32Pseudo_UPD:
4454 case ARM::VLD4q8Pseudo_UPD:
4455 case ARM::VLD4q16Pseudo_UPD:
4456 case ARM::VLD4q32Pseudo_UPD:
4457 case ARM::VLD4q8oddPseudo:
4458 case ARM::VLD4q16oddPseudo:
4459 case ARM::VLD4q32oddPseudo:
4460 case ARM::VLD4q8oddPseudo_UPD:
4461 case ARM::VLD4q16oddPseudo_UPD:
4462 case ARM::VLD4q32oddPseudo_UPD:
4463 case ARM::VLD1DUPq8:
4464 case ARM::VLD1DUPq16:
4465 case ARM::VLD1DUPq32:
4466 case ARM::VLD1DUPq8wb_fixed:
4467 case ARM::VLD1DUPq16wb_fixed:
4468 case ARM::VLD1DUPq32wb_fixed:
4469 case ARM::VLD1DUPq8wb_register:
4470 case ARM::VLD1DUPq16wb_register:
4471 case ARM::VLD1DUPq32wb_register:
4472 case ARM::VLD2DUPd8:
4473 case ARM::VLD2DUPd16:
4474 case ARM::VLD2DUPd32:
4475 case ARM::VLD2DUPd8wb_fixed:
4476 case ARM::VLD2DUPd16wb_fixed:
4477 case ARM::VLD2DUPd32wb_fixed:
4478 case ARM::VLD2DUPd8wb_register:
4479 case ARM::VLD2DUPd16wb_register:
4480 case ARM::VLD2DUPd32wb_register:
4481 case ARM::VLD2DUPq8EvenPseudo:
4482 case ARM::VLD2DUPq8OddPseudo:
4483 case ARM::VLD2DUPq16EvenPseudo:
4484 case ARM::VLD2DUPq16OddPseudo:
4485 case ARM::VLD2DUPq32EvenPseudo:
4486 case ARM::VLD2DUPq32OddPseudo:
4487 case ARM::VLD3DUPq8EvenPseudo:
4488 case ARM::VLD3DUPq8OddPseudo:
4489 case ARM::VLD3DUPq16EvenPseudo:
4490 case ARM::VLD3DUPq16OddPseudo:
4491 case ARM::VLD3DUPq32EvenPseudo:
4492 case ARM::VLD3DUPq32OddPseudo:
4493 case ARM::VLD4DUPd8Pseudo:
4494 case ARM::VLD4DUPd16Pseudo:
4495 case ARM::VLD4DUPd32Pseudo:
4496 case ARM::VLD4DUPd8Pseudo_UPD:
4497 case ARM::VLD4DUPd16Pseudo_UPD:
4498 case ARM::VLD4DUPd32Pseudo_UPD:
4499 case ARM::VLD4DUPq8EvenPseudo:
4500 case ARM::VLD4DUPq8OddPseudo:
4501 case ARM::VLD4DUPq16EvenPseudo:
4502 case ARM::VLD4DUPq16OddPseudo:
4503 case ARM::VLD4DUPq32EvenPseudo:
4504 case ARM::VLD4DUPq32OddPseudo:
4505 case ARM::VLD1LNq8Pseudo:
4506 case ARM::VLD1LNq16Pseudo:
4507 case ARM::VLD1LNq32Pseudo:
4508 case ARM::VLD1LNq8Pseudo_UPD:
4509 case ARM::VLD1LNq16Pseudo_UPD:
4510 case ARM::VLD1LNq32Pseudo_UPD:
4511 case ARM::VLD2LNd8Pseudo:
4512 case ARM::VLD2LNd16Pseudo:
4513 case ARM::VLD2LNd32Pseudo:
4514 case ARM::VLD2LNq16Pseudo:
4515 case ARM::VLD2LNq32Pseudo:
4516 case ARM::VLD2LNd8Pseudo_UPD:
4517 case ARM::VLD2LNd16Pseudo_UPD:
4518 case ARM::VLD2LNd32Pseudo_UPD:
4519 case ARM::VLD2LNq16Pseudo_UPD:
4520 case ARM::VLD2LNq32Pseudo_UPD:
4521 case ARM::VLD4LNd8Pseudo:
4522 case ARM::VLD4LNd16Pseudo:
4523 case ARM::VLD4LNd32Pseudo:
4524 case ARM::VLD4LNq16Pseudo:
4525 case ARM::VLD4LNq32Pseudo:
4526 case ARM::VLD4LNd8Pseudo_UPD:
4527 case ARM::VLD4LNd16Pseudo_UPD:
4528 case ARM::VLD4LNd32Pseudo_UPD:
4529 case ARM::VLD4LNq16Pseudo_UPD:
4530 case ARM::VLD4LNq32Pseudo_UPD:
4531 // If the address is not 64-bit aligned, the latencies of these
4532 // instructions increases by one.
4533 Latency = *Latency + 1;
4534 break;
4535 }
4536
4537 return Latency;
4538}
4539
4540unsigned ARMBaseInstrInfo::getPredicationCost(const MachineInstr &MI) const {
4541 if (MI.isCopyLike() || MI.isInsertSubreg() || MI.isRegSequence() ||
4542 MI.isImplicitDef())
4543 return 0;
4544
4545 if (MI.isBundle())
4546 return 0;
4547
4548 const MCInstrDesc &MCID = MI.getDesc();
4549
4550 if (MCID.isCall() || (MCID.hasImplicitDefOfPhysReg(ARM::CPSR) &&
4551 !Subtarget.cheapPredicableCPSRDef())) {
4552 // When predicated, CPSR is an additional source operand for CPSR updating
4553 // instructions, this apparently increases their latencies.
4554 return 1;
4555 }
4556 return 0;
4557}
4558
4559unsigned ARMBaseInstrInfo::getInstrLatency(const InstrItineraryData *ItinData,
4560 const MachineInstr &MI,
4561 unsigned *PredCost) const {
4562 if (MI.isCopyLike() || MI.isInsertSubreg() || MI.isRegSequence() ||
4563 MI.isImplicitDef())
4564 return 1;
4565
4566 // An instruction scheduler typically runs on unbundled instructions, however
4567 // other passes may query the latency of a bundled instruction.
4568 if (MI.isBundle()) {
4569 unsigned Latency = 0;
4571 MachineBasicBlock::const_instr_iterator E = MI.getParent()->instr_end();
4572 while (++I != E && I->isInsideBundle()) {
4573 if (I->getOpcode() != ARM::t2IT)
4574 Latency += getInstrLatency(ItinData, *I, PredCost);
4575 }
4576 return Latency;
4577 }
4578
4579 const MCInstrDesc &MCID = MI.getDesc();
4580 if (PredCost && (MCID.isCall() || (MCID.hasImplicitDefOfPhysReg(ARM::CPSR) &&
4581 !Subtarget.cheapPredicableCPSRDef()))) {
4582 // When predicated, CPSR is an additional source operand for CPSR updating
4583 // instructions, this apparently increases their latencies.
4584 *PredCost = 1;
4585 }
4586 // Be sure to call getStageLatency for an empty itinerary in case it has a
4587 // valid MinLatency property.
4588 if (!ItinData)
4589 return MI.mayLoad() ? 3 : 1;
4590
4591 unsigned Class = MCID.getSchedClass();
4592
4593 // For instructions with variable uops, use uops as latency.
4594 if (!ItinData->isEmpty() && ItinData->getNumMicroOps(Class) < 0)
4595 return getNumMicroOps(ItinData, MI);
4596
4597 // For the common case, fall back on the itinerary's latency.
4598 unsigned Latency = ItinData->getStageLatency(Class);
4599
4600 // Adjust for dynamic def-side opcode variants not captured by the itinerary.
4601 unsigned DefAlign =
4602 MI.hasOneMemOperand() ? (*MI.memoperands_begin())->getAlign().value() : 0;
4603 int Adj = adjustDefLatency(Subtarget, MI, MCID, DefAlign);
4604 if (Adj >= 0 || (int)Latency > -Adj) {
4605 return Latency + Adj;
4606 }
4607 return Latency;
4608}
4609
4610unsigned ARMBaseInstrInfo::getInstrLatency(const InstrItineraryData *ItinData,
4611 SDNode *Node) const {
4612 if (!Node->isMachineOpcode())
4613 return 1;
4614
4615 if (!ItinData || ItinData->isEmpty())
4616 return 1;
4617
4618 unsigned Opcode = Node->getMachineOpcode();
4619 switch (Opcode) {
4620 default:
4621 return ItinData->getStageLatency(get(Opcode).getSchedClass());
4622 case ARM::VLDMQIA:
4623 case ARM::VSTMQIA:
4624 return 2;
4625 }
4626}
4627
4628bool ARMBaseInstrInfo::hasHighOperandLatency(const TargetSchedModel &SchedModel,
4629 const MachineRegisterInfo *MRI,
4630 const MachineInstr &DefMI,
4631 unsigned DefIdx,
4632 const MachineInstr &UseMI,
4633 unsigned UseIdx) const {
4634 unsigned DDomain = DefMI.getDesc().TSFlags & ARMII::DomainMask;
4635 unsigned UDomain = UseMI.getDesc().TSFlags & ARMII::DomainMask;
4636 if (Subtarget.nonpipelinedVFP() &&
4637 (DDomain == ARMII::DomainVFP || UDomain == ARMII::DomainVFP))
4638 return true;
4639
4640 // Hoist VFP / NEON instructions with 4 or higher latency.
4641 unsigned Latency =
4642 SchedModel.computeOperandLatency(&DefMI, DefIdx, &UseMI, UseIdx);
4643 if (Latency <= 3)
4644 return false;
4645 return DDomain == ARMII::DomainVFP || DDomain == ARMII::DomainNEON ||
4646 UDomain == ARMII::DomainVFP || UDomain == ARMII::DomainNEON;
4647}
4648
4649bool ARMBaseInstrInfo::hasLowDefLatency(const TargetSchedModel &SchedModel,
4650 const MachineInstr &DefMI,
4651 unsigned DefIdx) const {
4652 const InstrItineraryData *ItinData = SchedModel.getInstrItineraries();
4653 if (!ItinData || ItinData->isEmpty())
4654 return false;
4655
4656 unsigned DDomain = DefMI.getDesc().TSFlags & ARMII::DomainMask;
4657 if (DDomain == ARMII::DomainGeneral) {
4658 unsigned DefClass = DefMI.getDesc().getSchedClass();
4659 std::optional<unsigned> DefCycle =
4660 ItinData->getOperandCycle(DefClass, DefIdx);
4661 return DefCycle && DefCycle <= 2U;
4662 }
4663 return false;
4664}
4665
4666bool ARMBaseInstrInfo::verifyInstruction(const MachineInstr &MI,
4667 StringRef &ErrInfo) const {
4668 if (convertAddSubFlagsOpcode(MI.getOpcode())) {
4669 ErrInfo = "Pseudo flag setting opcodes only exist in Selection DAG";
4670 return false;
4671 }
4672 if (MI.getOpcode() == ARM::tMOVr && !Subtarget.hasV6Ops()) {
4673 // Make sure we don't generate a lo-lo mov that isn't supported.
4674 if (!ARM::hGPRRegClass.contains(MI.getOperand(0).getReg()) &&
4675 !ARM::hGPRRegClass.contains(MI.getOperand(1).getReg())) {
4676 ErrInfo = "Non-flag-setting Thumb1 mov is v6-only";
4677 return false;
4678 }
4679 }
4680 if (MI.getOpcode() == ARM::tPUSH ||
4681 MI.getOpcode() == ARM::tPOP ||
4682 MI.getOpcode() == ARM::tPOP_RET) {
4683 for (const MachineOperand &MO : llvm::drop_begin(MI.operands(), 2)) {
4684 if (MO.isImplicit() || !MO.isReg())
4685 continue;
4686 Register Reg = MO.getReg();
4687 if (Reg < ARM::R0 || Reg > ARM::R7) {
4688 if (!(MI.getOpcode() == ARM::tPUSH && Reg == ARM::LR) &&
4689 !(MI.getOpcode() == ARM::tPOP_RET && Reg == ARM::PC)) {
4690 ErrInfo = "Unsupported register in Thumb1 push/pop";
4691 return false;
4692 }
4693 }
4694 }
4695 }
4696 if (MI.getOpcode() == ARM::MVE_VMOV_q_rr) {
4697 assert(MI.getOperand(4).isImm() && MI.getOperand(5).isImm());
4698 if ((MI.getOperand(4).getImm() != 2 && MI.getOperand(4).getImm() != 3) ||
4699 MI.getOperand(4).getImm() != MI.getOperand(5).getImm() + 2) {
4700 ErrInfo = "Incorrect array index for MVE_VMOV_q_rr";
4701 return false;
4702 }
4703 }
4704
4705 // Check the address model by taking the first Imm operand and checking it is
4706 // legal for that addressing mode.
4708 (ARMII::AddrMode)(MI.getDesc().TSFlags & ARMII::AddrModeMask);
4709 switch (AddrMode) {
4710 default:
4711 break;
4719 case ARMII::AddrModeT2_i12: {
4720 uint32_t Imm = 0;
4721 for (auto Op : MI.operands()) {
4722 if (Op.isImm()) {
4723 Imm = Op.getImm();
4724 break;
4725 }
4726 }
4727 if (!isLegalAddressImm(MI.getOpcode(), Imm, this)) {
4728 ErrInfo = "Incorrect AddrMode Imm for instruction";
4729 return false;
4730 }
4731 break;
4732 }
4733 }
4734 return true;
4735}
4736
4738 unsigned LoadImmOpc,
4739 unsigned LoadOpc) const {
4740 assert(!Subtarget.isROPI() && !Subtarget.isRWPI() &&
4741 "ROPI/RWPI not currently supported with stack guard");
4742
4743 MachineBasicBlock &MBB = *MI->getParent();
4744 DebugLoc DL = MI->getDebugLoc();
4745 Register Reg = MI->getOperand(0).getReg();
4747 unsigned int Offset = 0;
4748
4749 if (LoadImmOpc == ARM::MRC || LoadImmOpc == ARM::t2MRC) {
4750 assert(!Subtarget.isReadTPSoft() &&
4751 "TLS stack protector requires hardware TLS register");
4752
4753 BuildMI(MBB, MI, DL, get(LoadImmOpc), Reg)
4754 .addImm(15)
4755 .addImm(0)
4756 .addImm(13)
4757 .addImm(0)
4758 .addImm(3)
4760
4761 Module &M = *MBB.getParent()->getFunction().getParent();
4762 Offset = M.getStackProtectorGuardOffset();
4763 if (Offset & ~0xfffU) {
4764 // The offset won't fit in the LDR's 12-bit immediate field, so emit an
4765 // extra ADD to cover the delta. This gives us a guaranteed 8 additional
4766 // bits, resulting in a range of 0 to +1 MiB for the guard offset.
4767 unsigned AddOpc = (LoadImmOpc == ARM::MRC) ? ARM::ADDri : ARM::t2ADDri;
4768 BuildMI(MBB, MI, DL, get(AddOpc), Reg)
4769 .addReg(Reg, RegState::Kill)
4770 .addImm(Offset & ~0xfffU)
4772 .addReg(0);
4773 Offset &= 0xfffU;
4774 }
4775 } else {
4776 const GlobalValue *GV =
4777 cast<GlobalValue>((*MI->memoperands_begin())->getValue());
4778 bool IsIndirect = Subtarget.isGVIndirectSymbol(GV);
4779
4780 unsigned TargetFlags = ARMII::MO_NO_FLAG;
4781 if (Subtarget.isTargetMachO()) {
4782 TargetFlags |= ARMII::MO_NONLAZY;
4783 } else if (Subtarget.isTargetCOFF()) {
4784 if (GV->hasDLLImportStorageClass())
4785 TargetFlags |= ARMII::MO_DLLIMPORT;
4786 else if (IsIndirect)
4787 TargetFlags |= ARMII::MO_COFFSTUB;
4788 } else if (IsIndirect) {
4789 TargetFlags |= ARMII::MO_GOT;
4790 }
4791
4792 if (LoadImmOpc == ARM::tMOVi32imm) { // Thumb-1 execute-only
4793 Register CPSRSaveReg = ARM::R12; // Use R12 as scratch register
4794 auto APSREncoding =
4795 ARMSysReg::lookupMClassSysRegByName("apsr_nzcvq")->Encoding;
4796 BuildMI(MBB, MI, DL, get(ARM::t2MRS_M), CPSRSaveReg)
4797 .addImm(APSREncoding)
4799 BuildMI(MBB, MI, DL, get(LoadImmOpc), Reg)
4800 .addGlobalAddress(GV, 0, TargetFlags);
4801 BuildMI(MBB, MI, DL, get(ARM::t2MSR_M))
4802 .addImm(APSREncoding)
4803 .addReg(CPSRSaveReg, RegState::Kill)
4805 } else {
4806 BuildMI(MBB, MI, DL, get(LoadImmOpc), Reg)
4807 .addGlobalAddress(GV, 0, TargetFlags);
4808 }
4809
4810 if (IsIndirect) {
4811 MIB = BuildMI(MBB, MI, DL, get(LoadOpc), Reg);
4812 MIB.addReg(Reg, RegState::Kill).addImm(0);
4813 auto Flags = MachineMemOperand::MOLoad |
4816 MachineMemOperand *MMO = MBB.getParent()->getMachineMemOperand(
4817 MachinePointerInfo::getGOT(*MBB.getParent()), Flags, 4, Align(4));
4819 }
4820 }
4821
4822 MIB = BuildMI(MBB, MI, DL, get(LoadOpc), Reg);
4823 MIB.addReg(Reg, RegState::Kill)
4824 .addImm(Offset)
4825 .cloneMemRefs(*MI)
4827}
4828
4829bool
4830ARMBaseInstrInfo::isFpMLxInstruction(unsigned Opcode, unsigned &MulOpc,
4831 unsigned &AddSubOpc,
4832 bool &NegAcc, bool &HasLane) const {
4833 auto I = MLxEntryMap.find(Opcode);
4834 if (I == MLxEntryMap.end())
4835 return false;
4836
4837 const ARM_MLxEntry &Entry = ARM_MLxTable[I->second];
4838 MulOpc = Entry.MulOpc;
4839 AddSubOpc = Entry.AddSubOpc;
4840 NegAcc = Entry.NegAcc;
4841 HasLane = Entry.HasLane;
4842 return true;
4843}
4844
4845//===----------------------------------------------------------------------===//
4846// Execution domains.
4847//===----------------------------------------------------------------------===//
4848//
4849// Some instructions go down the NEON pipeline, some go down the VFP pipeline,
4850// and some can go down both. The vmov instructions go down the VFP pipeline,
4851// but they can be changed to vorr equivalents that are executed by the NEON
4852// pipeline.
4853//
4854// We use the following execution domain numbering:
4855//
4861
4862//
4863// Also see ARMInstrFormats.td and Domain* enums in ARMBaseInfo.h
4864//
4865std::pair<uint16_t, uint16_t>
4867 // If we don't have access to NEON instructions then we won't be able
4868 // to swizzle anything to the NEON domain. Check to make sure.
4869 if (Subtarget.hasNEON()) {
4870 // VMOVD, VMOVRS and VMOVSR are VFP instructions, but can be changed to NEON
4871 // if they are not predicated.
4872 if (MI.getOpcode() == ARM::VMOVD && !isPredicated(MI))
4873 return std::make_pair(ExeVFP, (1 << ExeVFP) | (1 << ExeNEON));
4874
4875 // CortexA9 is particularly picky about mixing the two and wants these
4876 // converted.
4877 if (Subtarget.useNEONForFPMovs() && !isPredicated(MI) &&
4878 (MI.getOpcode() == ARM::VMOVRS || MI.getOpcode() == ARM::VMOVSR ||
4879 MI.getOpcode() == ARM::VMOVS))
4880 return std::make_pair(ExeVFP, (1 << ExeVFP) | (1 << ExeNEON));
4881 }
4882 // No other instructions can be swizzled, so just determine their domain.
4883 unsigned Domain = MI.getDesc().TSFlags & ARMII::DomainMask;
4884
4886 return std::make_pair(ExeNEON, 0);
4887
4888 // Certain instructions can go either way on Cortex-A8.
4889 // Treat them as NEON instructions.
4890 if ((Domain & ARMII::DomainNEONA8) && Subtarget.isCortexA8())
4891 return std::make_pair(ExeNEON, 0);
4892
4894 return std::make_pair(ExeVFP, 0);
4895
4896 return std::make_pair(ExeGeneric, 0);
4897}
4898
4900 unsigned SReg, unsigned &Lane) {
4901 MCRegister DReg =
4902 TRI->getMatchingSuperReg(SReg, ARM::ssub_0, &ARM::DPRRegClass);
4903 Lane = 0;
4904
4905 if (DReg)
4906 return DReg;
4907
4908 Lane = 1;
4909 DReg = TRI->getMatchingSuperReg(SReg, ARM::ssub_1, &ARM::DPRRegClass);
4910
4911 assert(DReg && "S-register with no D super-register?");
4912 return DReg;
4913}
4914
4915/// getImplicitSPRUseForDPRUse - Given a use of a DPR register and lane,
4916/// set ImplicitSReg to a register number that must be marked as implicit-use or
4917/// zero if no register needs to be defined as implicit-use.
4918///
4919/// If the function cannot determine if an SPR should be marked implicit use or
4920/// not, it returns false.
4921///
4922/// This function handles cases where an instruction is being modified from taking
4923/// an SPR to a DPR[Lane]. A use of the DPR is being added, which may conflict
4924/// with an earlier def of an SPR corresponding to DPR[Lane^1] (i.e. the other
4925/// lane of the DPR).
4926///
4927/// If the other SPR is defined, an implicit-use of it should be added. Else,
4928/// (including the case where the DPR itself is defined), it should not.
4929///
4931 MachineInstr &MI, MCRegister DReg,
4932 unsigned Lane,
4933 MCRegister &ImplicitSReg) {
4934 // If the DPR is defined or used already, the other SPR lane will be chained
4935 // correctly, so there is nothing to be done.
4936 if (MI.definesRegister(DReg, TRI) || MI.readsRegister(DReg, TRI)) {
4937 ImplicitSReg = MCRegister();
4938 return true;
4939 }
4940
4941 // Otherwise we need to go searching to see if the SPR is set explicitly.
4942 ImplicitSReg = TRI->getSubReg(DReg,
4943 (Lane & 1) ? ARM::ssub_0 : ARM::ssub_1);
4945 MI.getParent()->computeRegisterLiveness(TRI, ImplicitSReg, MI);
4946
4947 if (LQR == MachineBasicBlock::LQR_Live)
4948 return true;
4949 else if (LQR == MachineBasicBlock::LQR_Unknown)
4950 return false;
4951
4952 // If the register is known not to be live, there is no need to add an
4953 // implicit-use.
4954 ImplicitSReg = MCRegister();
4955 return true;
4956}
4957
4959 unsigned Domain) const {
4960 unsigned DstReg, SrcReg;
4961 MCRegister DReg;
4962 unsigned Lane;
4963 MachineInstrBuilder MIB(*MI.getParent()->getParent(), MI);
4965 switch (MI.getOpcode()) {
4966 default:
4967 llvm_unreachable("cannot handle opcode!");
4968 break;
4969 case ARM::VMOVD:
4970 if (Domain != ExeNEON)
4971 break;
4972
4973 // Zap the predicate operands.
4974 assert(!isPredicated(MI) && "Cannot predicate a VORRd");
4975
4976 // Make sure we've got NEON instructions.
4977 assert(Subtarget.hasNEON() && "VORRd requires NEON");
4978
4979 // Source instruction is %DDst = VMOVD %DSrc, 14, %noreg (; implicits)
4980 DstReg = MI.getOperand(0).getReg();
4981 SrcReg = MI.getOperand(1).getReg();
4982
4983 for (unsigned i = MI.getDesc().getNumOperands(); i; --i)
4984 MI.removeOperand(i - 1);
4985
4986 // Change to a %DDst = VORRd %DSrc, %DSrc, 14, %noreg (; implicits)
4987 MI.setDesc(get(ARM::VORRd));
4988 MIB.addReg(DstReg, RegState::Define)
4989 .addReg(SrcReg)
4990 .addReg(SrcReg)
4992 break;
4993 case ARM::VMOVRS:
4994 if (Domain != ExeNEON)
4995 break;
4996 assert(!isPredicated(MI) && "Cannot predicate a VGETLN");
4997
4998 // Source instruction is %RDst = VMOVRS %SSrc, 14, %noreg (; implicits)
4999 DstReg = MI.getOperand(0).getReg();
5000 SrcReg = MI.getOperand(1).getReg();
5001
5002 for (unsigned i = MI.getDesc().getNumOperands(); i; --i)
5003 MI.removeOperand(i - 1);
5004
5005 DReg = getCorrespondingDRegAndLane(TRI, SrcReg, Lane);
5006
5007 // Convert to %RDst = VGETLNi32 %DSrc, Lane, 14, %noreg (; imps)
5008 // Note that DSrc has been widened and the other lane may be undef, which
5009 // contaminates the entire register.
5010 MI.setDesc(get(ARM::VGETLNi32));
5011 MIB.addReg(DstReg, RegState::Define)
5012 .addReg(DReg, RegState::Undef)
5013 .addImm(Lane)
5015
5016 // The old source should be an implicit use, otherwise we might think it
5017 // was dead before here.
5018 MIB.addReg(SrcReg, RegState::Implicit);
5019 break;
5020 case ARM::VMOVSR: {
5021 if (Domain != ExeNEON)
5022 break;
5023 assert(!isPredicated(MI) && "Cannot predicate a VSETLN");
5024
5025 // Source instruction is %SDst = VMOVSR %RSrc, 14, %noreg (; implicits)
5026 DstReg = MI.getOperand(0).getReg();
5027 SrcReg = MI.getOperand(1).getReg();
5028
5029 DReg = getCorrespondingDRegAndLane(TRI, DstReg, Lane);
5030
5031 MCRegister ImplicitSReg;
5032 if (!getImplicitSPRUseForDPRUse(TRI, MI, DReg, Lane, ImplicitSReg))
5033 break;
5034
5035 for (unsigned i = MI.getDesc().getNumOperands(); i; --i)
5036 MI.removeOperand(i - 1);
5037
5038 // Convert to %DDst = VSETLNi32 %DDst, %RSrc, Lane, 14, %noreg (; imps)
5039 // Again DDst may be undefined at the beginning of this instruction.
5040 MI.setDesc(get(ARM::VSETLNi32));
5041 MIB.addReg(DReg, RegState::Define)
5042 .addReg(DReg, getUndefRegState(!MI.readsRegister(DReg, TRI)))
5043 .addReg(SrcReg)
5044 .addImm(Lane)
5046
5047 // The narrower destination must be marked as set to keep previous chains
5048 // in place.
5050 if (ImplicitSReg)
5051 MIB.addReg(ImplicitSReg, RegState::Implicit);
5052 break;
5053 }
5054 case ARM::VMOVS: {
5055 if (Domain != ExeNEON)
5056 break;
5057
5058 // Source instruction is %SDst = VMOVS %SSrc, 14, %noreg (; implicits)
5059 DstReg = MI.getOperand(0).getReg();
5060 SrcReg = MI.getOperand(1).getReg();
5061
5062 unsigned DstLane = 0, SrcLane = 0;
5063 MCRegister DDst, DSrc;
5064 DDst = getCorrespondingDRegAndLane(TRI, DstReg, DstLane);
5065 DSrc = getCorrespondingDRegAndLane(TRI, SrcReg, SrcLane);
5066
5067 MCRegister ImplicitSReg;
5068 if (!getImplicitSPRUseForDPRUse(TRI, MI, DSrc, SrcLane, ImplicitSReg))
5069 break;
5070
5071 for (unsigned i = MI.getDesc().getNumOperands(); i; --i)
5072 MI.removeOperand(i - 1);
5073
5074 if (DSrc == DDst) {
5075 // Destination can be:
5076 // %DDst = VDUPLN32d %DDst, Lane, 14, %noreg (; implicits)
5077 MI.setDesc(get(ARM::VDUPLN32d));
5078 MIB.addReg(DDst, RegState::Define)
5079 .addReg(DDst, getUndefRegState(!MI.readsRegister(DDst, TRI)))
5080 .addImm(SrcLane)
5082
5083 // Neither the source or the destination are naturally represented any
5084 // more, so add them in manually.
5086 MIB.addReg(SrcReg, RegState::Implicit);
5087 if (ImplicitSReg)
5088 MIB.addReg(ImplicitSReg, RegState::Implicit);
5089 break;
5090 }
5091
5092 // In general there's no single instruction that can perform an S <-> S
5093 // move in NEON space, but a pair of VEXT instructions *can* do the
5094 // job. It turns out that the VEXTs needed will only use DSrc once, with
5095 // the position based purely on the combination of lane-0 and lane-1
5096 // involved. For example
5097 // vmov s0, s2 -> vext.32 d0, d0, d1, #1 vext.32 d0, d0, d0, #1
5098 // vmov s1, s3 -> vext.32 d0, d1, d0, #1 vext.32 d0, d0, d0, #1
5099 // vmov s0, s3 -> vext.32 d0, d0, d0, #1 vext.32 d0, d1, d0, #1
5100 // vmov s1, s2 -> vext.32 d0, d0, d0, #1 vext.32 d0, d0, d1, #1
5101 //
5102 // Pattern of the MachineInstrs is:
5103 // %DDst = VEXTd32 %DSrc1, %DSrc2, Lane, 14, %noreg (;implicits)
5104 MachineInstrBuilder NewMIB;
5105 NewMIB = BuildMI(*MI.getParent(), MI, MI.getDebugLoc(), get(ARM::VEXTd32),
5106 DDst);
5107
5108 // On the first instruction, both DSrc and DDst may be undef if present.
5109 // Specifically when the original instruction didn't have them as an
5110 // <imp-use>.
5111 MCRegister CurReg = SrcLane == 1 && DstLane == 1 ? DSrc : DDst;
5112 bool CurUndef = !MI.readsRegister(CurReg, TRI);
5113 NewMIB.addReg(CurReg, getUndefRegState(CurUndef));
5114
5115 CurReg = SrcLane == 0 && DstLane == 0 ? DSrc : DDst;
5116 CurUndef = !MI.readsRegister(CurReg, TRI);
5117 NewMIB.addReg(CurReg, getUndefRegState(CurUndef))
5118 .addImm(1)
5120
5121 if (SrcLane == DstLane)
5122 NewMIB.addReg(SrcReg, RegState::Implicit);
5123
5124 MI.setDesc(get(ARM::VEXTd32));
5125 MIB.addReg(DDst, RegState::Define);
5126
5127 // On the second instruction, DDst has definitely been defined above, so
5128 // it is not undef. DSrc, if present, can be undef as above.
5129 CurReg = SrcLane == 1 && DstLane == 0 ? DSrc : DDst;
5130 CurUndef = CurReg == DSrc && !MI.readsRegister(CurReg, TRI);
5131 MIB.addReg(CurReg, getUndefRegState(CurUndef));
5132
5133 CurReg = SrcLane == 0 && DstLane == 1 ? DSrc : DDst;
5134 CurUndef = CurReg == DSrc && !MI.readsRegister(CurReg, TRI);
5135 MIB.addReg(CurReg, getUndefRegState(CurUndef))
5136 .addImm(1)
5138
5139 if (SrcLane != DstLane)
5140 MIB.addReg(SrcReg, RegState::Implicit);
5141
5142 // As before, the original destination is no longer represented, add it
5143 // implicitly.
5145 if (ImplicitSReg != 0)
5146 MIB.addReg(ImplicitSReg, RegState::Implicit);
5147 break;
5148 }
5149 }
5150}
5151
5152//===----------------------------------------------------------------------===//
5153// Partial register updates
5154//===----------------------------------------------------------------------===//
5155//
5156// Swift renames NEON registers with 64-bit granularity. That means any
5157// instruction writing an S-reg implicitly reads the containing D-reg. The
5158// problem is mostly avoided by translating f32 operations to v2f32 operations
5159// on D-registers, but f32 loads are still a problem.
5160//
5161// These instructions can load an f32 into a NEON register:
5162//
5163// VLDRS - Only writes S, partial D update.
5164// VLD1LNd32 - Writes all D-regs, explicit partial D update, 2 uops.
5165// VLD1DUPd32 - Writes all D-regs, no partial reg update, 2 uops.
5166//
5167// FCONSTD can be used as a dependency-breaking instruction.
5169 const MachineInstr &MI, unsigned OpNum,
5170 const TargetRegisterInfo *TRI) const {
5171 auto PartialUpdateClearance = Subtarget.getPartialUpdateClearance();
5172 if (!PartialUpdateClearance)
5173 return 0;
5174
5175 assert(TRI && "Need TRI instance");
5176
5177 const MachineOperand &MO = MI.getOperand(OpNum);
5178 if (MO.readsReg())
5179 return 0;
5180 Register Reg = MO.getReg();
5181 int UseOp = -1;
5182
5183 switch (MI.getOpcode()) {
5184 // Normal instructions writing only an S-register.
5185 case ARM::VLDRS:
5186 case ARM::FCONSTS:
5187 case ARM::VMOVSR:
5188 case ARM::VMOVv8i8:
5189 case ARM::VMOVv4i16:
5190 case ARM::VMOVv2i32:
5191 case ARM::VMOVv2f32:
5192 case ARM::VMOVv1i64:
5193 UseOp = MI.findRegisterUseOperandIdx(Reg, TRI, false);
5194 break;
5195
5196 // Explicitly reads the dependency.
5197 case ARM::VLD1LNd32:
5198 UseOp = 3;
5199 break;
5200 default:
5201 return 0;
5202 }
5203
5204 // If this instruction actually reads a value from Reg, there is no unwanted
5205 // dependency.
5206 if (UseOp != -1 && MI.getOperand(UseOp).readsReg())
5207 return 0;
5208
5209 // We must be able to clobber the whole D-reg.
5210 if (Reg.isVirtual()) {
5211 // Virtual register must be a def undef foo:ssub_0 operand.
5212 if (!MO.getSubReg() || MI.readsVirtualRegister(Reg))
5213 return 0;
5214 } else if (ARM::SPRRegClass.contains(Reg)) {
5215 // Physical register: MI must define the full D-reg.
5216 MCRegister DReg =
5217 TRI->getMatchingSuperReg(Reg, ARM::ssub_0, &ARM::DPRRegClass);
5218 if (!DReg || !MI.definesRegister(DReg, TRI))
5219 return 0;
5220 }
5221
5222 // MI has an unwanted D-register dependency.
5223 // Avoid defs in the previous N instructrions.
5224 return PartialUpdateClearance;
5225}
5226
5227// Break a partial register dependency after getPartialRegUpdateClearance
5228// returned non-zero.
5230 MachineInstr &MI, unsigned OpNum, const TargetRegisterInfo *TRI) const {
5231 assert(OpNum < MI.getDesc().getNumDefs() && "OpNum is not a def");
5232 assert(TRI && "Need TRI instance");
5233
5234 const MachineOperand &MO = MI.getOperand(OpNum);
5235 Register Reg = MO.getReg();
5236 assert(Reg.isPhysical() && "Can't break virtual register dependencies.");
5237 unsigned DReg = Reg;
5238
5239 // If MI defines an S-reg, find the corresponding D super-register.
5240 if (ARM::SPRRegClass.contains(Reg)) {
5241 DReg = ARM::D0 + (Reg - ARM::S0) / 2;
5242 assert(TRI->isSuperRegister(Reg, DReg) && "Register enums broken");
5243 }
5244
5245 assert(ARM::DPRRegClass.contains(DReg) && "Can only break D-reg deps");
5246 assert(MI.definesRegister(DReg, TRI) && "MI doesn't clobber full D-reg");
5247
5248 // FIXME: In some cases, VLDRS can be changed to a VLD1DUPd32 which defines
5249 // the full D-register by loading the same value to both lanes. The
5250 // instruction is micro-coded with 2 uops, so don't do this until we can
5251 // properly schedule micro-coded instructions. The dispatcher stalls cause
5252 // too big regressions.
5253
5254 // Insert the dependency-breaking FCONSTD before MI.
5255 // 96 is the encoding of 0.5, but the actual value doesn't matter here.
5256 BuildMI(*MI.getParent(), MI, MI.getDebugLoc(), get(ARM::FCONSTD), DReg)
5257 .addImm(96)
5259 MI.addRegisterKilled(DReg, TRI, true);
5260}
5261
5263 return Subtarget.hasFeature(ARM::HasV6KOps);
5264}
5265
5267 if (MI->getNumOperands() < 4)
5268 return true;
5269 unsigned ShOpVal = MI->getOperand(3).getImm();
5270 unsigned ShImm = ARM_AM::getSORegOffset(ShOpVal);
5271 // Swift supports faster shifts for: lsl 2, lsl 1, and lsr 1.
5272 if ((ShImm == 1 && ARM_AM::getSORegShOp(ShOpVal) == ARM_AM::lsr) ||
5273 ((ShImm == 1 || ShImm == 2) &&
5274 ARM_AM::getSORegShOp(ShOpVal) == ARM_AM::lsl))
5275 return true;
5276
5277 return false;
5278}
5279
5281 const MachineInstr &MI, unsigned DefIdx,
5282 SmallVectorImpl<RegSubRegPairAndIdx> &InputRegs) const {
5283 assert(DefIdx < MI.getDesc().getNumDefs() && "Invalid definition index");
5284 assert(MI.isRegSequenceLike() && "Invalid kind of instruction");
5285
5286 switch (MI.getOpcode()) {
5287 case ARM::VMOVDRR:
5288 // dX = VMOVDRR rY, rZ
5289 // is the same as:
5290 // dX = REG_SEQUENCE rY, ssub_0, rZ, ssub_1
5291 // Populate the InputRegs accordingly.
5292 // rY
5293 const MachineOperand *MOReg = &MI.getOperand(1);
5294 if (!MOReg->isUndef())
5295 InputRegs.push_back(RegSubRegPairAndIdx(MOReg->getReg(),
5296 MOReg->getSubReg(), ARM::ssub_0));
5297 // rZ
5298 MOReg = &MI.getOperand(2);
5299 if (!MOReg->isUndef())
5300 InputRegs.push_back(RegSubRegPairAndIdx(MOReg->getReg(),
5301 MOReg->getSubReg(), ARM::ssub_1));
5302 return true;
5303 }
5304 llvm_unreachable("Target dependent opcode missing");
5305}
5306
5308 const MachineInstr &MI, unsigned DefIdx,
5309 RegSubRegPairAndIdx &InputReg) const {
5310 assert(DefIdx < MI.getDesc().getNumDefs() && "Invalid definition index");
5311 assert(MI.isExtractSubregLike() && "Invalid kind of instruction");
5312
5313 switch (MI.getOpcode()) {
5314 case ARM::VMOVRRD:
5315 // rX, rY = VMOVRRD dZ
5316 // is the same as:
5317 // rX = EXTRACT_SUBREG dZ, ssub_0
5318 // rY = EXTRACT_SUBREG dZ, ssub_1
5319 const MachineOperand &MOReg = MI.getOperand(2);
5320 if (MOReg.isUndef())
5321 return false;
5322 InputReg.Reg = MOReg.getReg();
5323 InputReg.SubReg = MOReg.getSubReg();
5324 InputReg.SubIdx = DefIdx == 0 ? ARM::ssub_0 : ARM::ssub_1;
5325 return true;
5326 }
5327 llvm_unreachable("Target dependent opcode missing");
5328}
5329
5331 const MachineInstr &MI, unsigned DefIdx, RegSubRegPair &BaseReg,
5332 RegSubRegPairAndIdx &InsertedReg) const {
5333 assert(DefIdx < MI.getDesc().getNumDefs() && "Invalid definition index");
5334 assert(MI.isInsertSubregLike() && "Invalid kind of instruction");
5335
5336 switch (MI.getOpcode()) {
5337 case ARM::VSETLNi32:
5338 case ARM::MVE_VMOV_to_lane_32:
5339 // dX = VSETLNi32 dY, rZ, imm
5340 // qX = MVE_VMOV_to_lane_32 qY, rZ, imm
5341 const MachineOperand &MOBaseReg = MI.getOperand(1);
5342 const MachineOperand &MOInsertedReg = MI.getOperand(2);
5343 if (MOInsertedReg.isUndef())
5344 return false;
5345 const MachineOperand &MOIndex = MI.getOperand(3);
5346 BaseReg.Reg = MOBaseReg.getReg();
5347 BaseReg.SubReg = MOBaseReg.getSubReg();
5348
5349 InsertedReg.Reg = MOInsertedReg.getReg();
5350 InsertedReg.SubReg = MOInsertedReg.getSubReg();
5351 InsertedReg.SubIdx = ARM::ssub_0 + MOIndex.getImm();
5352 return true;
5353 }
5354 llvm_unreachable("Target dependent opcode missing");
5355}
5356
5357std::pair<unsigned, unsigned>
5359 const unsigned Mask = ARMII::MO_OPTION_MASK;
5360 return std::make_pair(TF & Mask, TF & ~Mask);
5361}
5362
5365 using namespace ARMII;
5366
5367 static const std::pair<unsigned, const char *> TargetFlags[] = {
5368 {MO_LO16, "arm-lo16"}, {MO_HI16, "arm-hi16"},
5369 {MO_LO_0_7, "arm-lo-0-7"}, {MO_HI_0_7, "arm-hi-0-7"},
5370 {MO_LO_8_15, "arm-lo-8-15"}, {MO_HI_8_15, "arm-hi-8-15"},
5371 };
5372 return ArrayRef(TargetFlags);
5373}
5374
5377 using namespace ARMII;
5378
5379 static const std::pair<unsigned, const char *> TargetFlags[] = {
5380 {MO_COFFSTUB, "arm-coffstub"},
5381 {MO_GOT, "arm-got"},
5382 {MO_SBREL, "arm-sbrel"},
5383 {MO_DLLIMPORT, "arm-dllimport"},
5384 {MO_SECREL, "arm-secrel"},
5385 {MO_NONLAZY, "arm-nonlazy"}};
5386 return ArrayRef(TargetFlags);
5387}
5388
5389std::optional<RegImmPair>
5391 int Sign = 1;
5392 unsigned Opcode = MI.getOpcode();
5393 int64_t Offset = 0;
5394
5395 // TODO: Handle cases where Reg is a super- or sub-register of the
5396 // destination register.
5397 const MachineOperand &Op0 = MI.getOperand(0);
5398 if (!Op0.isReg() || Reg != Op0.getReg())
5399 return std::nullopt;
5400
5401 // We describe SUBri or ADDri instructions.
5402 if (Opcode == ARM::SUBri)
5403 Sign = -1;
5404 else if (Opcode != ARM::ADDri)
5405 return std::nullopt;
5406
5407 // TODO: Third operand can be global address (usually some string). Since
5408 // strings can be relocated we cannot calculate their offsets for
5409 // now.
5410 if (!MI.getOperand(1).isReg() || !MI.getOperand(2).isImm())
5411 return std::nullopt;
5412
5413 Offset = MI.getOperand(2).getImm() * Sign;
5414 return RegImmPair{MI.getOperand(1).getReg(), Offset};
5415}
5416
5420 const TargetRegisterInfo *TRI) {
5421 for (auto I = From; I != To; ++I)
5422 if (I->modifiesRegister(Reg, TRI))
5423 return true;
5424 return false;
5425}
5426
5428 const TargetRegisterInfo *TRI) {
5429 // Search backwards to the instruction that defines CSPR. This may or not
5430 // be a CMP, we check that after this loop. If we find another instruction
5431 // that reads cpsr, we return nullptr.
5432 MachineBasicBlock::iterator CmpMI = Br;
5433 while (CmpMI != Br->getParent()->begin()) {
5434 --CmpMI;
5435 if (CmpMI->modifiesRegister(ARM::CPSR, TRI))
5436 break;
5437 if (CmpMI->readsRegister(ARM::CPSR, TRI))
5438 break;
5439 }
5440
5441 // Check that this inst is a CMP r[0-7], #0 and that the register
5442 // is not redefined between the cmp and the br.
5443 if (CmpMI->getOpcode() != ARM::tCMPi8 && CmpMI->getOpcode() != ARM::t2CMPri)
5444 return nullptr;
5445 Register Reg = CmpMI->getOperand(0).getReg();
5446 Register PredReg;
5447 ARMCC::CondCodes Pred = getInstrPredicate(*CmpMI, PredReg);
5448 if (Pred != ARMCC::AL || CmpMI->getOperand(1).getImm() != 0)
5449 return nullptr;
5450 if (!isARMLowRegister(Reg))
5451 return nullptr;
5452 if (registerDefinedBetween(Reg, CmpMI->getNextNode(), Br, TRI))
5453 return nullptr;
5454
5455 return &*CmpMI;
5456}
5457
5459 const ARMSubtarget *Subtarget,
5460 bool ForCodesize) {
5461 if (Subtarget->isThumb()) {
5462 if (Val <= 255) // MOV
5463 return ForCodesize ? 2 : 1;
5464 if (Subtarget->hasV6T2Ops() && (Val <= 0xffff || // MOV
5465 ARM_AM::getT2SOImmVal(Val) != -1 || // MOVW
5466 ARM_AM::getT2SOImmVal(~Val) != -1)) // MVN
5467 return ForCodesize ? 4 : 1;
5468 if (Val <= 510) // MOV + ADDi8
5469 return ForCodesize ? 4 : 2;
5470 if (~Val <= 255) // MOV + MVN
5471 return ForCodesize ? 4 : 2;
5472 if (ARM_AM::isThumbImmShiftedVal(Val)) // MOV + LSL
5473 return ForCodesize ? 4 : 2;
5474 } else {
5475 if (ARM_AM::getSOImmVal(Val) != -1) // MOV
5476 return ForCodesize ? 4 : 1;
5477 if (ARM_AM::getSOImmVal(~Val) != -1) // MVN
5478 return ForCodesize ? 4 : 1;
5479 if (Subtarget->hasV6T2Ops() && Val <= 0xffff) // MOVW
5480 return ForCodesize ? 4 : 1;
5481 if (ARM_AM::isSOImmTwoPartVal(Val)) // two instrs
5482 return ForCodesize ? 8 : 2;
5483 if (ARM_AM::isSOImmTwoPartValNeg(Val)) // two instrs
5484 return ForCodesize ? 8 : 2;
5485 }
5486 if (Subtarget->useMovt()) // MOVW + MOVT
5487 return ForCodesize ? 8 : 2;
5488 return ForCodesize ? 8 : 3; // Literal pool load
5489}
5490
5491bool llvm::HasLowerConstantMaterializationCost(unsigned Val1, unsigned Val2,
5492 const ARMSubtarget *Subtarget,
5493 bool ForCodesize) {
5494 // Check with ForCodesize
5495 unsigned Cost1 = ConstantMaterializationCost(Val1, Subtarget, ForCodesize);
5496 unsigned Cost2 = ConstantMaterializationCost(Val2, Subtarget, ForCodesize);
5497 if (Cost1 < Cost2)
5498 return true;
5499 if (Cost1 > Cost2)
5500 return false;
5501
5502 // If they are equal, try with !ForCodesize
5503 return ConstantMaterializationCost(Val1, Subtarget, !ForCodesize) <
5504 ConstantMaterializationCost(Val2, Subtarget, !ForCodesize);
5505}
5506
5507/// Constants defining how certain sequences should be outlined.
5508/// This encompasses how an outlined function should be called, and what kind of
5509/// frame should be emitted for that outlined function.
5510///
5511/// \p MachineOutlinerTailCall implies that the function is being created from
5512/// a sequence of instructions ending in a return.
5513///
5514/// That is,
5515///
5516/// I1 OUTLINED_FUNCTION:
5517/// I2 --> B OUTLINED_FUNCTION I1
5518/// BX LR I2
5519/// BX LR
5520///
5521/// +-------------------------+--------+-----+
5522/// | | Thumb2 | ARM |
5523/// +-------------------------+--------+-----+
5524/// | Call overhead in Bytes | 4 | 4 |
5525/// | Frame overhead in Bytes | 0 | 0 |
5526/// | Stack fixup required | No | No |
5527/// +-------------------------+--------+-----+
5528///
5529/// \p MachineOutlinerThunk implies that the function is being created from
5530/// a sequence of instructions ending in a call. The outlined function is
5531/// called with a BL instruction, and the outlined function tail-calls the
5532/// original call destination.
5533///
5534/// That is,
5535///
5536/// I1 OUTLINED_FUNCTION:
5537/// I2 --> BL OUTLINED_FUNCTION I1
5538/// BL f I2
5539/// B f
5540///
5541/// +-------------------------+--------+-----+
5542/// | | Thumb2 | ARM |
5543/// +-------------------------+--------+-----+
5544/// | Call overhead in Bytes | 4 | 4 |
5545/// | Frame overhead in Bytes | 0 | 0 |
5546/// | Stack fixup required | No | No |
5547/// +-------------------------+--------+-----+
5548///
5549/// \p MachineOutlinerNoLRSave implies that the function should be called using
5550/// a BL instruction, but doesn't require LR to be saved and restored. This
5551/// happens when LR is known to be dead.
5552///
5553/// That is,
5554///
5555/// I1 OUTLINED_FUNCTION:
5556/// I2 --> BL OUTLINED_FUNCTION I1
5557/// I3 I2
5558/// I3
5559/// BX LR
5560///
5561/// +-------------------------+--------+-----+
5562/// | | Thumb2 | ARM |
5563/// +-------------------------+--------+-----+
5564/// | Call overhead in Bytes | 4 | 4 |
5565/// | Frame overhead in Bytes | 2 | 4 |
5566/// | Stack fixup required | No | No |
5567/// +-------------------------+--------+-----+
5568///
5569/// \p MachineOutlinerRegSave implies that the function should be called with a
5570/// save and restore of LR to an available register. This allows us to avoid
5571/// stack fixups. Note that this outlining variant is compatible with the
5572/// NoLRSave case.
5573///
5574/// That is,
5575///
5576/// I1 Save LR OUTLINED_FUNCTION:
5577/// I2 --> BL OUTLINED_FUNCTION I1
5578/// I3 Restore LR I2
5579/// I3
5580/// BX LR
5581///
5582/// +-------------------------+--------+-----+
5583/// | | Thumb2 | ARM |
5584/// +-------------------------+--------+-----+
5585/// | Call overhead in Bytes | 8 | 12 |
5586/// | Frame overhead in Bytes | 2 | 4 |
5587/// | Stack fixup required | No | No |
5588/// +-------------------------+--------+-----+
5589///
5590/// \p MachineOutlinerDefault implies that the function should be called with
5591/// a save and restore of LR to the stack.
5592///
5593/// That is,
5594///
5595/// I1 Save LR OUTLINED_FUNCTION:
5596/// I2 --> BL OUTLINED_FUNCTION I1
5597/// I3 Restore LR I2
5598/// I3
5599/// BX LR
5600///
5601/// +-------------------------+--------+-----+
5602/// | | Thumb2 | ARM |
5603/// +-------------------------+--------+-----+
5604/// | Call overhead in Bytes | 8 | 12 |
5605/// | Frame overhead in Bytes | 2 | 4 |
5606/// | Stack fixup required | Yes | Yes |
5607/// +-------------------------+--------+-----+
5608
5616
5622
5635
5637 : CallTailCall(target.isThumb() ? 4 : 4),
5638 FrameTailCall(target.isThumb() ? 0 : 0),
5639 CallThunk(target.isThumb() ? 4 : 4),
5640 FrameThunk(target.isThumb() ? 0 : 0),
5641 CallNoLRSave(target.isThumb() ? 4 : 4),
5642 FrameNoLRSave(target.isThumb() ? 2 : 4),
5643 CallRegSave(target.isThumb() ? 8 : 12),
5644 FrameRegSave(target.isThumb() ? 2 : 4),
5645 CallDefault(target.isThumb() ? 8 : 12),
5646 FrameDefault(target.isThumb() ? 2 : 4),
5647 SaveRestoreLROnStack(target.isThumb() ? 8 : 8) {}
5648};
5649
5651ARMBaseInstrInfo::findRegisterToSaveLRTo(outliner::Candidate &C) const {
5652 MachineFunction *MF = C.getMF();
5653 const TargetRegisterInfo &TRI = *MF->getSubtarget().getRegisterInfo();
5654 const ARMBaseRegisterInfo *ARI =
5655 static_cast<const ARMBaseRegisterInfo *>(&TRI);
5656
5657 BitVector regsReserved = ARI->getReservedRegs(*MF);
5658 // Check if there is an available register across the sequence that we can
5659 // use.
5660 for (Register Reg : ARM::rGPRRegClass) {
5661 if (!(Reg < regsReserved.size() && regsReserved.test(Reg)) &&
5662 Reg != ARM::LR && // LR is not reserved, but don't use it.
5663 Reg != ARM::R12 && // R12 is not guaranteed to be preserved.
5664 C.isAvailableAcrossAndOutOfSeq(Reg, TRI) &&
5665 C.isAvailableInsideSeq(Reg, TRI))
5666 return Reg;
5667 }
5668 return Register();
5669}
5670
5671// Compute liveness of LR at the point after the interval [I, E), which
5672// denotes a *backward* iteration through instructions. Used only for return
5673// basic blocks, which do not end with a tail call.
5677 // At the end of the function LR dead.
5678 bool Live = false;
5679 for (; I != E; ++I) {
5680 const MachineInstr &MI = *I;
5681
5682 // Check defs of LR.
5683 if (MI.modifiesRegister(ARM::LR, &TRI))
5684 Live = false;
5685
5686 // Check uses of LR.
5687 unsigned Opcode = MI.getOpcode();
5688 if (Opcode == ARM::BX_RET || Opcode == ARM::MOVPCLR ||
5689 Opcode == ARM::SUBS_PC_LR || Opcode == ARM::tBX_RET ||
5690 Opcode == ARM::tBXNS_RET || Opcode == ARM::t2BXAUT_RET) {
5691 // These instructions use LR, but it's not an (explicit or implicit)
5692 // operand.
5693 Live = true;
5694 continue;
5695 }
5696 if (MI.readsRegister(ARM::LR, &TRI))
5697 Live = true;
5698 }
5699 return !Live;
5700}
5701
5702/// Return true if \p MI is a call instruction that the outliner can rewrite as
5703/// a tail call.
5705 auto Opcode = MI.getOpcode();
5706 return (Opcode == ARM::BL || Opcode == ARM::BLX || Opcode == ARM::BLX_noip ||
5707 Opcode == ARM::tBL || Opcode == ARM::tBLXi || Opcode == ARM::tBLXr ||
5708 Opcode == ARM::tBLXr_noip);
5709}
5710
5711std::optional<std::unique_ptr<outliner::OutlinedFunction>>
5713 const MachineModuleInfo &MMI,
5714 std::vector<outliner::Candidate> &RepeatedSequenceLocs,
5715 unsigned MinRepeats) const {
5716 unsigned SequenceSize = 0;
5717 for (auto &MI : RepeatedSequenceLocs[0])
5718 SequenceSize += getInstSizeInBytes(MI);
5719
5720 // Properties about candidate MBBs that hold for all of them.
5721 unsigned FlagsSetInAll = 0xF;
5722
5723 // Compute liveness information for each candidate, and set FlagsSetInAll.
5725 for (outliner::Candidate &C : RepeatedSequenceLocs)
5726 FlagsSetInAll &= C.Flags;
5727
5728 // According to the ARM Procedure Call Standard, the following are
5729 // undefined on entry/exit from a function call:
5730 //
5731 // * Register R12(IP),
5732 // * Condition codes (and thus the CPSR register)
5733 //
5734 // Since we control the instructions which are part of the outlined regions
5735 // we don't need to be fully compliant with the AAPCS, but we have to
5736 // guarantee that if a veneer is inserted at link time the code is still
5737 // correct. Because of this, we can't outline any sequence of instructions
5738 // where one of these registers is live into/across it. Thus, we need to
5739 // delete those candidates.
5740 auto CantGuaranteeValueAcrossCall = [&TRI](outliner::Candidate &C) {
5741 // If the unsafe registers in this block are all dead, then we don't need
5742 // to compute liveness here.
5743 if (C.Flags & UnsafeRegsDead)
5744 return false;
5745 return C.isAnyUnavailableAcrossOrOutOfSeq({ARM::R12, ARM::CPSR}, TRI);
5746 };
5747
5748 // Are there any candidates where those registers are live?
5749 if (!(FlagsSetInAll & UnsafeRegsDead)) {
5750 // Erase every candidate that violates the restrictions above. (It could be
5751 // true that we have viable candidates, so it's not worth bailing out in
5752 // the case that, say, 1 out of 20 candidates violate the restructions.)
5753 llvm::erase_if(RepeatedSequenceLocs, CantGuaranteeValueAcrossCall);
5754
5755 // If the sequence doesn't have enough candidates left, then we're done.
5756 if (RepeatedSequenceLocs.size() < MinRepeats)
5757 return std::nullopt;
5758 }
5759
5760 // We expect the majority of the outlining candidates to be in consensus with
5761 // regard to return address sign and authentication, and branch target
5762 // enforcement, in other words, partitioning according to all the four
5763 // possible combinations of PAC-RET and BTI is going to yield one big subset
5764 // and three small (likely empty) subsets. That allows us to cull incompatible
5765 // candidates separately for PAC-RET and BTI.
5766
5767 // Partition the candidates in two sets: one with BTI enabled and one with BTI
5768 // disabled. Remove the candidates from the smaller set. If they are the same
5769 // number prefer the non-BTI ones for outlining, since they have less
5770 // overhead.
5771 auto NoBTI =
5772 llvm::partition(RepeatedSequenceLocs, [](const outliner::Candidate &C) {
5773 const ARMFunctionInfo &AFI = *C.getMF()->getInfo<ARMFunctionInfo>();
5774 return AFI.branchTargetEnforcement();
5775 });
5776 if (std::distance(RepeatedSequenceLocs.begin(), NoBTI) >
5777 std::distance(NoBTI, RepeatedSequenceLocs.end()))
5778 RepeatedSequenceLocs.erase(NoBTI, RepeatedSequenceLocs.end());
5779 else
5780 RepeatedSequenceLocs.erase(RepeatedSequenceLocs.begin(), NoBTI);
5781
5782 if (RepeatedSequenceLocs.size() < MinRepeats)
5783 return std::nullopt;
5784
5785 // Likewise, partition the candidates according to PAC-RET enablement.
5786 auto NoPAC =
5787 llvm::partition(RepeatedSequenceLocs, [](const outliner::Candidate &C) {
5788 const ARMFunctionInfo &AFI = *C.getMF()->getInfo<ARMFunctionInfo>();
5789 // If the function happens to not spill the LR, do not disqualify it
5790 // from the outlining.
5791 return AFI.shouldSignReturnAddress(true);
5792 });
5793 if (std::distance(RepeatedSequenceLocs.begin(), NoPAC) >
5794 std::distance(NoPAC, RepeatedSequenceLocs.end()))
5795 RepeatedSequenceLocs.erase(NoPAC, RepeatedSequenceLocs.end());
5796 else
5797 RepeatedSequenceLocs.erase(RepeatedSequenceLocs.begin(), NoPAC);
5798
5799 if (RepeatedSequenceLocs.size() < MinRepeats)
5800 return std::nullopt;
5801
5802 // At this point, we have only "safe" candidates to outline. Figure out
5803 // frame + call instruction information.
5804
5805 // Helper lambda which sets call information for every candidate.
5806 auto SetCandidateCallInfo =
5807 [&RepeatedSequenceLocs](unsigned CallID, unsigned NumBytesForCall) {
5808 for (outliner::Candidate &C : RepeatedSequenceLocs)
5809 C.setCallInfo(CallID, NumBytesForCall);
5810 };
5811
5812 OutlinerCosts Costs(Subtarget);
5813
5814 const auto &SomeMFI =
5815 *RepeatedSequenceLocs.front().getMF()->getInfo<ARMFunctionInfo>();
5816 // Adjust costs to account for the BTI instructions.
5817 if (SomeMFI.branchTargetEnforcement()) {
5818 Costs.FrameDefault += 4;
5819 Costs.FrameNoLRSave += 4;
5820 Costs.FrameRegSave += 4;
5821 Costs.FrameTailCall += 4;
5822 Costs.FrameThunk += 4;
5823 }
5824
5825 // Adjust costs to account for sign and authentication instructions.
5826 if (SomeMFI.shouldSignReturnAddress(true)) {
5827 Costs.CallDefault += 8; // +PAC instr, +AUT instr
5828 Costs.SaveRestoreLROnStack += 8; // +PAC instr, +AUT instr
5829 }
5830
5831 unsigned FrameID = MachineOutlinerDefault;
5832 unsigned NumBytesToCreateFrame = Costs.FrameDefault;
5833
5834 // If the last instruction in any candidate is a terminator, then we should
5835 // tail call all of the candidates.
5836 if (RepeatedSequenceLocs[0].back().isTerminator()) {
5837 FrameID = MachineOutlinerTailCall;
5838 NumBytesToCreateFrame = Costs.FrameTailCall;
5839 SetCandidateCallInfo(MachineOutlinerTailCall, Costs.CallTailCall);
5840 } else if (CanTransformInstrIntoTailCall(RepeatedSequenceLocs[0].back())) {
5841 FrameID = MachineOutlinerThunk;
5842 NumBytesToCreateFrame = Costs.FrameThunk;
5843 SetCandidateCallInfo(MachineOutlinerThunk, Costs.CallThunk);
5844 } else {
5845 // We need to decide how to emit calls + frames. We can always emit the same
5846 // frame if we don't need to save to the stack. If we have to save to the
5847 // stack, then we need a different frame.
5848 unsigned NumBytesNoStackCalls = 0;
5849 std::vector<outliner::Candidate> CandidatesWithoutStackFixups;
5850
5851 for (outliner::Candidate &C : RepeatedSequenceLocs) {
5852 // LR liveness is overestimated in return blocks, unless they end with a
5853 // tail call.
5854 const auto Last = C.getMBB()->rbegin();
5855 const bool LRIsAvailable =
5856 C.getMBB()->isReturnBlock() && !Last->isCall()
5859 : C.isAvailableAcrossAndOutOfSeq(ARM::LR, TRI);
5860 if (LRIsAvailable) {
5861 FrameID = MachineOutlinerNoLRSave;
5862 NumBytesNoStackCalls += Costs.CallNoLRSave;
5863 C.setCallInfo(MachineOutlinerNoLRSave, Costs.CallNoLRSave);
5864 CandidatesWithoutStackFixups.push_back(C);
5865 }
5866
5867 // Is an unused register available? If so, we won't modify the stack, so
5868 // we can outline with the same frame type as those that don't save LR.
5869 else if (findRegisterToSaveLRTo(C)) {
5870 FrameID = MachineOutlinerRegSave;
5871 NumBytesNoStackCalls += Costs.CallRegSave;
5872 C.setCallInfo(MachineOutlinerRegSave, Costs.CallRegSave);
5873 CandidatesWithoutStackFixups.push_back(C);
5874 }
5875
5876 // Is SP used in the sequence at all? If not, we don't have to modify
5877 // the stack, so we are guaranteed to get the same frame.
5878 else if (C.isAvailableInsideSeq(ARM::SP, TRI)) {
5879 NumBytesNoStackCalls += Costs.CallDefault;
5880 C.setCallInfo(MachineOutlinerDefault, Costs.CallDefault);
5881 CandidatesWithoutStackFixups.push_back(C);
5882 }
5883
5884 // If we outline this, we need to modify the stack. Pretend we don't
5885 // outline this by saving all of its bytes.
5886 else
5887 NumBytesNoStackCalls += SequenceSize;
5888 }
5889
5890 // If there are no places where we have to save LR, then note that we don't
5891 // have to update the stack. Otherwise, give every candidate the default
5892 // call type
5893 if (NumBytesNoStackCalls <=
5894 RepeatedSequenceLocs.size() * Costs.CallDefault) {
5895 RepeatedSequenceLocs = CandidatesWithoutStackFixups;
5896 FrameID = MachineOutlinerNoLRSave;
5897 if (RepeatedSequenceLocs.size() < MinRepeats)
5898 return std::nullopt;
5899 } else
5900 SetCandidateCallInfo(MachineOutlinerDefault, Costs.CallDefault);
5901 }
5902
5903 // Does every candidate's MBB contain a call? If so, then we might have a
5904 // call in the range.
5905 if (FlagsSetInAll & MachineOutlinerMBBFlags::HasCalls) {
5906 // check if the range contains a call. These require a save + restore of
5907 // the link register.
5908 outliner::Candidate &FirstCand = RepeatedSequenceLocs[0];
5909 if (any_of(drop_end(FirstCand),
5910 [](const MachineInstr &MI) { return MI.isCall(); }))
5911 NumBytesToCreateFrame += Costs.SaveRestoreLROnStack;
5912
5913 // Handle the last instruction separately. If it is tail call, then the
5914 // last instruction is a call, we don't want to save + restore in this
5915 // case. However, it could be possible that the last instruction is a
5916 // call without it being valid to tail call this sequence. We should
5917 // consider this as well.
5918 else if (FrameID != MachineOutlinerThunk &&
5919 FrameID != MachineOutlinerTailCall && FirstCand.back().isCall())
5920 NumBytesToCreateFrame += Costs.SaveRestoreLROnStack;
5921 }
5922
5923 return std::make_unique<outliner::OutlinedFunction>(
5924 RepeatedSequenceLocs, SequenceSize, NumBytesToCreateFrame, FrameID);
5925}
5926
5927bool ARMBaseInstrInfo::checkAndUpdateStackOffset(MachineInstr *MI,
5928 int64_t Fixup,
5929 bool Updt) const {
5930 int SPIdx = MI->findRegisterUseOperandIdx(ARM::SP, /*TRI=*/nullptr);
5931 unsigned AddrMode = (MI->getDesc().TSFlags & ARMII::AddrModeMask);
5932 if (SPIdx < 0)
5933 // No SP operand
5934 return true;
5935 else if (SPIdx != 1 && (AddrMode != ARMII::AddrModeT2_i8s4 || SPIdx != 2))
5936 // If SP is not the base register we can't do much
5937 return false;
5938
5939 // Stack might be involved but addressing mode doesn't handle any offset.
5940 // Rq: AddrModeT1_[1|2|4] don't operate on SP
5941 if (AddrMode == ARMII::AddrMode1 || // Arithmetic instructions
5942 AddrMode == ARMII::AddrMode4 || // Load/Store Multiple
5943 AddrMode == ARMII::AddrMode6 || // Neon Load/Store Multiple
5944 AddrMode == ARMII::AddrModeT2_so || // SP can't be used as based register
5945 AddrMode == ARMII::AddrModeT2_pc || // PCrel access
5946 AddrMode == ARMII::AddrMode2 || // Used by PRE and POST indexed LD/ST
5947 AddrMode == ARMII::AddrModeT2_i7 || // v8.1-M MVE
5948 AddrMode == ARMII::AddrModeT2_i7s2 || // v8.1-M MVE
5949 AddrMode == ARMII::AddrModeT2_i7s4 || // v8.1-M sys regs VLDR/VSTR
5951 AddrMode == ARMII::AddrModeT2_i8 || // Pre/Post inc instructions
5952 AddrMode == ARMII::AddrModeT2_i8neg) // Always negative imm
5953 return false;
5954
5955 unsigned NumOps = MI->getDesc().getNumOperands();
5956 unsigned ImmIdx = NumOps - 3;
5957
5958 const MachineOperand &Offset = MI->getOperand(ImmIdx);
5959 assert(Offset.isImm() && "Is not an immediate");
5960 int64_t OffVal = Offset.getImm();
5961
5962 if (OffVal < 0)
5963 // Don't override data if the are below SP.
5964 return false;
5965
5966 unsigned NumBits = 0;
5967 unsigned Scale = 1;
5968
5969 switch (AddrMode) {
5970 case ARMII::AddrMode3:
5971 if (ARM_AM::getAM3Op(OffVal) == ARM_AM::sub)
5972 return false;
5973 OffVal = ARM_AM::getAM3Offset(OffVal);
5974 NumBits = 8;
5975 break;
5976 case ARMII::AddrMode5:
5977 if (ARM_AM::getAM5Op(OffVal) == ARM_AM::sub)
5978 return false;
5979 OffVal = ARM_AM::getAM5Offset(OffVal);
5980 NumBits = 8;
5981 Scale = 4;
5982 break;
5984 if (ARM_AM::getAM5FP16Op(OffVal) == ARM_AM::sub)
5985 return false;
5986 OffVal = ARM_AM::getAM5FP16Offset(OffVal);
5987 NumBits = 8;
5988 Scale = 2;
5989 break;
5991 NumBits = 8;
5992 break;
5994 // FIXME: Values are already scaled in this addressing mode.
5995 assert((Fixup & 3) == 0 && "Can't encode this offset!");
5996 NumBits = 10;
5997 break;
5999 NumBits = 8;
6000 Scale = 4;
6001 break;
6004 NumBits = 12;
6005 break;
6006 case ARMII::AddrModeT1_s: // SP-relative LD/ST
6007 NumBits = 8;
6008 Scale = 4;
6009 break;
6010 default:
6011 llvm_unreachable("Unsupported addressing mode!");
6012 }
6013 // Make sure the offset is encodable for instructions that scale the
6014 // immediate.
6015 assert(((OffVal * Scale + Fixup) & (Scale - 1)) == 0 &&
6016 "Can't encode this offset!");
6017 OffVal += Fixup / Scale;
6018
6019 unsigned Mask = (1 << NumBits) - 1;
6020
6021 if (OffVal <= Mask) {
6022 if (Updt)
6023 MI->getOperand(ImmIdx).setImm(OffVal);
6024 return true;
6025 }
6026
6027 return false;
6028}
6029
6031 Function &F, std::vector<outliner::Candidate> &Candidates) const {
6032 outliner::Candidate &C = Candidates.front();
6033 // branch-target-enforcement is guaranteed to be consistent between all
6034 // candidates, so we only need to look at one.
6035 const Function &CFn = C.getMF()->getFunction();
6036 if (CFn.hasFnAttribute("branch-target-enforcement"))
6037 F.addFnAttr(CFn.getFnAttribute("branch-target-enforcement"));
6038
6039 if (CFn.hasFnAttribute("sign-return-address"))
6040 F.addFnAttr(CFn.getFnAttribute("sign-return-address"));
6041
6042 ARMGenInstrInfo::mergeOutliningCandidateAttributes(F, Candidates);
6043}
6044
6046 MachineFunction &MF, bool OutlineFromLinkOnceODRs) const {
6047 const Function &F = MF.getFunction();
6048
6049 // Can F be deduplicated by the linker? If it can, don't outline from it.
6050 if (!OutlineFromLinkOnceODRs && F.hasLinkOnceODRLinkage())
6051 return false;
6052
6053 // Don't outline from functions with section markings; the program could
6054 // expect that all the code is in the named section.
6055 // FIXME: Allow outlining from multiple functions with the same section
6056 // marking.
6057 if (F.hasSection())
6058 return false;
6059
6060 // FIXME: Thumb1 outlining is not handled
6062 return false;
6063
6064 // It's safe to outline from MF.
6065 return true;
6066}
6067
6069 unsigned &Flags) const {
6070 // Check if LR is available through all of the MBB. If it's not, then set
6071 // a flag.
6072 assert(MBB.getParent()->getRegInfo().tracksLiveness() &&
6073 "Suitable Machine Function for outlining must track liveness");
6074
6076
6078 LRU.accumulate(MI);
6079
6080 // Check if each of the unsafe registers are available...
6081 bool R12AvailableInBlock = LRU.available(ARM::R12);
6082 bool CPSRAvailableInBlock = LRU.available(ARM::CPSR);
6083
6084 // If all of these are dead (and not live out), we know we don't have to check
6085 // them later.
6086 if (R12AvailableInBlock && CPSRAvailableInBlock)
6088
6089 // Now, add the live outs to the set.
6090 LRU.addLiveOuts(MBB);
6091
6092 // If any of these registers is available in the MBB, but also a live out of
6093 // the block, then we know outlining is unsafe.
6094 if (R12AvailableInBlock && !LRU.available(ARM::R12))
6095 return false;
6096 if (CPSRAvailableInBlock && !LRU.available(ARM::CPSR))
6097 return false;
6098
6099 // Check if there's a call inside this MachineBasicBlock. If there is, then
6100 // set a flag.
6101 if (any_of(MBB, [](MachineInstr &MI) { return MI.isCall(); }))
6103
6104 // LR liveness is overestimated in return blocks.
6105
6106 bool LRIsAvailable =
6107 MBB.isReturnBlock() && !MBB.back().isCall()
6108 ? isLRAvailable(getRegisterInfo(), MBB.rbegin(), MBB.rend())
6109 : LRU.available(ARM::LR);
6110 if (!LRIsAvailable)
6112
6113 return true;
6114}
6115
6119 unsigned Flags) const {
6120 MachineInstr &MI = *MIT;
6122
6123 // PIC instructions contain labels, outlining them would break offset
6124 // computing. unsigned Opc = MI.getOpcode();
6125 unsigned Opc = MI.getOpcode();
6126 if (Opc == ARM::tPICADD || Opc == ARM::PICADD || Opc == ARM::PICSTR ||
6127 Opc == ARM::PICSTRB || Opc == ARM::PICSTRH || Opc == ARM::PICLDR ||
6128 Opc == ARM::PICLDRB || Opc == ARM::PICLDRH || Opc == ARM::PICLDRSB ||
6129 Opc == ARM::PICLDRSH || Opc == ARM::t2LDRpci_pic ||
6130 Opc == ARM::t2MOVi16_ga_pcrel || Opc == ARM::t2MOVTi16_ga_pcrel ||
6131 Opc == ARM::t2MOV_ga_pcrel)
6133
6134 // Be conservative with ARMv8.1 MVE instructions.
6135 if (Opc == ARM::t2BF_LabelPseudo || Opc == ARM::t2DoLoopStart ||
6136 Opc == ARM::t2DoLoopStartTP || Opc == ARM::t2WhileLoopStart ||
6137 Opc == ARM::t2WhileLoopStartLR || Opc == ARM::t2WhileLoopStartTP ||
6138 Opc == ARM::t2LoopDec || Opc == ARM::t2LoopEnd ||
6139 Opc == ARM::t2LoopEndDec)
6141
6142 const MCInstrDesc &MCID = MI.getDesc();
6143 uint64_t MIFlags = MCID.TSFlags;
6144 if ((MIFlags & ARMII::DomainMask) == ARMII::DomainMVE)
6146
6147 // Is this a terminator for a basic block?
6148 if (MI.isTerminator())
6149 // TargetInstrInfo::getOutliningType has already filtered out anything
6150 // that would break this, so we can allow it here.
6152
6153 // Don't outline if link register or program counter value are used.
6154 if (MI.readsRegister(ARM::LR, TRI) || MI.readsRegister(ARM::PC, TRI))
6156
6157 if (MI.isCall()) {
6158 // Get the function associated with the call. Look at each operand and find
6159 // the one that represents the calle and get its name.
6160 const Function *Callee = nullptr;
6161 for (const MachineOperand &MOP : MI.operands()) {
6162 if (MOP.isGlobal()) {
6163 Callee = dyn_cast<Function>(MOP.getGlobal());
6164 break;
6165 }
6166 }
6167
6168 // Dont't outline calls to "mcount" like functions, in particular Linux
6169 // kernel function tracing relies on it.
6170 if (Callee &&
6171 (Callee->getName() == "\01__gnu_mcount_nc" ||
6172 Callee->getName() == "\01mcount" || Callee->getName() == "__mcount"))
6174
6175 // If we don't know anything about the callee, assume it depends on the
6176 // stack layout of the caller. In that case, it's only legal to outline
6177 // as a tail-call. Explicitly list the call instructions we know about so
6178 // we don't get unexpected results with call pseudo-instructions.
6179 auto UnknownCallOutlineType = outliner::InstrType::Illegal;
6181 UnknownCallOutlineType = outliner::InstrType::LegalTerminator;
6182
6183 if (!Callee)
6184 return UnknownCallOutlineType;
6185
6186 // We have a function we have information about. Check if it's something we
6187 // can safely outline.
6188 MachineFunction *CalleeMF = MMI.getMachineFunction(*Callee);
6189
6190 // We don't know what's going on with the callee at all. Don't touch it.
6191 if (!CalleeMF)
6192 return UnknownCallOutlineType;
6193
6194 // Check if we know anything about the callee saves on the function. If we
6195 // don't, then don't touch it, since that implies that we haven't computed
6196 // anything about its stack frame yet.
6197 MachineFrameInfo &MFI = CalleeMF->getFrameInfo();
6198 if (!MFI.isCalleeSavedInfoValid() || MFI.getStackSize() > 0 ||
6199 MFI.getNumObjects() > 0)
6200 return UnknownCallOutlineType;
6201
6202 // At this point, we can say that CalleeMF ought to not pass anything on the
6203 // stack. Therefore, we can outline it.
6205 }
6206
6207 // Since calls are handled, don't touch LR or PC
6208 if (MI.modifiesRegister(ARM::LR, TRI) || MI.modifiesRegister(ARM::PC, TRI))
6210
6211 // Does this use the stack?
6212 if (MI.modifiesRegister(ARM::SP, TRI) || MI.readsRegister(ARM::SP, TRI)) {
6213 // True if there is no chance that any outlined candidate from this range
6214 // could require stack fixups. That is, both
6215 // * LR is available in the range (No save/restore around call)
6216 // * The range doesn't include calls (No save/restore in outlined frame)
6217 // are true.
6218 // These conditions also ensure correctness of the return address
6219 // authentication - we insert sign and authentication instructions only if
6220 // we save/restore LR on stack, but then this condition ensures that the
6221 // outlined range does not modify the SP, therefore the SP value used for
6222 // signing is the same as the one used for authentication.
6223 // FIXME: This is very restrictive; the flags check the whole block,
6224 // not just the bit we will try to outline.
6225 bool MightNeedStackFixUp =
6228
6229 if (!MightNeedStackFixUp)
6231
6232 // Any modification of SP will break our code to save/restore LR.
6233 // FIXME: We could handle some instructions which add a constant offset to
6234 // SP, with a bit more work.
6235 if (MI.modifiesRegister(ARM::SP, TRI))
6237
6238 // At this point, we have a stack instruction that we might need to fix up.
6239 // up. We'll handle it if it's a load or store.
6240 if (checkAndUpdateStackOffset(&MI, Subtarget.getStackAlignment().value(),
6241 false))
6243
6244 // We can't fix it up, so don't outline it.
6246 }
6247
6248 // Be conservative with IT blocks.
6249 if (MI.readsRegister(ARM::ITSTATE, TRI) ||
6250 MI.modifiesRegister(ARM::ITSTATE, TRI))
6252
6253 // Don't outline CFI instructions.
6254 if (MI.isCFIInstruction())
6256
6258}
6259
6260void ARMBaseInstrInfo::fixupPostOutline(MachineBasicBlock &MBB) const {
6261 for (MachineInstr &MI : MBB) {
6262 checkAndUpdateStackOffset(&MI, Subtarget.getStackAlignment().value(), true);
6263 }
6264}
6265
6266void ARMBaseInstrInfo::saveLROnStack(MachineBasicBlock &MBB,
6267 MachineBasicBlock::iterator It, bool CFI,
6268 bool Auth) const {
6269 int Align = std::max(Subtarget.getStackAlignment().value(), uint64_t(8));
6270 unsigned MIFlags = CFI ? MachineInstr::FrameSetup : 0;
6271 assert(Align >= 8 && Align <= 256);
6272 if (Auth) {
6273 assert(Subtarget.isThumb2());
6274 // Compute PAC in R12. Outlining ensures R12 is dead across the outlined
6275 // sequence.
6276 BuildMI(MBB, It, DebugLoc(), get(ARM::t2PAC)).setMIFlags(MIFlags);
6277 BuildMI(MBB, It, DebugLoc(), get(ARM::t2STRD_PRE), ARM::SP)
6278 .addReg(ARM::R12, RegState::Kill)
6279 .addReg(ARM::LR, RegState::Kill)
6280 .addReg(ARM::SP)
6281 .addImm(-Align)
6283 .setMIFlags(MIFlags);
6284 } else {
6285 unsigned Opc = Subtarget.isThumb() ? ARM::t2STR_PRE : ARM::STR_PRE_IMM;
6286 BuildMI(MBB, It, DebugLoc(), get(Opc), ARM::SP)
6287 .addReg(ARM::LR, RegState::Kill)
6288 .addReg(ARM::SP)
6289 .addImm(-Align)
6291 .setMIFlags(MIFlags);
6292 }
6293
6294 if (!CFI)
6295 return;
6296
6297 // Add a CFI, saying CFA is offset by Align bytes from SP.
6298 CFIInstBuilder CFIBuilder(MBB, It, MachineInstr::FrameSetup);
6299 CFIBuilder.buildDefCFAOffset(Align);
6300
6301 // Add a CFI saying that the LR that we want to find is now higher than
6302 // before.
6303 int LROffset = Auth ? Align - 4 : Align;
6304 CFIBuilder.buildOffset(ARM::LR, -LROffset);
6305 if (Auth) {
6306 // Add a CFI for the location of the return address PAC.
6307 CFIBuilder.buildOffset(ARM::RA_AUTH_CODE, -Align);
6308 }
6309}
6310
6311void ARMBaseInstrInfo::restoreLRFromStack(MachineBasicBlock &MBB,
6313 bool CFI, bool Auth) const {
6314 int Align = Subtarget.getStackAlignment().value();
6315 unsigned MIFlags = CFI ? MachineInstr::FrameDestroy : 0;
6316 if (Auth) {
6317 assert(Subtarget.isThumb2());
6318 // Restore return address PAC and LR.
6319 BuildMI(MBB, It, DebugLoc(), get(ARM::t2LDRD_POST))
6320 .addReg(ARM::R12, RegState::Define)
6321 .addReg(ARM::LR, RegState::Define)
6322 .addReg(ARM::SP, RegState::Define)
6323 .addReg(ARM::SP)
6324 .addImm(Align)
6326 .setMIFlags(MIFlags);
6327 // LR authentication is after the CFI instructions, below.
6328 } else {
6329 unsigned Opc = Subtarget.isThumb() ? ARM::t2LDR_POST : ARM::LDR_POST_IMM;
6330 MachineInstrBuilder MIB = BuildMI(MBB, It, DebugLoc(), get(Opc), ARM::LR)
6331 .addReg(ARM::SP, RegState::Define)
6332 .addReg(ARM::SP);
6333 if (!Subtarget.isThumb())
6334 MIB.addReg(0);
6335 MIB.addImm(Subtarget.getStackAlignment().value())
6337 .setMIFlags(MIFlags);
6338 }
6339
6340 if (CFI) {
6341 // Now stack has moved back up and we have restored LR.
6342 CFIInstBuilder CFIBuilder(MBB, It, MachineInstr::FrameDestroy);
6343 CFIBuilder.buildDefCFAOffset(0);
6344 CFIBuilder.buildRestore(ARM::LR);
6345 if (Auth)
6346 CFIBuilder.buildUndefined(ARM::RA_AUTH_CODE);
6347 }
6348
6349 if (Auth)
6350 BuildMI(MBB, It, DebugLoc(), get(ARM::t2AUT));
6351}
6352
6355 const outliner::OutlinedFunction &OF) const {
6356 // For thunk outlining, rewrite the last instruction from a call to a
6357 // tail-call.
6358 if (OF.FrameConstructionID == MachineOutlinerThunk) {
6359 MachineInstr *Call = &*--MBB.instr_end();
6360 bool isThumb = Subtarget.isThumb();
6361 unsigned FuncOp = isThumb ? 2 : 0;
6362 unsigned Opc = Call->getOperand(FuncOp).isReg()
6363 ? isThumb ? ARM::tTAILJMPr : ARM::TAILJMPr
6364 : isThumb ? Subtarget.isTargetMachO() ? ARM::tTAILJMPd
6365 : ARM::tTAILJMPdND
6366 : ARM::TAILJMPd;
6367 MachineInstrBuilder MIB = BuildMI(MBB, MBB.end(), DebugLoc(), get(Opc))
6368 .add(Call->getOperand(FuncOp));
6369 if (isThumb && !Call->getOperand(FuncOp).isReg())
6370 MIB.add(predOps(ARMCC::AL));
6371 Call->eraseFromParent();
6372 }
6373
6374 // Is there a call in the outlined range?
6375 auto IsNonTailCall = [](MachineInstr &MI) {
6376 return MI.isCall() && !MI.isReturn();
6377 };
6378 if (llvm::any_of(MBB.instrs(), IsNonTailCall)) {
6379 MachineBasicBlock::iterator It = MBB.begin();
6381
6382 if (OF.FrameConstructionID == MachineOutlinerTailCall ||
6383 OF.FrameConstructionID == MachineOutlinerThunk)
6384 Et = std::prev(MBB.end());
6385
6386 // We have to save and restore LR, we need to add it to the liveins if it
6387 // is not already part of the set. This is sufficient since outlined
6388 // functions only have one block.
6389 if (!MBB.isLiveIn(ARM::LR))
6390 MBB.addLiveIn(ARM::LR);
6391
6392 // Insert a save before the outlined region
6393 bool Auth = MF.getInfo<ARMFunctionInfo>()->shouldSignReturnAddress(true);
6394 saveLROnStack(MBB, It, true, Auth);
6395
6396 // Fix up the instructions in the range, since we're going to modify the
6397 // stack.
6398 assert(OF.FrameConstructionID != MachineOutlinerDefault &&
6399 "Can only fix up stack references once");
6400 fixupPostOutline(MBB);
6401
6402 // Insert a restore before the terminator for the function. Restore LR.
6403 restoreLRFromStack(MBB, Et, true, Auth);
6404 }
6405
6406 // If this is a tail call outlined function, then there's already a return.
6407 if (OF.FrameConstructionID == MachineOutlinerTailCall ||
6408 OF.FrameConstructionID == MachineOutlinerThunk)
6409 return;
6410
6411 // Here we have to insert the return ourselves. Get the correct opcode from
6412 // current feature set.
6413 BuildMI(MBB, MBB.end(), DebugLoc(), get(Subtarget.getReturnOpcode()))
6415
6416 // Did we have to modify the stack by saving the link register?
6417 if (OF.FrameConstructionID != MachineOutlinerDefault &&
6418 OF.Candidates[0].CallConstructionID != MachineOutlinerDefault)
6419 return;
6420
6421 // We modified the stack.
6422 // Walk over the basic block and fix up all the stack accesses.
6423 fixupPostOutline(MBB);
6424}
6425
6431 unsigned Opc;
6432 bool isThumb = Subtarget.isThumb();
6433
6434 // Are we tail calling?
6435 if (C.CallConstructionID == MachineOutlinerTailCall) {
6436 // If yes, then we can just branch to the label.
6437 Opc = isThumb
6438 ? Subtarget.isTargetMachO() ? ARM::tTAILJMPd : ARM::tTAILJMPdND
6439 : ARM::TAILJMPd;
6440 MIB = BuildMI(MF, DebugLoc(), get(Opc))
6441 .addGlobalAddress(M.getNamedValue(MF.getName()));
6442 if (isThumb)
6443 MIB.add(predOps(ARMCC::AL));
6444 It = MBB.insert(It, MIB);
6445 return It;
6446 }
6447
6448 // Create the call instruction.
6449 Opc = isThumb ? ARM::tBL : ARM::BL;
6450 MachineInstrBuilder CallMIB = BuildMI(MF, DebugLoc(), get(Opc));
6451 if (isThumb)
6452 CallMIB.add(predOps(ARMCC::AL));
6453 CallMIB.addGlobalAddress(M.getNamedValue(MF.getName()));
6454
6455 if (C.CallConstructionID == MachineOutlinerNoLRSave ||
6456 C.CallConstructionID == MachineOutlinerThunk) {
6457 // No, so just insert the call.
6458 It = MBB.insert(It, CallMIB);
6459 return It;
6460 }
6461
6462 const ARMFunctionInfo &AFI = *C.getMF()->getInfo<ARMFunctionInfo>();
6463 // Can we save to a register?
6464 if (C.CallConstructionID == MachineOutlinerRegSave) {
6465 Register Reg = findRegisterToSaveLRTo(C);
6466 assert(Reg != 0 && "No callee-saved register available?");
6467
6468 // Save and restore LR from that register.
6469 copyPhysReg(MBB, It, DebugLoc(), Reg, ARM::LR, true);
6470 if (!AFI.isLRSpilled())
6472 .buildRegister(ARM::LR, Reg);
6473 CallPt = MBB.insert(It, CallMIB);
6474 copyPhysReg(MBB, It, DebugLoc(), ARM::LR, Reg, true);
6475 if (!AFI.isLRSpilled())
6477 It--;
6478 return CallPt;
6479 }
6480 // We have the default case. Save and restore from SP.
6481 if (!MBB.isLiveIn(ARM::LR))
6482 MBB.addLiveIn(ARM::LR);
6483 bool Auth = !AFI.isLRSpilled() && AFI.shouldSignReturnAddress(true);
6484 saveLROnStack(MBB, It, !AFI.isLRSpilled(), Auth);
6485 CallPt = MBB.insert(It, CallMIB);
6486 restoreLRFromStack(MBB, It, !AFI.isLRSpilled(), Auth);
6487 It--;
6488 return CallPt;
6489}
6490
6492 MachineFunction &MF) const {
6493 return Subtarget.isMClass() && MF.getFunction().hasMinSize();
6494}
6495
6496bool ARMBaseInstrInfo::isReMaterializableImpl(
6497 const MachineInstr &MI) const {
6498 // Try hard to rematerialize any VCTPs because if we spill P0, it will block
6499 // the tail predication conversion. This means that the element count
6500 // register has to be live for longer, but that has to be better than
6501 // spill/restore and VPT predication.
6502 return (isVCTP(&MI) && !isPredicated(MI)) ||
6504}
6505
6507 return (MF.getSubtarget<ARMSubtarget>().hardenSlsBlr()) ? ARM::BLX_noip
6508 : ARM::BLX;
6509}
6510
6512 return (MF.getSubtarget<ARMSubtarget>().hardenSlsBlr()) ? ARM::tBLXr_noip
6513 : ARM::tBLXr;
6514}
6515
6517 return (MF.getSubtarget<ARMSubtarget>().hardenSlsBlr()) ? ARM::BLX_pred_noip
6518 : ARM::BLX_pred;
6519}
6520
6521namespace {
6522class ARMPipelinerLoopInfo : public TargetInstrInfo::PipelinerLoopInfo {
6523 MachineInstr *EndLoop, *LoopCount;
6524 MachineFunction *MF;
6525 const TargetInstrInfo *TII;
6526
6527 // Bitset[0 .. MAX_STAGES-1] ... iterations needed
6528 // [LAST_IS_USE] : last reference to register in schedule is a use
6529 // [SEEN_AS_LIVE] : Normal pressure algorithm believes register is live
6530 static int constexpr MAX_STAGES = 30;
6531 static int constexpr LAST_IS_USE = MAX_STAGES;
6532 static int constexpr SEEN_AS_LIVE = MAX_STAGES + 1;
6533 typedef std::bitset<MAX_STAGES + 2> IterNeed;
6534 typedef std::map<Register, IterNeed> IterNeeds;
6535
6536 void bumpCrossIterationPressure(RegPressureTracker &RPT,
6537 const IterNeeds &CIN);
6538 bool tooMuchRegisterPressure(SwingSchedulerDAG &SSD, SMSchedule &SMS);
6539
6540 // Meanings of the various stuff with loop types:
6541 // t2Bcc:
6542 // EndLoop = branch at end of original BB that will become a kernel
6543 // LoopCount = CC setter live into branch
6544 // t2LoopEnd:
6545 // EndLoop = branch at end of original BB
6546 // LoopCount = t2LoopDec
6547public:
6548 ARMPipelinerLoopInfo(MachineInstr *EndLoop, MachineInstr *LoopCount)
6549 : EndLoop(EndLoop), LoopCount(LoopCount),
6550 MF(EndLoop->getParent()->getParent()),
6551 TII(MF->getSubtarget().getInstrInfo()) {}
6552
6553 bool shouldIgnoreForPipelining(const MachineInstr *MI) const override {
6554 // Only ignore the terminator.
6555 return MI == EndLoop || MI == LoopCount;
6556 }
6557
6558 bool shouldUseSchedule(SwingSchedulerDAG &SSD, SMSchedule &SMS) override {
6559 if (tooMuchRegisterPressure(SSD, SMS))
6560 return false;
6561
6562 return true;
6563 }
6564
6565 std::optional<bool> createTripCountGreaterCondition(
6566 int TC, MachineBasicBlock &MBB,
6567 SmallVectorImpl<MachineOperand> &Cond) override {
6568
6569 if (isCondBranchOpcode(EndLoop->getOpcode())) {
6570 Cond.push_back(EndLoop->getOperand(1));
6571 Cond.push_back(EndLoop->getOperand(2));
6572 if (EndLoop->getOperand(0).getMBB() == EndLoop->getParent()) {
6574 }
6575 return {};
6576 } else if (EndLoop->getOpcode() == ARM::t2LoopEnd) {
6577 // General case just lets the unrolled t2LoopDec do the subtraction and
6578 // therefore just needs to check if zero has been reached.
6579 MachineInstr *LoopDec = nullptr;
6580 for (auto &I : MBB.instrs())
6581 if (I.getOpcode() == ARM::t2LoopDec)
6582 LoopDec = &I;
6583 assert(LoopDec && "Unable to find copied LoopDec");
6584 // Check if we're done with the loop.
6585 BuildMI(&MBB, LoopDec->getDebugLoc(), TII->get(ARM::t2CMPri))
6586 .addReg(LoopDec->getOperand(0).getReg())
6587 .addImm(0)
6589 .addReg(ARM::NoRegister);
6591 Cond.push_back(MachineOperand::CreateReg(ARM::CPSR, false));
6592 return {};
6593 } else
6594 llvm_unreachable("Unknown EndLoop");
6595 }
6596
6597 void setPreheader(MachineBasicBlock *NewPreheader) override {}
6598
6599 void adjustTripCount(int TripCountAdjust) override {}
6600};
6601
6602void ARMPipelinerLoopInfo::bumpCrossIterationPressure(RegPressureTracker &RPT,
6603 const IterNeeds &CIN) {
6604 // Increase pressure by the amounts in CrossIterationNeeds
6605 for (const auto &N : CIN) {
6606 int Cnt = N.second.count() - N.second[SEEN_AS_LIVE] * 2;
6607 for (int I = 0; I < Cnt; ++I)
6610 }
6611 // Decrease pressure by the amounts in CrossIterationNeeds
6612 for (const auto &N : CIN) {
6613 int Cnt = N.second.count() - N.second[SEEN_AS_LIVE] * 2;
6614 for (int I = 0; I < Cnt; ++I)
6617 }
6618}
6619
6620bool ARMPipelinerLoopInfo::tooMuchRegisterPressure(SwingSchedulerDAG &SSD,
6621 SMSchedule &SMS) {
6622 IterNeeds CrossIterationNeeds;
6623
6624 // Determine which values will be loop-carried after the schedule is
6625 // applied
6626
6627 for (auto &SU : SSD.SUnits) {
6628 const MachineInstr *MI = SU.getInstr();
6629 int Stg = SMS.stageScheduled(const_cast<SUnit *>(&SU));
6630 for (auto &S : SU.Succs)
6631 if (MI->isPHI() && S.getKind() == SDep::Anti) {
6632 Register Reg = S.getReg();
6633 if (Reg.isVirtual())
6634 CrossIterationNeeds[Reg.id()].set(0);
6635 } else if (S.isAssignedRegDep()) {
6636 int OStg = SMS.stageScheduled(S.getSUnit());
6637 if (OStg >= 0 && OStg != Stg) {
6638 Register Reg = S.getReg();
6639 if (Reg.isVirtual())
6640 CrossIterationNeeds[Reg.id()] |= ((1 << (OStg - Stg)) - 1);
6641 }
6642 }
6643 }
6644
6645 // Determine more-or-less what the proposed schedule (reversed) is going to
6646 // be; it might not be quite the same because the within-cycle ordering
6647 // created by SMSchedule depends upon changes to help with address offsets and
6648 // the like.
6649 std::vector<SUnit *> ProposedSchedule;
6650 for (int Cycle = SMS.getFinalCycle(); Cycle >= SMS.getFirstCycle(); --Cycle)
6651 for (int Stage = 0, StageEnd = SMS.getMaxStageCount(); Stage <= StageEnd;
6652 ++Stage) {
6653 std::deque<SUnit *> Instrs =
6654 SMS.getInstructions(Cycle + Stage * SMS.getInitiationInterval());
6655 std::sort(Instrs.begin(), Instrs.end(),
6656 [](SUnit *A, SUnit *B) { return A->NodeNum > B->NodeNum; });
6657 llvm::append_range(ProposedSchedule, Instrs);
6658 }
6659
6660 // Learn whether the last use/def of each cross-iteration register is a use or
6661 // def. If it is a def, RegisterPressure will implicitly increase max pressure
6662 // and we do not have to add the pressure.
6663 for (auto *SU : ProposedSchedule)
6664 for (ConstMIBundleOperands OperI(*SU->getInstr()); OperI.isValid();
6665 ++OperI) {
6666 auto MO = *OperI;
6667 if (!MO.isReg() || !MO.getReg())
6668 continue;
6669 Register Reg = MO.getReg();
6670 auto CIter = CrossIterationNeeds.find(Reg.id());
6671 if (CIter == CrossIterationNeeds.end() || CIter->second[LAST_IS_USE] ||
6672 CIter->second[SEEN_AS_LIVE])
6673 continue;
6674 if (MO.isDef() && !MO.isDead())
6675 CIter->second.set(SEEN_AS_LIVE);
6676 else if (MO.isUse())
6677 CIter->second.set(LAST_IS_USE);
6678 }
6679 for (auto &CI : CrossIterationNeeds)
6680 CI.second.reset(LAST_IS_USE);
6681
6682 RegionPressure RecRegPressure;
6683 RegPressureTracker RPTracker(RecRegPressure);
6684 RegisterClassInfo RegClassInfo;
6685 RegClassInfo.runOnMachineFunction(*MF);
6686 RPTracker.init(MF, &RegClassInfo, nullptr, EndLoop->getParent(),
6687 EndLoop->getParent()->end(), false, false);
6688
6689 bumpCrossIterationPressure(RPTracker, CrossIterationNeeds);
6690
6691 for (auto *SU : ProposedSchedule) {
6692 MachineBasicBlock::const_iterator CurInstI = SU->getInstr();
6693 RPTracker.setPos(std::next(CurInstI));
6694 RPTracker.recede();
6695
6696 // Track what cross-iteration registers would be seen as live
6697 for (ConstMIBundleOperands OperI(*CurInstI); OperI.isValid(); ++OperI) {
6698 auto MO = *OperI;
6699 if (!MO.isReg() || !MO.getReg())
6700 continue;
6701 Register Reg = MO.getReg();
6702 if (MO.isDef() && !MO.isDead()) {
6703 auto CIter = CrossIterationNeeds.find(Reg.id());
6704 if (CIter != CrossIterationNeeds.end()) {
6705 CIter->second.reset(0);
6706 CIter->second.reset(SEEN_AS_LIVE);
6707 }
6708 }
6709 }
6710 for (auto &S : SU->Preds) {
6711 auto Stg = SMS.stageScheduled(SU);
6712 if (S.isAssignedRegDep()) {
6713 Register Reg = S.getReg();
6714 auto CIter = CrossIterationNeeds.find(Reg.id());
6715 if (CIter != CrossIterationNeeds.end()) {
6716 auto Stg2 = SMS.stageScheduled(S.getSUnit());
6717 assert(Stg2 <= Stg && "Data dependence upon earlier stage");
6718 if (Stg - Stg2 < MAX_STAGES)
6719 CIter->second.set(Stg - Stg2);
6720 CIter->second.set(SEEN_AS_LIVE);
6721 }
6722 }
6723 }
6724
6725 bumpCrossIterationPressure(RPTracker, CrossIterationNeeds);
6726 }
6727
6728 auto &P = RPTracker.getPressure().MaxSetPressure;
6729 for (unsigned I = 0, E = P.size(); I < E; ++I) {
6730 // Exclude some Neon register classes.
6731 if (I == ARM::DQuad_with_ssub_0 || I == ARM::DTripleSpc_with_ssub_0 ||
6732 I == ARM::DTriple_with_qsub_0_in_QPR)
6733 continue;
6734
6735 if (P[I] > RegClassInfo.getRegPressureSetLimit(I)) {
6736 return true;
6737 }
6738 }
6739 return false;
6740}
6741
6742} // namespace
6743
6744std::unique_ptr<TargetInstrInfo::PipelinerLoopInfo>
6747 MachineBasicBlock *Preheader = *LoopBB->pred_begin();
6748 if (Preheader == LoopBB)
6749 Preheader = *std::next(LoopBB->pred_begin());
6750
6751 if (I != LoopBB->end() && I->getOpcode() == ARM::t2Bcc) {
6752 // If the branch is a Bcc, then the CPSR should be set somewhere within the
6753 // block. We need to determine the reaching definition of CPSR so that
6754 // it can be marked as non-pipelineable, allowing the pipeliner to force
6755 // it into stage 0 or give up if it cannot or will not do so.
6756 MachineInstr *CCSetter = nullptr;
6757 for (auto &L : LoopBB->instrs()) {
6758 if (L.isCall())
6759 return nullptr;
6760 if (isCPSRDefined(L))
6761 CCSetter = &L;
6762 }
6763 if (CCSetter)
6764 return std::make_unique<ARMPipelinerLoopInfo>(&*I, CCSetter);
6765 else
6766 return nullptr; // Unable to find the CC setter, so unable to guarantee
6767 // that pipeline will work
6768 }
6769
6770 // Recognize:
6771 // preheader:
6772 // %1 = t2DoopLoopStart %0
6773 // loop:
6774 // %2 = phi %1, <not loop>, %..., %loop
6775 // %3 = t2LoopDec %2, <imm>
6776 // t2LoopEnd %3, %loop
6777
6778 if (I != LoopBB->end() && I->getOpcode() == ARM::t2LoopEnd) {
6779 for (auto &L : LoopBB->instrs())
6780 if (L.isCall())
6781 return nullptr;
6782 else if (isVCTP(&L))
6783 return nullptr;
6784 Register LoopDecResult = I->getOperand(0).getReg();
6785 MachineRegisterInfo &MRI = LoopBB->getParent()->getRegInfo();
6786 MachineInstr *LoopDec = MRI.getUniqueVRegDef(LoopDecResult);
6787 if (!LoopDec || LoopDec->getOpcode() != ARM::t2LoopDec)
6788 return nullptr;
6789 MachineInstr *LoopStart = nullptr;
6790 for (auto &J : Preheader->instrs())
6791 if (J.getOpcode() == ARM::t2DoLoopStart)
6792 LoopStart = &J;
6793 if (!LoopStart)
6794 return nullptr;
6795 return std::make_unique<ARMPipelinerLoopInfo>(&*I, LoopDec);
6796 }
6797 return nullptr;
6798}
MachineInstrBuilder & UseMI
MachineInstrBuilder MachineInstrBuilder & DefMI
MachineOutlinerMBBFlags
@ LRUnavailableSomewhere
@ UnsafeRegsDead
MachineOutlinerClass
Constants defining how certain sequences should be outlined.
@ MachineOutlinerTailCall
Emit a save, restore, call, and return.
@ MachineOutlinerRegSave
Emit a call and tail-call.
@ MachineOutlinerNoLRSave
Only emit a branch.
@ MachineOutlinerThunk
Emit a call and return.
@ MachineOutlinerDefault
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
unsigned Imm
unsigned uint64_t
static bool isThumb(const MCSubtargetInfo &STI)
static bool getImplicitSPRUseForDPRUse(const TargetRegisterInfo *TRI, MachineInstr &MI, MCRegister DReg, unsigned Lane, MCRegister &ImplicitSReg)
getImplicitSPRUseForDPRUse - Given a use of a DPR register and lane, set ImplicitSReg to a register n...
static const MachineInstr * getBundledUseMI(const TargetRegisterInfo *TRI, const MachineInstr &MI, unsigned Reg, unsigned &UseIdx, unsigned &Dist)
static unsigned duplicateCPV(MachineFunction &MF, unsigned &CPI)
Create a copy of a const pool value.
static bool isSuitableForMask(MachineInstr *&MI, Register SrcReg, int CmpMask, bool CommonUse)
isSuitableForMask - Identify a suitable 'and' instruction that operates on the given source register ...
static int adjustDefLatency(const ARMSubtarget &Subtarget, const MachineInstr &DefMI, const MCInstrDesc &DefMCID, unsigned DefAlign)
Return the number of cycles to add to (or subtract from) the static itinerary based on the def opcode...
static unsigned getNumMicroOpsSwiftLdSt(const InstrItineraryData *ItinData, const MachineInstr &MI)
static MCRegister getCorrespondingDRegAndLane(const TargetRegisterInfo *TRI, unsigned SReg, unsigned &Lane)
static bool CanTransformInstrIntoTailCall(const MachineInstr &MI)
Return true if MI is a call instruction that the outliner can rewrite as a tail call.
static const AddSubFlagsOpcodePair AddSubFlagsOpcodeMap[]
static bool isEligibleForITBlock(const MachineInstr *MI)
static ARMCC::CondCodes getCmpToAddCondition(ARMCC::CondCodes CC)
getCmpToAddCondition - assume the flags are set by CMP(a,b), return the condition code if we modify t...
static bool isOptimizeCompareCandidate(MachineInstr *MI, bool &IsThumb1)
static bool isLRAvailable(const TargetRegisterInfo &TRI, MachineBasicBlock::reverse_iterator I, MachineBasicBlock::reverse_iterator E)
static const ARM_MLxEntry ARM_MLxTable[]
static bool isRedundantFlagInstr(const MachineInstr *CmpI, Register SrcReg, Register SrcReg2, int64_t ImmValue, const MachineInstr *OI, bool &IsThumb1)
isRedundantFlagInstr - check whether the first instruction, whose only purpose is to update flags,...
static unsigned getNumMicroOpsSingleIssuePlusExtras(unsigned Opc, unsigned NumRegs)
static const MachineInstr * getBundledDefMI(const TargetRegisterInfo *TRI, const MachineInstr *MI, unsigned Reg, unsigned &DefIdx, unsigned &Dist)
MachineBasicBlock & MBB
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
MachineBasicBlock MachineBasicBlock::iterator MBBI
This file contains the simple types necessary to represent the attributes associated with functions a...
static const Function * getParent(const Value *V)
static GCRegistry::Add< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
DXIL Forward Handle Accesses
This file defines the DenseMap class.
const HexagonInstrInfo * TII
IRTranslator LLVM IR MI
Module.h This file contains the declarations for the Module class.
const size_t AbstractManglingParser< Derived, Alloc >::NumOps
#define F(x, y, z)
Definition MD5.cpp:54
#define I(x, y, z)
Definition MD5.cpp:57
This file declares the MachineConstantPool class which is an abstract constant pool to keep track of ...
TargetInstrInfo::RegSubRegPair RegSubRegPair
Register Reg
Register const TargetRegisterInfo * TRI
Promote Memory to Register
Definition Mem2Reg.cpp:110
static MCRegister getReg(const MCDisassembler *D, unsigned RC, unsigned RegNo)
uint64_t IntrinsicInst * II
#define P(N)
PowerPC TLS Dynamic Call Fixup
TargetInstrInfo::RegSubRegPairAndIdx RegSubRegPairAndIdx
const SmallVectorImpl< MachineOperand > MachineBasicBlock * TBB
const SmallVectorImpl< MachineOperand > & Cond
This file contains some templates that are useful if you are working with the STL at all.
static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)
Definition Value.cpp:484
This file defines the SmallSet class.
This file defines the SmallVector class.
#define LLVM_DEBUG(...)
Definition Debug.h:119
static X86::CondCode getSwappedCondition(X86::CondCode CC)
Assuming the flags are set by MI(a,b), return the condition code if we modify the instructions such t...
static bool isCPSRDefined(const MachineInstr &MI)
bool optimizeCompareInstr(MachineInstr &CmpInstr, Register SrcReg, Register SrcReg2, int64_t CmpMask, int64_t CmpValue, const MachineRegisterInfo *MRI) const override
optimizeCompareInstr - Convert the instruction to set the zero flag so that we can remove a "comparis...
bool reverseBranchCondition(SmallVectorImpl< MachineOperand > &Cond) const override
ScheduleHazardRecognizer * CreateTargetHazardRecognizer(const TargetSubtargetInfo *STI, const ScheduleDAG *DAG) const override
void copyPhysReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, const DebugLoc &DL, Register DestReg, Register SrcReg, bool KillSrc, bool RenamableDest=false, bool RenamableSrc=false) const override
bool foldImmediate(MachineInstr &UseMI, MachineInstr &DefMI, Register Reg, MachineRegisterInfo *MRI) const override
foldImmediate - 'Reg' is known to be defined by a move immediate instruction, try to fold the immedia...
std::pair< unsigned, unsigned > decomposeMachineOperandsTargetFlags(unsigned TF) const override
bool isProfitableToIfCvt(MachineBasicBlock &MBB, unsigned NumCycles, unsigned ExtraPredCycles, BranchProbability Probability) const override
bool ClobbersPredicate(MachineInstr &MI, std::vector< MachineOperand > &Pred, bool SkipDead) const override
void loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, Register DestReg, int FrameIndex, const TargetRegisterClass *RC, Register VReg, unsigned SubReg=0, MachineInstr::MIFlag Flags=MachineInstr::NoFlags) const override
void copyFromCPSR(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, MCRegister DestReg, bool KillSrc, const ARMSubtarget &Subtarget) const
unsigned getNumMicroOps(const InstrItineraryData *ItinData, const MachineInstr &MI) const override
std::optional< RegImmPair > isAddImmediate(const MachineInstr &MI, Register Reg) const override
unsigned getPartialRegUpdateClearance(const MachineInstr &, unsigned, const TargetRegisterInfo *) const override
unsigned getNumLDMAddresses(const MachineInstr &MI) const
Get the number of addresses by LDM or VLDM or zero for unknown.
MachineInstr * optimizeSelect(MachineInstr &MI, SmallPtrSetImpl< MachineInstr * > &SeenMIs, bool) const override
bool produceSameValue(const MachineInstr &MI0, const MachineInstr &MI1, const MachineRegisterInfo *MRI) const override
void setExecutionDomain(MachineInstr &MI, unsigned Domain) const override
ArrayRef< std::pair< unsigned, const char * > > getSerializableBitmaskMachineOperandTargetFlags() const override
ScheduleHazardRecognizer * CreateTargetPostRAHazardRecognizer(const InstrItineraryData *II, const ScheduleDAG *DAG) const override
std::unique_ptr< TargetInstrInfo::PipelinerLoopInfo > analyzeLoopForPipelining(MachineBasicBlock *LoopBB) const override
Analyze loop L, which must be a single-basic-block loop, and if the conditions can be understood enou...
unsigned getInstSizeInBytes(const MachineInstr &MI) const override
GetInstSize - Returns the size of the specified MachineInstr.
void copyToCPSR(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, MCRegister SrcReg, bool KillSrc, const ARMSubtarget &Subtarget) const
unsigned removeBranch(MachineBasicBlock &MBB, int *BytesRemoved=nullptr) const override
void mergeOutliningCandidateAttributes(Function &F, std::vector< outliner::Candidate > &Candidates) const override
const MachineInstrBuilder & AddDReg(MachineInstrBuilder &MIB, unsigned Reg, unsigned SubIdx, RegState State) const
bool isFunctionSafeToOutlineFrom(MachineFunction &MF, bool OutlineFromLinkOnceODRs) const override
ARM supports the MachineOutliner.
bool shouldOutlineFromFunctionByDefault(MachineFunction &MF) const override
Enable outlining by default at -Oz.
std::optional< DestSourcePair > isCopyInstrImpl(const MachineInstr &MI) const override
If the specific machine instruction is an instruction that moves/copies value from one register to an...
MachineInstr & duplicate(MachineBasicBlock &MBB, MachineBasicBlock::iterator InsertBefore, const MachineInstr &Orig) const override
ScheduleHazardRecognizer * CreateTargetMIHazardRecognizer(const InstrItineraryData *II, const ScheduleDAGMI *DAG) const override
MachineBasicBlock::iterator insertOutlinedCall(Module &M, MachineBasicBlock &MBB, MachineBasicBlock::iterator &It, MachineFunction &MF, outliner::Candidate &C) const override
std::string createMIROperandComment(const MachineInstr &MI, const MachineOperand &Op, unsigned OpIdx, const TargetRegisterInfo *TRI) const override
bool isPredicated(const MachineInstr &MI) const override
bool isSchedulingBoundary(const MachineInstr &MI, const MachineBasicBlock *MBB, const MachineFunction &MF) const override
void expandLoadStackGuardBase(MachineBasicBlock::iterator MI, unsigned LoadImmOpc, unsigned LoadOpc) const
bool isPredicable(const MachineInstr &MI) const override
isPredicable - Return true if the specified instruction can be predicated.
Register isLoadFromStackSlotPostFE(const MachineInstr &MI, int &FrameIndex) const override
std::optional< ParamLoadedValue > describeLoadedValue(const MachineInstr &MI, Register Reg) const override
Specialization of TargetInstrInfo::describeLoadedValue, used to enhance debug entry value description...
std::optional< std::unique_ptr< outliner::OutlinedFunction > > getOutliningCandidateInfo(const MachineModuleInfo &MMI, std::vector< outliner::Candidate > &RepeatedSequenceLocs, unsigned MinRepeats) const override
bool analyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB, MachineBasicBlock *&FBB, SmallVectorImpl< MachineOperand > &Cond, bool AllowModify=false) const override
unsigned extraSizeToPredicateInstructions(const MachineFunction &MF, unsigned NumInsts) const override
unsigned insertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB, MachineBasicBlock *FBB, ArrayRef< MachineOperand > Cond, const DebugLoc &DL, int *BytesAdded=nullptr) const override
const ARMBaseRegisterInfo & getRegisterInfo() const
bool areLoadsFromSameBasePtr(SDNode *Load1, SDNode *Load2, int64_t &Offset1, int64_t &Offset2) const override
areLoadsFromSameBasePtr - This is used by the pre-regalloc scheduler to determine if two loads are lo...
std::optional< unsigned > getOperandLatency(const InstrItineraryData *ItinData, const MachineInstr &DefMI, unsigned DefIdx, const MachineInstr &UseMI, unsigned UseIdx) const override
bool getRegSequenceLikeInputs(const MachineInstr &MI, unsigned DefIdx, SmallVectorImpl< RegSubRegPairAndIdx > &InputRegs) const override
Build the equivalent inputs of a REG_SEQUENCE for the given MI and DefIdx.
unsigned predictBranchSizeForIfCvt(MachineInstr &MI) const override
bool getInsertSubregLikeInputs(const MachineInstr &MI, unsigned DefIdx, RegSubRegPair &BaseReg, RegSubRegPairAndIdx &InsertedReg) const override
Build the equivalent inputs of a INSERT_SUBREG for the given MI and DefIdx.
bool expandPostRAPseudo(MachineInstr &MI) const override
outliner::InstrType getOutliningTypeImpl(const MachineModuleInfo &MMI, MachineBasicBlock::iterator &MIT, unsigned Flags) const override
bool SubsumesPredicate(ArrayRef< MachineOperand > Pred1, ArrayRef< MachineOperand > Pred2) const override
bool shouldScheduleLoadsNear(SDNode *Load1, SDNode *Load2, int64_t Offset1, int64_t Offset2, unsigned NumLoads) const override
shouldScheduleLoadsNear - This is a used by the pre-regalloc scheduler to determine (in conjunction w...
bool PredicateInstruction(MachineInstr &MI, ArrayRef< MachineOperand > Pred) const override
std::pair< uint16_t, uint16_t > getExecutionDomain(const MachineInstr &MI) const override
VFP/NEON execution domains.
bool isProfitableToUnpredicate(MachineBasicBlock &TMBB, MachineBasicBlock &FMBB) const override
void storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, Register SrcReg, bool isKill, int FrameIndex, const TargetRegisterClass *RC, Register VReg, MachineInstr::MIFlag Flags=MachineInstr::NoFlags) const override
bool isFpMLxInstruction(unsigned Opcode) const
isFpMLxInstruction - Return true if the specified opcode is a fp MLA / MLS instruction.
bool isSwiftFastImmShift(const MachineInstr *MI) const
Returns true if the instruction has a shift by immediate that can be executed in one cycle less.
void reMaterialize(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, Register DestReg, unsigned SubIdx, const MachineInstr &Orig, LaneBitmask UsedLanes=LaneBitmask::getAll()) const override
ARMBaseInstrInfo(const ARMSubtarget &STI, const ARMBaseRegisterInfo &TRI)
ArrayRef< std::pair< unsigned, const char * > > getSerializableDirectMachineOperandTargetFlags() const override
Register isStoreToStackSlotPostFE(const MachineInstr &MI, int &FrameIndex) const override
bool analyzeCompare(const MachineInstr &MI, Register &SrcReg, Register &SrcReg2, int64_t &CmpMask, int64_t &CmpValue) const override
analyzeCompare - For a comparison instruction, return the source registers in SrcReg and SrcReg2 if h...
Register isStoreToStackSlot(const MachineInstr &MI, int &FrameIndex) const override
void breakPartialRegDependency(MachineInstr &, unsigned, const TargetRegisterInfo *TRI) const override
bool isMBBSafeToOutlineFrom(MachineBasicBlock &MBB, unsigned &Flags) const override
void buildOutlinedFrame(MachineBasicBlock &MBB, MachineFunction &MF, const outliner::OutlinedFunction &OF) const override
Register isLoadFromStackSlot(const MachineInstr &MI, int &FrameIndex) const override
const ARMSubtarget & getSubtarget() const
MachineInstr * commuteInstructionImpl(MachineInstr &MI, bool NewMI, unsigned OpIdx1, unsigned OpIdx2) const override
Commutes the operands in the given instruction.
bool getExtractSubregLikeInputs(const MachineInstr &MI, unsigned DefIdx, RegSubRegPairAndIdx &InputReg) const override
Build the equivalent inputs of a EXTRACT_SUBREG for the given MI and DefIdx.
bool shouldSink(const MachineInstr &MI) const override
BitVector getReservedRegs(const MachineFunction &MF) const override
static ARMConstantPoolConstant * Create(const Constant *C, unsigned ID)
static ARMConstantPoolMBB * Create(LLVMContext &C, const MachineBasicBlock *mbb, unsigned ID, unsigned char PCAdj)
static ARMConstantPoolSymbol * Create(LLVMContext &C, StringRef s, unsigned ID, unsigned char PCAdj, ARMCP::ARMCPModifier Modifier=ARMCP::no_modifier, bool AddCurrentAddress=false)
ARMConstantPoolValue - ARM specific constantpool value.
ARMCP::ARMCPModifier getModifier() const
virtual bool hasSameValue(ARMConstantPoolValue *ACPV)
hasSameValue - Return true if this ARM constpool value can share the same constantpool entry as anoth...
ARMFunctionInfo - This class is derived from MachineFunctionInfo and contains private ARM-specific in...
bool isCortexA7() const
bool isSwift() const
const ARMBaseInstrInfo * getInstrInfo() const override
bool isThumb1Only() const
bool isThumb2() const
bool isLikeA9() const
Align getStackAlignment() const
getStackAlignment - Returns the minimum alignment known to hold of the stack frame on entry to the fu...
bool enableMachinePipeliner() const override
Returns true if machine pipeliner should be enabled.
bool hasMinSize() const
bool isCortexA8() const
@ DoubleIssueCheckUnalignedAccess
Can load/store 2 registers/cycle, but needs an extra cycle if the access is not 64-bit aligned.
@ SingleIssue
Can load/store 1 register/cycle.
@ DoubleIssue
Can load/store 2 registers/cycle.
@ SingleIssuePlusExtras
Can load/store 1 register/cycle, but needs an extra cycle for address computation and potentially als...
Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition ArrayRef.h:40
size_t size() const
Get the array size.
Definition ArrayRef.h:141
bool test(unsigned Idx) const
Returns true if bit Idx is set.
Definition BitVector.h:482
size_type size() const
Returns the number of bits in this bitvector.
Definition BitVector.h:178
LLVM_ABI uint64_t scale(uint64_t Num) const
Scale a large integer.
BranchProbability getCompl() const
Helper class for creating CFI instructions and inserting them into MIR.
void buildRegister(MCRegister Reg1, MCRegister Reg2) const
void buildRestore(MCRegister Reg) const
ConstMIBundleOperands - Iterate over all operands in a const bundle of machine instructions.
A debug info location.
Definition DebugLoc.h:126
bool hasOptSize() const
Optimize this function for size (-Os) or minimum size (-Oz).
Definition Function.h:699
Attribute getFnAttribute(Attribute::AttrKind Kind) const
Return the attribute for the given attribute kind.
Definition Function.cpp:765
bool hasMinSize() const
Optimize this function for minimum size (-Oz).
Definition Function.h:696
LLVMContext & getContext() const
getContext - Return a reference to the LLVMContext associated with this function.
Definition Function.cpp:356
bool hasFnAttribute(Attribute::AttrKind Kind) const
Return true if the function has the attribute.
Definition Function.cpp:730
bool hasDLLImportStorageClass() const
bool reverseBranchCondition(SmallVectorImpl< MachineOperand > &Cond) const override
Reverses the branch condition of the specified condition list, returning false on success and true if...
Itinerary data supplied by a subtarget to be used by a target.
int getNumMicroOps(unsigned ItinClassIndx) const
Return the number of micro-ops that the given class decodes to.
std::optional< unsigned > getOperandCycle(unsigned ItinClassIndx, unsigned OperandIdx) const
Return the cycle for the given class and operand.
unsigned getStageLatency(unsigned ItinClassIndx) const
Return the total stage latency of the given class.
std::optional< unsigned > getOperandLatency(unsigned DefClass, unsigned DefIdx, unsigned UseClass, unsigned UseIdx) const
Compute and return the use operand latency of a given itinerary class and operand index if the value ...
bool hasPipelineForwarding(unsigned DefClass, unsigned DefIdx, unsigned UseClass, unsigned UseIdx) const
Return true if there is a pipeline forwarding between instructions of itinerary classes DefClass and ...
bool isEmpty() const
Returns true if there are no itineraries.
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.
LLVM_ABI void addLiveOuts(const MachineBasicBlock &MBB)
Adds registers living out of block MBB.
LLVM_ABI void accumulate(const MachineInstr &MI)
Adds all register units used, defined or clobbered in MI.
This class is intended to be used as a base class for asm properties and features specific to the tar...
Definition MCAsmInfo.h:67
Describe properties that are true of each instruction in the target description file.
unsigned getSchedClass() const
Return the scheduling class for this instruction.
unsigned getNumOperands() const
Return the number of declared MachineOperands for this MachineInstruction.
ArrayRef< MCOperandInfo > operands() const
bool mayLoad() const
Return true if this instruction could possibly read memory.
bool hasOptionalDef() const
Set if this instruction has an optional definition, e.g.
unsigned getNumDefs() const
Return the number of MachineOperands that are register definitions.
bool isCall() const
Return true if the instruction is a call.
unsigned getOpcode() const
Return the opcode number for this descriptor.
LLVM_ABI bool hasImplicitDefOfPhysReg(MCRegister Reg, const MCRegisterInfo *MRI=nullptr) const
Return true if this instruction implicitly defines the specified physical register.
MCRegister getRegister(unsigned i) const
getRegister - Return the specified register in the class.
Wrapper class representing physical registers. Should be passed by value.
Definition MCRegister.h:41
bool isValid() const
isValid - Returns true until all the operands have been visited.
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 iterator getFirstTerminator()
Returns an iterator to the first terminator instruction of this basic block.
Instructions::iterator instr_iterator
MachineInstrBundleIterator< MachineInstr, true > reverse_iterator
Instructions::const_iterator const_instr_iterator
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.
MachineInstrBundleIterator< MachineInstr > iterator
LivenessQueryResult
Possible outcome of a register liveness query to computeRegisterLiveness()
@ LQR_Dead
Register is known to be fully dead.
@ LQR_Live
Register is known to be (at least partially) live.
@ LQR_Unknown
Register liveness not decidable from local neighborhood.
This class is a data container for one entry in a MachineConstantPool.
union llvm::MachineConstantPoolEntry::@004270020304201266316354007027341142157160323045 Val
The constant itself.
bool isMachineConstantPoolEntry() const
isMachineConstantPoolEntry - Return true if the MachineConstantPoolEntry is indeed a target specific ...
MachineConstantPoolValue * MachineCPVal
The MachineConstantPool class keeps track of constants referenced by a function which must be spilled...
const std::vector< MachineConstantPoolEntry > & getConstants() const
LLVM_ABI unsigned getConstantPoolIndex(const Constant *C, Align Alignment)
getConstantPoolIndex - Create a new entry in the constant pool or return an existing one.
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted.
uint64_t getStackSize() const
Return the number of bytes that must be allocated to hold all of the fixed size frame objects.
bool isCalleeSavedInfoValid() const
Has the callee saved info been calculated yet?
Align getObjectAlign(int ObjectIdx) const
Return the alignment of the specified stack object.
int64_t getObjectSize(int ObjectIdx) const
Return the size of the specified object.
unsigned getNumObjects() const
Return the number of objects.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
StringRef getName() const
getName - Return the name of the corresponding LLVM function.
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
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...
MachineConstantPool * getConstantPool()
getConstantPool - Return the constant pool object for the current function.
MachineMemOperand * getMachineMemOperand(MachinePointerInfo PtrInfo, MachineMemOperand::Flags F, LLT MemTy, Align BaseAlignment, const MMOMetadata &Metadata=MMOMetadata(), SyncScope::ID SSID=SyncScope::System, AtomicOrdering Ordering=AtomicOrdering::NotAtomic, AtomicOrdering FailureOrdering=AtomicOrdering::NotAtomic)
getMachineMemOperand - Allocate a new MachineMemOperand.
const TargetMachine & getTarget() const
getTarget - Return the target machine this machine code is compiled with
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 & addFrameIndex(int Idx) const
const MachineInstrBuilder & addConstantPoolIndex(unsigned Idx, int Offset=0, unsigned TargetFlags=0) const
const MachineInstrBuilder & addGlobalAddress(const GlobalValue *GV, int64_t Offset=0, unsigned TargetFlags=0) const
const MachineInstrBuilder & addMBB(MachineBasicBlock *MBB, unsigned TargetFlags=0) const
const MachineInstrBuilder & cloneMemRefs(const MachineInstr &OtherMI) const
const MachineInstrBuilder & setMIFlags(unsigned Flags) const
const MachineInstrBuilder & addMemOperand(MachineMemOperand *MMO) const
Representation of each machine instruction.
ArrayRef< MachineMemOperand * >::iterator mmo_iterator
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
bool isImplicitDef() const
const MachineBasicBlock * getParent() const
bool isCopyLike() const
Return true if the instruction behaves like a copy.
bool isCall(QueryType Type=AnyInBundle) const
unsigned getNumOperands() const
Retuns the total number of operands.
LLVM_ABI int findFirstPredOperandIdx() const
Find the index of the first operand in the operand list that is used to represent the predicate.
const MCInstrDesc & getDesc() const
Returns the target instruction descriptor of this MachineInstr.
bool isRegSequence() const
bool isInsertSubreg() const
LLVM_ABI void tieOperands(unsigned DefIdx, unsigned UseIdx)
Add a tie between the register operands at DefIdx and UseIdx.
LLVM_ABI bool isIdenticalTo(const MachineInstr &Other, MICheckType Check=CheckDefs) const
Return true if this instruction is identical to Other.
const DebugLoc & getDebugLoc() const
Returns the debug location id of this MachineInstr.
LLVM_ABI bool addRegisterKilled(Register IncomingReg, const TargetRegisterInfo *RegInfo, bool AddIfNotFound=false)
We have determined MI kills a register.
bool hasOptionalDef(QueryType Type=IgnoreBundle) const
Set if this instruction has an optional definition, e.g.
LLVM_ABI void addRegisterDefined(Register Reg, const TargetRegisterInfo *RegInfo=nullptr)
We have determined MI defines a register.
const MachineOperand & getOperand(unsigned i) const
LLVM_ABI void clearKillInfo()
Clears kill flags on all operands.
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.
@ MODereferenceable
The memory access is dereferenceable (i.e., doesn't trap).
@ MOLoad
The memory access reads data.
@ MOInvariant
The memory access always returns the same value (or traps).
@ MOStore
The memory access writes data.
This class contains meta information specific to a module.
LLVM_ABI MachineFunction * getMachineFunction(const Function &F) const
Returns the MachineFunction associated to IR function F if there is one, otherwise nullptr.
MachineOperand class - Representation of each machine instruction operand.
unsigned getSubReg() const
const GlobalValue * getGlobal() const
void setImplicit(bool Val=true)
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.
bool isRegMask() const
isRegMask - Tests if this is a MO_RegisterMask operand.
MachineBasicBlock * getMBB() const
LLVM_ABI void ChangeToImmediate(int64_t ImmVal, unsigned TargetFlags=0)
ChangeToImmediate - Replace this operand with a new immediate operand of the specified value.
static MachineOperand CreateImm(int64_t Val)
Register getReg() const
getReg - Returns the register number.
LLVM_ABI bool isIdenticalTo(const MachineOperand &Other) const
Returns true if this operand is identical to the specified operand except for liveness related flags ...
static bool clobbersPhysReg(const uint32_t *RegMask, MCRegister PhysReg)
clobbersPhysReg - Returns true if this RegMask clobbers PhysReg.
static MachineOperand CreateReg(Register Reg, bool isDef, bool isImp=false, bool isKill=false, bool isDead=false, bool isUndef=false, bool isEarlyClobber=false, unsigned SubReg=0, bool isDebug=false, bool isInternalRead=false, bool isRenamable=false)
int64_t getOffset() const
Return the offset from the symbol in this operand.
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
LLVM_ABI bool hasOneNonDBGUse(Register RegNo) const
hasOneNonDBGUse - Return true if there is exactly one non-Debug use of the specified register.
defusechain_instr_iterator< true, false, false, true > use_instr_iterator
use_instr_iterator/use_instr_begin/use_instr_end - Walk all uses of the specified register,...
const TargetRegisterClass * getRegClass(Register Reg) const
Return the register class of the specified virtual register.
LLVM_ABI LLVM_READONLY MachineInstr * getVRegDef(Register Reg) const
getVRegDef - Return the machine instr that defines the specified virtual register or null if none is ...
use_instr_iterator use_instr_begin(Register RegNo) const
LLVM_ABI Register createVirtualRegister(const TargetRegisterClass *RegClass, StringRef Name="")
createVirtualRegister - Create and return a new virtual register in the function with the specified r...
static use_instr_iterator use_instr_end()
const TargetRegisterInfo * getTargetRegisterInfo() const
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...
LLVM_ABI LLVM_READONLY MachineInstr * getUniqueVRegDef(Register Reg) const
getUniqueVRegDef - Return the unique machine instr that defines the specified virtual register or nul...
A Module instance is used to store all the information related to an LLVM module.
Definition Module.h:68
void AddHazardRecognizer(std::unique_ptr< ScheduleHazardRecognizer > &&)
Track the current register pressure at some position in the instruction stream, and remember the high...
LLVM_ABI void increaseRegPressure(VirtRegOrUnit VRegOrUnit, LaneBitmask PreviousMask, LaneBitmask NewMask)
LLVM_ABI void decreaseRegPressure(VirtRegOrUnit VRegOrUnit, LaneBitmask PreviousMask, LaneBitmask NewMask)
unsigned getRegPressureSetLimit(unsigned Idx) const
Get the register unit limit for the given pressure set index.
LLVM_ABI void runOnMachineFunction(const MachineFunction &MF, bool Rev=false)
runOnFunction - Prepare to answer questions about MF.
Wrapper class representing virtual and physical registers.
Definition Register.h:20
constexpr bool isVirtual() const
Return true if the specified register number is in the virtual register namespace.
Definition Register.h:79
static constexpr bool isPhysicalRegister(unsigned Reg)
Return true if the specified register number is in the physical register namespace.
Definition Register.h:60
constexpr unsigned id() const
Definition Register.h:100
constexpr bool isPhysical() const
Return true if the specified register number is in the physical register namespace.
Definition Register.h:83
Represents one node in the SelectionDAG.
bool isMachineOpcode() const
Test if this node has a post-isel opcode, directly corresponding to a MachineInstr opcode.
unsigned getMachineOpcode() const
This may only be called if isMachineOpcode returns true.
const SDValue & getOperand(unsigned Num) const
uint64_t getConstantOperandVal(unsigned Num) const
Helper method returns the integer value of a ConstantSDNode operand.
@ Anti
A register anti-dependence (aka WAR).
Definition ScheduleDAG.h:57
This class represents the scheduled code.
unsigned getMaxStageCount()
Return the maximum stage count needed for this schedule.
int stageScheduled(SUnit *SU) const
Return the stage for a scheduled instruction.
int getInitiationInterval() const
Return the initiation interval for this schedule.
std::deque< SUnit * > & getInstructions(int cycle)
Return the instructions that are scheduled at the specified cycle.
int getFirstCycle() const
Return the first cycle in the completed schedule.
int getFinalCycle() const
Return the last cycle in the finalized schedule.
Scheduling unit. This is a node in the scheduling DAG.
ScheduleDAGMI is an implementation of ScheduleDAGInstrs that simply schedules machine instructions ac...
virtual bool hasVRegLiveness() const
Return true if this DAG supports VReg liveness and RegPressure.
std::vector< SUnit > SUnits
The scheduling units.
HazardRecognizer - This determines whether or not an instruction can be issued this cycle,...
A templated base class for SmallPtrSet which provides the typesafe interface that is common across al...
bool erase(PtrType Ptr)
Remove pointer from the set.
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
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.
Represent a constant reference to a string, i.e.
Definition StringRef.h:56
This class builds the dependence graph for the instructions in a loop, and attempts to schedule the i...
Object returned by analyzeLoopForPipelining.
TargetInstrInfo - Interface to description of machine instruction set.
virtual ScheduleHazardRecognizer * CreateTargetPostRAHazardRecognizer(const InstrItineraryData *, const ScheduleDAG *DAG) const
Allocate and return a hazard recognizer to use for this target when scheduling the machine instructio...
virtual ScheduleHazardRecognizer * CreateTargetMIHazardRecognizer(const InstrItineraryData *, const ScheduleDAGMI *DAG) const
Allocate and return a hazard recognizer to use for this target when scheduling the machine instructio...
virtual std::optional< ParamLoadedValue > describeLoadedValue(const MachineInstr &MI, Register Reg) const
Produce the expression describing the MI loading a value into the physical register Reg.
virtual ScheduleHazardRecognizer * CreateTargetHazardRecognizer(const TargetSubtargetInfo *STI, const ScheduleDAG *DAG) const
Allocate and return a hazard recognizer to use for this target when scheduling the machine instructio...
virtual bool isReMaterializableImpl(const MachineInstr &MI) const
For instructions with opcodes for which the M_REMATERIALIZABLE flag is set, this hook lets the target...
virtual MachineInstr & duplicate(MachineBasicBlock &MBB, MachineBasicBlock::iterator InsertBefore, const MachineInstr &Orig) const
Clones instruction or the whole instruction bundle Orig and insert into MBB before InsertBefore.
virtual MachineInstr * commuteInstructionImpl(MachineInstr &MI, bool NewMI, unsigned OpIdx1, unsigned OpIdx2) const
This method commutes the operands of the given machine instruction MI.
virtual std::string createMIROperandComment(const MachineInstr &MI, const MachineOperand &Op, unsigned OpIdx, const TargetRegisterInfo *TRI) const
const MCAsmInfo & getMCAsmInfo() const
Return target specific asm information.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
Provide an instruction scheduling machine model to CodeGen passes.
LLVM_ABI unsigned computeOperandLatency(const MachineInstr *DefMI, unsigned DefOperIdx, const MachineInstr *UseMI, unsigned UseOperIdx) const
Compute operand latency based on the available machine model.
const InstrItineraryData * getInstrItineraries() const
TargetSubtargetInfo - Generic base class for all target subtargets.
virtual const TargetRegisterInfo * getRegisterInfo() const =0
Return the target's register information.
Wrapper class representing a virtual register or register unit.
Definition Register.h:175
self_iterator getIterator()
Definition ilist_node.h:123
CallInst * Call
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
static CondCodes getOppositeCondition(CondCodes CC)
Definition ARMBaseInfo.h:49
ARMII - This namespace holds all of the target specific flags that instruction info tracks.
@ ThumbArithFlagSetting
@ MO_OPTION_MASK
MO_OPTION_MASK - Most flags are mutually exclusive; this mask selects just that part of the flag set.
@ MO_NONLAZY
MO_NONLAZY - This is an independent flag, on a symbol operand "FOO" it represents a symbol which,...
@ MO_DLLIMPORT
MO_DLLIMPORT - On a symbol operand, this represents that the reference to the symbol is for an import...
@ MO_GOT
MO_GOT - On a symbol operand, this represents a GOT relative relocation.
@ MO_COFFSTUB
MO_COFFSTUB - On a symbol operand "FOO", this indicates that the reference is actually to the "....
AddrMode
ARM Addressing Modes.
unsigned char getAM3Offset(unsigned AM3Opc)
unsigned char getAM5FP16Offset(unsigned AM5Opc)
unsigned getSORegOffset(unsigned Op)
int getSOImmVal(unsigned Arg)
getSOImmVal - Given a 32-bit immediate, if it is something that can fit into an shifter_operand immed...
ShiftOpc getAM2ShiftOpc(unsigned AM2Opc)
unsigned getAM2Offset(unsigned AM2Opc)
unsigned getSOImmValRotate(unsigned Imm)
getSOImmValRotate - Try to handle Imm with an immediate shifter operand, computing the rotate amount ...
bool isThumbImmShiftedVal(unsigned V)
isThumbImmShiftedVal - Return true if the specified value can be obtained by left shifting a 8-bit im...
int getT2SOImmVal(unsigned Arg)
getT2SOImmVal - Given a 32-bit immediate, if it is something that can fit into a Thumb-2 shifter_oper...
ShiftOpc getSORegShOp(unsigned Op)
AddrOpc getAM5Op(unsigned AM5Opc)
bool isSOImmTwoPartValNeg(unsigned V)
isSOImmTwoPartValNeg - Return true if the specified value can be obtained by two SOImmVal,...
unsigned getSOImmTwoPartSecond(unsigned V)
getSOImmTwoPartSecond - If V is a value that satisfies isSOImmTwoPartVal, return the second chunk of ...
bool isSOImmTwoPartVal(unsigned V)
isSOImmTwoPartVal - Return true if the specified value can be obtained by or'ing together two SOImmVa...
AddrOpc getAM5FP16Op(unsigned AM5Opc)
unsigned getT2SOImmTwoPartSecond(unsigned Imm)
unsigned getT2SOImmTwoPartFirst(unsigned Imm)
bool isT2SOImmTwoPartVal(unsigned Imm)
unsigned char getAM5Offset(unsigned AM5Opc)
unsigned getSOImmTwoPartFirst(unsigned V)
getSOImmTwoPartFirst - If V is a value that satisfies isSOImmTwoPartVal, return the first chunk of it...
AddrOpc getAM2Op(unsigned AM2Opc)
AddrOpc getAM3Op(unsigned AM3Opc)
Define some predicates that are used for node matching.
Definition ARMEHABI.h:25
InstrType
Represents how an instruction should be mapped by the outliner.
NodeAddr< NodeBase * > Node
Definition RDFGraph.h:381
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:577
constexpr T rotr(T V, int R)
Definition bit.h:399
static bool isIndirectCall(const MachineInstr &MI)
MachineInstr * findCMPToFoldIntoCBZ(MachineInstr *Br, const TargetRegisterInfo *TRI)
Search backwards from a tBcc to find a tCMPi8 against 0, meaning we can convert them to a tCBZ or tCB...
static bool isCondBranchOpcode(int Opc)
bool HasLowerConstantMaterializationCost(unsigned Val1, unsigned Val2, const ARMSubtarget *Subtarget, bool ForCodesize=false)
Returns true if Val1 has a lower Constant Materialization Cost than Val2.
static bool isPushOpcode(int Opc)
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
void addPredicatedMveVpredNOp(MachineInstrBuilder &MIB, unsigned Cond)
static bool isVCTP(const MachineInstr *MI)
RegState
Flags to represent properties of register accesses.
@ Implicit
Not emitted register (e.g. carry, or temporary result).
@ Kill
The last use of a register.
@ Undef
Value of the register doesn't matter.
@ Define
Register definition.
bool IsCPSRDead< MachineInstr >(const MachineInstr *MI)
constexpr RegState getKillRegState(bool B)
unsigned getBLXpredOpcode(const MachineFunction &MF)
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:643
static bool isARMLowRegister(MCRegister Reg)
isARMLowRegister - Returns true if the register is a low register (r0-r7).
static bool isIndirectBranchOpcode(int Opc)
bool isLegalAddressImm(unsigned Opcode, int Imm, const TargetInstrInfo *TII)
void append_range(Container &C, Range &&R)
Wrapper function to append range R to container C.
Definition STLExtras.h:2208
bool registerDefinedBetween(unsigned Reg, MachineBasicBlock::iterator From, MachineBasicBlock::iterator To, const TargetRegisterInfo *TRI)
Return true if Reg is defd between From and To.
static std::array< MachineOperand, 2 > predOps(ARMCC::CondCodes Pred, unsigned PredReg=0)
Get the operands corresponding to the given Pred value.
Op::Description Desc
static bool isSEHInstruction(const MachineInstr &MI)
static bool isCalleeSavedRegister(MCRegister Reg, const MCPhysReg *CSRegs)
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1746
bool tryFoldSPUpdateIntoPushPop(const ARMSubtarget &Subtarget, MachineFunction &MF, MachineInstr *MI, unsigned NumBytes)
Tries to add registers to the reglist of a given base-updating push/pop instruction to adjust the sta...
auto reverse(ContainerTy &&C)
Definition STLExtras.h:407
static bool isJumpTableBranchOpcode(int Opc)
MachineInstr * getImm(const MachineOperand &MO, const MachineRegisterInfo *MRI)
decltype(auto) get(const PointerIntPair< PointerTy, IntBits, IntType, PtrTraits, Info > &Pair)
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 uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
Definition Alignment.h:144
static bool isPopOpcode(int Opc)
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
Definition Casting.h:547
void addPredicatedMveVpredROp(MachineInstrBuilder &MIB, unsigned Cond, unsigned Inactive)
auto drop_end(T &&RangeOrContainer, size_t N=1)
Return a range covering RangeOrContainer with the last N elements excluded.
Definition STLExtras.h:322
constexpr T divideCeil(U Numerator, V Denominator)
Returns the integer ceil(Numerator / Denominator).
Definition MathExtras.h:389
void addUnpredicatedMveVpredROp(MachineInstrBuilder &MIB, Register DestReg)
unsigned ConstantMaterializationCost(unsigned Val, const ARMSubtarget *Subtarget, bool ForCodesize=false)
Returns the number of instructions required to materialize the given constant in a register,...
uint16_t MCPhysReg
An unsigned integer type large enough to represent all physical registers, but not necessarily virtua...
Definition MCRegister.h:21
bool rewriteARMFrameIndex(MachineInstr &MI, unsigned FrameRegIdx, Register FrameReg, int &Offset, const ARMBaseInstrInfo &TII)
rewriteARMFrameIndex / rewriteT2FrameIndex - Rewrite MI to access 'Offset' bytes from the FP.
static bool isIndirectControlFlowNotComingBack(const MachineInstr &MI)
ARMCC::CondCodes getInstrPredicate(const MachineInstr &MI, Register &PredReg)
getInstrPredicate - If instruction is predicated, returns its predicate condition,...
unsigned getMatchingCondBranchOpcode(unsigned Opc)
DWARFExpression::Operation Op
ArrayRef(const T &OneElt) -> ArrayRef< T >
static bool isUncondBranchOpcode(int Opc)
auto partition(R &&Range, UnaryPredicate P)
Provide wrappers to std::partition which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:2033
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:559
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
static const char * ARMCondCodeToString(ARMCC::CondCodes CC)
static MachineOperand condCodeOp(unsigned CCReg=0)
Get the operand corresponding to the conditional code result.
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Next
Definition InstrProf.h:147
unsigned gettBLXrOpcode(const MachineFunction &MF)
static bool isSpeculationBarrierEndBBOpcode(int Opc)
unsigned getBLXOpcode(const MachineFunction &MF)
void addUnpredicatedMveVpredNOp(MachineInstrBuilder &MIB)
bool isV8EligibleForIT(const InstrType *Instr)
Definition ARMFeatures.h:24
void emitARMRegPlusImmediate(MachineBasicBlock &MBB, MachineBasicBlock::iterator &MBBI, const DebugLoc &dl, Register DestReg, Register BaseReg, int NumBytes, ARMCC::CondCodes Pred, Register PredReg, const ARMBaseInstrInfo &TII, unsigned MIFlags=0)
emitARMRegPlusImmediate / emitT2RegPlusImmediate - Emits a series of instructions to materializea des...
constexpr RegState getUndefRegState(bool B)
unsigned convertAddSubFlagsOpcode(unsigned OldOpc)
Map pseudo instructions that imply an 'S' bit onto real opcodes.
MCRegisterClass TargetRegisterClass
Definition FastISel.h:58
#define N
ARM_MLxEntry - Record information about MLA / MLS instructions.
Map pseudo instructions that imply an 'S' bit onto real opcodes.
OutlinerCosts(const ARMSubtarget &target)
This struct is a compact representation of a valid (non-zero power of two) alignment.
Definition Alignment.h:39
constexpr uint64_t value() const
This is a hole in the type system and should not be abused.
Definition Alignment.h:77
static constexpr LaneBitmask getAll()
Definition LaneBitmask.h:82
static constexpr LaneBitmask getNone()
Definition LaneBitmask.h:81
static LLVM_ABI MachinePointerInfo getGOT(MachineFunction &MF)
Return a MachinePointerInfo record that refers to a GOT entry.
static LLVM_ABI MachinePointerInfo getFixedStack(MachineFunction &MF, int FI, int64_t Offset=0)
Return a MachinePointerInfo record that refers to the specified FrameIndex.
Used to describe a register and immediate addition.
RegisterPressure computed within a region of instructions delimited by TopPos and BottomPos.
An individual sequence of instructions to be replaced with a call to an outlined function.
The information necessary to create an outlined function for some class of candidate.