1 //===-- ARMBaseInstrInfo.h - ARM Base Instruction Information ---*- C++ -*-===// 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 #ifndef LLVM_LIB_TARGET_ARM_ARMBASEINSTRINFO_H 14 #define LLVM_LIB_TARGET_ARM_ARMBASEINSTRINFO_H 15 16 #include "ARMBaseRegisterInfo.h" 17 #include "MCTargetDesc/ARMBaseInfo.h" 18 #include "MCTargetDesc/ARMMCTargetDesc.h" 19 #include "llvm/ADT/DenseMap.h" 20 #include "llvm/ADT/SmallSet.h" 21 #include "llvm/CodeGen/MachineBasicBlock.h" 22 #include "llvm/CodeGen/MachineInstr.h" 23 #include "llvm/CodeGen/MachineInstrBuilder.h" 24 #include "llvm/CodeGen/MachineOperand.h" 25 #include "llvm/CodeGen/MachineRegisterInfo.h" 26 #include "llvm/CodeGen/Register.h" 27 #include "llvm/CodeGen/TargetInstrInfo.h" 28 #include "llvm/IR/IntrinsicInst.h" 29 #include "llvm/IR/IntrinsicsARM.h" 30 #include "llvm/Support/ErrorHandling.h" 31 #include <array> 32 #include <cstdint> 33 34 #define GET_INSTRINFO_HEADER 35 #include "ARMGenInstrInfo.inc" 36 37 namespace llvm { 38 39 class ARMBaseRegisterInfo; 40 class ARMSubtarget; 41 42 class ARMBaseInstrInfo : public ARMGenInstrInfo { 43 const ARMSubtarget &Subtarget; 44 45 protected: 46 // Can be only subclassed. 47 explicit ARMBaseInstrInfo(const ARMSubtarget &STI); 48 49 void expandLoadStackGuardBase(MachineBasicBlock::iterator MI, 50 unsigned LoadImmOpc, unsigned LoadOpc) const; 51 52 /// Build the equivalent inputs of a REG_SEQUENCE for the given \p MI 53 /// and \p DefIdx. 54 /// \p [out] InputRegs of the equivalent REG_SEQUENCE. Each element of 55 /// the list is modeled as <Reg:SubReg, SubIdx>. 56 /// E.g., REG_SEQUENCE %1:sub1, sub0, %2, sub1 would produce 57 /// two elements: 58 /// - %1:sub1, sub0 59 /// - %2<:0>, sub1 60 /// 61 /// \returns true if it is possible to build such an input sequence 62 /// with the pair \p MI, \p DefIdx. False otherwise. 63 /// 64 /// \pre MI.isRegSequenceLike(). 65 bool getRegSequenceLikeInputs( 66 const MachineInstr &MI, unsigned DefIdx, 67 SmallVectorImpl<RegSubRegPairAndIdx> &InputRegs) const override; 68 69 /// Build the equivalent inputs of a EXTRACT_SUBREG for the given \p MI 70 /// and \p DefIdx. 71 /// \p [out] InputReg of the equivalent EXTRACT_SUBREG. 72 /// E.g., EXTRACT_SUBREG %1:sub1, sub0, sub1 would produce: 73 /// - %1:sub1, sub0 74 /// 75 /// \returns true if it is possible to build such an input sequence 76 /// with the pair \p MI, \p DefIdx. False otherwise. 77 /// 78 /// \pre MI.isExtractSubregLike(). 79 bool getExtractSubregLikeInputs(const MachineInstr &MI, unsigned DefIdx, 80 RegSubRegPairAndIdx &InputReg) const override; 81 82 /// Build the equivalent inputs of a INSERT_SUBREG for the given \p MI 83 /// and \p DefIdx. 84 /// \p [out] BaseReg and \p [out] InsertedReg contain 85 /// the equivalent inputs of INSERT_SUBREG. 86 /// E.g., INSERT_SUBREG %0:sub0, %1:sub1, sub3 would produce: 87 /// - BaseReg: %0:sub0 88 /// - InsertedReg: %1:sub1, sub3 89 /// 90 /// \returns true if it is possible to build such an input sequence 91 /// with the pair \p MI, \p DefIdx. False otherwise. 92 /// 93 /// \pre MI.isInsertSubregLike(). 94 bool 95 getInsertSubregLikeInputs(const MachineInstr &MI, unsigned DefIdx, 96 RegSubRegPair &BaseReg, 97 RegSubRegPairAndIdx &InsertedReg) const override; 98 99 /// Commutes the operands in the given instruction. 100 /// The commutable operands are specified by their indices OpIdx1 and OpIdx2. 101 /// 102 /// Do not call this method for a non-commutable instruction or for 103 /// non-commutable pair of operand indices OpIdx1 and OpIdx2. 104 /// Even though the instruction is commutable, the method may still 105 /// fail to commute the operands, null pointer is returned in such cases. 106 MachineInstr *commuteInstructionImpl(MachineInstr &MI, bool NewMI, 107 unsigned OpIdx1, 108 unsigned OpIdx2) const override; 109 /// If the specific machine instruction is an instruction that moves/copies 110 /// value from one register to another register return destination and source 111 /// registers as machine operands. 112 std::optional<DestSourcePair> 113 isCopyInstrImpl(const MachineInstr &MI) const override; 114 115 /// Specialization of \ref TargetInstrInfo::describeLoadedValue, used to 116 /// enhance debug entry value descriptions for ARM targets. 117 std::optional<ParamLoadedValue> 118 describeLoadedValue(const MachineInstr &MI, Register Reg) const override; 119 120 public: 121 // Return whether the target has an explicit NOP encoding. 122 bool hasNOP() const; 123 124 // Return the non-pre/post incrementing version of 'Opc'. Return 0 125 // if there is not such an opcode. 126 virtual unsigned getUnindexedOpcode(unsigned Opc) const = 0; 127 128 MachineInstr *convertToThreeAddress(MachineInstr &MI, LiveVariables *LV, 129 LiveIntervals *LIS) const override; 130 131 virtual const ARMBaseRegisterInfo &getRegisterInfo() const = 0; 132 const ARMSubtarget &getSubtarget() const { return Subtarget; } 133 134 ScheduleHazardRecognizer * 135 CreateTargetHazardRecognizer(const TargetSubtargetInfo *STI, 136 const ScheduleDAG *DAG) const override; 137 138 ScheduleHazardRecognizer * 139 CreateTargetMIHazardRecognizer(const InstrItineraryData *II, 140 const ScheduleDAGMI *DAG) const override; 141 142 ScheduleHazardRecognizer * 143 CreateTargetPostRAHazardRecognizer(const InstrItineraryData *II, 144 const ScheduleDAG *DAG) const override; 145 146 // Branch analysis. 147 bool analyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB, 148 MachineBasicBlock *&FBB, 149 SmallVectorImpl<MachineOperand> &Cond, 150 bool AllowModify = false) const override; 151 unsigned removeBranch(MachineBasicBlock &MBB, 152 int *BytesRemoved = nullptr) const override; 153 unsigned insertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB, 154 MachineBasicBlock *FBB, ArrayRef<MachineOperand> Cond, 155 const DebugLoc &DL, 156 int *BytesAdded = nullptr) const override; 157 158 bool 159 reverseBranchCondition(SmallVectorImpl<MachineOperand> &Cond) const override; 160 161 // Predication support. 162 bool isPredicated(const MachineInstr &MI) const override; 163 164 // MIR printer helper function to annotate Operands with a comment. 165 std::string 166 createMIROperandComment(const MachineInstr &MI, const MachineOperand &Op, 167 unsigned OpIdx, 168 const TargetRegisterInfo *TRI) const override; 169 170 ARMCC::CondCodes getPredicate(const MachineInstr &MI) const { 171 int PIdx = MI.findFirstPredOperandIdx(); 172 return PIdx != -1 ? (ARMCC::CondCodes)MI.getOperand(PIdx).getImm() 173 : ARMCC::AL; 174 } 175 176 bool PredicateInstruction(MachineInstr &MI, 177 ArrayRef<MachineOperand> Pred) const override; 178 179 bool SubsumesPredicate(ArrayRef<MachineOperand> Pred1, 180 ArrayRef<MachineOperand> Pred2) const override; 181 182 bool ClobbersPredicate(MachineInstr &MI, std::vector<MachineOperand> &Pred, 183 bool SkipDead) const override; 184 185 bool isPredicable(const MachineInstr &MI) const override; 186 187 // CPSR defined in instruction 188 static bool isCPSRDefined(const MachineInstr &MI); 189 190 /// GetInstSize - Returns the size of the specified MachineInstr. 191 /// 192 unsigned getInstSizeInBytes(const MachineInstr &MI) const override; 193 194 Register isLoadFromStackSlot(const MachineInstr &MI, 195 int &FrameIndex) const override; 196 Register isStoreToStackSlot(const MachineInstr &MI, 197 int &FrameIndex) const override; 198 Register isLoadFromStackSlotPostFE(const MachineInstr &MI, 199 int &FrameIndex) const override; 200 Register isStoreToStackSlotPostFE(const MachineInstr &MI, 201 int &FrameIndex) const override; 202 203 void copyToCPSR(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, 204 MCRegister SrcReg, bool KillSrc, 205 const ARMSubtarget &Subtarget) const; 206 void copyFromCPSR(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, 207 MCRegister DestReg, bool KillSrc, 208 const ARMSubtarget &Subtarget) const; 209 210 void copyPhysReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, 211 const DebugLoc &DL, MCRegister DestReg, MCRegister SrcReg, 212 bool KillSrc, bool RenamableDest = false, 213 bool RenamableSrc = false) const override; 214 215 void storeRegToStackSlot( 216 MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, Register SrcReg, 217 bool isKill, int FrameIndex, const TargetRegisterClass *RC, 218 const TargetRegisterInfo *TRI, Register VReg, 219 MachineInstr::MIFlag Flags = MachineInstr::NoFlags) const override; 220 221 void loadRegFromStackSlot( 222 MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, 223 Register DestReg, int FrameIndex, const TargetRegisterClass *RC, 224 const TargetRegisterInfo *TRI, Register VReg, 225 MachineInstr::MIFlag Flags = MachineInstr::NoFlags) const override; 226 227 bool expandPostRAPseudo(MachineInstr &MI) const override; 228 229 bool shouldSink(const MachineInstr &MI) const override; 230 231 void reMaterialize(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, 232 Register DestReg, unsigned SubIdx, 233 const MachineInstr &Orig, 234 const TargetRegisterInfo &TRI) const override; 235 236 MachineInstr & 237 duplicate(MachineBasicBlock &MBB, MachineBasicBlock::iterator InsertBefore, 238 const MachineInstr &Orig) const override; 239 240 const MachineInstrBuilder &AddDReg(MachineInstrBuilder &MIB, unsigned Reg, 241 unsigned SubIdx, unsigned State, 242 const TargetRegisterInfo *TRI) const; 243 244 bool produceSameValue(const MachineInstr &MI0, const MachineInstr &MI1, 245 const MachineRegisterInfo *MRI) const override; 246 247 /// areLoadsFromSameBasePtr - This is used by the pre-regalloc scheduler to 248 /// determine if two loads are loading from the same base address. It should 249 /// only return true if the base pointers are the same and the only 250 /// differences between the two addresses is the offset. It also returns the 251 /// offsets by reference. 252 bool areLoadsFromSameBasePtr(SDNode *Load1, SDNode *Load2, int64_t &Offset1, 253 int64_t &Offset2) const override; 254 255 /// shouldScheduleLoadsNear - This is a used by the pre-regalloc scheduler to 256 /// determine (in conjunction with areLoadsFromSameBasePtr) if two loads 257 /// should be scheduled togther. On some targets if two loads are loading from 258 /// addresses in the same cache line, it's better if they are scheduled 259 /// together. This function takes two integers that represent the load offsets 260 /// from the common base address. It returns true if it decides it's desirable 261 /// to schedule the two loads together. "NumLoads" is the number of loads that 262 /// have already been scheduled after Load1. 263 bool shouldScheduleLoadsNear(SDNode *Load1, SDNode *Load2, 264 int64_t Offset1, int64_t Offset2, 265 unsigned NumLoads) const override; 266 267 bool isSchedulingBoundary(const MachineInstr &MI, 268 const MachineBasicBlock *MBB, 269 const MachineFunction &MF) const override; 270 271 bool isProfitableToIfCvt(MachineBasicBlock &MBB, 272 unsigned NumCycles, unsigned ExtraPredCycles, 273 BranchProbability Probability) const override; 274 275 bool isProfitableToIfCvt(MachineBasicBlock &TMBB, unsigned NumT, 276 unsigned ExtraT, MachineBasicBlock &FMBB, 277 unsigned NumF, unsigned ExtraF, 278 BranchProbability Probability) const override; 279 280 bool isProfitableToDupForIfCvt(MachineBasicBlock &MBB, unsigned NumCycles, 281 BranchProbability Probability) const override { 282 return NumCycles == 1; 283 } 284 285 unsigned extraSizeToPredicateInstructions(const MachineFunction &MF, 286 unsigned NumInsts) const override; 287 unsigned predictBranchSizeForIfCvt(MachineInstr &MI) const override; 288 289 bool isProfitableToUnpredicate(MachineBasicBlock &TMBB, 290 MachineBasicBlock &FMBB) const override; 291 292 /// analyzeCompare - For a comparison instruction, return the source registers 293 /// in SrcReg and SrcReg2 if having two register operands, and the value it 294 /// compares against in CmpValue. Return true if the comparison instruction 295 /// can be analyzed. 296 bool analyzeCompare(const MachineInstr &MI, Register &SrcReg, 297 Register &SrcReg2, int64_t &CmpMask, 298 int64_t &CmpValue) const override; 299 300 /// optimizeCompareInstr - Convert the instruction to set the zero flag so 301 /// that we can remove a "comparison with zero"; Remove a redundant CMP 302 /// instruction if the flags can be updated in the same way by an earlier 303 /// instruction such as SUB. 304 bool optimizeCompareInstr(MachineInstr &CmpInstr, Register SrcReg, 305 Register SrcReg2, int64_t CmpMask, int64_t CmpValue, 306 const MachineRegisterInfo *MRI) const override; 307 308 bool analyzeSelect(const MachineInstr &MI, 309 SmallVectorImpl<MachineOperand> &Cond, unsigned &TrueOp, 310 unsigned &FalseOp, bool &Optimizable) const override; 311 312 MachineInstr *optimizeSelect(MachineInstr &MI, 313 SmallPtrSetImpl<MachineInstr *> &SeenMIs, 314 bool) const override; 315 316 /// foldImmediate - 'Reg' is known to be defined by a move immediate 317 /// instruction, try to fold the immediate into the use instruction. 318 bool foldImmediate(MachineInstr &UseMI, MachineInstr &DefMI, Register Reg, 319 MachineRegisterInfo *MRI) const override; 320 321 unsigned getNumMicroOps(const InstrItineraryData *ItinData, 322 const MachineInstr &MI) const override; 323 324 std::optional<unsigned> getOperandLatency(const InstrItineraryData *ItinData, 325 const MachineInstr &DefMI, 326 unsigned DefIdx, 327 const MachineInstr &UseMI, 328 unsigned UseIdx) const override; 329 std::optional<unsigned> getOperandLatency(const InstrItineraryData *ItinData, 330 SDNode *DefNode, unsigned DefIdx, 331 SDNode *UseNode, 332 unsigned UseIdx) const override; 333 334 /// VFP/NEON execution domains. 335 std::pair<uint16_t, uint16_t> 336 getExecutionDomain(const MachineInstr &MI) const override; 337 void setExecutionDomain(MachineInstr &MI, unsigned Domain) const override; 338 339 unsigned 340 getPartialRegUpdateClearance(const MachineInstr &, unsigned, 341 const TargetRegisterInfo *) const override; 342 void breakPartialRegDependency(MachineInstr &, unsigned, 343 const TargetRegisterInfo *TRI) const override; 344 345 /// Get the number of addresses by LDM or VLDM or zero for unknown. 346 unsigned getNumLDMAddresses(const MachineInstr &MI) const; 347 348 std::pair<unsigned, unsigned> 349 decomposeMachineOperandsTargetFlags(unsigned TF) const override; 350 ArrayRef<std::pair<unsigned, const char *>> 351 getSerializableDirectMachineOperandTargetFlags() const override; 352 ArrayRef<std::pair<unsigned, const char *>> 353 getSerializableBitmaskMachineOperandTargetFlags() const override; 354 355 /// ARM supports the MachineOutliner. 356 bool isFunctionSafeToOutlineFrom(MachineFunction &MF, 357 bool OutlineFromLinkOnceODRs) const override; 358 std::optional<std::unique_ptr<outliner::OutlinedFunction>> 359 getOutliningCandidateInfo( 360 const MachineModuleInfo &MMI, 361 std::vector<outliner::Candidate> &RepeatedSequenceLocs, 362 unsigned MinRepeats) const override; 363 void mergeOutliningCandidateAttributes( 364 Function &F, std::vector<outliner::Candidate> &Candidates) const override; 365 outliner::InstrType getOutliningTypeImpl(const MachineModuleInfo &MMI, 366 MachineBasicBlock::iterator &MIT, 367 unsigned Flags) const override; 368 bool isMBBSafeToOutlineFrom(MachineBasicBlock &MBB, 369 unsigned &Flags) const override; 370 void buildOutlinedFrame(MachineBasicBlock &MBB, MachineFunction &MF, 371 const outliner::OutlinedFunction &OF) const override; 372 MachineBasicBlock::iterator 373 insertOutlinedCall(Module &M, MachineBasicBlock &MBB, 374 MachineBasicBlock::iterator &It, MachineFunction &MF, 375 outliner::Candidate &C) const override; 376 377 /// Enable outlining by default at -Oz. 378 bool shouldOutlineFromFunctionByDefault(MachineFunction &MF) const override; 379 380 bool isUnspillableTerminatorImpl(const MachineInstr *MI) const override { 381 return MI->getOpcode() == ARM::t2LoopEndDec || 382 MI->getOpcode() == ARM::t2DoLoopStartTP || 383 MI->getOpcode() == ARM::t2WhileLoopStartLR || 384 MI->getOpcode() == ARM::t2WhileLoopStartTP; 385 } 386 387 /// Analyze loop L, which must be a single-basic-block loop, and if the 388 /// conditions can be understood enough produce a PipelinerLoopInfo object. 389 std::unique_ptr<TargetInstrInfo::PipelinerLoopInfo> 390 analyzeLoopForPipelining(MachineBasicBlock *LoopBB) const override; 391 392 private: 393 /// Returns an unused general-purpose register which can be used for 394 /// constructing an outlined call if one exists. Returns 0 otherwise. 395 Register findRegisterToSaveLRTo(outliner::Candidate &C) const; 396 397 /// Adds an instruction which saves the link register on top of the stack into 398 /// the MachineBasicBlock \p MBB at position \p It. If \p Auth is true, 399 /// compute and store an authentication code alongiside the link register. 400 /// If \p CFI is true, emit CFI instructions. 401 void saveLROnStack(MachineBasicBlock &MBB, MachineBasicBlock::iterator It, 402 bool CFI, bool Auth) const; 403 404 /// Adds an instruction which restores the link register from the top the 405 /// stack into the MachineBasicBlock \p MBB at position \p It. If \p Auth is 406 /// true, restore an authentication code and authenticate LR. 407 /// If \p CFI is true, emit CFI instructions. 408 void restoreLRFromStack(MachineBasicBlock &MBB, 409 MachineBasicBlock::iterator It, bool CFI, 410 bool Auth) const; 411 412 /// Emit CFI instructions into the MachineBasicBlock \p MBB at position \p It, 413 /// for the case when the LR is saved in the register \p Reg. 414 void emitCFIForLRSaveToReg(MachineBasicBlock &MBB, 415 MachineBasicBlock::iterator It, 416 Register Reg) const; 417 418 /// Emit CFI instructions into the MachineBasicBlock \p MBB at position \p It, 419 /// after the LR is was restored from a register. 420 void emitCFIForLRRestoreFromReg(MachineBasicBlock &MBB, 421 MachineBasicBlock::iterator It) const; 422 /// \brief Sets the offsets on outlined instructions in \p MBB which use SP 423 /// so that they will be valid post-outlining. 424 /// 425 /// \param MBB A \p MachineBasicBlock in an outlined function. 426 void fixupPostOutline(MachineBasicBlock &MBB) const; 427 428 /// Returns true if the machine instruction offset can handle the stack fixup 429 /// and updates it if requested. 430 bool checkAndUpdateStackOffset(MachineInstr *MI, int64_t Fixup, 431 bool Updt) const; 432 433 unsigned getInstBundleLength(const MachineInstr &MI) const; 434 435 std::optional<unsigned> getVLDMDefCycle(const InstrItineraryData *ItinData, 436 const MCInstrDesc &DefMCID, 437 unsigned DefClass, unsigned DefIdx, 438 unsigned DefAlign) const; 439 std::optional<unsigned> getLDMDefCycle(const InstrItineraryData *ItinData, 440 const MCInstrDesc &DefMCID, 441 unsigned DefClass, unsigned DefIdx, 442 unsigned DefAlign) const; 443 std::optional<unsigned> getVSTMUseCycle(const InstrItineraryData *ItinData, 444 const MCInstrDesc &UseMCID, 445 unsigned UseClass, unsigned UseIdx, 446 unsigned UseAlign) const; 447 std::optional<unsigned> getSTMUseCycle(const InstrItineraryData *ItinData, 448 const MCInstrDesc &UseMCID, 449 unsigned UseClass, unsigned UseIdx, 450 unsigned UseAlign) const; 451 std::optional<unsigned> getOperandLatency(const InstrItineraryData *ItinData, 452 const MCInstrDesc &DefMCID, 453 unsigned DefIdx, unsigned DefAlign, 454 const MCInstrDesc &UseMCID, 455 unsigned UseIdx, 456 unsigned UseAlign) const; 457 458 std::optional<unsigned> getOperandLatencyImpl( 459 const InstrItineraryData *ItinData, const MachineInstr &DefMI, 460 unsigned DefIdx, const MCInstrDesc &DefMCID, unsigned DefAdj, 461 const MachineOperand &DefMO, unsigned Reg, const MachineInstr &UseMI, 462 unsigned UseIdx, const MCInstrDesc &UseMCID, unsigned UseAdj) const; 463 464 unsigned getPredicationCost(const MachineInstr &MI) const override; 465 466 unsigned getInstrLatency(const InstrItineraryData *ItinData, 467 const MachineInstr &MI, 468 unsigned *PredCost = nullptr) const override; 469 470 unsigned getInstrLatency(const InstrItineraryData *ItinData, 471 SDNode *Node) const override; 472 473 bool hasHighOperandLatency(const TargetSchedModel &SchedModel, 474 const MachineRegisterInfo *MRI, 475 const MachineInstr &DefMI, unsigned DefIdx, 476 const MachineInstr &UseMI, 477 unsigned UseIdx) const override; 478 bool hasLowDefLatency(const TargetSchedModel &SchedModel, 479 const MachineInstr &DefMI, 480 unsigned DefIdx) const override; 481 482 /// verifyInstruction - Perform target specific instruction verification. 483 bool verifyInstruction(const MachineInstr &MI, 484 StringRef &ErrInfo) const override; 485 486 virtual void expandLoadStackGuard(MachineBasicBlock::iterator MI) const = 0; 487 488 void expandMEMCPY(MachineBasicBlock::iterator) const; 489 490 /// Identify instructions that can be folded into a MOVCC instruction, and 491 /// return the defining instruction. 492 MachineInstr *canFoldIntoMOVCC(Register Reg, const MachineRegisterInfo &MRI, 493 const TargetInstrInfo *TII) const; 494 495 bool isReallyTriviallyReMaterializable(const MachineInstr &MI) const override; 496 497 private: 498 /// Modeling special VFP / NEON fp MLA / MLS hazards. 499 500 /// MLxEntryMap - Map fp MLA / MLS to the corresponding entry in the internal 501 /// MLx table. 502 DenseMap<unsigned, unsigned> MLxEntryMap; 503 504 /// MLxHazardOpcodes - Set of add / sub and multiply opcodes that would cause 505 /// stalls when scheduled together with fp MLA / MLS opcodes. 506 SmallSet<unsigned, 16> MLxHazardOpcodes; 507 508 public: 509 /// isFpMLxInstruction - Return true if the specified opcode is a fp MLA / MLS 510 /// instruction. 511 bool isFpMLxInstruction(unsigned Opcode) const { 512 return MLxEntryMap.count(Opcode); 513 } 514 515 /// isFpMLxInstruction - This version also returns the multiply opcode and the 516 /// addition / subtraction opcode to expand to. Return true for 'HasLane' for 517 /// the MLX instructions with an extra lane operand. 518 bool isFpMLxInstruction(unsigned Opcode, unsigned &MulOpc, 519 unsigned &AddSubOpc, bool &NegAcc, 520 bool &HasLane) const; 521 522 /// canCauseFpMLxStall - Return true if an instruction of the specified opcode 523 /// will cause stalls when scheduled after (within 4-cycle window) a fp 524 /// MLA / MLS instruction. 525 bool canCauseFpMLxStall(unsigned Opcode) const { 526 return MLxHazardOpcodes.count(Opcode); 527 } 528 529 /// Returns true if the instruction has a shift by immediate that can be 530 /// executed in one cycle less. 531 bool isSwiftFastImmShift(const MachineInstr *MI) const; 532 533 /// Returns predicate register associated with the given frame instruction. 534 unsigned getFramePred(const MachineInstr &MI) const { 535 assert(isFrameInstr(MI)); 536 // Operands of ADJCALLSTACKDOWN/ADJCALLSTACKUP: 537 // - argument declared in the pattern: 538 // 0 - frame size 539 // 1 - arg of CALLSEQ_START/CALLSEQ_END 540 // 2 - predicate code (like ARMCC::AL) 541 // - added by predOps: 542 // 3 - predicate reg 543 return MI.getOperand(3).getReg(); 544 } 545 546 std::optional<RegImmPair> isAddImmediate(const MachineInstr &MI, 547 Register Reg) const override; 548 }; 549 550 /// Get the operands corresponding to the given \p Pred value. By default, the 551 /// predicate register is assumed to be 0 (no register), but you can pass in a 552 /// \p PredReg if that is not the case. 553 static inline std::array<MachineOperand, 2> predOps(ARMCC::CondCodes Pred, 554 unsigned PredReg = 0) { 555 return {{MachineOperand::CreateImm(static_cast<int64_t>(Pred)), 556 MachineOperand::CreateReg(PredReg, false)}}; 557 } 558 559 /// Get the operand corresponding to the conditional code result. By default, 560 /// this is 0 (no register). 561 static inline MachineOperand condCodeOp(unsigned CCReg = 0) { 562 return MachineOperand::CreateReg(CCReg, false); 563 } 564 565 /// Get the operand corresponding to the conditional code result for Thumb1. 566 /// This operand will always refer to CPSR and it will have the Define flag set. 567 /// You can optionally set the Dead flag by means of \p isDead. 568 static inline MachineOperand t1CondCodeOp(bool isDead = false) { 569 return MachineOperand::CreateReg(ARM::CPSR, 570 /*Define*/ true, /*Implicit*/ false, 571 /*Kill*/ false, isDead); 572 } 573 574 static inline 575 bool isUncondBranchOpcode(int Opc) { 576 return Opc == ARM::B || Opc == ARM::tB || Opc == ARM::t2B; 577 } 578 579 // This table shows the VPT instruction variants, i.e. the different 580 // mask field encodings, see also B5.6. Predication/conditional execution in 581 // the ArmARM. 582 static inline bool isVPTOpcode(int Opc) { 583 return Opc == ARM::MVE_VPTv16i8 || Opc == ARM::MVE_VPTv16u8 || 584 Opc == ARM::MVE_VPTv16s8 || Opc == ARM::MVE_VPTv8i16 || 585 Opc == ARM::MVE_VPTv8u16 || Opc == ARM::MVE_VPTv8s16 || 586 Opc == ARM::MVE_VPTv4i32 || Opc == ARM::MVE_VPTv4u32 || 587 Opc == ARM::MVE_VPTv4s32 || Opc == ARM::MVE_VPTv4f32 || 588 Opc == ARM::MVE_VPTv8f16 || Opc == ARM::MVE_VPTv16i8r || 589 Opc == ARM::MVE_VPTv16u8r || Opc == ARM::MVE_VPTv16s8r || 590 Opc == ARM::MVE_VPTv8i16r || Opc == ARM::MVE_VPTv8u16r || 591 Opc == ARM::MVE_VPTv8s16r || Opc == ARM::MVE_VPTv4i32r || 592 Opc == ARM::MVE_VPTv4u32r || Opc == ARM::MVE_VPTv4s32r || 593 Opc == ARM::MVE_VPTv4f32r || Opc == ARM::MVE_VPTv8f16r || 594 Opc == ARM::MVE_VPST; 595 } 596 597 static inline 598 unsigned VCMPOpcodeToVPT(unsigned Opcode) { 599 switch (Opcode) { 600 default: 601 return 0; 602 case ARM::MVE_VCMPf32: 603 return ARM::MVE_VPTv4f32; 604 case ARM::MVE_VCMPf16: 605 return ARM::MVE_VPTv8f16; 606 case ARM::MVE_VCMPi8: 607 return ARM::MVE_VPTv16i8; 608 case ARM::MVE_VCMPi16: 609 return ARM::MVE_VPTv8i16; 610 case ARM::MVE_VCMPi32: 611 return ARM::MVE_VPTv4i32; 612 case ARM::MVE_VCMPu8: 613 return ARM::MVE_VPTv16u8; 614 case ARM::MVE_VCMPu16: 615 return ARM::MVE_VPTv8u16; 616 case ARM::MVE_VCMPu32: 617 return ARM::MVE_VPTv4u32; 618 case ARM::MVE_VCMPs8: 619 return ARM::MVE_VPTv16s8; 620 case ARM::MVE_VCMPs16: 621 return ARM::MVE_VPTv8s16; 622 case ARM::MVE_VCMPs32: 623 return ARM::MVE_VPTv4s32; 624 625 case ARM::MVE_VCMPf32r: 626 return ARM::MVE_VPTv4f32r; 627 case ARM::MVE_VCMPf16r: 628 return ARM::MVE_VPTv8f16r; 629 case ARM::MVE_VCMPi8r: 630 return ARM::MVE_VPTv16i8r; 631 case ARM::MVE_VCMPi16r: 632 return ARM::MVE_VPTv8i16r; 633 case ARM::MVE_VCMPi32r: 634 return ARM::MVE_VPTv4i32r; 635 case ARM::MVE_VCMPu8r: 636 return ARM::MVE_VPTv16u8r; 637 case ARM::MVE_VCMPu16r: 638 return ARM::MVE_VPTv8u16r; 639 case ARM::MVE_VCMPu32r: 640 return ARM::MVE_VPTv4u32r; 641 case ARM::MVE_VCMPs8r: 642 return ARM::MVE_VPTv16s8r; 643 case ARM::MVE_VCMPs16r: 644 return ARM::MVE_VPTv8s16r; 645 case ARM::MVE_VCMPs32r: 646 return ARM::MVE_VPTv4s32r; 647 } 648 } 649 650 static inline 651 bool isCondBranchOpcode(int Opc) { 652 return Opc == ARM::Bcc || Opc == ARM::tBcc || Opc == ARM::t2Bcc; 653 } 654 655 static inline bool isJumpTableBranchOpcode(int Opc) { 656 return Opc == ARM::BR_JTr || Opc == ARM::BR_JTm_i12 || 657 Opc == ARM::BR_JTm_rs || Opc == ARM::BR_JTadd || Opc == ARM::tBR_JTr || 658 Opc == ARM::t2BR_JT; 659 } 660 661 static inline 662 bool isIndirectBranchOpcode(int Opc) { 663 return Opc == ARM::BX || Opc == ARM::MOVPCRX || Opc == ARM::tBRIND; 664 } 665 666 static inline bool isIndirectCall(const MachineInstr &MI) { 667 int Opc = MI.getOpcode(); 668 switch (Opc) { 669 // indirect calls: 670 case ARM::BLX: 671 case ARM::BLX_noip: 672 case ARM::BLX_pred: 673 case ARM::BLX_pred_noip: 674 case ARM::BX_CALL: 675 case ARM::BMOVPCRX_CALL: 676 case ARM::TCRETURNri: 677 case ARM::TCRETURNrinotr12: 678 case ARM::TAILJMPr: 679 case ARM::TAILJMPr4: 680 case ARM::tBLXr: 681 case ARM::tBLXr_noip: 682 case ARM::tBLXNSr: 683 case ARM::tBLXNS_CALL: 684 case ARM::tBX_CALL: 685 case ARM::tTAILJMPr: 686 assert(MI.isCall(MachineInstr::IgnoreBundle)); 687 return true; 688 // direct calls: 689 case ARM::BL: 690 case ARM::BL_pred: 691 case ARM::BMOVPCB_CALL: 692 case ARM::BL_PUSHLR: 693 case ARM::BLXi: 694 case ARM::TCRETURNdi: 695 case ARM::TAILJMPd: 696 case ARM::SVC: 697 case ARM::HVC: 698 case ARM::TPsoft: 699 case ARM::tTAILJMPd: 700 case ARM::t2SMC: 701 case ARM::t2HVC: 702 case ARM::tBL: 703 case ARM::tBLXi: 704 case ARM::tBL_PUSHLR: 705 case ARM::tTAILJMPdND: 706 case ARM::tSVC: 707 case ARM::tTPsoft: 708 assert(MI.isCall(MachineInstr::IgnoreBundle)); 709 return false; 710 } 711 assert(!MI.isCall(MachineInstr::IgnoreBundle)); 712 return false; 713 } 714 715 static inline bool isIndirectControlFlowNotComingBack(const MachineInstr &MI) { 716 int opc = MI.getOpcode(); 717 return MI.isReturn() || isIndirectBranchOpcode(MI.getOpcode()) || 718 isJumpTableBranchOpcode(opc); 719 } 720 721 static inline bool isSpeculationBarrierEndBBOpcode(int Opc) { 722 return Opc == ARM::SpeculationBarrierISBDSBEndBB || 723 Opc == ARM::SpeculationBarrierSBEndBB || 724 Opc == ARM::t2SpeculationBarrierISBDSBEndBB || 725 Opc == ARM::t2SpeculationBarrierSBEndBB; 726 } 727 728 static inline bool isPopOpcode(int Opc) { 729 return Opc == ARM::tPOP_RET || Opc == ARM::LDMIA_RET || 730 Opc == ARM::t2LDMIA_RET || Opc == ARM::tPOP || Opc == ARM::LDMIA_UPD || 731 Opc == ARM::t2LDMIA_UPD || Opc == ARM::VLDMDIA_UPD; 732 } 733 734 static inline bool isPushOpcode(int Opc) { 735 return Opc == ARM::tPUSH || Opc == ARM::t2STMDB_UPD || 736 Opc == ARM::STMDB_UPD || Opc == ARM::VSTMDDB_UPD; 737 } 738 739 static inline bool isSubImmOpcode(int Opc) { 740 return Opc == ARM::SUBri || 741 Opc == ARM::tSUBi3 || Opc == ARM::tSUBi8 || 742 Opc == ARM::tSUBSi3 || Opc == ARM::tSUBSi8 || 743 Opc == ARM::t2SUBri || Opc == ARM::t2SUBri12 || Opc == ARM::t2SUBSri; 744 } 745 746 static inline bool isMovRegOpcode(int Opc) { 747 return Opc == ARM::MOVr || Opc == ARM::tMOVr || Opc == ARM::t2MOVr; 748 } 749 /// isValidCoprocessorNumber - decide whether an explicit coprocessor 750 /// number is legal in generic instructions like CDP. The answer can 751 /// vary with the subtarget. 752 static inline bool isValidCoprocessorNumber(unsigned Num, 753 const FeatureBitset& featureBits) { 754 // In Armv7 and Armv8-M CP10 and CP11 clash with VFP/NEON, however, the 755 // coprocessor is still valid for CDP/MCR/MRC and friends. Allowing it is 756 // useful for code which is shared with older architectures which do not know 757 // the new VFP/NEON mnemonics. 758 759 // Armv8-A disallows everything *other* than 111x (CP14 and CP15). 760 if (featureBits[ARM::HasV8Ops] && (Num & 0xE) != 0xE) 761 return false; 762 763 // Armv8.1-M disallows 100x (CP8,CP9) and 111x (CP14,CP15) 764 // which clash with MVE. 765 if (featureBits[ARM::HasV8_1MMainlineOps] && 766 ((Num & 0xE) == 0x8 || (Num & 0xE) == 0xE)) 767 return false; 768 769 return true; 770 } 771 772 static inline bool isSEHInstruction(const MachineInstr &MI) { 773 unsigned Opc = MI.getOpcode(); 774 switch (Opc) { 775 case ARM::SEH_StackAlloc: 776 case ARM::SEH_SaveRegs: 777 case ARM::SEH_SaveRegs_Ret: 778 case ARM::SEH_SaveSP: 779 case ARM::SEH_SaveFRegs: 780 case ARM::SEH_SaveLR: 781 case ARM::SEH_Nop: 782 case ARM::SEH_Nop_Ret: 783 case ARM::SEH_PrologEnd: 784 case ARM::SEH_EpilogStart: 785 case ARM::SEH_EpilogEnd: 786 return true; 787 default: 788 return false; 789 } 790 } 791 792 /// getInstrPredicate - If instruction is predicated, returns its predicate 793 /// condition, otherwise returns AL. It also returns the condition code 794 /// register by reference. 795 ARMCC::CondCodes getInstrPredicate(const MachineInstr &MI, Register &PredReg); 796 797 unsigned getMatchingCondBranchOpcode(unsigned Opc); 798 799 /// Map pseudo instructions that imply an 'S' bit onto real opcodes. Whether 800 /// the instruction is encoded with an 'S' bit is determined by the optional 801 /// CPSR def operand. 802 unsigned convertAddSubFlagsOpcode(unsigned OldOpc); 803 804 /// emitARMRegPlusImmediate / emitT2RegPlusImmediate - Emits a series of 805 /// instructions to materializea destreg = basereg + immediate in ARM / Thumb2 806 /// code. 807 void emitARMRegPlusImmediate(MachineBasicBlock &MBB, 808 MachineBasicBlock::iterator &MBBI, 809 const DebugLoc &dl, Register DestReg, 810 Register BaseReg, int NumBytes, 811 ARMCC::CondCodes Pred, Register PredReg, 812 const ARMBaseInstrInfo &TII, unsigned MIFlags = 0); 813 814 void emitT2RegPlusImmediate(MachineBasicBlock &MBB, 815 MachineBasicBlock::iterator &MBBI, 816 const DebugLoc &dl, Register DestReg, 817 Register BaseReg, int NumBytes, 818 ARMCC::CondCodes Pred, Register PredReg, 819 const ARMBaseInstrInfo &TII, unsigned MIFlags = 0); 820 void emitThumbRegPlusImmediate(MachineBasicBlock &MBB, 821 MachineBasicBlock::iterator &MBBI, 822 const DebugLoc &dl, Register DestReg, 823 Register BaseReg, int NumBytes, 824 const TargetInstrInfo &TII, 825 const ARMBaseRegisterInfo &MRI, 826 unsigned MIFlags = 0); 827 828 /// Tries to add registers to the reglist of a given base-updating 829 /// push/pop instruction to adjust the stack by an additional 830 /// NumBytes. This can save a few bytes per function in code-size, but 831 /// obviously generates more memory traffic. As such, it only takes 832 /// effect in functions being optimised for size. 833 bool tryFoldSPUpdateIntoPushPop(const ARMSubtarget &Subtarget, 834 MachineFunction &MF, MachineInstr *MI, 835 unsigned NumBytes); 836 837 /// rewriteARMFrameIndex / rewriteT2FrameIndex - 838 /// Rewrite MI to access 'Offset' bytes from the FP. Return false if the 839 /// offset could not be handled directly in MI, and return the left-over 840 /// portion by reference. 841 bool rewriteARMFrameIndex(MachineInstr &MI, unsigned FrameRegIdx, 842 Register FrameReg, int &Offset, 843 const ARMBaseInstrInfo &TII); 844 845 bool rewriteT2FrameIndex(MachineInstr &MI, unsigned FrameRegIdx, 846 Register FrameReg, int &Offset, 847 const ARMBaseInstrInfo &TII, 848 const TargetRegisterInfo *TRI); 849 850 /// Return true if Reg is defd between From and To 851 bool registerDefinedBetween(unsigned Reg, MachineBasicBlock::iterator From, 852 MachineBasicBlock::iterator To, 853 const TargetRegisterInfo *TRI); 854 855 /// Search backwards from a tBcc to find a tCMPi8 against 0, meaning 856 /// we can convert them to a tCBZ or tCBNZ. Return nullptr if not found. 857 MachineInstr *findCMPToFoldIntoCBZ(MachineInstr *Br, 858 const TargetRegisterInfo *TRI); 859 860 void addUnpredicatedMveVpredNOp(MachineInstrBuilder &MIB); 861 void addUnpredicatedMveVpredROp(MachineInstrBuilder &MIB, Register DestReg); 862 863 void addPredicatedMveVpredNOp(MachineInstrBuilder &MIB, unsigned Cond); 864 void addPredicatedMveVpredROp(MachineInstrBuilder &MIB, unsigned Cond, 865 unsigned Inactive); 866 867 /// Returns the number of instructions required to materialize the given 868 /// constant in a register, or 3 if a literal pool load is needed. 869 /// If ForCodesize is specified, an approximate cost in bytes is returned. 870 unsigned ConstantMaterializationCost(unsigned Val, 871 const ARMSubtarget *Subtarget, 872 bool ForCodesize = false); 873 874 /// Returns true if Val1 has a lower Constant Materialization Cost than Val2. 875 /// Uses the cost from ConstantMaterializationCost, first with ForCodesize as 876 /// specified. If the scores are equal, return the comparison for !ForCodesize. 877 bool HasLowerConstantMaterializationCost(unsigned Val1, unsigned Val2, 878 const ARMSubtarget *Subtarget, 879 bool ForCodesize = false); 880 881 // Return the immediate if this is ADDri or SUBri, scaled as appropriate. 882 // Returns 0 for unknown instructions. 883 inline int getAddSubImmediate(MachineInstr &MI) { 884 int Scale = 1; 885 unsigned ImmOp; 886 switch (MI.getOpcode()) { 887 case ARM::t2ADDri: 888 ImmOp = 2; 889 break; 890 case ARM::t2SUBri: 891 case ARM::t2SUBri12: 892 ImmOp = 2; 893 Scale = -1; 894 break; 895 case ARM::tSUBi3: 896 case ARM::tSUBi8: 897 ImmOp = 3; 898 Scale = -1; 899 break; 900 default: 901 return 0; 902 } 903 return Scale * MI.getOperand(ImmOp).getImm(); 904 } 905 906 // Given a memory access Opcode, check that the give Imm would be a valid Offset 907 // for this instruction using its addressing mode. 908 inline bool isLegalAddressImm(unsigned Opcode, int Imm, 909 const TargetInstrInfo *TII) { 910 const MCInstrDesc &Desc = TII->get(Opcode); 911 unsigned AddrMode = (Desc.TSFlags & ARMII::AddrModeMask); 912 switch (AddrMode) { 913 case ARMII::AddrModeT2_i7: 914 return std::abs(Imm) < ((1 << 7) * 1); 915 case ARMII::AddrModeT2_i7s2: 916 return std::abs(Imm) < ((1 << 7) * 2) && Imm % 2 == 0; 917 case ARMII::AddrModeT2_i7s4: 918 return std::abs(Imm) < ((1 << 7) * 4) && Imm % 4 == 0; 919 case ARMII::AddrModeT2_i8: 920 return std::abs(Imm) < ((1 << 8) * 1); 921 case ARMII::AddrModeT2_i8pos: 922 return Imm >= 0 && Imm < ((1 << 8) * 1); 923 case ARMII::AddrModeT2_i8neg: 924 return Imm < 0 && -Imm < ((1 << 8) * 1); 925 case ARMII::AddrModeT2_i8s4: 926 return std::abs(Imm) < ((1 << 8) * 4) && Imm % 4 == 0; 927 case ARMII::AddrModeT2_i12: 928 return Imm >= 0 && Imm < ((1 << 12) * 1); 929 case ARMII::AddrMode2: 930 return std::abs(Imm) < ((1 << 12) * 1); 931 default: 932 llvm_unreachable("Unhandled Addressing mode"); 933 } 934 } 935 936 // Return true if the given intrinsic is a gather 937 inline bool isGather(IntrinsicInst *IntInst) { 938 if (IntInst == nullptr) 939 return false; 940 unsigned IntrinsicID = IntInst->getIntrinsicID(); 941 return (IntrinsicID == Intrinsic::masked_gather || 942 IntrinsicID == Intrinsic::arm_mve_vldr_gather_base || 943 IntrinsicID == Intrinsic::arm_mve_vldr_gather_base_predicated || 944 IntrinsicID == Intrinsic::arm_mve_vldr_gather_base_wb || 945 IntrinsicID == Intrinsic::arm_mve_vldr_gather_base_wb_predicated || 946 IntrinsicID == Intrinsic::arm_mve_vldr_gather_offset || 947 IntrinsicID == Intrinsic::arm_mve_vldr_gather_offset_predicated); 948 } 949 950 // Return true if the given intrinsic is a scatter 951 inline bool isScatter(IntrinsicInst *IntInst) { 952 if (IntInst == nullptr) 953 return false; 954 unsigned IntrinsicID = IntInst->getIntrinsicID(); 955 return (IntrinsicID == Intrinsic::masked_scatter || 956 IntrinsicID == Intrinsic::arm_mve_vstr_scatter_base || 957 IntrinsicID == Intrinsic::arm_mve_vstr_scatter_base_predicated || 958 IntrinsicID == Intrinsic::arm_mve_vstr_scatter_base_wb || 959 IntrinsicID == Intrinsic::arm_mve_vstr_scatter_base_wb_predicated || 960 IntrinsicID == Intrinsic::arm_mve_vstr_scatter_offset || 961 IntrinsicID == Intrinsic::arm_mve_vstr_scatter_offset_predicated); 962 } 963 964 // Return true if the given intrinsic is a gather or scatter 965 inline bool isGatherScatter(IntrinsicInst *IntInst) { 966 if (IntInst == nullptr) 967 return false; 968 return isGather(IntInst) || isScatter(IntInst); 969 } 970 971 unsigned getBLXOpcode(const MachineFunction &MF); 972 unsigned gettBLXrOpcode(const MachineFunction &MF); 973 unsigned getBLXpredOpcode(const MachineFunction &MF); 974 975 inline bool isMVEVectorInstruction(const MachineInstr *MI) { 976 // This attempts to remove non-mve instructions (scalar shifts), which 977 // are just DPU CX instruction. 978 switch (MI->getOpcode()) { 979 case ARM::MVE_SQSHL: 980 case ARM::MVE_SRSHR: 981 case ARM::MVE_UQSHL: 982 case ARM::MVE_URSHR: 983 case ARM::MVE_SQRSHR: 984 case ARM::MVE_UQRSHL: 985 case ARM::MVE_ASRLr: 986 case ARM::MVE_ASRLi: 987 case ARM::MVE_LSLLr: 988 case ARM::MVE_LSLLi: 989 case ARM::MVE_LSRL: 990 case ARM::MVE_SQRSHRL: 991 case ARM::MVE_SQSHLL: 992 case ARM::MVE_SRSHRL: 993 case ARM::MVE_UQRSHLL: 994 case ARM::MVE_UQSHLL: 995 case ARM::MVE_URSHRL: 996 return false; 997 } 998 const MCInstrDesc &MCID = MI->getDesc(); 999 uint64_t Flags = MCID.TSFlags; 1000 return (Flags & ARMII::DomainMask) == ARMII::DomainMVE; 1001 } 1002 1003 } // end namespace llvm 1004 1005 #endif // LLVM_LIB_TARGET_ARM_ARMBASEINSTRINFO_H 1006