]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/lib/Target/AArch64/AArch64RedundantCopyElimination.cpp
Merge ^/head r319480 through r319547.
[FreeBSD/FreeBSD.git] / contrib / llvm / lib / Target / AArch64 / AArch64RedundantCopyElimination.cpp
1 //=- AArch64RedundantCopyElimination.cpp - Remove useless copy for AArch64 -=//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
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.
11 //  BB#1:
12 //    CBZW %W0, <BB#2>
13 //  BB#2:
14 //    %W0 = COPY %WZR
15 // Similarly, this pass also handles non-zero copies.
16 //  BB#0:
17 //    cmp x0, #1
18 //    b.eq .LBB0_1
19 //  .LBB0_1:
20 //    orr x0, xzr, #0x1
21 //
22 // This pass should be run after register allocation.
23 //
24 // FIXME: This could also be extended to check the whole dominance subtree below
25 // the comparison if the compile time regression is acceptable.
26 //
27 //===----------------------------------------------------------------------===//
28
29 #include "AArch64.h"
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"
37
38 using namespace llvm;
39
40 #define DEBUG_TYPE "aarch64-copyelim"
41
42 STATISTIC(NumCopiesRemoved, "Number of copies removed.");
43
44 namespace {
45 class AArch64RedundantCopyElimination : public MachineFunctionPass {
46   const MachineRegisterInfo *MRI;
47   const TargetRegisterInfo *TRI;
48   BitVector ClobberedRegs;
49
50 public:
51   static char ID;
52   AArch64RedundantCopyElimination() : MachineFunctionPass(ID) {
53     initializeAArch64RedundantCopyEliminationPass(
54         *PassRegistry::getPassRegistry());
55   }
56
57   struct RegImm {
58     MCPhysReg Reg;
59     int32_t Imm;
60     RegImm(MCPhysReg Reg, int32_t Imm) : Reg(Reg), Imm(Imm) {}
61   };
62
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);
71   }
72   StringRef getPassName() const override {
73     return "AArch64 Redundant Copy Elimination";
74   }
75 };
76 char AArch64RedundantCopyElimination::ID = 0;
77 }
78
79 INITIALIZE_PASS(AArch64RedundantCopyElimination, "aarch64-copyelim",
80                 "AArch64 redundant copy elimination pass", false, false)
81
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()) {
86     if (MO.isRegMask()) {
87       ClobberedRegs.setBitsNotInMask(MO.getRegMask());
88       continue;
89     }
90
91     if (!MO.isReg())
92       continue;
93     unsigned Reg = MO.getReg();
94     if (!Reg)
95       continue;
96     if (!MO.isDef())
97       continue;
98
99     for (MCRegAliasIterator AI(Reg, TRI, true); AI.isValid(); ++AI)
100       ClobberedRegs.set(*AI);
101   }
102 }
103
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();
114
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())) {
121     FirstUse = CondBr;
122     return RegImm(CondBr.getOperand(0).getReg(), 0);
123   }
124
125   // Otherwise, must be a conditional branch.
126   if (Opc != AArch64::Bcc)
127     return None;
128
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)
132     return None;
133
134   MachineBasicBlock *BrTarget = CondBr.getOperand(1).getMBB();
135   if ((CC == AArch64CC::EQ && BrTarget != MBB) ||
136       (CC == AArch64CC::NE && BrTarget == MBB))
137     return None;
138
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())
144     return None;
145
146   // Registers clobbered in PredMBB between CondBr instruction and current
147   // instruction being checked in loop.
148   ClobberedRegs.reset();
149
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())) {
153
154     // Track clobbered registers.
155     trackRegDefs(PredI, ClobberedRegs, TRI);
156
157     bool IsCMN = false;
158     switch (PredI.getOpcode()) {
159     default:
160       break;
161
162     // CMN is an alias for ADDS with a dead destination register.
163     case AArch64::ADDSWri:
164     case AArch64::ADDSXri:
165       IsCMN = true;
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();
170
171       // Must not be a symbolic immediate.
172       if (!PredI.getOperand(2).isImm())
173         return None;
174
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])
178         return None;
179
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();
183       KnownImm <<= Shift;
184       if (IsCMN)
185         KnownImm = -KnownImm;
186       FirstUse = PredI;
187       return RegImm(SrcReg, KnownImm);
188     }
189     }
190
191     // Bail if we see an instruction that defines NZCV that we don't handle.
192     if (PredI.definesRegister(AArch64::NZCV))
193       return None;
194   }
195   return None;
196 }
197
198 bool AArch64RedundantCopyElimination::optimizeCopy(MachineBasicBlock *MBB) {
199   // Check if the current basic block has a single predecessor.
200   if (MBB->pred_size() != 1)
201     return false;
202
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)
207     return false;
208
209   MachineBasicBlock::iterator CondBr = PredMBB->getLastNonDebugInstr();
210   if (CondBr == PredMBB->end())
211     return false;
212
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
220   // update FirstUse.
221   bool SeenFirstUse = false;
222   // Registers that contain a known value at the start of MBB.
223   SmallVector<RegImm, 4> KnownRegs;
224
225   MachineBasicBlock::iterator Itr = std::next(CondBr);
226   do {
227     --Itr;
228
229     Optional<RegImm> KnownRegImm = knownRegValInBlock(*Itr, MBB, FirstUse);
230     if (KnownRegImm == None)
231       continue;
232
233     KnownRegs.push_back(*KnownRegImm);
234
235     // Reset the clobber list, which is used by knownRegValInBlock.
236     ClobberedRegs.reset();
237
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)
242         SeenFirstUse = true;
243
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])
249             continue;
250           // If we have X = COPY Y, and Y is known to be zero, then now X is
251           // known to be zero.
252           if (CopySrcReg == KnownReg.Reg && !ClobberedRegs[CopyDstReg]) {
253             KnownRegs.push_back(RegImm(CopyDstReg, KnownReg.Imm));
254             if (SeenFirstUse)
255               FirstUse = PredI;
256             break;
257           }
258           // If we have X = COPY Y, and X is known to be zero, then now Y is
259           // known to be zero.
260           if (CopyDstReg == KnownReg.Reg && !ClobberedRegs[CopySrcReg]) {
261             KnownRegs.push_back(RegImm(CopySrcReg, KnownReg.Imm));
262             if (SeenFirstUse)
263               FirstUse = PredI;
264             break;
265           }
266         }
267       }
268
269       // Stop if we get to the beginning of PredMBB.
270       if (PredI == PredMBB->begin())
271         break;
272
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];
277           }))
278         break;
279     }
280     break;
281
282   } while (Itr != PredMBB->begin() && Itr->isTerminator());
283
284   // We've not found a registers with a known value, time to bail out.
285   if (KnownRegs.empty())
286     return false;
287
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;
295     ++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)) ||
305            IsMoveImm)) {
306         for (RegImm &KnownReg : KnownRegs) {
307           if (KnownReg.Reg != DefReg &&
308               !TRI->isSuperRegister(DefReg, KnownReg.Reg))
309             continue;
310
311           // For a copy, the known value must be a zero.
312           if (IsCopy && KnownReg.Imm != 0)
313             continue;
314
315           if (IsMoveImm) {
316             // For a move immediate, the known immediate must match the source
317             // immediate.
318             if (KnownReg.Imm != SrcImm)
319               continue;
320
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;
327                 }))
328               continue;
329           }
330
331           if (IsCopy)
332             DEBUG(dbgs() << "Remove redundant Copy : " << *MI);
333           else
334             DEBUG(dbgs() << "Remove redundant Move : " << *MI);
335
336           MI->eraseFromParent();
337           Changed = true;
338           LastChange = I;
339           NumCopiesRemoved++;
340           UsedKnownRegs.insert(KnownReg.Reg);
341           RemovedMI = true;
342           break;
343         }
344       }
345     }
346
347     // Skip to the next instruction if we removed the COPY/MovImm.
348     if (RemovedMI)
349       continue;
350
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
357         // KnownRegs[RI].
358       } else {
359         ++RI;
360       }
361
362     // Continue until the KnownRegs set is empty.
363     if (KnownRegs.empty())
364       break;
365   }
366
367   if (!Changed)
368     return false;
369
370   // Add newly used regs to the block's live-in list if they aren't there
371   // already.
372   for (MCPhysReg KnownReg : UsedKnownRegs)
373     if (!MBB->isLiveIn(KnownReg))
374       MBB->addLiveIn(KnownReg);
375
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()))
381     MMI.clearKillInfo();
382   for (MachineInstr &MMI : make_range(MBB->begin(), LastChange))
383     MMI.clearKillInfo();
384
385   return true;
386 }
387
388 bool AArch64RedundantCopyElimination::runOnMachineFunction(
389     MachineFunction &MF) {
390   if (skipFunction(*MF.getFunction()))
391     return false;
392   TRI = MF.getSubtarget().getRegisterInfo();
393   MRI = &MF.getRegInfo();
394
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());
398
399   bool Changed = false;
400   for (MachineBasicBlock &MBB : MF)
401     Changed |= optimizeCopy(&MBB);
402   return Changed;
403 }
404
405 FunctionPass *llvm::createAArch64RedundantCopyEliminationPass() {
406   return new AArch64RedundantCopyElimination();
407 }