1303231Sdim//=- AArch64RedundantCopyElimination.cpp - Remove useless copy for AArch64 -=// 2303231Sdim// 3353358Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4353358Sdim// See https://llvm.org/LICENSE.txt for license information. 5353358Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6303231Sdim// 7327952Sdim// This pass removes unnecessary copies/moves in BBs based on a dominating 8327952Sdim// condition. 9327952Sdim// 10327952Sdim// We handle three cases: 11327952Sdim// 1. For BBs that are targets of CBZ/CBNZ instructions, we know the value of 12327952Sdim// the CBZ/CBNZ source register is zero on the taken/not-taken path. For 13327952Sdim// instance, the copy instruction in the code below can be removed because 14327952Sdim// the CBZW jumps to %bb.2 when w0 is zero. 15327952Sdim// 16327952Sdim// %bb.1: 17327952Sdim// cbz w0, .LBB0_2 18327952Sdim// .LBB0_2: 19327952Sdim// mov w0, wzr ; <-- redundant 20327952Sdim// 21327952Sdim// 2. If the flag setting instruction defines a register other than WZR/XZR, we 22327952Sdim// can remove a zero copy in some cases. 23327952Sdim// 24327952Sdim// %bb.0: 25327952Sdim// subs w0, w1, w2 26327952Sdim// str w0, [x1] 27327952Sdim// b.ne .LBB0_2 28327952Sdim// %bb.1: 29327952Sdim// mov w0, wzr ; <-- redundant 30327952Sdim// str w0, [x2] 31327952Sdim// .LBB0_2 32327952Sdim// 33327952Sdim// 3. Finally, if the flag setting instruction is a comparison against a 34327952Sdim// constant (i.e., ADDS[W|X]ri, SUBS[W|X]ri), we can remove a mov immediate 35327952Sdim// in some cases. 36327952Sdim// 37327952Sdim// %bb.0: 38327952Sdim// subs xzr, x0, #1 39321369Sdim// b.eq .LBB0_1 40321369Sdim// .LBB0_1: 41327952Sdim// orr x0, xzr, #0x1 ; <-- redundant 42321369Sdim// 43303231Sdim// This pass should be run after register allocation. 44303231Sdim// 45303231Sdim// FIXME: This could also be extended to check the whole dominance subtree below 46303231Sdim// the comparison if the compile time regression is acceptable. 47303231Sdim// 48327952Sdim// FIXME: Add support for handling CCMP instructions. 49327952Sdim// FIXME: If the known register value is zero, we should be able to rewrite uses 50327952Sdim// to use WZR/XZR directly in some cases. 51303231Sdim//===----------------------------------------------------------------------===// 52303231Sdim#include "AArch64.h" 53321369Sdim#include "llvm/ADT/Optional.h" 54303231Sdim#include "llvm/ADT/SetVector.h" 55303231Sdim#include "llvm/ADT/Statistic.h" 56303231Sdim#include "llvm/ADT/iterator_range.h" 57341825Sdim#include "llvm/CodeGen/LiveRegUnits.h" 58303231Sdim#include "llvm/CodeGen/MachineFunctionPass.h" 59303231Sdim#include "llvm/CodeGen/MachineRegisterInfo.h" 60303231Sdim#include "llvm/Support/Debug.h" 61303231Sdim 62303231Sdimusing namespace llvm; 63303231Sdim 64303231Sdim#define DEBUG_TYPE "aarch64-copyelim" 65303231Sdim 66303231SdimSTATISTIC(NumCopiesRemoved, "Number of copies removed."); 67303231Sdim 68303231Sdimnamespace { 69303231Sdimclass AArch64RedundantCopyElimination : public MachineFunctionPass { 70303231Sdim const MachineRegisterInfo *MRI; 71303231Sdim const TargetRegisterInfo *TRI; 72303231Sdim 73327952Sdim // DomBBClobberedRegs is used when computing known values in the dominating 74327952Sdim // BB. 75341825Sdim LiveRegUnits DomBBClobberedRegs, DomBBUsedRegs; 76327952Sdim 77327952Sdim // OptBBClobberedRegs is used when optimizing away redundant copies/moves. 78341825Sdim LiveRegUnits OptBBClobberedRegs, OptBBUsedRegs; 79327952Sdim 80303231Sdimpublic: 81303231Sdim static char ID; 82314564Sdim AArch64RedundantCopyElimination() : MachineFunctionPass(ID) { 83314564Sdim initializeAArch64RedundantCopyEliminationPass( 84314564Sdim *PassRegistry::getPassRegistry()); 85314564Sdim } 86321369Sdim 87321369Sdim struct RegImm { 88321369Sdim MCPhysReg Reg; 89321369Sdim int32_t Imm; 90321369Sdim RegImm(MCPhysReg Reg, int32_t Imm) : Reg(Reg), Imm(Imm) {} 91321369Sdim }; 92321369Sdim 93327952Sdim bool knownRegValInBlock(MachineInstr &CondBr, MachineBasicBlock *MBB, 94327952Sdim SmallVectorImpl<RegImm> &KnownRegs, 95327952Sdim MachineBasicBlock::iterator &FirstUse); 96327952Sdim bool optimizeBlock(MachineBasicBlock *MBB); 97303231Sdim bool runOnMachineFunction(MachineFunction &MF) override; 98303231Sdim MachineFunctionProperties getRequiredProperties() const override { 99303231Sdim return MachineFunctionProperties().set( 100314564Sdim MachineFunctionProperties::Property::NoVRegs); 101303231Sdim } 102314564Sdim StringRef getPassName() const override { 103303231Sdim return "AArch64 Redundant Copy Elimination"; 104303231Sdim } 105303231Sdim}; 106303231Sdimchar AArch64RedundantCopyElimination::ID = 0; 107303231Sdim} 108303231Sdim 109303231SdimINITIALIZE_PASS(AArch64RedundantCopyElimination, "aarch64-copyelim", 110303231Sdim "AArch64 redundant copy elimination pass", false, false) 111303231Sdim 112321369Sdim/// It's possible to determine the value of a register based on a dominating 113321369Sdim/// condition. To do so, this function checks to see if the basic block \p MBB 114327952Sdim/// is the target of a conditional branch \p CondBr with an equality comparison. 115327952Sdim/// If the branch is a CBZ/CBNZ, we know the value of its source operand is zero 116327952Sdim/// in \p MBB for some cases. Otherwise, we find and inspect the NZCV setting 117327952Sdim/// instruction (e.g., SUBS, ADDS). If this instruction defines a register 118327952Sdim/// other than WZR/XZR, we know the value of the destination register is zero in 119327952Sdim/// \p MMB for some cases. In addition, if the NZCV setting instruction is 120327952Sdim/// comparing against a constant we know the other source register is equal to 121327952Sdim/// the constant in \p MBB for some cases. If we find any constant values, push 122327952Sdim/// a physical register and constant value pair onto the KnownRegs vector and 123327952Sdim/// return true. Otherwise, return false if no known values were found. 124327952Sdimbool AArch64RedundantCopyElimination::knownRegValInBlock( 125321369Sdim MachineInstr &CondBr, MachineBasicBlock *MBB, 126327952Sdim SmallVectorImpl<RegImm> &KnownRegs, MachineBasicBlock::iterator &FirstUse) { 127321369Sdim unsigned Opc = CondBr.getOpcode(); 128321369Sdim 129303231Sdim // Check if the current basic block is the target block to which the 130303231Sdim // CBZ/CBNZ instruction jumps when its Wt/Xt is zero. 131321369Sdim if (((Opc == AArch64::CBZW || Opc == AArch64::CBZX) && 132321369Sdim MBB == CondBr.getOperand(1).getMBB()) || 133321369Sdim ((Opc == AArch64::CBNZW || Opc == AArch64::CBNZX) && 134321369Sdim MBB != CondBr.getOperand(1).getMBB())) { 135321369Sdim FirstUse = CondBr; 136327952Sdim KnownRegs.push_back(RegImm(CondBr.getOperand(0).getReg(), 0)); 137327952Sdim return true; 138321369Sdim } 139303231Sdim 140321369Sdim // Otherwise, must be a conditional branch. 141321369Sdim if (Opc != AArch64::Bcc) 142327952Sdim return false; 143321369Sdim 144321369Sdim // Must be an equality check (i.e., == or !=). 145321369Sdim AArch64CC::CondCode CC = (AArch64CC::CondCode)CondBr.getOperand(0).getImm(); 146321369Sdim if (CC != AArch64CC::EQ && CC != AArch64CC::NE) 147327952Sdim return false; 148321369Sdim 149321369Sdim MachineBasicBlock *BrTarget = CondBr.getOperand(1).getMBB(); 150321369Sdim if ((CC == AArch64CC::EQ && BrTarget != MBB) || 151321369Sdim (CC == AArch64CC::NE && BrTarget == MBB)) 152327952Sdim return false; 153321369Sdim 154321369Sdim // Stop if we get to the beginning of PredMBB. 155321369Sdim MachineBasicBlock *PredMBB = *MBB->pred_begin(); 156321369Sdim assert(PredMBB == CondBr.getParent() && 157321369Sdim "Conditional branch not in predecessor block!"); 158321369Sdim if (CondBr == PredMBB->begin()) 159327952Sdim return false; 160321369Sdim 161321369Sdim // Registers clobbered in PredMBB between CondBr instruction and current 162321369Sdim // instruction being checked in loop. 163341825Sdim DomBBClobberedRegs.clear(); 164341825Sdim DomBBUsedRegs.clear(); 165321369Sdim 166321369Sdim // Find compare instruction that sets NZCV used by CondBr. 167321369Sdim MachineBasicBlock::reverse_iterator RIt = CondBr.getReverseIterator(); 168321369Sdim for (MachineInstr &PredI : make_range(std::next(RIt), PredMBB->rend())) { 169321369Sdim 170321369Sdim bool IsCMN = false; 171321369Sdim switch (PredI.getOpcode()) { 172321369Sdim default: 173321369Sdim break; 174321369Sdim 175321369Sdim // CMN is an alias for ADDS with a dead destination register. 176321369Sdim case AArch64::ADDSWri: 177321369Sdim case AArch64::ADDSXri: 178321369Sdim IsCMN = true; 179321369Sdim LLVM_FALLTHROUGH; 180321369Sdim // CMP is an alias for SUBS with a dead destination register. 181321369Sdim case AArch64::SUBSWri: 182321369Sdim case AArch64::SUBSXri: { 183324826Sdim // Sometimes the first operand is a FrameIndex. Bail if tht happens. 184324826Sdim if (!PredI.getOperand(1).isReg()) 185327952Sdim return false; 186327952Sdim MCPhysReg DstReg = PredI.getOperand(0).getReg(); 187321369Sdim MCPhysReg SrcReg = PredI.getOperand(1).getReg(); 188321369Sdim 189327952Sdim bool Res = false; 190327952Sdim // If we're comparing against a non-symbolic immediate and the source 191327952Sdim // register of the compare is not modified (including a self-clobbering 192327952Sdim // compare) between the compare and conditional branch we known the value 193327952Sdim // of the 1st source operand. 194341825Sdim if (PredI.getOperand(2).isImm() && DomBBClobberedRegs.available(SrcReg) && 195327952Sdim SrcReg != DstReg) { 196327952Sdim // We've found the instruction that sets NZCV. 197327952Sdim int32_t KnownImm = PredI.getOperand(2).getImm(); 198327952Sdim int32_t Shift = PredI.getOperand(3).getImm(); 199327952Sdim KnownImm <<= Shift; 200327952Sdim if (IsCMN) 201327952Sdim KnownImm = -KnownImm; 202327952Sdim FirstUse = PredI; 203327952Sdim KnownRegs.push_back(RegImm(SrcReg, KnownImm)); 204327952Sdim Res = true; 205327952Sdim } 206321369Sdim 207327952Sdim // If this instructions defines something other than WZR/XZR, we know it's 208327952Sdim // result is zero in some cases. 209327952Sdim if (DstReg == AArch64::WZR || DstReg == AArch64::XZR) 210327952Sdim return Res; 211321369Sdim 212327952Sdim // The destination register must not be modified between the NZCV setting 213327952Sdim // instruction and the conditional branch. 214341825Sdim if (!DomBBClobberedRegs.available(DstReg)) 215327952Sdim return Res; 216327952Sdim 217321369Sdim FirstUse = PredI; 218327952Sdim KnownRegs.push_back(RegImm(DstReg, 0)); 219327952Sdim return true; 220321369Sdim } 221327952Sdim 222327952Sdim // Look for NZCV setting instructions that define something other than 223327952Sdim // WZR/XZR. 224327952Sdim case AArch64::ADCSWr: 225327952Sdim case AArch64::ADCSXr: 226327952Sdim case AArch64::ADDSWrr: 227327952Sdim case AArch64::ADDSWrs: 228327952Sdim case AArch64::ADDSWrx: 229327952Sdim case AArch64::ADDSXrr: 230327952Sdim case AArch64::ADDSXrs: 231327952Sdim case AArch64::ADDSXrx: 232327952Sdim case AArch64::ADDSXrx64: 233327952Sdim case AArch64::ANDSWri: 234327952Sdim case AArch64::ANDSWrr: 235327952Sdim case AArch64::ANDSWrs: 236327952Sdim case AArch64::ANDSXri: 237327952Sdim case AArch64::ANDSXrr: 238327952Sdim case AArch64::ANDSXrs: 239327952Sdim case AArch64::BICSWrr: 240327952Sdim case AArch64::BICSWrs: 241327952Sdim case AArch64::BICSXrs: 242327952Sdim case AArch64::BICSXrr: 243327952Sdim case AArch64::SBCSWr: 244327952Sdim case AArch64::SBCSXr: 245327952Sdim case AArch64::SUBSWrr: 246327952Sdim case AArch64::SUBSWrs: 247327952Sdim case AArch64::SUBSWrx: 248327952Sdim case AArch64::SUBSXrr: 249327952Sdim case AArch64::SUBSXrs: 250327952Sdim case AArch64::SUBSXrx: 251327952Sdim case AArch64::SUBSXrx64: { 252327952Sdim MCPhysReg DstReg = PredI.getOperand(0).getReg(); 253327952Sdim if (DstReg == AArch64::WZR || DstReg == AArch64::XZR) 254327952Sdim return false; 255327952Sdim 256327952Sdim // The destination register of the NZCV setting instruction must not be 257327952Sdim // modified before the conditional branch. 258341825Sdim if (!DomBBClobberedRegs.available(DstReg)) 259327952Sdim return false; 260327952Sdim 261327952Sdim // We've found the instruction that sets NZCV whose DstReg == 0. 262327952Sdim FirstUse = PredI; 263327952Sdim KnownRegs.push_back(RegImm(DstReg, 0)); 264327952Sdim return true; 265321369Sdim } 266327952Sdim } 267321369Sdim 268321369Sdim // Bail if we see an instruction that defines NZCV that we don't handle. 269321369Sdim if (PredI.definesRegister(AArch64::NZCV)) 270327952Sdim return false; 271327952Sdim 272341825Sdim // Track clobbered and used registers. 273341825Sdim LiveRegUnits::accumulateUsedDefed(PredI, DomBBClobberedRegs, DomBBUsedRegs, 274341825Sdim TRI); 275321369Sdim } 276327952Sdim return false; 277303231Sdim} 278303231Sdim 279327952Sdimbool AArch64RedundantCopyElimination::optimizeBlock(MachineBasicBlock *MBB) { 280303231Sdim // Check if the current basic block has a single predecessor. 281303231Sdim if (MBB->pred_size() != 1) 282303231Sdim return false; 283303231Sdim 284321369Sdim // Check if the predecessor has two successors, implying the block ends in a 285321369Sdim // conditional branch. 286303231Sdim MachineBasicBlock *PredMBB = *MBB->pred_begin(); 287321369Sdim if (PredMBB->succ_size() != 2) 288303231Sdim return false; 289303231Sdim 290321369Sdim MachineBasicBlock::iterator CondBr = PredMBB->getLastNonDebugInstr(); 291321369Sdim if (CondBr == PredMBB->end()) 292321369Sdim return false; 293321369Sdim 294321369Sdim // Keep track of the earliest point in the PredMBB block where kill markers 295321369Sdim // need to be removed if a COPY is removed. 296321369Sdim MachineBasicBlock::iterator FirstUse; 297321369Sdim // After calling knownRegValInBlock, FirstUse will either point to a CBZ/CBNZ 298321369Sdim // or a compare (i.e., SUBS). In the latter case, we must take care when 299321369Sdim // updating FirstUse when scanning for COPY instructions. In particular, if 300321369Sdim // there's a COPY in between the compare and branch the COPY should not 301321369Sdim // update FirstUse. 302321369Sdim bool SeenFirstUse = false; 303321369Sdim // Registers that contain a known value at the start of MBB. 304321369Sdim SmallVector<RegImm, 4> KnownRegs; 305321369Sdim 306321369Sdim MachineBasicBlock::iterator Itr = std::next(CondBr); 307303231Sdim do { 308321369Sdim --Itr; 309303231Sdim 310327952Sdim if (!knownRegValInBlock(*Itr, MBB, KnownRegs, FirstUse)) 311321369Sdim continue; 312303231Sdim 313341825Sdim // Reset the clobbered and used register units. 314341825Sdim OptBBClobberedRegs.clear(); 315341825Sdim OptBBUsedRegs.clear(); 316321369Sdim 317321369Sdim // Look backward in PredMBB for COPYs from the known reg to find other 318321369Sdim // registers that are known to be a constant value. 319321369Sdim for (auto PredI = Itr;; --PredI) { 320321369Sdim if (FirstUse == PredI) 321321369Sdim SeenFirstUse = true; 322321369Sdim 323321369Sdim if (PredI->isCopy()) { 324321369Sdim MCPhysReg CopyDstReg = PredI->getOperand(0).getReg(); 325321369Sdim MCPhysReg CopySrcReg = PredI->getOperand(1).getReg(); 326321369Sdim for (auto &KnownReg : KnownRegs) { 327341825Sdim if (!OptBBClobberedRegs.available(KnownReg.Reg)) 328321369Sdim continue; 329321369Sdim // If we have X = COPY Y, and Y is known to be zero, then now X is 330321369Sdim // known to be zero. 331341825Sdim if (CopySrcReg == KnownReg.Reg && 332341825Sdim OptBBClobberedRegs.available(CopyDstReg)) { 333321369Sdim KnownRegs.push_back(RegImm(CopyDstReg, KnownReg.Imm)); 334321369Sdim if (SeenFirstUse) 335321369Sdim FirstUse = PredI; 336321369Sdim break; 337321369Sdim } 338321369Sdim // If we have X = COPY Y, and X is known to be zero, then now Y is 339321369Sdim // known to be zero. 340341825Sdim if (CopyDstReg == KnownReg.Reg && 341341825Sdim OptBBClobberedRegs.available(CopySrcReg)) { 342321369Sdim KnownRegs.push_back(RegImm(CopySrcReg, KnownReg.Imm)); 343321369Sdim if (SeenFirstUse) 344321369Sdim FirstUse = PredI; 345321369Sdim break; 346321369Sdim } 347321369Sdim } 348321369Sdim } 349321369Sdim 350321369Sdim // Stop if we get to the beginning of PredMBB. 351321369Sdim if (PredI == PredMBB->begin()) 352321369Sdim break; 353321369Sdim 354341825Sdim LiveRegUnits::accumulateUsedDefed(*PredI, OptBBClobberedRegs, 355341825Sdim OptBBUsedRegs, TRI); 356321369Sdim // Stop if all of the known-zero regs have been clobbered. 357321369Sdim if (all_of(KnownRegs, [&](RegImm KnownReg) { 358341825Sdim return !OptBBClobberedRegs.available(KnownReg.Reg); 359321369Sdim })) 360321369Sdim break; 361321369Sdim } 362321369Sdim break; 363321369Sdim 364321369Sdim } while (Itr != PredMBB->begin() && Itr->isTerminator()); 365321369Sdim 366321369Sdim // We've not found a registers with a known value, time to bail out. 367321369Sdim if (KnownRegs.empty()) 368303231Sdim return false; 369303231Sdim 370303231Sdim bool Changed = false; 371321369Sdim // UsedKnownRegs is the set of KnownRegs that have had uses added to MBB. 372321369Sdim SmallSetVector<unsigned, 4> UsedKnownRegs; 373303231Sdim MachineBasicBlock::iterator LastChange = MBB->begin(); 374327952Sdim // Remove redundant copy/move instructions unless KnownReg is modified. 375303231Sdim for (MachineBasicBlock::iterator I = MBB->begin(), E = MBB->end(); I != E;) { 376303231Sdim MachineInstr *MI = &*I; 377303231Sdim ++I; 378321369Sdim bool RemovedMI = false; 379321369Sdim bool IsCopy = MI->isCopy(); 380321369Sdim bool IsMoveImm = MI->isMoveImmediate(); 381321369Sdim if (IsCopy || IsMoveImm) { 382353358Sdim Register DefReg = MI->getOperand(0).getReg(); 383353358Sdim Register SrcReg = IsCopy ? MI->getOperand(1).getReg() : Register(); 384321369Sdim int64_t SrcImm = IsMoveImm ? MI->getOperand(1).getImm() : 0; 385321369Sdim if (!MRI->isReserved(DefReg) && 386321369Sdim ((IsCopy && (SrcReg == AArch64::XZR || SrcReg == AArch64::WZR)) || 387321369Sdim IsMoveImm)) { 388321369Sdim for (RegImm &KnownReg : KnownRegs) { 389321369Sdim if (KnownReg.Reg != DefReg && 390321369Sdim !TRI->isSuperRegister(DefReg, KnownReg.Reg)) 391321369Sdim continue; 392303231Sdim 393321369Sdim // For a copy, the known value must be a zero. 394321369Sdim if (IsCopy && KnownReg.Imm != 0) 395321369Sdim continue; 396303231Sdim 397321369Sdim if (IsMoveImm) { 398321369Sdim // For a move immediate, the known immediate must match the source 399321369Sdim // immediate. 400321369Sdim if (KnownReg.Imm != SrcImm) 401321369Sdim continue; 402303231Sdim 403321369Sdim // Don't remove a move immediate that implicitly defines the upper 404321369Sdim // bits when only the lower 32 bits are known. 405321369Sdim MCPhysReg CmpReg = KnownReg.Reg; 406321369Sdim if (any_of(MI->implicit_operands(), [CmpReg](MachineOperand &O) { 407321369Sdim return !O.isDead() && O.isReg() && O.isDef() && 408321369Sdim O.getReg() != CmpReg; 409321369Sdim })) 410321369Sdim continue; 411321369Sdim } 412321369Sdim 413321369Sdim if (IsCopy) 414341825Sdim LLVM_DEBUG(dbgs() << "Remove redundant Copy : " << *MI); 415321369Sdim else 416341825Sdim LLVM_DEBUG(dbgs() << "Remove redundant Move : " << *MI); 417321369Sdim 418321369Sdim MI->eraseFromParent(); 419321369Sdim Changed = true; 420321369Sdim LastChange = I; 421321369Sdim NumCopiesRemoved++; 422321369Sdim UsedKnownRegs.insert(KnownReg.Reg); 423321369Sdim RemovedMI = true; 424321369Sdim break; 425321369Sdim } 426303231Sdim } 427303231Sdim } 428303231Sdim 429321369Sdim // Skip to the next instruction if we removed the COPY/MovImm. 430321369Sdim if (RemovedMI) 431321369Sdim continue; 432321369Sdim 433321369Sdim // Remove any regs the MI clobbers from the KnownConstRegs set. 434321369Sdim for (unsigned RI = 0; RI < KnownRegs.size();) 435321369Sdim if (MI->modifiesRegister(KnownRegs[RI].Reg, TRI)) { 436321369Sdim std::swap(KnownRegs[RI], KnownRegs[KnownRegs.size() - 1]); 437321369Sdim KnownRegs.pop_back(); 438321369Sdim // Don't increment RI since we need to now check the swapped-in 439321369Sdim // KnownRegs[RI]. 440321369Sdim } else { 441321369Sdim ++RI; 442321369Sdim } 443321369Sdim 444321369Sdim // Continue until the KnownRegs set is empty. 445321369Sdim if (KnownRegs.empty()) 446303231Sdim break; 447303231Sdim } 448303231Sdim 449303231Sdim if (!Changed) 450303231Sdim return false; 451303231Sdim 452321369Sdim // Add newly used regs to the block's live-in list if they aren't there 453321369Sdim // already. 454321369Sdim for (MCPhysReg KnownReg : UsedKnownRegs) 455321369Sdim if (!MBB->isLiveIn(KnownReg)) 456321369Sdim MBB->addLiveIn(KnownReg); 457303231Sdim 458321369Sdim // Clear kills in the range where changes were made. This is conservative, 459321369Sdim // but should be okay since kill markers are being phased out. 460341825Sdim LLVM_DEBUG(dbgs() << "Clearing kill flags.\n\tFirstUse: " << *FirstUse 461341825Sdim << "\tLastChange: " << *LastChange); 462321369Sdim for (MachineInstr &MMI : make_range(FirstUse, PredMBB->end())) 463321369Sdim MMI.clearKillInfo(); 464314564Sdim for (MachineInstr &MMI : make_range(MBB->begin(), LastChange)) 465321369Sdim MMI.clearKillInfo(); 466303231Sdim 467303231Sdim return true; 468303231Sdim} 469303231Sdim 470303231Sdimbool AArch64RedundantCopyElimination::runOnMachineFunction( 471303231Sdim MachineFunction &MF) { 472327952Sdim if (skipFunction(MF.getFunction())) 473303231Sdim return false; 474303231Sdim TRI = MF.getSubtarget().getRegisterInfo(); 475303231Sdim MRI = &MF.getRegInfo(); 476321369Sdim 477341825Sdim // Resize the clobbered and used register unit trackers. We do this once per 478327952Sdim // function. 479341825Sdim DomBBClobberedRegs.init(*TRI); 480341825Sdim DomBBUsedRegs.init(*TRI); 481341825Sdim OptBBClobberedRegs.init(*TRI); 482341825Sdim OptBBUsedRegs.init(*TRI); 483321369Sdim 484303231Sdim bool Changed = false; 485303231Sdim for (MachineBasicBlock &MBB : MF) 486327952Sdim Changed |= optimizeBlock(&MBB); 487303231Sdim return Changed; 488303231Sdim} 489303231Sdim 490303231SdimFunctionPass *llvm::createAArch64RedundantCopyEliminationPass() { 491303231Sdim return new AArch64RedundantCopyElimination(); 492303231Sdim} 493