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