Go to the documentation of this file.
21 #define DEBUG_TYPE "riscv-sextw-removal"
23 STATISTIC(NumRemovedSExtW,
"Number of removed sign-extensions");
25 "Number of instructions transformed to W-ops");
28 cl::desc(
"Disable removal of sext.w"),
47 StringRef getPassName()
const override {
return "RISCV sext.w Removal"; }
57 return new RISCVSExtWRemoval();
65 const auto *
User = UserOp.getParent();
68 Worklist.push_back(
User);
84 while (!Worklist.empty()) {
91 unsigned opcode =
MI->getOpcode();
92 if (opcode ==
RISCV::LD || opcode == RISCV::LWU)
98 switch (
MI->getOpcode()) {
120 case RISCV::FCVT_S_W:
121 case RISCV::FCVT_S_WU:
122 case RISCV::FCVT_D_W:
123 case RISCV::FCVT_D_WU:
129 if (
MI->getOperand(2).getImm() >= 32)
134 if (isUInt<11>(
MI->getOperand(2).getImm()))
139 if (!isUInt<11>(
MI->getOperand(2).getImm()))
145 if (
MI->getOperand(2).getImm() >= 32)
172 case RISCV::SH1ADD_UW:
174 case RISCV::SH2ADD_UW:
176 case RISCV::SH3ADD_UW:
178 case RISCV::ZEXT_H_RV64:
197 switch (
MI.getOpcode()) {
220 case RISCV::FCVT_W_H:
221 case RISCV::FCVT_WU_H:
222 case RISCV::FCVT_W_S:
223 case RISCV::FCVT_WU_S:
224 case RISCV::FCVT_W_D:
225 case RISCV::FCVT_WU_D:
239 case RISCV::ZEXT_H_RV64:
249 return MI.getOperand(2).getImm() >= 32;
251 return MI.getOperand(2).getImm() > 32;
254 if (
MI.getOperand(1).isReg() &&
MI.getOperand(1).getReg() == RISCV::X0)
264 return isUInt<11>(
MI.getOperand(2).getImm());
267 return !isUInt<11>(
MI.getOperand(2).getImm());
270 return MI.getOperand(1).getReg() == RISCV::X0;
276 if (
MI.getOperand(2).getImm() >= 32)
299 Worklist.push_back(&OrigMI);
301 while (!Worklist.empty()) {
313 switch (
MI->getOpcode()) {
330 Worklist.push_back(SrcMI);
338 if (
MI->getOperand(2).getImm() >= 31)
356 Worklist.push_back(SrcMI);
376 unsigned E = 3,
D = 1;
377 if (
MI->getOpcode() == RISCV::PHI) {
378 E =
MI->getNumOperands();
382 for (
unsigned I = 1;
I !=
E;
I +=
D) {
383 if (!
MI->getOperand(
I).isReg())
394 Worklist.push_back(SrcMI);
407 static unsigned getWOp(
unsigned Opcode) {
446 if (
MI->getOpcode() != RISCV::ADDIW || !
MI->getOperand(2).isImm() ||
447 MI->getOperand(2).getImm() != 0 || !
MI->getOperand(1).isReg())
459 bool MadeChange =
false;
460 for (
auto MI : SExtWRemovalCands) {
480 for (
auto Op : Fixable->operands())
482 for (
auto Op : Fixable->memoperands())
488 Fixable->eraseFromParent();
489 ++NumTransformedToWInstrs;
495 MI->eraseFromParent();
static bool isSignExtendingOpW(MachineInstr &MI, MachineRegisterInfo &MRI, SmallPtrSetImpl< MachineInstr * > &FixableDef)
This is an optimization pass for GlobalISel generic memory operations.
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
const MachineInstrBuilder & add(const MachineOperand &MO) const
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
static cl::opt< bool > DisableSExtWRemoval("riscv-disable-sextw-removal", cl::desc("Disable removal of sext.w"), cl::init(false), cl::Hidden)
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
LLVM_NODISCARD T pop_back_val()
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
INITIALIZE_PASS(RISCVSExtWRemoval, DEBUG_TYPE, "RISCV sext.w Removal", false, false) FunctionPass *llvm
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
Represent the analysis usage information of a pass.
void initializeRISCVSExtWRemovalPass(PassRegistry &)
STATISTIC(NumFunctions, "Total number of functions")
@ AND
Bitwise operators - logical and, logical or, logical xor.
MachineInstr * getVRegDef(Register Reg) const
getVRegDef - Return the machine instr that defines the specified virtual register or null if none is ...
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
const TargetRegisterClass * getRegClass(Register Reg) const
Return the register class of the specified virtual register.
bool isVirtual() const
Return true if the specified register number is in the virtual register namespace.
void clearKillFlags(Register Reg) const
clearKillFlags - Iterate over all the uses of the given register and clear the kill flag from the Mac...
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
Representation of each machine instruction.
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
static bool isAllUsesReadW(const MachineInstr &OrigMI, MachineRegisterInfo &MRI)
initializer< Ty > init(const Ty &Val)
This should be recognized as CLZ
iterator_range< reg_iterator > reg_operands(Register Reg) const
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
const MachineInstrBuilder & addMemOperand(MachineMemOperand *MMO) const
StringRef - Represent a constant reference to a string, i.e.
void setPreservesCFG()
This function should be called by the pass, iff they do not:
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
#define LLVM_FALLTHROUGH
LLVM_FALLTHROUGH - Mark fallthrough cases in switch statements.
unsigned const MachineRegisterInfo * MRI
Wrapper class representing virtual and physical registers.
void replaceRegWith(Register FromReg, Register ToReg)
replaceRegWith - Replace all instances of FromReg with ToReg in the machine function.
static bool isSignExtendedW(MachineInstr &OrigMI, MachineRegisterInfo &MRI, SmallPtrSetImpl< MachineInstr * > &FixableDef)
FunctionPass * createRISCVSExtWRemovalPass()
Function & getFunction()
Return the LLVM function that this machine code represents.
static unsigned getWOp(unsigned Opcode)
@ ADD
Simple integer binary arithmetic operators.
MachineInstrBuilder BuildMI(MachineFunction &MF, const DebugLoc &DL, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
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...
static void addUses(const MachineInstr &MI, SmallVectorImpl< const MachineInstr * > &Worklist, MachineRegisterInfo &MRI)
A templated base class for SmallPtrSet which provides the typesafe interface that is common across al...
FunctionPass class - This class is used to implement most global optimizations.
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.