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[] = {
179 int &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,
int 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;
307 else if (
MI->getParent() != CmpInstr.
getParent() || CmpValue != 0) {
311 if (CmpInstr.
getOpcode() == Lanai::SFSUB_F_RI_LO)
320 for (--
I;
I !=
E; --
I) {
355 while (!isSafe && ++
I !=
E) {
357 for (
unsigned IO = 0, EO = Instr.
getNumOperands(); !isSafe && IO != EO;
384 OperandsToUpdate.push_back(
385 std::make_pair(&((*I).getOperand(IO - 1)), NewCC));
424 if ((*SI)->isLiveIn(Lanai::SR))
430 MI->addRegisterDefined(Lanai::SR);
440 unsigned &TrueOp,
unsigned &FalseOp,
441 bool &Optimizable)
const {
450 Cond.push_back(
MI.getOperand(3));
459 if (!
Reg.isVirtual())
467 if (!
MI->isPredicable())
471 for (
unsigned i = 1,
e =
MI->getNumOperands();
i !=
e; ++
i) {
486 bool DontMoveAcrossStores =
true;
487 if (!
MI->isSafeToMove(
nullptr, DontMoveAcrossStores))
499 bool Invert = !
DefMI;
522 unsigned CondCode =
MI.getOperand(3).getImm();
566 bool AllowModify)
const {
602 FalseBlock =
nullptr;
619 if (Opcode != Lanai::BRCC)
624 if (Condition.empty()) {
629 FalseBlock = TrueBlock;
648 assert((Condition.size() == 1) &&
649 "Lanai branch conditions should have one component.");
665 int *BytesAdded)
const {
667 assert(TrueBlock &&
"insertBranch must not be told to insert a fallthrough");
668 assert(!BytesAdded &&
"code size not handled");
671 if (Condition.
empty()) {
672 assert(!FalseBlock &&
"Unconditional branch with multiple successors!");
679 "Lanai branch conditions should have one component.");
680 unsigned ConditionalCode = Condition[0].getImm();
693 int *BytesRemoved)
const {
694 assert(!BytesRemoved &&
"code size not handled");
719 if (
MI.getOpcode() == Lanai::LDW_RI)
720 if (
MI.getOperand(1).isFI() &&
MI.getOperand(2).isImm() &&
721 MI.getOperand(2).getImm() == 0) {
723 return MI.getOperand(0).getReg();
730 if (
MI.getOpcode() == Lanai::LDW_RI) {
736 if (hasLoadFromStackSlot(
MI, Accesses)){
738 cast<FixedStackPseudoSourceValue>(Accesses.front()->getPseudoValue())
748 if (
MI.getOpcode() == Lanai::SW_RI)
749 if (
MI.getOperand(0).isFI() &&
MI.getOperand(1).isImm() &&
750 MI.getOperand(1).getImm() == 0) {
752 return MI.getOperand(2).getReg();
792 if (!BaseOp->
isReg())
800 int64_t &
Offset,
bool &OffsetIsScalable,
unsigned &
Width,
815 OffsetIsScalable =
false;
818 BaseOps.push_back(BaseOp);
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
This class represents lattice values for constants.
const MachineInstrBuilder & copyImplicitOps(const MachineInstr &OtherMI) const
Copy all the implicit operands from OtherMI onto this one.
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
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.
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...
bool isJTI() const
isJTI - Tests if this is a MO_JumpTableIndex operand.
const MCInstrDesc & getDesc() const
Returns the target instruction descriptor of this MachineInstr.
bool areMemAccessesTriviallyDisjoint(const MachineInstr &MIa, const MachineInstr &MIb) const override
bool isFI() const
isFI - Tests if this is a MO_FrameIndex operand.
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).
bool optimizeCompareInstr(MachineInstr &CmpInstr, Register SrcReg, Register SrcReg2, int CmpMask, int CmpValue, const MachineRegisterInfo *MRI) const override
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.
static bool isRedundantFlagInstr(MachineInstr *CmpI, unsigned SrcReg, unsigned SrcReg2, int ImmValue, MachineInstr *OI)
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...
std::vector< MachineBasicBlock * >::iterator succ_iterator
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.
bool isCPI() const
isCPI - Tests if this is a MO_ConstantPoolIndex operand.
unsigned isStoreToStackSlot(const MachineInstr &MI, int &FrameIndex) const override
bool analyzeCompare(const MachineInstr &MI, Register &SrcReg, Register &SrcReg2, int &CmpMask, int &CmpValue) const override
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
succ_iterator succ_begin()
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
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...
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.