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