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:
167 // CMP is an alias for SUBS with a dead destination register.
168 case AArch64::SUBSWri:
169 case AArch64::SUBSXri: {
170 // Sometimes the first operand is a FrameIndex. Bail if tht happens.
171 if (!PredI.getOperand(1).isReg())
173 MCPhysReg SrcReg = PredI.getOperand(1).getReg();
175 // Must not be a symbolic immediate.
176 if (!PredI.getOperand(2).isImm())
179 // The src register must not be modified between the cmp and conditional
180 // branch. This includes a self-clobbering compare.
181 if (ClobberedRegs[SrcReg])
184 // We've found the Cmp that sets NZCV.
185 int32_t KnownImm = PredI.getOperand(2).getImm();
186 int32_t Shift = PredI.getOperand(3).getImm();
189 KnownImm = -KnownImm;
191 return RegImm(SrcReg, KnownImm);
195 // Bail if we see an instruction that defines NZCV that we don't handle.
196 if (PredI.definesRegister(AArch64::NZCV))
202 bool AArch64RedundantCopyElimination::optimizeCopy(MachineBasicBlock *MBB) {
203 // Check if the current basic block has a single predecessor.
204 if (MBB->pred_size() != 1)
207 // Check if the predecessor has two successors, implying the block ends in a
208 // conditional branch.
209 MachineBasicBlock *PredMBB = *MBB->pred_begin();
210 if (PredMBB->succ_size() != 2)
213 MachineBasicBlock::iterator CondBr = PredMBB->getLastNonDebugInstr();
214 if (CondBr == PredMBB->end())
217 // Keep track of the earliest point in the PredMBB block where kill markers
218 // need to be removed if a COPY is removed.
219 MachineBasicBlock::iterator FirstUse;
220 // After calling knownRegValInBlock, FirstUse will either point to a CBZ/CBNZ
221 // or a compare (i.e., SUBS). In the latter case, we must take care when
222 // updating FirstUse when scanning for COPY instructions. In particular, if
223 // there's a COPY in between the compare and branch the COPY should not
225 bool SeenFirstUse = false;
226 // Registers that contain a known value at the start of MBB.
227 SmallVector<RegImm, 4> KnownRegs;
229 MachineBasicBlock::iterator Itr = std::next(CondBr);
233 Optional<RegImm> KnownRegImm = knownRegValInBlock(*Itr, MBB, FirstUse);
234 if (KnownRegImm == None)
237 KnownRegs.push_back(*KnownRegImm);
239 // Reset the clobber list, which is used by knownRegValInBlock.
240 ClobberedRegs.reset();
242 // Look backward in PredMBB for COPYs from the known reg to find other
243 // registers that are known to be a constant value.
244 for (auto PredI = Itr;; --PredI) {
245 if (FirstUse == PredI)
248 if (PredI->isCopy()) {
249 MCPhysReg CopyDstReg = PredI->getOperand(0).getReg();
250 MCPhysReg CopySrcReg = PredI->getOperand(1).getReg();
251 for (auto &KnownReg : KnownRegs) {
252 if (ClobberedRegs[KnownReg.Reg])
254 // If we have X = COPY Y, and Y is known to be zero, then now X is
256 if (CopySrcReg == KnownReg.Reg && !ClobberedRegs[CopyDstReg]) {
257 KnownRegs.push_back(RegImm(CopyDstReg, KnownReg.Imm));
262 // If we have X = COPY Y, and X is known to be zero, then now Y is
264 if (CopyDstReg == KnownReg.Reg && !ClobberedRegs[CopySrcReg]) {
265 KnownRegs.push_back(RegImm(CopySrcReg, KnownReg.Imm));
273 // Stop if we get to the beginning of PredMBB.
274 if (PredI == PredMBB->begin())
277 trackRegDefs(*PredI, ClobberedRegs, TRI);
278 // Stop if all of the known-zero regs have been clobbered.
279 if (all_of(KnownRegs, [&](RegImm KnownReg) {
280 return ClobberedRegs[KnownReg.Reg];
286 } while (Itr != PredMBB->begin() && Itr->isTerminator());
288 // We've not found a registers with a known value, time to bail out.
289 if (KnownRegs.empty())
292 bool Changed = false;
293 // UsedKnownRegs is the set of KnownRegs that have had uses added to MBB.
294 SmallSetVector<unsigned, 4> UsedKnownRegs;
295 MachineBasicBlock::iterator LastChange = MBB->begin();
296 // Remove redundant Copy instructions unless KnownReg is modified.
297 for (MachineBasicBlock::iterator I = MBB->begin(), E = MBB->end(); I != E;) {
298 MachineInstr *MI = &*I;
300 bool RemovedMI = false;
301 bool IsCopy = MI->isCopy();
302 bool IsMoveImm = MI->isMoveImmediate();
303 if (IsCopy || IsMoveImm) {
304 MCPhysReg DefReg = MI->getOperand(0).getReg();
305 MCPhysReg SrcReg = IsCopy ? MI->getOperand(1).getReg() : 0;
306 int64_t SrcImm = IsMoveImm ? MI->getOperand(1).getImm() : 0;
307 if (!MRI->isReserved(DefReg) &&
308 ((IsCopy && (SrcReg == AArch64::XZR || SrcReg == AArch64::WZR)) ||
310 for (RegImm &KnownReg : KnownRegs) {
311 if (KnownReg.Reg != DefReg &&
312 !TRI->isSuperRegister(DefReg, KnownReg.Reg))
315 // For a copy, the known value must be a zero.
316 if (IsCopy && KnownReg.Imm != 0)
320 // For a move immediate, the known immediate must match the source
322 if (KnownReg.Imm != SrcImm)
325 // Don't remove a move immediate that implicitly defines the upper
326 // bits when only the lower 32 bits are known.
327 MCPhysReg CmpReg = KnownReg.Reg;
328 if (any_of(MI->implicit_operands(), [CmpReg](MachineOperand &O) {
329 return !O.isDead() && O.isReg() && O.isDef() &&
330 O.getReg() != CmpReg;
336 DEBUG(dbgs() << "Remove redundant Copy : " << *MI);
338 DEBUG(dbgs() << "Remove redundant Move : " << *MI);
340 MI->eraseFromParent();
344 UsedKnownRegs.insert(KnownReg.Reg);
351 // Skip to the next instruction if we removed the COPY/MovImm.
355 // Remove any regs the MI clobbers from the KnownConstRegs set.
356 for (unsigned RI = 0; RI < KnownRegs.size();)
357 if (MI->modifiesRegister(KnownRegs[RI].Reg, TRI)) {
358 std::swap(KnownRegs[RI], KnownRegs[KnownRegs.size() - 1]);
359 KnownRegs.pop_back();
360 // Don't increment RI since we need to now check the swapped-in
366 // Continue until the KnownRegs set is empty.
367 if (KnownRegs.empty())
374 // Add newly used regs to the block's live-in list if they aren't there
376 for (MCPhysReg KnownReg : UsedKnownRegs)
377 if (!MBB->isLiveIn(KnownReg))
378 MBB->addLiveIn(KnownReg);
380 // Clear kills in the range where changes were made. This is conservative,
381 // but should be okay since kill markers are being phased out.
382 DEBUG(dbgs() << "Clearing kill flags.\n\tFirstUse: " << *FirstUse
383 << "\tLastChange: " << *LastChange);
384 for (MachineInstr &MMI : make_range(FirstUse, PredMBB->end()))
386 for (MachineInstr &MMI : make_range(MBB->begin(), LastChange))
392 bool AArch64RedundantCopyElimination::runOnMachineFunction(
393 MachineFunction &MF) {
394 if (skipFunction(*MF.getFunction()))
396 TRI = MF.getSubtarget().getRegisterInfo();
397 MRI = &MF.getRegInfo();
399 // Resize the clobber register bitfield tracker. We do this once per
400 // function and then clear the bitfield each time we optimize a copy.
401 ClobberedRegs.resize(TRI->getNumRegs());
403 bool Changed = false;
404 for (MachineBasicBlock &MBB : MF)
405 Changed |= optimizeCopy(&MBB);
409 FunctionPass *llvm::createAArch64RedundantCopyEliminationPass() {
410 return new AArch64RedundantCopyElimination();