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