LLVM  15.0.0git
RISCVRedundantCopyElimination.cpp
Go to the documentation of this file.
1 //=- RISCVRedundantCopyElimination.cpp - Remove useless copy for RISCV ------=//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This pass removes unnecessary zero copies in BBs that are targets of
10 // beqz/bnez instructions. For instance, the copy instruction in the code below
11 // can be removed because the beqz jumps to BB#2 when a0 is zero.
12 // BB#1:
13 // beqz %a0, <BB#2>
14 // BB#2:
15 // %a0 = COPY %x0
16 // This pass should be run after register allocation.
17 //
18 // This pass is based on the earliest versions of
19 // AArch64RedundantCopyElimination.
20 //
21 // FIXME: Support compares with constants other than zero? This is harder to
22 // do on RISC-V since branches can't have immediates.
23 //
24 //===----------------------------------------------------------------------===//
25 
26 #include "RISCV.h"
27 #include "llvm/ADT/Statistic.h"
30 #include "llvm/Support/Debug.h"
31 
32 using namespace llvm;
33 
34 #define DEBUG_TYPE "riscv-copyelim"
35 
36 STATISTIC(NumCopiesRemoved, "Number of copies removed.");
37 
38 namespace {
39 class RISCVRedundantCopyElimination : public MachineFunctionPass {
40  const MachineRegisterInfo *MRI;
41  const TargetRegisterInfo *TRI;
42 
43 public:
44  static char ID;
45  RISCVRedundantCopyElimination() : MachineFunctionPass(ID) {
48  }
49 
50  bool runOnMachineFunction(MachineFunction &MF) override;
51  MachineFunctionProperties getRequiredProperties() const override {
54  }
55 
56  StringRef getPassName() const override {
57  return "RISCV Redundant Copy Elimination";
58  }
59 
60 private:
62 };
63 
64 } // end anonymous namespace
65 
67 
68 INITIALIZE_PASS(RISCVRedundantCopyElimination, "riscv-copyelim",
69  "RISCV redundant copy elimination pass", false, false)
70 
71 static bool guaranteesZeroRegInBlock(const MachineInstr &MI,
73  unsigned Opc = MI.getOpcode();
74  if (Opc == RISCV::BEQ && MI.getOperand(1).getReg() == RISCV::X0 &&
75  &MBB == MI.getOperand(2).getMBB())
76  return true;
77  if (Opc == RISCV::BNE && MI.getOperand(1).getReg() == RISCV::X0 &&
78  &MBB != MI.getOperand(2).getMBB())
79  return true;
80 
81  return false;
82 }
83 
85  // Check if the current basic block has a single predecessor.
86  if (MBB.pred_size() != 1)
87  return false;
88 
89  // Check if the predecessor has two successors, implying the block ends in a
90  // conditional branch.
91  MachineBasicBlock *PredMBB = *MBB.pred_begin();
92  if (PredMBB->succ_size() != 2)
93  return false;
94 
96  if (CondBr == PredMBB->end())
97  return false;
98 
99  while (true) {
100  // If we run out of terminators, give up.
101  if (!CondBr->isTerminator())
102  return false;
103  // If we found a branch with X0, stop searching and try to remove copies.
104  // TODO: Handle multiple branches with different registers.
105  if (guaranteesZeroRegInBlock(*CondBr, MBB))
106  break;
107  // If we reached the beginning of the basic block, give up.
108  if (CondBr == PredMBB->begin())
109  return false;
110  --CondBr;
111  }
112 
113  Register TargetReg = CondBr->getOperand(0).getReg();
114  if (!TargetReg)
115  return false;
116 
117  bool Changed = false;
118  MachineBasicBlock::iterator LastChange = MBB.begin();
119  // Remove redundant Copy instructions unless TargetReg is modified.
120  for (MachineBasicBlock::iterator I = MBB.begin(), E = MBB.end(); I != E;) {
121  MachineInstr *MI = &*I;
122  ++I;
123  if (MI->isCopy() && MI->getOperand(0).isReg() &&
124  MI->getOperand(1).isReg()) {
125  Register DefReg = MI->getOperand(0).getReg();
126  Register SrcReg = MI->getOperand(1).getReg();
127 
128  if (SrcReg == RISCV::X0 && !MRI->isReserved(DefReg) &&
129  TargetReg == DefReg) {
130  LLVM_DEBUG(dbgs() << "Remove redundant Copy : ");
131  LLVM_DEBUG(MI->print(dbgs()));
132 
133  MI->eraseFromParent();
134  Changed = true;
135  LastChange = I;
136  ++NumCopiesRemoved;
137  continue;
138  }
139  }
140 
141  if (MI->modifiesRegister(TargetReg, TRI))
142  break;
143  }
144 
145  if (!Changed)
146  return false;
147 
148  // Otherwise, we have to fixup the use-def chain, starting with the
149  // BEQ/BNE. Conservatively mark as much as we can live.
150  CondBr->clearRegisterKills(TargetReg, TRI);
151 
152  // Add newly used reg to the block's live-in list if it isn't there already.
153  if (!MBB.isLiveIn(TargetReg))
154  MBB.addLiveIn(TargetReg);
155 
156  // Clear any kills of TargetReg between CondBr and the last removed COPY.
157  for (MachineInstr &MMI : make_range(MBB.begin(), LastChange))
158  MMI.clearRegisterKills(TargetReg, TRI);
159 
160  return true;
161 }
162 
163 bool RISCVRedundantCopyElimination::runOnMachineFunction(MachineFunction &MF) {
164  if (skipFunction(MF.getFunction()))
165  return false;
166 
168  MRI = &MF.getRegInfo();
169 
170  bool Changed = false;
171  for (MachineBasicBlock &MBB : MF)
172  Changed |= optimizeBlock(MBB);
173 
174  return Changed;
175 }
176 
178  return new RISCVRedundantCopyElimination();
179 }
llvm::MachineBasicBlock::succ_size
unsigned succ_size() const
Definition: MachineBasicBlock.h:354
llvm::MachineBasicBlock::pred_begin
pred_iterator pred_begin()
Definition: MachineBasicBlock.h:326
MI
IRTranslator LLVM IR MI
Definition: IRTranslator.cpp:105
llvm
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:17
llvm::make_range
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
Definition: iterator_range.h:53
llvm::MachineBasicBlock::isLiveIn
bool isLiveIn(MCPhysReg Reg, LaneBitmask LaneMask=LaneBitmask::getAll()) const
Return true if the specified register is in the live in set.
Definition: MachineBasicBlock.cpp:576
llvm::MachineRegisterInfo
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
Definition: MachineRegisterInfo.h:50
Statistic.h
llvm::MachineFunctionPass
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
Definition: MachineFunctionPass.h:30
llvm::TargetSubtargetInfo::getRegisterInfo
virtual const TargetRegisterInfo * getRegisterInfo() const
getRegisterInfo - If register information is available, return it.
Definition: TargetSubtargetInfo.h:125
llvm::TargetRegisterInfo
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
Definition: TargetRegisterInfo.h:234
llvm::MachineFunctionProperties
Properties which a MachineFunction may have at a given point in time.
Definition: MachineFunction.h:127
TRI
unsigned const TargetRegisterInfo * TRI
Definition: MachineSink.cpp:1628
LLVM_DEBUG
#define LLVM_DEBUG(X)
Definition: Debug.h:101
MachineRegisterInfo.h
llvm::dbgs
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:163
llvm::MachineBasicBlock::pred_size
unsigned pred_size() const
Definition: MachineBasicBlock.h:338
llvm::MachineFunction::getRegInfo
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
Definition: MachineFunction.h:666
llvm::PassRegistry::getPassRegistry
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
Definition: PassRegistry.cpp:24
E
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
llvm::MachineRegisterInfo::isReserved
bool isReserved(MCRegister PhysReg) const
isReserved - Returns true when PhysReg is a reserved register.
Definition: MachineRegisterInfo.h:925
llvm::initializeRISCVRedundantCopyEliminationPass
void initializeRISCVRedundantCopyEliminationPass(PassRegistry &)
llvm::MachineFunctionProperties::set
MachineFunctionProperties & set(Property P)
Definition: MachineFunction.h:196
llvm::STATISTIC
STATISTIC(NumFunctions, "Total number of functions")
llvm::CallingConv::ID
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
Definition: CallingConv.h:24
llvm::MachineBasicBlock
Definition: MachineBasicBlock.h:94
llvm::Pass::print
virtual void print(raw_ostream &OS, const Module *M) const
print - Print out the internal state of the pass.
Definition: Pass.cpp:129
llvm::MachineFunctionProperties::Property::NoVRegs
@ NoVRegs
llvm::MachineFunction::getSubtarget
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
Definition: MachineFunction.h:656
INITIALIZE_PASS
INITIALIZE_PASS(RISCVRedundantCopyElimination, "riscv-copyelim", "RISCV redundant copy elimination pass", false, false) static bool guaranteesZeroRegInBlock(const MachineInstr &MI
llvm::MachineInstr
Representation of each machine instruction.
Definition: MachineInstr.h:66
const
aarch64 promote const
Definition: AArch64PromoteConstant.cpp:232
I
#define I(x, y, z)
Definition: MD5.cpp:58
llvm::MachineBasicBlock::getLastNonDebugInstr
iterator getLastNonDebugInstr(bool SkipPseudoOp=true)
Returns an iterator to the last non-debug instruction in the basic block, or end().
Definition: MachineBasicBlock.cpp:263
MachineFunctionPass.h
RISCV.h
llvm::MachineFunction
Definition: MachineFunction.h:257
MBB
const MachineBasicBlock & MBB
Definition: RISCVRedundantCopyElimination.cpp:72
llvm::StringRef
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:58
MRI
unsigned const MachineRegisterInfo * MRI
Definition: AArch64AdvSIMDScalarPass.cpp:105
llvm::Register
Wrapper class representing virtual and physical registers.
Definition: Register.h:19
llvm::MachineBasicBlock::addLiveIn
void addLiveIn(MCRegister PhysReg, LaneBitmask LaneMask=LaneBitmask::getAll())
Adds the specified register as a live in.
Definition: MachineBasicBlock.h:377
llvm::MachineFunction::getFunction
Function & getFunction()
Return the LLVM function that this machine code represents.
Definition: MachineFunction.h:622
llvm::createRISCVRedundantCopyEliminationPass
FunctionPass * createRISCVRedundantCopyEliminationPass()
Definition: RISCVRedundantCopyElimination.cpp:177
optimizeBlock
static bool optimizeBlock(BasicBlock &BB, bool &ModifiedDT, const TargetTransformInfo &TTI, const DataLayout &DL, DomTreeUpdater *DTU)
Definition: ScalarizeMaskedMemIntrin.cpp:908
llvm::MachineBasicBlock::begin
iterator begin()
Definition: MachineBasicBlock.h:278
llvm::FunctionPass
FunctionPass class - This class is used to implement most global optimizations.
Definition: Pass.h:308
llvm::MachineInstrBundleIterator< MachineInstr >
Debug.h
llvm::MachineBasicBlock::end
iterator end()
Definition: MachineBasicBlock.h:280
llvm::Intrinsic::ID
unsigned ID
Definition: TargetTransformInfo.h:38