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