#ifndef LLVM_LIB_TARGET_AMDGPU_R600INSTRINFO_H
#define LLVM_LIB_TARGET_AMDGPU_R600INSTRINFO_H
#include "R600RegisterInfo.h"
#include "llvm/CodeGen/TargetInstrInfo.h"
#define GET_INSTRINFO_HEADER
#include "R600GenInstrInfo.inc"
namespace llvm {
namespace R600InstrFlags {
enum : uint64_t {
REGISTER_STORE = UINT64_C(1) << 62,
REGISTER_LOAD = UINT64_C(1) << 63
};
}
class DFAPacketizer;
class MachineFunction;
class MachineInstr;
class MachineInstrBuilder;
class R600Subtarget;
class R600InstrInfo final : public R600GenInstrInfo {
private:
const R600RegisterInfo RI;
const R600Subtarget &ST;
std::vector<std::pair<int, unsigned>>
ExtractSrcs(MachineInstr &MI, const DenseMap<unsigned, unsigned> &PV,
unsigned &ConstCount) const;
MachineInstrBuilder buildIndirectRead(MachineBasicBlock *MBB,
MachineBasicBlock::iterator I,
unsigned ValueReg, unsigned Address,
unsigned OffsetReg,
unsigned AddrChan) const;
MachineInstrBuilder buildIndirectWrite(MachineBasicBlock *MBB,
MachineBasicBlock::iterator I,
unsigned ValueReg, unsigned Address,
unsigned OffsetReg,
unsigned AddrChan) const;
public:
enum BankSwizzle {
ALU_VEC_012_SCL_210 = 0,
ALU_VEC_021_SCL_122,
ALU_VEC_120_SCL_212,
ALU_VEC_102_SCL_221,
ALU_VEC_201,
ALU_VEC_210
};
explicit R600InstrInfo(const R600Subtarget &);
const R600RegisterInfo &getRegisterInfo() const {
return RI;
}
void copyPhysReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI,
const DebugLoc &DL, MCRegister DestReg, MCRegister SrcReg,
bool KillSrc) const override;
bool isLegalToSplitMBBAt(MachineBasicBlock &MBB,
MachineBasicBlock::iterator MBBI) const override;
bool isReductionOp(unsigned opcode) const;
bool isCubeOp(unsigned opcode) const;
bool isALUInstr(unsigned Opcode) const;
bool hasInstrModifiers(unsigned Opcode) const;
bool isLDSInstr(unsigned Opcode) const;
bool isLDSRetInstr(unsigned Opcode) const;
bool canBeConsideredALU(const MachineInstr &MI) const;
bool isTransOnly(unsigned Opcode) const;
bool isTransOnly(const MachineInstr &MI) const;
bool isVectorOnly(unsigned Opcode) const;
bool isVectorOnly(const MachineInstr &MI) const;
bool isExport(unsigned Opcode) const;
bool usesVertexCache(unsigned Opcode) const;
bool usesVertexCache(const MachineInstr &MI) const;
bool usesTextureCache(unsigned Opcode) const;
bool usesTextureCache(const MachineInstr &MI) const;
bool mustBeLastInClause(unsigned Opcode) const;
bool usesAddressRegister(MachineInstr &MI) const;
bool definesAddressRegister(MachineInstr &MI) const;
bool readsLDSSrcReg(const MachineInstr &MI) const;
int getSelIdx(unsigned Opcode, unsigned SrcIdx) const;
SmallVector<std::pair<MachineOperand *, int64_t>, 3>
getSrcs(MachineInstr &MI) const;
unsigned isLegalUpTo(
const std::vector<std::vector<std::pair<int, unsigned> > > &IGSrcs,
const std::vector<R600InstrInfo::BankSwizzle> &Swz,
const std::vector<std::pair<int, unsigned> > &TransSrcs,
R600InstrInfo::BankSwizzle TransSwz) const;
bool FindSwizzleForVectorSlot(
const std::vector<std::vector<std::pair<int, unsigned> > > &IGSrcs,
std::vector<R600InstrInfo::BankSwizzle> &SwzCandidate,
const std::vector<std::pair<int, unsigned> > &TransSrcs,
R600InstrInfo::BankSwizzle TransSwz) const;
bool fitsReadPortLimitations(const std::vector<MachineInstr *> &MIs,
const DenseMap<unsigned, unsigned> &PV,
std::vector<BankSwizzle> &BS,
bool isLastAluTrans) const;
bool fitsConstReadLimitations(const std::vector<MachineInstr *> &) const;
bool fitsConstReadLimitations(const std::vector<unsigned>&) const;
bool isVector(const MachineInstr &MI) const;
bool isMov(unsigned Opcode) const;
DFAPacketizer *
CreateTargetScheduleState(const TargetSubtargetInfo &) const override;
bool reverseBranchCondition(
SmallVectorImpl<MachineOperand> &Cond) const override;
bool analyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB,
MachineBasicBlock *&FBB,
SmallVectorImpl<MachineOperand> &Cond,
bool AllowModify) const override;
unsigned insertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB,
MachineBasicBlock *FBB, ArrayRef<MachineOperand> Cond,
const DebugLoc &DL,
int *BytesAdded = nullptr) const override;
unsigned removeBranch(MachineBasicBlock &MBB,
int *BytesRemoved = nullptr) const override;
bool isPredicated(const MachineInstr &MI) const override;
bool isPredicable(const MachineInstr &MI) const override;
bool isProfitableToDupForIfCvt(MachineBasicBlock &MBB, unsigned NumCycles,
BranchProbability Probability) const override;
bool isProfitableToIfCvt(MachineBasicBlock &MBB, unsigned NumCycles,
unsigned ExtraPredCycles,
BranchProbability Probability) const override ;
bool isProfitableToIfCvt(MachineBasicBlock &TMBB,
unsigned NumTCycles, unsigned ExtraTCycles,
MachineBasicBlock &FMBB,
unsigned NumFCycles, unsigned ExtraFCycles,
BranchProbability Probability) const override;
bool ClobbersPredicate(MachineInstr &MI, std::vector<MachineOperand> &Pred,
bool SkipDead) const override;
bool isProfitableToUnpredicate(MachineBasicBlock &TMBB,
MachineBasicBlock &FMBB) const override;
bool PredicateInstruction(MachineInstr &MI,
ArrayRef<MachineOperand> Pred) const override;
unsigned int getPredicationCost(const MachineInstr &) const override;
unsigned int getInstrLatency(const InstrItineraryData *ItinData,
const MachineInstr &MI,
unsigned *PredCost = nullptr) const override;
bool expandPostRAPseudo(MachineInstr &MI) const override;
void reserveIndirectRegisters(BitVector &Reserved,
const MachineFunction &MF,
const R600RegisterInfo &TRI) const;
unsigned calculateIndirectAddress(unsigned RegIndex, unsigned Channel) const;
const TargetRegisterClass *getIndirectAddrRegClass() const;
int getIndirectIndexBegin(const MachineFunction &MF) const;
int getIndirectIndexEnd(const MachineFunction &MF) const;
MachineInstrBuilder buildIndirectWrite(MachineBasicBlock *MBB,
MachineBasicBlock::iterator I,
unsigned ValueReg, unsigned Address,
unsigned OffsetReg) const;
MachineInstrBuilder buildIndirectRead(MachineBasicBlock *MBB,
MachineBasicBlock::iterator I,
unsigned ValueReg, unsigned Address,
unsigned OffsetReg) const;
unsigned getMaxAlusPerClause() const;
MachineInstrBuilder buildDefaultInstruction(MachineBasicBlock &MBB,
MachineBasicBlock::iterator I,
unsigned Opcode,
unsigned DstReg,
unsigned Src0Reg,
unsigned Src1Reg = 0) const;
MachineInstr *buildSlotOfVectorInstruction(MachineBasicBlock &MBB,
MachineInstr *MI,
unsigned Slot,
unsigned DstReg) const;
MachineInstr *buildMovImm(MachineBasicBlock &BB,
MachineBasicBlock::iterator I,
unsigned DstReg,
uint64_t Imm) const;
MachineInstr *buildMovInstr(MachineBasicBlock *MBB,
MachineBasicBlock::iterator I,
unsigned DstReg, unsigned SrcReg) const;
int getOperandIdx(const MachineInstr &MI, unsigned Op) const;
int getOperandIdx(unsigned Opcode, unsigned Op) const;
void setImmOperand(MachineInstr &MI, unsigned Op, int64_t Imm) const;
void addFlag(MachineInstr &MI, unsigned Operand, unsigned Flag) const;
bool isFlagSet(const MachineInstr &MI, unsigned Operand, unsigned Flag) const;
MachineOperand &getFlagOp(MachineInstr &MI, unsigned SrcIdx = 0,
unsigned Flag = 0) const;
void clearFlag(MachineInstr &MI, unsigned Operand, unsigned Flag) const;
bool isRegisterStore(const MachineInstr &MI) const {
return get(MI.getOpcode()).TSFlags & R600InstrFlags::REGISTER_STORE;
}
bool isRegisterLoad(const MachineInstr &MI) const {
return get(MI.getOpcode()).TSFlags & R600InstrFlags::REGISTER_LOAD;
}
};
namespace R600 {
int getLDSNoRetOp(uint16_t Opcode);
}
}
#endif