Go to the documentation of this file.
27 #define GET_INSTRINFO_CTOR_DTOR
28 #include "LanaiGenInstrInfo.inc"
39 bool KillSource)
const {
40 if (!Lanai::GPRRegClass.
contains(DestinationRegister, SourceRegister)) {
55 if (Position !=
MBB.
end()) {
56 DL = Position->getDebugLoc();
59 if (!Lanai::GPRRegClass.hasSubClassEq(RegisterClass)) {
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)
162 std::pair<unsigned, unsigned>
164 return std::make_pair(TF, 0u);
169 using namespace LanaiII;
170 static const std::pair<unsigned, const char *> TargetFlags[] = {
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) {
356 while (!isSafe && ++
I !=
E) {
358 for (
unsigned IO = 0, EO = Instr.
getNumOperands(); !isSafe && IO != EO;
385 OperandsToUpdate.push_back(
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 {
449 Cond.push_back(
MI.getOperand(3));
458 if (!
Reg.isVirtual())
466 if (!
MI->isPredicable())
472 if (MO.isFI() || MO.isCPI() || MO.isJTI())
481 if (MO.isDef() && !MO.isDead())
484 bool DontMoveAcrossStores =
true;
485 if (!
MI->isSafeToMove(
nullptr, DontMoveAcrossStores))
497 bool Invert = !
DefMI;
520 unsigned CondCode =
MI.getOperand(3).getImm();
564 bool AllowModify)
const {
600 FalseBlock =
nullptr;
617 if (Opcode != Lanai::BRCC)
622 if (Condition.empty()) {
627 FalseBlock = TrueBlock;
646 assert((Condition.size() == 1) &&
647 "Lanai branch conditions should have one component.");
663 int *BytesAdded)
const {
665 assert(TrueBlock &&
"insertBranch must not be told to insert a fallthrough");
666 assert(!BytesAdded &&
"code size not handled");
669 if (Condition.
empty()) {
670 assert(!FalseBlock &&
"Unconditional branch with multiple successors!");
677 "Lanai branch conditions should have one component.");
678 unsigned ConditionalCode = Condition[0].getImm();
691 int *BytesRemoved)
const {
692 assert(!BytesRemoved &&
"code size not handled");
717 if (
MI.getOpcode() == Lanai::LDW_RI)
718 if (
MI.getOperand(1).isFI() &&
MI.getOperand(2).isImm() &&
719 MI.getOperand(2).getImm() == 0) {
721 return MI.getOperand(0).getReg();
728 if (
MI.getOpcode() == Lanai::LDW_RI) {
734 if (hasLoadFromStackSlot(
MI, Accesses)){
736 cast<FixedStackPseudoSourceValue>(Accesses.front()->getPseudoValue())
746 if (
MI.getOpcode() == Lanai::SW_RI)
747 if (
MI.getOperand(0).isFI() &&
MI.getOperand(1).isImm() &&
748 MI.getOperand(1).getImm() == 0) {
750 return MI.getOperand(2).getReg();
790 if (!BaseOp->
isReg())
798 int64_t &Offset,
bool &OffsetIsScalable,
unsigned &
Width,
813 OffsetIsScalable =
false;
816 BaseOps.push_back(BaseOp);
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
This is an optimization pass for GlobalISel generic memory operations.
const MachineInstrBuilder & copyImplicitOps(const MachineInstr &OtherMI) const
Copy all the implicit operands from OtherMI onto this one.
auto drop_begin(T &&RangeOrContainer, size_t N=1)
Return a range covering RangeOrContainer with the first N elements excluded.
bool erase(PtrType Ptr)
erase - If the set contains the specified pointer, remove it and return true, otherwise return false.
unsigned isLoadFromStackSlotPostFE(const MachineInstr &MI, int &FrameIndex) const override
unsigned insertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TrueBlock, MachineBasicBlock *FalseBlock, ArrayRef< MachineOperand > Condition, const DebugLoc &DL, int *BytesAdded=nullptr) const override
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
bool mayLoadOrStore(QueryType Type=AnyInBundle) const
Return true if this instruction could possibly read or modify memory.
const MachineInstrBuilder & add(const MachineOperand &MO) const
bool analyzeCompare(const MachineInstr &MI, Register &SrcReg, Register &SrcReg2, int64_t &CmpMask, int64_t &CmpValue) const override
static MachineInstr * canFoldIntoSelect(Register Reg, const MachineRegisterInfo &MRI)
return AArch64::GPR64RegClass contains(Reg)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Reg
All possible values of the reg field in the ModR/M byte.
MachineInstr * getUniqueVRegDef(Register Reg) const
getUniqueVRegDef - Return the unique machine instr that defines the specified virtual register or nul...
void storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator Position, Register SourceRegister, bool IsKill, int FrameIndex, const TargetRegisterClass *RegisterClass, const TargetRegisterInfo *RegisterInfo) const override
bool analyzeSelect(const MachineInstr &MI, SmallVectorImpl< MachineOperand > &Cond, unsigned &TrueOp, unsigned &FalseOp, bool &Optimizable) const override
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
const MCInstrDesc & getDesc() const
Returns the target instruction descriptor of this MachineInstr.
bool areMemAccessesTriviallyDisjoint(const MachineInstr &MIa, const MachineInstr &MIb) const override
static bool isRedundantFlagInstr(MachineInstr *CmpI, unsigned SrcReg, unsigned SrcReg2, int64_t ImmValue, MachineInstr *OI)
unsigned const TargetRegisterInfo * TRI
bool getMemOperandWithOffsetWidth(const MachineInstr &LdSt, const MachineOperand *&BaseOp, int64_t &Offset, unsigned &Width, const TargetRegisterInfo *TRI) const
bool empty() const
empty - Check if the array is empty.
bool hasOrderedMemoryRef() const
Return true if this instruction may have an ordered or volatile memory reference, or if the informati...
unsigned getOpcode() const
Returns a member of one of the enums like Instruction::Add.
const MachineInstrBuilder & addMBB(MachineBasicBlock *MBB, unsigned TargetFlags=0) const
@ SELECT
Select(COND, TRUEVAL, FALSEVAL).
static MachineOperand CreateImm(int64_t Val)
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
const MachineOperand & getOperand(unsigned i) const
void clearKillInfo()
Clears kill flags on all operands.
void loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator Position, Register DestinationRegister, int FrameIndex, const TargetRegisterClass *RegisterClass, const TargetRegisterInfo *RegisterInfo) const override
virtual const LanaiRegisterInfo & getRegisterInfo() const
static bool isPhysicalRegister(unsigned Reg)
Return true if the specified register number is in the physical register namespace.
Describe properties that are true of each instruction in the target description file.
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
MachineOperand class - Representation of each machine instruction operand.
MachineInstr * getVRegDef(Register Reg) const
getVRegDef - Return the machine instr that defines the specified virtual register or null if none is ...
const TargetRegisterClass * getRegClass(Register Reg) const
Return the register class of the specified virtual register.
bool isPredicate() const
Set if this is one of the operands that made up of the predicate operand that controls an isPredicabl...
const MachineInstrBuilder & addFrameIndex(int Idx) const
static bool clobbersPhysReg(const uint32_t *RegMask, MCRegister PhysReg)
clobbersPhysReg - Returns true if this RegMask clobbers PhysReg.
SymbolTableList< Instruction >::iterator eraseFromParent()
This method unlinks 'this' from the containing basic block and deletes it.
bool isReg() const
isReg - Tests if this is a MO_Register operand.
Representation of each machine instruction.
unsigned isStoreToStackSlot(const MachineInstr &MI, int &FrameIndex) const override
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
CondCode
ISD::CondCode enum - These are ordered carefully to make the bitfields below work out,...
const MCOperandInfo * OpInfo
bool isRegMask() const
isRegMask - Tests if this is a MO_RegisterMask operand.
const MachineInstrBuilder & addReg(Register RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
Register getReg() const
getReg - Returns the register number.
bool readsRegister(Register Reg, const TargetRegisterInfo *TRI=nullptr) const
Return true if the MachineInstr reads the specified register.
static LPCC::CondCode getOppositeCondition(LPCC::CondCode CC)
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
bool analyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TrueBlock, MachineBasicBlock *&FalseBlock, SmallVectorImpl< MachineOperand > &Condition, bool AllowModify) const override
void copyPhysReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator Position, const DebugLoc &DL, MCRegister DestinationRegister, MCRegister SourceRegister, bool KillSource) const override
Expected< ExpressionValue > min(const ExpressionValue &Lhs, const ExpressionValue &Rhs)
SmallVector< MachineOperand, 4 > Cond
iterator_range< succ_iterator > successors()
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
bool hasOneNonDBGUse(Register RegNo) const
hasOneNonDBGUse - Return true if there is exactly one non-Debug use of the specified register.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
bool getMemOperandsWithOffsetWidth(const MachineInstr &LdSt, SmallVectorImpl< const MachineOperand * > &BaseOps, int64_t &Offset, bool &OffsetIsScalable, unsigned &Width, const TargetRegisterInfo *TRI) const override
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
const MachineBasicBlock * getParent() const
unsigned const MachineRegisterInfo * MRI
Wrapper class representing virtual and physical registers.
unsigned removeBranch(MachineBasicBlock &MBB, int *BytesRemoved=nullptr) const override
bool modifiesRegister(Register Reg, const TargetRegisterInfo *TRI=nullptr) const
Return true if the MachineInstr modifies (fully define or partially define) the specified register.
Should compile to something r4 addze r3 instead we get
bool hasUnmodeledSideEffects() const
Return true if this instruction has side effects that are not modeled by mayLoad / mayStore,...
MachineInstr * optimizeSelect(MachineInstr &MI, SmallPtrSetImpl< MachineInstr * > &SeenMIs, bool PreferFalse) const override
bool isLayoutSuccessor(const MachineBasicBlock *MBB) const
Return true if the specified MBB will be emitted immediately after this block, such that if this bloc...
void setImplicit(bool Val=true)
bool isImm() const
isImm - Tests if this is a MO_Immediate operand.
bool expandPostRAPseudo(MachineInstr &MI) const override
ArrayRef< T > makeArrayRef(const T &OneElt)
Construct an ArrayRef from a single element.
unsigned getKillRegState(bool B)
static unsigned flagSettingOpcodeVariant(unsigned OldOpcode)
MachineInstrBuilder BuildMI(MachineFunction &MF, const DebugLoc &DL, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
MachineInstrBuilder MachineInstrBuilder & DefMI
unsigned getNumOperands() const
Retuns the total number of operands.
size_t size() const
size - Get the array size.
Align max(MaybeAlign Lhs, Align Rhs)
const TargetRegisterClass * constrainRegClass(Register Reg, const TargetRegisterClass *RC, unsigned MinNumRegs=0)
constrainRegClass - Constrain the register class of the specified virtual register to be a common sub...
bool optimizeCompareInstr(MachineInstr &CmpInstr, Register SrcReg, Register SrcReg2, int64_t CmpMask, int64_t CmpValue, const MachineRegisterInfo *MRI) const override
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
A templated base class for SmallPtrSet which provides the typesafe interface that is common across al...
unsigned isLoadFromStackSlot(const MachineInstr &MI, int &FrameIndex) const override
ArrayRef< std::pair< unsigned, const char * > > getSerializableDirectMachineOperandTargetFlags() const override
Value * getOperand(unsigned i) const
void tieOperands(unsigned DefIdx, unsigned UseIdx)
Add a tie between the register operands at DefIdx and UseIdx.
void eraseFromParent()
Unlink 'this' from the containing basic block and delete it.
unsigned getNumOperands() const
Return the number of declared MachineOperands for this MachineInstruction.
std::pair< unsigned, unsigned > decomposeMachineOperandsTargetFlags(unsigned TF) const override
bool reverseBranchCondition(SmallVectorImpl< MachineOperand > &Condition) const override
bool isIdenticalTo(const MachineOperand &Other) const
Returns true if this operand is identical to the specified operand except for liveness related flags ...
Wrapper class representing physical registers. Should be passed by value.
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.