27#define GET_INSTRINFO_CTOR_DTOR
28#include "LanaiGenInstrInfo.inc"
39 bool KillSource)
const {
40 if (!Lanai::GPRRegClass.
contains(DestinationRegister, SourceRegister)) {
51 Register SourceRegister,
bool IsKill,
int FrameIndex,
55 if (Position !=
MBB.
end()) {
56 DL = Position->getDebugLoc();
59 if (!Lanai::GPRRegClass.hasSubClassEq(RegisterClass)) {
71 Register DestinationRegister,
int FrameIndex,
75 if (Position !=
MBB.
end()) {
76 DL = Position->getDebugLoc();
79 if (!Lanai::GPRRegClass.hasSubClassEq(RegisterClass)) {
104 int64_t OffsetA = 0, OffsetB = 0;
105 unsigned int WidthA = 0, WidthB = 0;
109 int LowOffset = std::min(OffsetA, OffsetB);
110 int HighOffset = std::max(OffsetA, OffsetB);
111 int LowWidth = (LowOffset == OffsetA) ? WidthA : WidthB;
112 if (LowOffset + LowWidth <= HighOffset)
162std::pair<unsigned, unsigned>
164 return std::make_pair(TF, 0u);
169 using namespace LanaiII;
170 static const std::pair<unsigned, const char *> TargetFlags[] = {
171 {MO_ABS_HI,
"lanai-hi"},
172 {MO_ABS_LO,
"lanai-lo"},
173 {MO_NO_FLAG,
"lanai-nf"}};
178 Register &SrcReg2, int64_t &CmpMask,
179 int64_t &CmpValue)
const {
180 switch (
MI.getOpcode()) {
183 case Lanai::SFSUB_F_RI_LO:
184 case Lanai::SFSUB_F_RI_HI:
185 SrcReg =
MI.getOperand(0).getReg();
188 CmpValue =
MI.getOperand(1).getImm();
190 case Lanai::SFSUB_F_RR:
191 SrcReg =
MI.getOperand(0).getReg();
192 SrcReg2 =
MI.getOperand(1).getReg();
206 unsigned SrcReg2, int64_t ImmValue,
208 if (CmpI->
getOpcode() == Lanai::SFSUB_F_RR &&
216 if (((CmpI->
getOpcode() == Lanai::SFSUB_F_RI_LO &&
218 (CmpI->
getOpcode() == Lanai::SFSUB_F_RI_HI &&
228 case Lanai::ADD_I_HI:
229 return Lanai::ADD_F_I_HI;
230 case Lanai::ADD_I_LO:
231 return Lanai::ADD_F_I_LO;
233 return Lanai::ADD_F_R;
234 case Lanai::ADDC_I_HI:
235 return Lanai::ADDC_F_I_HI;
236 case Lanai::ADDC_I_LO:
237 return Lanai::ADDC_F_I_LO;
239 return Lanai::ADDC_F_R;
240 case Lanai::AND_I_HI:
241 return Lanai::AND_F_I_HI;
242 case Lanai::AND_I_LO:
243 return Lanai::AND_F_I_LO;
245 return Lanai::AND_F_R;
247 return Lanai::OR_F_I_HI;
249 return Lanai::OR_F_I_LO;
251 return Lanai::OR_F_R;
253 return Lanai::SL_F_I;
255 return Lanai::SRL_F_R;
257 return Lanai::SA_F_I;
259 return Lanai::SRA_F_R;
260 case Lanai::SUB_I_HI:
261 return Lanai::SUB_F_I_HI;
262 case Lanai::SUB_I_LO:
263 return Lanai::SUB_F_I_LO;
265 return Lanai::SUB_F_R;
266 case Lanai::SUBB_I_HI:
267 return Lanai::SUBB_F_I_HI;
268 case Lanai::SUBB_I_LO:
269 return Lanai::SUBB_F_I_LO;
271 return Lanai::SUBB_F_R;
272 case Lanai::XOR_I_HI:
273 return Lanai::XOR_F_I_HI;
274 case Lanai::XOR_I_LO:
275 return Lanai::XOR_F_I_LO;
277 return Lanai::XOR_F_R;
285 int64_t , int64_t CmpValue,
308 else if (
MI->getParent() != CmpInstr.
getParent() || CmpValue != 0) {
312 if (CmpInstr.
getOpcode() == Lanai::SFSUB_F_RI_LO)
321 for (--
I;
I !=
E; --
I) {
324 if (Instr.modifiesRegister(Lanai::SR,
TRI) ||
325 Instr.readsRegister(Lanai::SR,
TRI))
356 while (!isSafe && ++
I !=
E) {
358 for (
unsigned IO = 0, EO = Instr.getNumOperands(); !isSafe && IO != EO;
386 std::make_pair(&((*I).getOperand(IO - 1)), NewCC));
423 if (Succ->isLiveIn(Lanai::SR))
429 MI->addRegisterDefined(Lanai::SR);
439 unsigned &TrueOp,
unsigned &FalseOp,
440 bool &Optimizable)
const {
441 assert(
MI.getOpcode() == Lanai::SELECT &&
"unknown select instruction");
449 Cond.push_back(
MI.getOperand(3));
458 if (!Reg.isVirtual())
460 if (!
MRI.hasOneNonDBGUse(Reg))
466 if (!
MI->isPredicable())
472 if (MO.isFI() || MO.isCPI() || MO.isJTI())
479 if (MO.getReg().isPhysical())
481 if (MO.isDef() && !MO.isDead())
484 bool DontMoveAcrossStores =
true;
485 if (!
MI->isSafeToMove(
nullptr, DontMoveAcrossStores))
494 assert(
MI.getOpcode() == Lanai::SELECT &&
"unknown select instruction");
497 bool Invert = !
DefMI;
507 if (!
MRI.constrainRegClass(DestReg, PreviousClass))
517 i != e && !DefDesc.
operands()[i].isPredicate(); ++i)
520 unsigned CondCode =
MI.getOperand(3).getImm();
564 bool AllowModify)
const {
598 FalseBlock =
nullptr;
615 if (Opcode != Lanai::BRCC)
620 if (Condition.
empty()) {
625 FalseBlock = TrueBlock;
645 "Lanai branch conditions should have one component.");
661 int *BytesAdded)
const {
663 assert(TrueBlock &&
"insertBranch must not be told to insert a fallthrough");
664 assert(!BytesAdded &&
"code size not handled");
667 if (Condition.
empty()) {
668 assert(!FalseBlock &&
"Unconditional branch with multiple successors!");
675 "Lanai branch conditions should have one component.");
676 unsigned ConditionalCode = Condition[0].getImm();
689 int *BytesRemoved)
const {
690 assert(!BytesRemoved &&
"code size not handled");
714 int &FrameIndex)
const {
715 if (
MI.getOpcode() == Lanai::LDW_RI)
716 if (
MI.getOperand(1).isFI() &&
MI.getOperand(2).isImm() &&
717 MI.getOperand(2).getImm() == 0) {
718 FrameIndex =
MI.getOperand(1).getIndex();
719 return MI.getOperand(0).getReg();
725 int &FrameIndex)
const {
726 if (
MI.getOpcode() == Lanai::LDW_RI) {
732 if (hasLoadFromStackSlot(
MI, Accesses)){
734 cast<FixedStackPseudoSourceValue>(Accesses.
front()->getPseudoValue())
743 int &FrameIndex)
const {
744 if (
MI.getOpcode() == Lanai::SW_RI)
745 if (
MI.getOperand(0).isFI() &&
MI.getOperand(1).isImm() &&
746 MI.getOperand(1).getImm() == 0) {
747 FrameIndex =
MI.getOperand(0).getIndex();
748 return MI.getOperand(2).getReg();
788 if (!BaseOp->
isReg())
796 int64_t &
Offset,
bool &OffsetIsScalable,
unsigned &Width,
811 OffsetIsScalable =
false;
unsigned const MachineRegisterInfo * MRI
MachineInstrBuilder MachineInstrBuilder & DefMI
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static bool isRedundantFlagInstr(const MachineInstr *CmpI, Register SrcReg, Register SrcReg2, int64_t ImmValue, const MachineInstr *OI, bool &IsThumb1)
isRedundantFlagInstr - check whether the first instruction, whose only purpose is to update flags,...
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static LPCC::CondCode getOppositeCondition(LPCC::CondCode CC)
static unsigned flagSettingOpcodeVariant(unsigned OldOpcode)
static MachineInstr * canFoldIntoSelect(Register Reg, const MachineRegisterInfo &MRI)
unsigned const TargetRegisterInfo * TRI
const SmallVectorImpl< MachineOperand > & Cond
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file defines the SmallVector class.
static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
size_t size() const
size - Get the array size.
bool empty() const
empty - Check if the array is empty.
unsigned getOpcode() const
Returns a member of one of the enums like Instruction::Add.
SymbolTableList< Instruction >::iterator eraseFromParent()
This method unlinks 'this' from the containing basic block and deletes it.
bool areMemAccessesTriviallyDisjoint(const MachineInstr &MIa, const MachineInstr &MIb) const override
bool getMemOperandWithOffsetWidth(const MachineInstr &LdSt, const MachineOperand *&BaseOp, int64_t &Offset, unsigned &Width, const TargetRegisterInfo *TRI) const
unsigned insertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TrueBlock, MachineBasicBlock *FalseBlock, ArrayRef< MachineOperand > Condition, const DebugLoc &DL, int *BytesAdded=nullptr) const override
bool analyzeSelect(const MachineInstr &MI, SmallVectorImpl< MachineOperand > &Cond, unsigned &TrueOp, unsigned &FalseOp, bool &Optimizable) const override
void copyPhysReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator Position, const DebugLoc &DL, MCRegister DestinationRegister, MCRegister SourceRegister, bool KillSource) const override
std::pair< unsigned, unsigned > decomposeMachineOperandsTargetFlags(unsigned TF) const override
bool analyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TrueBlock, MachineBasicBlock *&FalseBlock, SmallVectorImpl< MachineOperand > &Condition, bool AllowModify) const override
virtual const LanaiRegisterInfo & getRegisterInfo() const
MachineInstr * optimizeSelect(MachineInstr &MI, SmallPtrSetImpl< MachineInstr * > &SeenMIs, bool PreferFalse) const override
void loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator Position, Register DestinationRegister, int FrameIndex, const TargetRegisterClass *RegisterClass, const TargetRegisterInfo *RegisterInfo, Register VReg) const override
bool expandPostRAPseudo(MachineInstr &MI) const override
unsigned isLoadFromStackSlotPostFE(const MachineInstr &MI, int &FrameIndex) const override
unsigned isLoadFromStackSlot(const MachineInstr &MI, int &FrameIndex) const override
ArrayRef< std::pair< unsigned, const char * > > getSerializableDirectMachineOperandTargetFlags() const override
bool optimizeCompareInstr(MachineInstr &CmpInstr, Register SrcReg, Register SrcReg2, int64_t CmpMask, int64_t CmpValue, const MachineRegisterInfo *MRI) const override
bool analyzeCompare(const MachineInstr &MI, Register &SrcReg, Register &SrcReg2, int64_t &CmpMask, int64_t &CmpValue) const override
unsigned removeBranch(MachineBasicBlock &MBB, int *BytesRemoved=nullptr) const override
unsigned isStoreToStackSlot(const MachineInstr &MI, int &FrameIndex) const override
bool getMemOperandsWithOffsetWidth(const MachineInstr &LdSt, SmallVectorImpl< const MachineOperand * > &BaseOps, int64_t &Offset, bool &OffsetIsScalable, unsigned &Width, const TargetRegisterInfo *TRI) const override
bool reverseBranchCondition(SmallVectorImpl< MachineOperand > &Condition) const override
void storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator Position, Register SourceRegister, bool IsKill, int FrameIndex, const TargetRegisterClass *RegisterClass, const TargetRegisterInfo *RegisterInfo, Register VReg) const override
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.
bool isLayoutSuccessor(const MachineBasicBlock *MBB) const
Return true if the specified MBB will be emitted immediately after this block, such that if this bloc...
instr_iterator erase(instr_iterator I)
Remove an instruction from the instruction list and delete it.
iterator_range< succ_iterator > successors()
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 & addMBB(MachineBasicBlock *MBB, unsigned TargetFlags=0) const
const MachineInstrBuilder & copyImplicitOps(const MachineInstr &OtherMI) const
Copy all the implicit operands from OtherMI onto this one.
Representation of each machine instruction.
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
bool mayLoadOrStore(QueryType Type=AnyInBundle) const
Return true if this instruction could possibly read or modify memory.
const MachineBasicBlock * getParent() const
unsigned getNumOperands() const
Retuns the total number of operands.
const MCInstrDesc & getDesc() const
Returns the target instruction descriptor of this MachineInstr.
bool hasUnmodeledSideEffects() const
Return true if this instruction has side effects that are not modeled by mayLoad / mayStore,...
void tieOperands(unsigned DefIdx, unsigned UseIdx)
Add a tie between the register operands at DefIdx and UseIdx.
bool hasOrderedMemoryRef() const
Return true if this instruction may have an ordered or volatile memory reference, or if the informati...
void eraseFromParent()
Unlink 'this' from the containing basic block and delete it.
const MachineOperand & getOperand(unsigned i) const
void clearKillInfo()
Clears kill flags on all operands.
MachineOperand class - Representation of each machine instruction operand.
void setImplicit(bool Val=true)
bool isReg() const
isReg - Tests if this is a MO_Register operand.
bool isRegMask() const
isRegMask - Tests if this is a MO_RegisterMask operand.
bool isImm() const
isImm - Tests if this is a MO_Immediate operand.
static MachineOperand CreateImm(int64_t Val)
Register getReg() const
getReg - Returns the register number.
bool isIdenticalTo(const MachineOperand &Other) const
Returns true if this operand is identical to the specified operand except for liveness related flags ...
static bool clobbersPhysReg(const uint32_t *RegMask, MCRegister PhysReg)
clobbersPhysReg - Returns true if this RegMask clobbers PhysReg.
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
Wrapper class representing virtual and physical registers.
A templated base class for SmallPtrSet which provides the typesafe interface that is common across al...
bool erase(PtrType Ptr)
erase - If the set contains the specified pointer, remove it and return true, otherwise return false.
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
Value * getOperand(unsigned i) const
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
This is an optimization pass for GlobalISel generic memory operations.
auto drop_begin(T &&RangeOrContainer, size_t N=1)
Return a range covering RangeOrContainer with the first N elements excluded.
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
decltype(auto) get(const PointerIntPair< PointerTy, IntBits, IntType, PtrTraits, Info > &Pair)
unsigned getKillRegState(bool B)