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";
61 void getAnalysisUsage(AnalysisUsage &AU)
const override {
72char RISCVRedundantCopyElimination::ID = 0;
75 "RISC-V Redundant Copy Elimination",
false,
false)
81 assert(
Cond.size() == 3 &&
"Unexpected number of operands");
82 assert(
TBB !=
nullptr &&
"Expected branch target basic block");
97 assert(
Cond.size() == 3 &&
"Unexpected number of operands");
98 assert(
TBB !=
nullptr &&
"Expected branch target basic block");
100 if ((
Opc == RISCV::QC_BEQI ||
Opc == RISCV::QC_E_BEQI ||
101 Opc == RISCV::NDS_BEQC ||
Opc == RISCV::BEQI) &&
104 if ((
Opc == RISCV::QC_BNEI ||
Opc == RISCV::QC_E_BNEI ||
105 Opc == RISCV::NDS_BNEC ||
Opc == RISCV::BNEI) &&
122 MachineBasicBlock *
TBB =
nullptr, *FBB =
nullptr;
133 bool IsZeroCopy = guaranteesZeroRegInBlock(
MBB,
Cond,
TBB);
142 MachineInstr *
MI = &*
I;
144 bool RemoveMI =
false;
146 if (
MI->isCopy() &&
MI->getOperand(0).isReg() &&
147 MI->getOperand(1).isReg()) {
151 if (SrcReg == RISCV::X0 && !MRI->
isReserved(DefReg) &&
158 if (
MI->getOpcode() == RISCV::ADDI &&
MI->getOperand(0).isReg() &&
159 MI->getOperand(1).isReg() &&
MI->getOperand(2).isImm()) {
162 int64_t
Imm =
MI->getOperand(2).getImm();
163 if (SrcReg == RISCV::X0 && !MRI->
isReserved(DefReg) &&
164 TargetReg == DefReg && Imm ==
Cond[2].getImm())
166 }
else if (
MI->getOpcode() == RISCV::QC_LI &&
MI->getOperand(0).isReg() &&
167 MI->getOperand(1).isImm()) {
169 int64_t
Imm =
MI->getOperand(1).getImm();
170 if (!MRI->
isReserved(DefReg) && TargetReg == DefReg &&
171 Imm ==
Cond[2].getImm())
180 MI->eraseFromParent();
187 if (
MI->modifiesRegister(TargetReg,
TRI))
195 assert((CondBr->getOpcode() == RISCV::BEQ ||
196 CondBr->getOpcode() == RISCV::BNE ||
197 CondBr->getOpcode() == RISCV::BEQI ||
198 CondBr->getOpcode() == RISCV::BNEI ||
199 CondBr->getOpcode() == RISCV::QC_BEQI ||
200 CondBr->getOpcode() == RISCV::QC_BNEI ||
201 CondBr->getOpcode() == RISCV::QC_E_BEQI ||
202 CondBr->getOpcode() == RISCV::QC_E_BNEI ||
203 CondBr->getOpcode() == RISCV::NDS_BEQC ||
204 CondBr->getOpcode() == RISCV::NDS_BNEC) &&
205 "Unexpected opcode");
206 assert(CondBr->getOperand(0).getReg() == TargetReg &&
"Unexpected register");
210 CondBr->clearRegisterKills(TargetReg,
TRI);
218 MMI.clearRegisterKills(TargetReg,
TRI);
223bool RISCVRedundantCopyElimination::runOnMachineFunction(MachineFunction &MF) {
232 for (MachineBasicBlock &
MBB : MF)
239 return new RISCVRedundantCopyElimination();
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)
AnalysisUsage & addPreserved()
Add the specified Pass class to the set of analyses preserved by this pass.
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...
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
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,...
bool isReserved(MCRegister PhysReg) const
isReserved - Returns true when PhysReg is a reserved register.
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...