27 #define DEBUG_TYPE "si-shrink-instructions"
30 "Number of 64-bit instruction reduced to 32-bit.");
32 "Number of literal constants folded into 32-bit instructions.");
48 StringRef getPassName()
const override {
return "SI Shrink Instructions"; }
59 "SI Shrink Instructions",
false,
false)
61 char SIShrinkInstructions::
ID = 0;
64 return new SIShrinkInstructions();
91 default:
return false;
93 case AMDGPU::V_ADDC_U32_e64:
94 case AMDGPU::V_SUBB_U32_e64:
98 case AMDGPU::V_MAC_F32_e64:
99 case AMDGPU::V_MAC_F16_e64:
100 if (!
isVGPR(Src2, TRI, MRI) ||
105 case AMDGPU::V_CNDMASK_B32_e64:
114 if (Src1 && (!
isVGPR(Src1, TRI, MRI) || (Src1Mod && Src1Mod->
getImm() != 0)))
155 bool ConstantFolded =
false;
160 ConstantFolded =
true;
162 if (ConstantFolded) {
165 ++NumLiteralConstantsFolded;
172 if (TryToCommute && MI.
isCommutable() && TII->commuteInstruction(MI))
182 if (
Use.isUse() &&
Use.getReg() == AMDGPU::VCC) {
222 int32_t &ReverseImm) {
226 ReverseImm = reverseBits<int32_t>(
static_cast<int32_t
>(Src.
getImm()));
227 return ReverseImm >= -16 && ReverseImm <= 64;
248 TII->commuteInstruction(MI,
false, 0, 1);
260 if (SOPKOpc == AMDGPU::S_CMPK_EQ_U32 || SOPKOpc == AMDGPU::S_CMPK_LG_U32) {
264 SOPKOpc = (SOPKOpc == AMDGPU::S_CMPK_EQ_U32) ?
265 AMDGPU::S_CMPK_EQ_I32 : AMDGPU::S_CMPK_LG_I32;
291 std::vector<unsigned> I1Defs;
298 for (I = MBB.
begin(); I != MBB.
end(); I = Next) {
302 if (MI.
getOpcode() == AMDGPU::V_MOV_B32_e32) {
316 MI.
setDesc(TII->get(AMDGPU::V_BFREV_B32_e32));
332 (*Next).getOpcode() == AMDGPU::S_NOP) {
342 if (Nop0 + Nop1 <= 8) {
355 if (MI.
getOpcode() == AMDGPU::S_ADD_I32 ||
362 if (TII->commuteInstruction(MI,
false, 1, 2))
378 unsigned Opc = (MI.
getOpcode() == AMDGPU::S_ADD_I32) ?
379 AMDGPU::S_ADDK_I32 : AMDGPU::S_MULK_I32;
394 if (MI.
getOpcode() == AMDGPU::S_MOV_B32) {
402 MI.
setDesc(TII->get(AMDGPU::S_MOVK_I32));
404 MI.
setDesc(TII->get(AMDGPU::S_BREV_B32));
412 if (!TII->hasVALU32BitEncoding(MI.
getOpcode()))
418 if (!MI.
isCommutable() || !TII->commuteInstruction(MI) ||
425 if (!TII->hasVALU32BitEncoding(MI.
getOpcode()))
430 if (TII->isVOPC(Op32)) {
444 if (DstReg != AMDGPU::VCC)
448 if (Op32 == AMDGPU::V_CNDMASK_B32_e32) {
452 TII->getNamedOperand(MI, AMDGPU::OpName::src2);
455 unsigned SReg = Src2->
getReg();
460 if (SReg != AMDGPU::VCC)
466 AMDGPU::OpName::sdst);
470 AMDGPU::OpName::src2);
473 if (SDst->
getReg() != AMDGPU::VCC) {
481 if (Src2 && Src2->
getReg() != AMDGPU::VCC) {
498 if (Op32DstIdx != -1) {
507 Inst32.
addOperand(*TII->getNamedOperand(MI, AMDGPU::OpName::src0));
510 TII->getNamedOperand(MI, AMDGPU::OpName::src1);
516 if (Op32Src2Idx != -1) {
526 ++NumInstructionsShrunk;
534 DEBUG(
dbgs() <<
"e32 MI = " << *Inst32 <<
'\n');
constexpr bool isUInt< 32 >(uint64_t x)
static bool isReverseInlineImm(const SIInstrInfo *TII, const MachineOperand &Src, int32_t &ReverseImm)
unsigned getNumImplicitUses() const
Return the number of implicit uses this instruction has.
MachineInstr * getParent()
getParent - Return the instruction that this operand belongs to.
AMDGPU specific subclass of TargetSubtarget.
static bool canShrink(MachineInstr &MI, const SIInstrInfo *TII, const SIRegisterInfo &TRI, const MachineRegisterInfo &MRI)
static bool sopkIsZext(const MachineInstr &MI)
unsigned getNumImplicitDefs() const
Return the number of implicit defs this instruct has.
Describe properties that are true of each instruction in the target description file.
static bool isVirtualRegister(unsigned Reg)
Return true if the specified register number is in the virtual register namespace.
const SIInstrInfo * getInstrInfo() const override
unsigned getOperandNo(const_mop_iterator I) const
Returns the number of the operand iterator I points to.
const MCInstrDesc & getDesc() const
Returns the target instruction descriptor of this MachineInstr.
constexpr bool isInt< 16 >(int64_t x)
const Function * getFunction() const
getFunction - Return the LLVM function that this machine code represents
static void copyFlagsToImplicitVCC(MachineInstr &MI, const MachineOperand &Orig)
LLVM_READONLY int16_t getNamedOperandIdx(uint16_t Opcode, uint16_t NamedIdx)
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
bool isLiteralConstant(const MachineOperand &MO, const MCOperandInfo &OpInfo) const
const HexagonInstrInfo * TII
bool isImm() const
isImm - Tests if this is a MO_Immediate operand.
A Use represents the edge between a Value definition and its users.
bool isReg() const
isReg - Tests if this is a MO_Register operand.
void eraseFromParent()
Unlink 'this' from the containing basic block and delete it.
LLVM_READONLY MachineOperand * getNamedOperand(MachineInstr &MI, unsigned OperandName) const
Returns the operand named Op.
const TargetRegisterClass * getRegClass(unsigned Reg) const
Return the register class of the specified virtual register.
Reg
All possible values of the reg field in the ModR/M byte.
static bool isVGPR(const MachineOperand *MO, const SIRegisterInfo &TRI, const MachineRegisterInfo &MRI)
static bool isKImmOrKUImmOperand(const SIInstrInfo *TII, const MachineOperand &Src, bool &IsUnsigned)
unsigned getNumOperands() const
Access to explicit operands of the instruction.
#define DEBUG_TYPE
The pass tries to use the 32-bit encoding for instructions when possible.
static bool isKUImmOperand(const SIInstrInfo *TII, const MachineOperand &Src)
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
void ChangeToImmediate(int64_t ImmVal)
ChangeToImmediate - Replace this operand with a new immediate operand of the specified value...
MachineInstrBuilder BuildMI(MachineFunction &MF, const DebugLoc &DL, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
STATISTIC(NumInstructionsShrunk,"Number of 64-bit instruction reduced to 32-bit.")
unsigned const MachineRegisterInfo * MRI
static void shrinkScalarCompare(const SIInstrInfo *TII, MachineInstr &MI)
bool hasVGPRs(const TargetRegisterClass *RC) const
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
This file contains the declarations for the subclasses of Constant, which represent the different fla...
const MachineOperand & getOperand(unsigned i) const
Represent the analysis usage information of a pass.
LLVM_READONLY int getSOPKOp(uint16_t Opcode)
void setImm(int64_t immVal)
FunctionPass class - This class is used to implement most global optimizations.
static bool isVOP2(const MachineInstr &MI)
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
bool isRegMask() const
isRegMask - Tests if this is a MO_RegisterMask operand.
bool isInlineConstant(const APInt &Imm) const
Iterator for intrusive lists based on ilist_node.
void setDesc(const MCInstrDesc &tid)
Replace the instruction descriptor (thus opcode) of the current instruction with a new one...
constexpr bool isInt< 32 >(int64_t x)
void addOperand(MachineFunction &MF, const MachineOperand &Op)
Add the specified operand to the instruction.
LLVM_READONLY int getVOPe32(uint16_t Opcode)
MachineOperand class - Representation of each machine instruction operand.
void setRegAllocationHint(unsigned VReg, unsigned Type, unsigned PrefReg)
setRegAllocationHint - Specify a register allocation hint for the specified virtual register...
bool hasOneUse(unsigned RegNo) const
hasOneUse - Return true if there is exactly one instruction using the specified register.
static bool isKImmOperand(const SIInstrInfo *TII, const MachineOperand &Src)
void setPreservesCFG()
This function should be called by the pass, iff they do not:
bool isCompare(QueryType Type=IgnoreBundle) const
Return true if this instruction is a comparison.
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
iterator_range< mop_iterator > implicit_operands()
MachineInstr * getUniqueVRegDef(unsigned Reg) const
getUniqueVRegDef - Return the unique machine instr that defines the specified virtual register or nul...
const TargetRegisterClass * getPhysRegClass(unsigned Reg) const
Return the 'base' register class for this register.
const DebugLoc & getDebugLoc() const
Returns the debug location id of this MachineInstr.
MachineRegisterInfo - Keep track of information for virtual and physical registers, including vreg register classes, use/def chains for registers, etc.
static MDTuple * get(LLVMContext &Context, ArrayRef< Metadata * > MDs)
Representation of each machine instruction.
static void copyExtraImplicitOps(MachineInstr &NewMI, MachineFunction &MF, const MachineInstr &MI)
Copy implicit register operands from specified instruction to this instruction that are not part of t...
static bool isPhysicalRegister(unsigned Reg)
Return true if the specified register number is in the physical register namespace.
Interface definition for SIInstrInfo.
FunctionPass * createSIShrinkInstructionsPass()
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
static bool isVOPC(const MachineInstr &MI)
constexpr bool isUInt< 16 >(uint64_t x)
unsigned getReg() const
getReg - Returns the register number.
bool isCommutable(QueryType Type=IgnoreBundle) const
Return true if this may be a 2- or 3-address instruction (of the form "X = op Y, Z, ..."), which produces the same result if Y and Z are exchanged.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
bool hasModifiersSet(const MachineInstr &MI, unsigned OpName) const
unsigned getNumOperands() const
Return the number of declared MachineOperands for this MachineInstruction.
const MachineInstrBuilder & addOperand(const MachineOperand &MO) const
StringRef - Represent a constant reference to a string, i.e.
static void foldImmediates(MachineInstr &MI, const SIInstrInfo *TII, MachineRegisterInfo &MRI, bool TryToCommute=true)
This function checks MI for operands defined by a move immediate instruction and then folds the liter...
bool isMoveImmediate(QueryType Type=IgnoreBundle) const
Return true if this instruction is a move immediate (including conditional moves) instruction...
static bool isVOP1(const MachineInstr &MI)
bool use_empty(unsigned RegNo) const
use_empty - Return true if there are no instructions using the specified register.
void tieOperands(unsigned DefIdx, unsigned UseIdx)
Add a tie between the register operands at DefIdx and UseIdx.