1 //=- AArch64RedundantCopyElimination.cpp - Remove useless copy for AArch64 -=//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 // This pass removes unnecessary zero copies in BBs that are targets of
9 // cbz/cbnz instructions. For instance, the copy instruction in the code below
10 // can be removed because the CBZW jumps to BB#2 when W0 is zero.
15 // Similarly, this pass also handles non-zero copies.
22 // This pass should be run after register allocation.
24 // FIXME: This could also be extended to check the whole dominance subtree below
25 // the comparison if the compile time regression is acceptable.
27 //===----------------------------------------------------------------------===//
30 #include "llvm/ADT/Optional.h"
31 #include "llvm/ADT/SetVector.h"
32 #include "llvm/ADT/Statistic.h"
33 #include "llvm/ADT/iterator_range.h"
34 #include "llvm/CodeGen/MachineFunctionPass.h"
35 #include "llvm/CodeGen/MachineRegisterInfo.h"
36 #include "llvm/Support/Debug.h"
40 #define DEBUG_TYPE "aarch64-copyelim"
42 STATISTIC(NumCopiesRemoved, "Number of copies removed.");
45 class AArch64RedundantCopyElimination : public MachineFunctionPass {
46 const MachineRegisterInfo *MRI;
47 const TargetRegisterInfo *TRI;
48 BitVector ClobberedRegs;
52 AArch64RedundantCopyElimination() : MachineFunctionPass(ID) {
53 initializeAArch64RedundantCopyEliminationPass(
54 *PassRegistry::getPassRegistry());
60 RegImm(MCPhysReg Reg, int32_t Imm) : Reg(Reg), Imm(Imm) {}
63 Optional<RegImm> knownRegValInBlock(MachineInstr &CondBr,
64 MachineBasicBlock *MBB,
65 MachineBasicBlock::iterator &FirstUse);
66 bool optimizeCopy(MachineBasicBlock *MBB);
67 bool runOnMachineFunction(MachineFunction &MF) override;
68 MachineFunctionProperties getRequiredProperties() const override {
69 return MachineFunctionProperties().set(
70 MachineFunctionProperties::Property::NoVRegs);
72 StringRef getPassName() const override {
73 return "AArch64 Redundant Copy Elimination";
76 char AArch64RedundantCopyElimination::ID = 0;
79 INITIALIZE_PASS(AArch64RedundantCopyElimination, "aarch64-copyelim",
80 "AArch64 redundant copy elimination pass", false, false)
82 /// Remember what registers the specified instruction modifies.
83 static void trackRegDefs(const MachineInstr &MI, BitVector &ClobberedRegs,
84 const TargetRegisterInfo *TRI) {
85 for (const MachineOperand &MO : MI.operands()) {
87 ClobberedRegs.setBitsNotInMask(MO.getRegMask());
93 unsigned Reg = MO.getReg();
99 for (MCRegAliasIterator AI(Reg, TRI, true); AI.isValid(); ++AI)
100 ClobberedRegs.set(*AI);
104 /// It's possible to determine the value of a register based on a dominating
105 /// condition. To do so, this function checks to see if the basic block \p MBB
106 /// is the target to which a conditional branch \p CondBr jumps and whose
107 /// equality comparison is against a constant. If so, return a known physical
108 /// register and constant value pair. Otherwise, return None.
109 Optional<AArch64RedundantCopyElimination::RegImm>
110 AArch64RedundantCopyElimination::knownRegValInBlock(
111 MachineInstr &CondBr, MachineBasicBlock *MBB,
112 MachineBasicBlock::iterator &FirstUse) {
113 unsigned Opc = CondBr.getOpcode();
115 // Check if the current basic block is the target block to which the
116 // CBZ/CBNZ instruction jumps when its Wt/Xt is zero.
117 if (((Opc == AArch64::CBZW || Opc == AArch64::CBZX) &&
118 MBB == CondBr.getOperand(1).getMBB()) ||
119 ((Opc == AArch64::CBNZW || Opc == AArch64::CBNZX) &&
120 MBB != CondBr.getOperand(1).getMBB())) {
122 return RegImm(CondBr.getOperand(0).getReg(), 0);
125 // Otherwise, must be a conditional branch.
126 if (Opc != AArch64::Bcc)
129 // Must be an equality check (i.e., == or !=).
130 AArch64CC::CondCode CC = (AArch64CC::CondCode)CondBr.getOperand(0).getImm();
131 if (CC != AArch64CC::EQ && CC != AArch64CC::NE)
134 MachineBasicBlock *BrTarget = CondBr.getOperand(1).getMBB();
135 if ((CC == AArch64CC::EQ && BrTarget != MBB) ||
136 (CC == AArch64CC::NE && BrTarget == MBB))
139 // Stop if we get to the beginning of PredMBB.
140 MachineBasicBlock *PredMBB = *MBB->pred_begin();
141 assert(PredMBB == CondBr.getParent() &&
142 "Conditional branch not in predecessor block!");
143 if (CondBr == PredMBB->begin())
146 // Registers clobbered in PredMBB between CondBr instruction and current
147 // instruction being checked in loop.
148 ClobberedRegs.reset();
150 // Find compare instruction that sets NZCV used by CondBr.
151 MachineBasicBlock::reverse_iterator RIt = CondBr.getReverseIterator();
152 for (MachineInstr &PredI : make_range(std::next(RIt), PredMBB->rend())) {
154 // Track clobbered registers.
155 trackRegDefs(PredI, ClobberedRegs, TRI);
158 switch (PredI.getOpcode()) {
162 // CMN is an alias for ADDS with a dead destination register.
163 case AArch64::ADDSWri:
164 case AArch64::ADDSXri:
166 // CMP is an alias for SUBS with a dead destination register.
167 case AArch64::SUBSWri:
168 case AArch64::SUBSXri: {
169 MCPhysReg SrcReg = PredI.getOperand(1).getReg();
171 // Must not be a symbolic immediate.
172 if (!PredI.getOperand(2).isImm())
175 // The src register must not be modified between the cmp and conditional
176 // branch. This includes a self-clobbering compare.
177 if (ClobberedRegs[SrcReg])
180 // We've found the Cmp that sets NZCV.
181 int32_t KnownImm = PredI.getOperand(2).getImm();
182 int32_t Shift = PredI.getOperand(3).getImm();
185 KnownImm = -KnownImm;
187 return RegImm(SrcReg, KnownImm);
191 // Bail if we see an instruction that defines NZCV that we don't handle.
192 if (PredI.definesRegister(AArch64::NZCV))
198 bool AArch64RedundantCopyElimination::optimizeCopy(MachineBasicBlock *MBB) {
199 // Check if the current basic block has a single predecessor.
200 if (MBB->pred_size() != 1)
203 // Check if the predecessor has two successors, implying the block ends in a
204 // conditional branch.
205 MachineBasicBlock *PredMBB = *MBB->pred_begin();
206 if (PredMBB->succ_size() != 2)
209 MachineBasicBlock::iterator CondBr = PredMBB->getLastNonDebugInstr();
210 if (CondBr == PredMBB->end())
213 // Keep track of the earliest point in the PredMBB block where kill markers
214 // need to be removed if a COPY is removed.
215 MachineBasicBlock::iterator FirstUse;
216 // After calling knownRegValInBlock, FirstUse will either point to a CBZ/CBNZ
217 // or a compare (i.e., SUBS). In the latter case, we must take care when
218 // updating FirstUse when scanning for COPY instructions. In particular, if
219 // there's a COPY in between the compare and branch the COPY should not
221 bool SeenFirstUse = false;
222 // Registers that contain a known value at the start of MBB.
223 SmallVector<RegImm, 4> KnownRegs;
225 MachineBasicBlock::iterator Itr = std::next(CondBr);
229 Optional<RegImm> KnownRegImm = knownRegValInBlock(*Itr, MBB, FirstUse);
230 if (KnownRegImm == None)
233 KnownRegs.push_back(*KnownRegImm);
235 // Reset the clobber list, which is used by knownRegValInBlock.
236 ClobberedRegs.reset();
238 // Look backward in PredMBB for COPYs from the known reg to find other
239 // registers that are known to be a constant value.
240 for (auto PredI = Itr;; --PredI) {
241 if (FirstUse == PredI)
244 if (PredI->isCopy()) {
245 MCPhysReg CopyDstReg = PredI->getOperand(0).getReg();
246 MCPhysReg CopySrcReg = PredI->getOperand(1).getReg();
247 for (auto &KnownReg : KnownRegs) {
248 if (ClobberedRegs[KnownReg.Reg])
250 // If we have X = COPY Y, and Y is known to be zero, then now X is
252 if (CopySrcReg == KnownReg.Reg && !ClobberedRegs[CopyDstReg]) {
253 KnownRegs.push_back(RegImm(CopyDstReg, KnownReg.Imm));
258 // If we have X = COPY Y, and X is known to be zero, then now Y is
260 if (CopyDstReg == KnownReg.Reg && !ClobberedRegs[CopySrcReg]) {
261 KnownRegs.push_back(RegImm(CopySrcReg, KnownReg.Imm));
269 // Stop if we get to the beginning of PredMBB.
270 if (PredI == PredMBB->begin())
273 trackRegDefs(*PredI, ClobberedRegs, TRI);
274 // Stop if all of the known-zero regs have been clobbered.
275 if (all_of(KnownRegs, [&](RegImm KnownReg) {
276 return ClobberedRegs[KnownReg.Reg];
282 } while (Itr != PredMBB->begin() && Itr->isTerminator());
284 // We've not found a registers with a known value, time to bail out.
285 if (KnownRegs.empty())
288 bool Changed = false;
289 // UsedKnownRegs is the set of KnownRegs that have had uses added to MBB.
290 SmallSetVector<unsigned, 4> UsedKnownRegs;
291 MachineBasicBlock::iterator LastChange = MBB->begin();
292 // Remove redundant Copy instructions unless KnownReg is modified.
293 for (MachineBasicBlock::iterator I = MBB->begin(), E = MBB->end(); I != E;) {
294 MachineInstr *MI = &*I;
296 bool RemovedMI = false;
297 bool IsCopy = MI->isCopy();
298 bool IsMoveImm = MI->isMoveImmediate();
299 if (IsCopy || IsMoveImm) {
300 MCPhysReg DefReg = MI->getOperand(0).getReg();
301 MCPhysReg SrcReg = IsCopy ? MI->getOperand(1).getReg() : 0;
302 int64_t SrcImm = IsMoveImm ? MI->getOperand(1).getImm() : 0;
303 if (!MRI->isReserved(DefReg) &&
304 ((IsCopy && (SrcReg == AArch64::XZR || SrcReg == AArch64::WZR)) ||
306 for (RegImm &KnownReg : KnownRegs) {
307 if (KnownReg.Reg != DefReg &&
308 !TRI->isSuperRegister(DefReg, KnownReg.Reg))
311 // For a copy, the known value must be a zero.
312 if (IsCopy && KnownReg.Imm != 0)
316 // For a move immediate, the known immediate must match the source
318 if (KnownReg.Imm != SrcImm)
321 // Don't remove a move immediate that implicitly defines the upper
322 // bits when only the lower 32 bits are known.
323 MCPhysReg CmpReg = KnownReg.Reg;
324 if (any_of(MI->implicit_operands(), [CmpReg](MachineOperand &O) {
325 return !O.isDead() && O.isReg() && O.isDef() &&
326 O.getReg() != CmpReg;
332 DEBUG(dbgs() << "Remove redundant Copy : " << *MI);
334 DEBUG(dbgs() << "Remove redundant Move : " << *MI);
336 MI->eraseFromParent();
340 UsedKnownRegs.insert(KnownReg.Reg);
347 // Skip to the next instruction if we removed the COPY/MovImm.
351 // Remove any regs the MI clobbers from the KnownConstRegs set.
352 for (unsigned RI = 0; RI < KnownRegs.size();)
353 if (MI->modifiesRegister(KnownRegs[RI].Reg, TRI)) {
354 std::swap(KnownRegs[RI], KnownRegs[KnownRegs.size() - 1]);
355 KnownRegs.pop_back();
356 // Don't increment RI since we need to now check the swapped-in
362 // Continue until the KnownRegs set is empty.
363 if (KnownRegs.empty())
370 // Add newly used regs to the block's live-in list if they aren't there
372 for (MCPhysReg KnownReg : UsedKnownRegs)
373 if (!MBB->isLiveIn(KnownReg))
374 MBB->addLiveIn(KnownReg);
376 // Clear kills in the range where changes were made. This is conservative,
377 // but should be okay since kill markers are being phased out.
378 DEBUG(dbgs() << "Clearing kill flags.\n\tFirstUse: " << *FirstUse
379 << "\tLastChange: " << *LastChange);
380 for (MachineInstr &MMI : make_range(FirstUse, PredMBB->end()))
382 for (MachineInstr &MMI : make_range(MBB->begin(), LastChange))
388 bool AArch64RedundantCopyElimination::runOnMachineFunction(
389 MachineFunction &MF) {
390 if (skipFunction(*MF.getFunction()))
392 TRI = MF.getSubtarget().getRegisterInfo();
393 MRI = &MF.getRegInfo();
395 // Resize the clobber register bitfield tracker. We do this once per
396 // function and then clear the bitfield each time we optimize a copy.
397 ClobberedRegs.resize(TRI->getNumRegs());
399 bool Changed = false;
400 for (MachineBasicBlock &MBB : MF)
401 Changed |= optimizeCopy(&MBB);
405 FunctionPass *llvm::createAArch64RedundantCopyEliminationPass() {
406 return new AArch64RedundantCopyElimination();