38#define DEBUG_TYPE "riscv-copyelim"
40STATISTIC(NumCopiesRemoved,
"Number of copies removed.");
52 bool runOnMachineFunction(MachineFunction &MF)
override;
53 MachineFunctionProperties getRequiredProperties()
const override {
54 return MachineFunctionProperties().setNoVRegs();
57 StringRef getPassName()
const override {
58 return "RISC-V Redundant Copy Elimination";
67char RISCVRedundantCopyElimination::ID = 0;
70 "RISC-V Redundant Copy Elimination",
false,
false)
76 assert(
Cond.size() == 3 &&
"Unexpected number of operands");
77 assert(
TBB !=
nullptr &&
"Expected branch target basic block");
92 assert(
Cond.size() == 3 &&
"Unexpected number of operands");
93 assert(
TBB !=
nullptr &&
"Expected branch target basic block");
95 if ((
Opc == RISCV::QC_BEQI ||
Opc == RISCV::QC_E_BEQI) &&
Cond[2].isImm() &&
98 if ((
Opc == RISCV::QC_BNEI ||
Opc == RISCV::QC_E_BNEI) &&
Cond[2].isImm() &&
115 MachineBasicBlock *
TBB =
nullptr, *FBB =
nullptr;
126 bool IsZeroCopy = guaranteesZeroRegInBlock(
MBB,
Cond,
TBB);
135 MachineInstr *
MI = &*
I;
137 bool RemoveMI =
false;
139 if (
MI->isCopy() &&
MI->getOperand(0).isReg() &&
140 MI->getOperand(1).isReg()) {
144 if (SrcReg == RISCV::X0 && !
MRI->isReserved(DefReg) &&
151 if (
MI->getOpcode() == RISCV::ADDI &&
MI->getOperand(0).isReg() &&
152 MI->getOperand(1).isReg() &&
MI->getOperand(2).isImm()) {
155 int64_t
Imm =
MI->getOperand(2).getImm();
156 if (SrcReg == RISCV::X0 && !
MRI->isReserved(DefReg) &&
157 TargetReg == DefReg && Imm ==
Cond[2].getImm())
159 }
else if (
MI->getOpcode() == RISCV::QC_LI &&
MI->getOperand(0).isReg() &&
160 MI->getOperand(1).isImm()) {
162 int64_t
Imm =
MI->getOperand(1).getImm();
163 if (!
MRI->isReserved(DefReg) && TargetReg == DefReg &&
164 Imm ==
Cond[2].getImm())
173 MI->eraseFromParent();
180 if (
MI->modifiesRegister(TargetReg,
TRI))
188 assert((CondBr->getOpcode() == RISCV::BEQ ||
189 CondBr->getOpcode() == RISCV::BNE ||
190 CondBr->getOpcode() == RISCV::QC_BEQI ||
191 CondBr->getOpcode() == RISCV::QC_BNEI ||
192 CondBr->getOpcode() == RISCV::QC_E_BEQI ||
193 CondBr->getOpcode() == RISCV::QC_E_BNEI) &&
194 "Unexpected opcode");
195 assert(CondBr->getOperand(0).getReg() == TargetReg &&
"Unexpected register");
199 CondBr->clearRegisterKills(TargetReg,
TRI);
207 MMI.clearRegisterKills(TargetReg,
TRI);
212bool RISCVRedundantCopyElimination::runOnMachineFunction(MachineFunction &MF) {
221 for (MachineBasicBlock &
MBB : MF)
228 return new RISCVRedundantCopyElimination();
unsigned const MachineRegisterInfo * MRI
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
const HexagonInstrInfo * TII
Register const TargetRegisterInfo * TRI
Promote Memory to Register
static MCRegister getReg(const MCDisassembler *D, unsigned RC, unsigned RegNo)
static bool isReg(const MCInst &MI, unsigned OpNo)
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
static bool guaranteesRegEqualsImmInBlock(MachineBasicBlock &MBB, const SmallVectorImpl< MachineOperand > &Cond, MachineBasicBlock *TBB)
const SmallVectorImpl< MachineOperand > MachineBasicBlock * TBB
const SmallVectorImpl< MachineOperand > & Cond
assert(TBB !=nullptr &&"Expected branch target basic block")
static bool optimizeBlock(BasicBlock &BB, bool &ModifiedDT, const TargetTransformInfo &TTI, const DataLayout &DL, bool HasBranchDivergence, DomTreeUpdater *DTU)
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
FunctionPass class - This class is used to implement most global optimizations.
bool analyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB, MachineBasicBlock *&FBB, SmallVectorImpl< MachineOperand > &Cond, bool AllowModify) const override
Analyze the branching code at the end of MBB, returning true if it cannot be understood (e....
unsigned pred_size() const
LLVM_ABI iterator getFirstTerminator()
Returns an iterator to the first terminator instruction of this basic block.
unsigned succ_size() const
pred_iterator pred_begin()
void addLiveIn(MCRegister PhysReg, LaneBitmask LaneMask=LaneBitmask::getAll())
Adds the specified register as a live in.
MachineInstrBundleIterator< MachineInstr > iterator
LLVM_ABI bool isLiveIn(MCRegister Reg, LaneBitmask LaneMask=LaneBitmask::getAll()) const
Return true if the specified register is in the live in set.
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
Function & getFunction()
Return the LLVM function that this machine code represents.
MachineOperand class - Representation of each machine instruction operand.
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
virtual void print(raw_ostream &OS, const Module *M) const
print - Print out the internal state of the pass.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
TargetInstrInfo - Interface to description of machine instruction set.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
virtual const TargetInstrInfo * getInstrInfo() const
virtual const TargetRegisterInfo * getRegisterInfo() const =0
Return the target's register information.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
This is an optimization pass for GlobalISel generic memory operations.
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
MachineInstr * getImm(const MachineOperand &MO, const MachineRegisterInfo *MRI)
FunctionPass * createRISCVRedundantCopyEliminationPass()
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...