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