25#define GET_INSTRINFO_CTOR_DTOR
26#include "LanaiGenInstrInfo.inc"
36 Register SourceRegister,
bool KillSource,
37 bool RenamableDest,
bool RenamableSrc)
const {
38 if (!Lanai::GPRRegClass.
contains(DestinationRegister, SourceRegister)) {
49 Register SourceRegister,
bool IsKill,
int FrameIndex,
54 if (Position !=
MBB.
end()) {
55 DL = Position->getDebugLoc();
58 if (!Lanai::GPRRegClass.hasSubClassEq(RegisterClass)) {
70 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;
110 int LowOffset = std::min(OffsetA, OffsetB);
111 int HighOffset = std::max(OffsetA, OffsetB);
112 LocationSize LowWidth = (LowOffset == OffsetA) ? WidthA : WidthB;
114 LowOffset + (int)LowWidth.
getValue() <= HighOffset)
164std::pair<unsigned, unsigned>
166 return std::make_pair(TF, 0u);
171 using namespace LanaiII;
172 static const std::pair<unsigned, const char *> TargetFlags[] = {
173 {MO_ABS_HI,
"lanai-hi"},
174 {MO_ABS_LO,
"lanai-lo"},
175 {MO_NO_FLAG,
"lanai-nf"}};
180 Register &SrcReg2, int64_t &CmpMask,
181 int64_t &CmpValue)
const {
182 switch (
MI.getOpcode()) {
185 case Lanai::SFSUB_F_RI_LO:
186 case Lanai::SFSUB_F_RI_HI:
187 SrcReg =
MI.getOperand(0).getReg();
190 CmpValue =
MI.getOperand(1).getImm();
192 case Lanai::SFSUB_F_RR:
193 SrcReg =
MI.getOperand(0).getReg();
194 SrcReg2 =
MI.getOperand(1).getReg();
208 unsigned SrcReg2, int64_t ImmValue,
210 if (CmpI->
getOpcode() == Lanai::SFSUB_F_RR &&
218 if (((CmpI->
getOpcode() == Lanai::SFSUB_F_RI_LO &&
220 (CmpI->
getOpcode() == Lanai::SFSUB_F_RI_HI &&
230 case Lanai::ADD_I_HI:
231 return Lanai::ADD_F_I_HI;
232 case Lanai::ADD_I_LO:
233 return Lanai::ADD_F_I_LO;
235 return Lanai::ADD_F_R;
236 case Lanai::ADDC_I_HI:
237 return Lanai::ADDC_F_I_HI;
238 case Lanai::ADDC_I_LO:
239 return Lanai::ADDC_F_I_LO;
241 return Lanai::ADDC_F_R;
242 case Lanai::AND_I_HI:
243 return Lanai::AND_F_I_HI;
244 case Lanai::AND_I_LO:
245 return Lanai::AND_F_I_LO;
247 return Lanai::AND_F_R;
249 return Lanai::OR_F_I_HI;
251 return Lanai::OR_F_I_LO;
253 return Lanai::OR_F_R;
255 return Lanai::SL_F_I;
257 return Lanai::SRL_F_R;
259 return Lanai::SA_F_I;
261 return Lanai::SRA_F_R;
262 case Lanai::SUB_I_HI:
263 return Lanai::SUB_F_I_HI;
264 case Lanai::SUB_I_LO:
265 return Lanai::SUB_F_I_LO;
267 return Lanai::SUB_F_R;
268 case Lanai::SUBB_I_HI:
269 return Lanai::SUBB_F_I_HI;
270 case Lanai::SUBB_I_LO:
271 return Lanai::SUBB_F_I_LO;
273 return Lanai::SUBB_F_R;
274 case Lanai::XOR_I_HI:
275 return Lanai::XOR_F_I_HI;
276 case Lanai::XOR_I_LO:
277 return Lanai::XOR_F_I_LO;
279 return Lanai::XOR_F_R;
287 int64_t , int64_t CmpValue,
310 else if (
MI->getParent() != CmpInstr.
getParent() || CmpValue != 0) {
314 if (CmpInstr.
getOpcode() == Lanai::SFSUB_F_RI_LO)
323 for (--
I;
I != E; --
I) {
326 if (Instr.modifiesRegister(Lanai::SR,
TRI) ||
327 Instr.readsRegister(Lanai::SR,
TRI))
358 while (!isSafe && ++
I != E) {
360 for (
unsigned IO = 0, EO = Instr.getNumOperands(); !isSafe && IO != EO;
385 if (SrcReg2 != 0 &&
Sub->getOperand(1).getReg() == SrcReg2 &&
386 Sub->getOperand(2).getReg() == SrcReg) {
388 std::make_pair(&((*I).getOperand(IO - 1)), NewCC));
425 if (Succ->isLiveIn(Lanai::SR))
431 MI->addRegisterDefined(Lanai::SR);
441 unsigned &TrueOp,
unsigned &FalseOp,
442 bool &Optimizable)
const {
443 assert(
MI.getOpcode() == Lanai::SELECT &&
"unknown select instruction");
451 Cond.push_back(
MI.getOperand(3));
460 if (!Reg.isVirtual())
462 if (!
MRI.hasOneNonDBGUse(Reg))
468 if (!
MI->isPredicable())
474 if (MO.isFI() || MO.isCPI() || MO.isJTI())
481 if (MO.getReg().isPhysical())
483 if (MO.isDef() && !MO.isDead())
486 bool DontMoveAcrossStores =
true;
487 if (!
MI->isSafeToMove(DontMoveAcrossStores))
496 assert(
MI.getOpcode() == Lanai::SELECT &&
"unknown select instruction");
499 bool Invert = !
DefMI;
509 if (!
MRI.constrainRegClass(DestReg, PreviousClass))
519 i != e && !DefDesc.
operands()[i].isPredicate(); ++i)
522 unsigned CondCode =
MI.getOperand(3).getImm();
566 bool AllowModify)
const {
600 FalseBlock =
nullptr;
617 if (Opcode != Lanai::BRCC)
622 if (Condition.
empty()) {
627 FalseBlock = TrueBlock;
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");
716 int &FrameIndex)
const {
717 if (
MI.getOpcode() == Lanai::LDW_RI)
718 if (
MI.getOperand(1).isFI() &&
MI.getOperand(2).isImm() &&
719 MI.getOperand(2).getImm() == 0) {
720 FrameIndex =
MI.getOperand(1).getIndex();
721 return MI.getOperand(0).getReg();
727 int &FrameIndex)
const {
728 if (
MI.getOpcode() == Lanai::LDW_RI) {
736 cast<FixedStackPseudoSourceValue>(
Accesses.front()->getPseudoValue())
745 int &FrameIndex)
const {
746 if (
MI.getOpcode() == Lanai::SW_RI)
747 if (
MI.getOperand(0).isFI() &&
MI.getOperand(1).isImm() &&
748 MI.getOperand(1).getImm() == 0) {
749 FrameIndex =
MI.getOperand(0).getIndex();
750 return MI.getOperand(2).getReg();
790 if (!BaseOp->
isReg())
813 OffsetIsScalable =
false;
unsigned const MachineRegisterInfo * MRI
MachineInstrBuilder MachineInstrBuilder & DefMI
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
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,...
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
DXIL Forward Handle Accesses
static LPCC::CondCode getOppositeCondition(LPCC::CondCode CC)
static unsigned flagSettingOpcodeVariant(unsigned OldOpcode)
static MachineInstr * canFoldIntoSelect(Register Reg, const MachineRegisterInfo &MRI)
Register const TargetRegisterInfo * TRI
const SmallVectorImpl< MachineOperand > & Cond
static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)
This file defines the SmallVector class.
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.
LLVM_ABI InstListType::iterator eraseFromParent()
This method unlinks 'this' from the containing basic block and deletes it.
unsigned getOpcode() const
Returns a member of one of the enums like Instruction::Add.
bool areMemAccessesTriviallyDisjoint(const MachineInstr &MIa, const MachineInstr &MIb) const override
unsigned insertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TrueBlock, MachineBasicBlock *FalseBlock, ArrayRef< MachineOperand > Condition, const DebugLoc &DL, int *BytesAdded=nullptr) const override
Register isStoreToStackSlot(const MachineInstr &MI, int &FrameIndex) const override
bool analyzeSelect(const MachineInstr &MI, SmallVectorImpl< MachineOperand > &Cond, unsigned &TrueOp, unsigned &FalseOp, bool &Optimizable) const override
void loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator Position, Register DestinationRegister, int FrameIndex, const TargetRegisterClass *RegisterClass, const TargetRegisterInfo *RegisterInfo, Register VReg, MachineInstr::MIFlag Flags=MachineInstr::NoFlags) const override
Register isLoadFromStackSlotPostFE(const MachineInstr &MI, int &FrameIndex) 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
bool expandPostRAPseudo(MachineInstr &MI) const override
bool getMemOperandWithOffsetWidth(const MachineInstr &LdSt, const MachineOperand *&BaseOp, int64_t &Offset, LocationSize &Width, const TargetRegisterInfo *TRI) const
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
Register isLoadFromStackSlot(const MachineInstr &MI, int &FrameIndex) const override
unsigned removeBranch(MachineBasicBlock &MBB, int *BytesRemoved=nullptr) const override
bool getMemOperandsWithOffsetWidth(const MachineInstr &LdSt, SmallVectorImpl< const MachineOperand * > &BaseOps, int64_t &Offset, bool &OffsetIsScalable, LocationSize &Width, const TargetRegisterInfo *TRI) const override
void storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator Position, Register SourceRegister, bool IsKill, int FrameIndex, const TargetRegisterClass *RegisterClass, const TargetRegisterInfo *RegisterInfo, Register VReg, MachineInstr::MIFlag Flags=MachineInstr::NoFlags) const override
bool reverseBranchCondition(SmallVectorImpl< MachineOperand > &Condition) const override
void copyPhysReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator Position, const DebugLoc &DL, Register DestinationRegister, Register SourceRegister, bool KillSource, bool RenamableDest=false, bool RenamableSrc=false) const override
static LocationSize precise(uint64_t Value)
TypeSize getValue() const
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
LLVM_ABI bool isLayoutSuccessor(const MachineBasicBlock *MBB) const
Return true if the specified MBB will be emitted immediately after this block, such that if this bloc...
LLVM_ABI 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.
LLVM_ABI bool hasUnmodeledSideEffects() const
Return true if this instruction has side effects that are not modeled by mayLoad / mayStore,...
LLVM_ABI void tieOperands(unsigned DefIdx, unsigned UseIdx)
Add a tie between the register operands at DefIdx and UseIdx.
LLVM_ABI bool hasOrderedMemoryRef() const
Return true if this instruction may have an ordered or volatile memory reference, or if the informati...
LLVM_ABI void eraseFromParent()
Unlink 'this' from the containing basic block and delete it.
const MachineOperand & getOperand(unsigned i) const
LLVM_ABI 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.
LLVM_ABI 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)
Remove pointer from the set.
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)
@ Sub
Subtraction of integers.
unsigned getKillRegState(bool B)