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