40 cl::desc(
"Use old-style Thumb2 if-conversion heuristics"),
45 cl::desc(
"Prefer predicated Move to CSEL"),
87 while (Count &&
MBBI !=
E) {
88 if (
MBBI->isDebugInstr()) {
92 if (
MBBI->getOpcode() == ARM::t2IT) {
93 unsigned Mask =
MBBI->getOperand(1).getImm();
97 unsigned MaskOn = 1 << Count;
98 unsigned MaskOff = ~(MaskOn - 1);
99 MBBI->getOperand(1).setImm((Mask & MaskOff) | MaskOn);
115 while (
MBBI->isDebugInstr()) {
128 bool PreferFalse)
const {
140 get(ARM::t2CSEL), DestReg)
141 .
add(
MI.getOperand(2))
142 .
add(
MI.getOperand(1))
143 .
add(
MI.getOperand(3));
155 if (!ARM::GPRRegClass.
contains(DestReg, SrcReg))
165 Register SrcReg,
bool isKill,
int FI,
178 if (ARM::GPRRegClass.hasSubClassEq(RC)) {
188 if (ARM::GPRPairRegClass.hasSubClassEq(RC)) {
194 MRI->constrainRegClass(SrcReg, &ARM::GPRPairnospRegClass);
222 if (ARM::GPRRegClass.hasSubClassEq(RC)) {
231 if (ARM::GPRPairRegClass.hasSubClassEq(RC)) {
237 MRI->constrainRegClass(DestReg, &ARM::GPRPairnospRegClass);
254void Thumb2InstrInfo::expandLoadStackGuard(
259 if (M.getStackProtectorGuard() ==
"tls") {
265 cast<GlobalValue>((*
MI->memoperands_begin())->getValue());
278 unsigned OpIdx2)
const {
279 switch (
MI.getOpcode()) {
280 case ARM::MVE_VMAXNMAf16:
281 case ARM::MVE_VMAXNMAf32:
282 case ARM::MVE_VMINNMAf16:
283 case ARM::MVE_VMINNMAf32:
298 if (NumBytes == 0 && DestReg != BaseReg) {
305 bool isSub = NumBytes < 0;
306 if (isSub) NumBytes = -NumBytes;
310 if (DestReg != ARM::SP && DestReg != BaseReg &&
314 if (NumBytes < 65536) {
320 }
else if ((NumBytes & 0xffff) == 0) {
355 unsigned ThisVal = NumBytes;
357 if (DestReg == ARM::SP && BaseReg != ARM::SP) {
367 assert((DestReg != ARM::SP || BaseReg == ARM::SP) &&
368 "Writing to SP, from other register.");
371 if ((DestReg == ARM::SP) && (ThisVal < ((1 << 7) - 1) * 4)) {
372 assert((ThisVal & 3) == 0 &&
"Stack update is not multiple of 4?");
373 Opc = isSub ? ARM::tSUBspi : ARM::tADDspi;
381 bool HasCCOut =
true;
383 bool ToSP = DestReg == ARM::SP;
384 unsigned t2SUB = ToSP ? ARM::t2SUBspImm : ARM::t2SUBri;
385 unsigned t2ADD = ToSP ? ARM::t2ADDspImm : ARM::t2ADDri;
386 unsigned t2SUBi12 = ToSP ? ARM::t2SUBspImm12 : ARM::t2SUBri12;
387 unsigned t2ADDi12 = ToSP ? ARM::t2ADDspImm12 : ARM::t2ADDri12;
388 Opc = isSub ? t2SUB : t2ADD;
390 if (ImmIsT2SO != -1) {
392 }
else if (ThisVal < 4096) {
395 Opc = isSub ? t2SUBi12 : t2ADDi12;
402 ThisVal = ThisVal & llvm::rotr<uint32_t>(0xff000000U, RotAmt);
403 NumBytes &= ~ThisVal;
405 "Bit extraction didn't work?");
425 case ARM::t2LDRi12:
return ARM::t2LDRi8;
426 case ARM::t2LDRHi12:
return ARM::t2LDRHi8;
427 case ARM::t2LDRBi12:
return ARM::t2LDRBi8;
428 case ARM::t2LDRSHi12:
return ARM::t2LDRSHi8;
429 case ARM::t2LDRSBi12:
return ARM::t2LDRSBi8;
430 case ARM::t2STRi12:
return ARM::t2STRi8;
431 case ARM::t2STRBi12:
return ARM::t2STRBi8;
432 case ARM::t2STRHi12:
return ARM::t2STRHi8;
433 case ARM::t2PLDi12:
return ARM::t2PLDi8;
434 case ARM::t2PLDWi12:
return ARM::t2PLDWi8;
435 case ARM::t2PLIi12:
return ARM::t2PLIi8;
459 case ARM::t2LDRi8:
return ARM::t2LDRi12;
460 case ARM::t2LDRHi8:
return ARM::t2LDRHi12;
461 case ARM::t2LDRBi8:
return ARM::t2LDRBi12;
462 case ARM::t2LDRSHi8:
return ARM::t2LDRSHi12;
463 case ARM::t2LDRSBi8:
return ARM::t2LDRSBi12;
464 case ARM::t2STRi8:
return ARM::t2STRi12;
465 case ARM::t2STRBi8:
return ARM::t2STRBi12;
466 case ARM::t2STRHi8:
return ARM::t2STRHi12;
467 case ARM::t2PLDi8:
return ARM::t2PLDi12;
468 case ARM::t2PLDWi8:
return ARM::t2PLDWi12;
469 case ARM::t2PLIi8:
return ARM::t2PLIi12;
474 case ARM::t2LDRSHi12:
475 case ARM::t2LDRSBi12:
493 case ARM::t2LDRs:
return ARM::t2LDRi12;
494 case ARM::t2LDRHs:
return ARM::t2LDRHi12;
495 case ARM::t2LDRBs:
return ARM::t2LDRBi12;
496 case ARM::t2LDRSHs:
return ARM::t2LDRSHi12;
497 case ARM::t2LDRSBs:
return ARM::t2LDRSBi12;
498 case ARM::t2STRs:
return ARM::t2STRi12;
499 case ARM::t2STRBs:
return ARM::t2STRBi12;
500 case ARM::t2STRHs:
return ARM::t2STRHi12;
501 case ARM::t2PLDs:
return ARM::t2PLDi12;
502 case ARM::t2PLDWs:
return ARM::t2PLDWi12;
503 case ARM::t2PLIs:
return ARM::t2PLIi12;
508 case ARM::t2LDRSHi12:
509 case ARM::t2LDRSBi12:
538 unsigned Opcode =
MI.getOpcode();
545 TII.getRegClass(Desc, FrameRegIdx,
TRI, MF);
548 if (Opcode == ARM::INLINEASM || Opcode == ARM::INLINEASM_BR)
551 const bool IsSP = Opcode == ARM::t2ADDspImm12 || Opcode == ARM::t2ADDspImm;
552 if (IsSP || Opcode == ARM::t2ADDri || Opcode == ARM::t2ADDri12) {
553 Offset +=
MI.getOperand(FrameRegIdx+1).getImm();
557 !
MI.definesRegister(ARM::CPSR)) {
559 MI.setDesc(
TII.get(ARM::tMOVr));
560 MI.getOperand(FrameRegIdx).ChangeToRegister(FrameReg,
false);
562 do MI.removeOperand(FrameRegIdx+1);
563 while (
MI.getNumOperands() > FrameRegIdx+1);
569 bool HasCCOut = (Opcode != ARM::t2ADDspImm12 && Opcode != ARM::t2ADDri12);
574 MI.setDesc(IsSP ?
TII.get(ARM::t2SUBspImm) :
TII.get(ARM::t2SUBri));
576 MI.setDesc(IsSP ?
TII.get(ARM::t2ADDspImm) :
TII.get(ARM::t2ADDri));
581 MI.getOperand(FrameRegIdx).ChangeToRegister(FrameReg,
false);
582 MI.getOperand(FrameRegIdx+1).ChangeToImmediate(
Offset);
591 (!HasCCOut ||
MI.getOperand(
MI.getNumOperands()-1).getReg() == 0)) {
592 unsigned NewOpc = isSub ? IsSP ? ARM::t2SUBspImm12 : ARM::t2SUBri12
593 : IsSP ? ARM::t2ADDspImm12 : ARM::t2ADDri12;
594 MI.setDesc(
TII.get(NewOpc));
595 MI.getOperand(FrameRegIdx).ChangeToRegister(FrameReg,
false);
596 MI.getOperand(FrameRegIdx+1).ChangeToImmediate(
Offset);
599 MI.removeOperand(
MI.getNumOperands()-1);
606 unsigned RotAmt = llvm::countl_zero<unsigned>(
Offset);
607 unsigned ThisImmVal =
Offset & llvm::rotr<uint32_t>(0xff000000U, RotAmt);
613 "Bit extraction didn't work?");
614 MI.getOperand(FrameRegIdx+1).ChangeToImmediate(ThisImmVal);
625 unsigned NewOpc = Opcode;
627 Register OffsetReg =
MI.getOperand(FrameRegIdx + 1).getReg();
628 if (OffsetReg != 0) {
629 MI.getOperand(FrameRegIdx).ChangeToRegister(FrameReg,
false);
633 MI.removeOperand(FrameRegIdx+1);
634 MI.getOperand(FrameRegIdx+1).ChangeToImmediate(0);
639 unsigned NumBits = 0;
646 Offset +=
MI.getOperand(FrameRegIdx+1).getImm();
665 assert((
Offset & (Scale-1)) == 0 &&
"Can't encode this offset!");
679 assert((
Offset & (Scale-1)) == 0 &&
"Can't encode this offset!");
687 Offset +=
MI.getOperand(FrameRegIdx + 1).getImm();
692 default: NumBits = 7; OffsetMask = 0x0;
break;
696 assert((
Offset & OffsetMask) == 0 &&
"Can't encode this offset!");
699 Offset +=
MI.getOperand(FrameRegIdx + 1).getImm();
703 assert((
Offset & 3) == 0 &&
"Can't encode this offset!");
705 Offset +=
MI.getOperand(FrameRegIdx + 1).getImm() * 4;
708 assert((
Offset & 3) == 0 &&
"Can't encode this offset!");
713 if (NewOpc != Opcode)
714 MI.setDesc(
TII.get(NewOpc));
722 int ImmedOffset =
Offset / Scale;
723 unsigned Mask = (1 << NumBits) - 1;
724 if ((
unsigned)
Offset <= Mask * Scale &&
729 if (!
MRI->constrainRegClass(FrameReg, RegClass))
734 MI.getOperand(FrameRegIdx).ChangeToRegister(FrameReg,
false);
738 ImmedOffset |= 1 << NumBits;
740 ImmedOffset = -ImmedOffset;
748 ImmedOffset = ImmedOffset & Mask;
752 ImmedOffset |= 1 << NumBits;
754 ImmedOffset = -ImmedOffset;
755 if (ImmedOffset == 0)
770 unsigned Opc =
MI.getOpcode();
771 if (Opc == ARM::tBcc || Opc == ARM::t2Bcc)
794 PredReg =
MI.getOperand(PIdx+1).getReg();
802 assert(MaskOp.
isImm() &&
"Operand 0 is not the block mask of the VPT/VPST?!");
807 while (Iter !=
End && Iter->isDebugInstr())
812 assert(Iter !=
End &&
"Expected some instructions in any VPT block");
815 "VPT/VPST should be followed by an instruction with a 'then' predicate!");
820 while (Iter !=
End) {
821 if (Iter->isDebugInstr()) {
833 MaskOp.
setImm((int64_t)(BlockMask));
unsigned const MachineRegisterInfo * MRI
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
MachineBasicBlock MachineBasicBlock::iterator MBBI
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
const HexagonInstrInfo * TII
unsigned const TargetRegisterInfo * TRI
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
static unsigned negativeOffsetOpcode(unsigned opcode)
static unsigned positiveOffsetOpcode(unsigned opcode)
static cl::opt< bool > OldT2IfCvt("old-thumb2-ifcvt", cl::Hidden, cl::desc("Use old-style Thumb2 if-conversion heuristics"), cl::init(false))
static cl::opt< bool > PreferNoCSEL("prefer-no-csel", cl::Hidden, cl::desc("Prefer predicated Move to CSEL"), cl::init(false))
static unsigned immediateOffsetOpcode(unsigned opcode)
static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)
void copyPhysReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, const DebugLoc &DL, MCRegister DestReg, MCRegister SrcReg, bool KillSrc) const override
const MachineInstrBuilder & AddDReg(MachineInstrBuilder &MIB, unsigned Reg, unsigned SubIdx, unsigned State, const TargetRegisterInfo *TRI) const
MachineInstr * optimizeSelect(MachineInstr &MI, SmallPtrSetImpl< MachineInstr * > &SeenMIs, bool) const override
void loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, Register DestReg, int FrameIndex, const TargetRegisterClass *RC, const TargetRegisterInfo *TRI, Register VReg) const override
void expandLoadStackGuardBase(MachineBasicBlock::iterator MI, unsigned LoadImmOpc, unsigned LoadOpc) const
void storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, Register SrcReg, bool isKill, int FrameIndex, const TargetRegisterClass *RC, const TargetRegisterInfo *TRI, Register VReg) 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.
ARMFunctionInfo - This class is derived from MachineFunctionInfo and contains private ARM-specific in...
bool isGVInGOT(const GlobalValue *GV) const
Returns the constant pool modifier needed to access the GV.
Module * getParent()
Get the module that this global value is contained inside of...
MCInstBuilder & addReg(unsigned Reg)
Add a new register operand.
MCInstBuilder & addImm(int64_t Val)
Add a new integer immediate operand.
Instances of this class represent a single low-level machine instruction.
Describe properties that are true of each instruction in the target description file.
unsigned getNumOperands() const
Return the number of declared MachineOperands for this MachineInstruction.
ArrayRef< MCOperandInfo > operands() const
Wrapper class representing physical registers. Should be passed by value.
void eraseFromParent()
This method unlinks 'this' from the containing function and deletes it.
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted.
Align getObjectAlign(int ObjectIdx) const
Return the alignment of the specified stack object.
int64_t getObjectSize(int ObjectIdx) const
Return the size of the specified object.
MachineMemOperand * getMachineMemOperand(MachinePointerInfo PtrInfo, MachineMemOperand::Flags f, uint64_t s, Align base_alignment, const AAMDNodes &AAInfo=AAMDNodes(), const MDNode *Ranges=nullptr, SyncScope::ID SSID=SyncScope::System, AtomicOrdering Ordering=AtomicOrdering::NotAtomic, AtomicOrdering FailureOrdering=AtomicOrdering::NotAtomic)
getMachineMemOperand - Allocate a new MachineMemOperand.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
Function & getFunction()
Return the LLVM function that this machine code represents.
const LLVMTargetMachine & getTarget() const
getTarget - Return the target machine this machine code is compiled with
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
const MachineInstrBuilder & add(const MachineOperand &MO) const
const MachineInstrBuilder & addFrameIndex(int Idx) const
const MachineInstrBuilder & addReg(Register RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
const MachineInstrBuilder & setMIFlags(unsigned Flags) const
const MachineInstrBuilder & addMemOperand(MachineMemOperand *MMO) const
Representation of each machine instruction.
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
const MachineBasicBlock * getParent() const
const MachineOperand & getOperand(unsigned i) const
A description of a memory reference used in the backend.
@ MOLoad
The memory access reads data.
@ MOStore
The memory access writes data.
MachineOperand class - Representation of each machine instruction operand.
void setImm(int64_t immVal)
bool isImm() const
isImm - Tests if this is a MO_Immediate operand.
void ChangeToImmediate(int64_t ImmVal, unsigned TargetFlags=0)
ChangeToImmediate - Replace this operand with a new immediate operand of the specified value.
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.
Wrapper class representing virtual and physical registers.
constexpr bool isVirtual() const
Return true if the specified register number is in the virtual register namespace.
constexpr bool isPhysical() const
Return true if the specified register number is in the physical register namespace.
A templated base class for SmallPtrSet which provides the typesafe interface that is common across al...
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
virtual void ReplaceTailWithBranchTo(MachineBasicBlock::iterator Tail, MachineBasicBlock *NewDest) const
Delete the instruction OldInst and everything after it, replacing it with an unconditional branch to ...
bool isPositionIndependent() const
bool contains(Register Reg) const
Return true if the specified register is included in this register class.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
bool isLegalToSplitMBBAt(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI) const override
unsigned getUnindexedOpcode(unsigned Opc) const override
void loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, Register DestReg, int FrameIndex, const TargetRegisterClass *RC, const TargetRegisterInfo *TRI, Register VReg) const override
MachineInstr * commuteInstructionImpl(MachineInstr &MI, bool NewMI, unsigned OpIdx1, unsigned OpIdx2) const override
void ReplaceTailWithBranchTo(MachineBasicBlock::iterator Tail, MachineBasicBlock *NewDest) const override
MachineInstr * optimizeSelect(MachineInstr &MI, SmallPtrSetImpl< MachineInstr * > &SeenMIs, bool) const override
Thumb2InstrInfo(const ARMSubtarget &STI)
void storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, Register SrcReg, bool isKill, int FrameIndex, const TargetRegisterClass *RC, const TargetRegisterInfo *TRI, Register VReg) const override
MCInst getNop() const override
Return the noop instruction to use for a noop.
void copyPhysReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, const DebugLoc &DL, MCRegister DestReg, MCRegister SrcReg, bool KillSrc) const override
self_iterator getIterator()
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
unsigned char getAM5FP16Offset(unsigned AM5Opc)
int getT2SOImmVal(unsigned Arg)
getT2SOImmVal - Given a 32-bit immediate, if it is something that can fit into a Thumb-2 shifter_oper...
AddrOpc getAM5Op(unsigned AM5Opc)
AddrOpc getAM5FP16Op(unsigned AM5Opc)
unsigned char getAM5Offset(unsigned AM5Opc)
PredBlockMask
Mask values for IT and VPT Blocks, to be used by MCOperands.
bool isVpred(OperandType op)
@ Tail
Attemps to make calls as fast as possible while guaranteeing that tail call optimization can always b...
@ Kill
The last use of a register.
initializer< Ty > init(const Ty &Val)
This is an optimization pass for GlobalISel generic memory operations.
int findFirstVPTPredOperandIdx(const MachineInstr &MI)
ARMVCC::VPTCodes getVPTInstrPredicate(const MachineInstr &MI, Register &PredReg)
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
static bool isVPTOpcode(int Opc)
bool rewriteT2FrameIndex(MachineInstr &MI, unsigned FrameRegIdx, Register FrameReg, int &Offset, const ARMBaseInstrInfo &TII, const TargetRegisterInfo *TRI)
static std::array< MachineOperand, 2 > predOps(ARMCC::CondCodes Pred, unsigned PredReg=0)
Get the operands corresponding to the given Pred value.
int countl_zero(T Val)
Count number of 0's from the most significant bit to the least stopping at the first 1.
ARMCC::CondCodes getITInstrPredicate(const MachineInstr &MI, Register &PredReg)
getITInstrPredicate - Valid only in Thumb2 mode.
decltype(auto) get(const PointerIntPair< PointerTy, IntBits, IntType, PtrTraits, Info > &Pair)
unsigned getKillRegState(bool B)
ARM::PredBlockMask expandPredBlockMask(ARM::PredBlockMask BlockMask, ARMVCC::VPTCodes Kind)
ARMCC::CondCodes getInstrPredicate(const MachineInstr &MI, Register &PredReg)
getInstrPredicate - If instruction is predicated, returns its predicate condition,...
static MachineOperand condCodeOp(unsigned CCReg=0)
Get the operand corresponding to the conditional code result.
void recomputeVPTBlockMask(MachineInstr &Instr)
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 MachinePointerInfo getFixedStack(MachineFunction &MF, int FI, int64_t Offset=0)
Return a MachinePointerInfo record that refers to the specified FrameIndex.