1aaf2d078SSumanth Gundapaneni //===------- HexagonTfrCleanup.cpp - Hexagon Transfer Cleanup Pass -------===// 2aaf2d078SSumanth Gundapaneni // 3aaf2d078SSumanth Gundapaneni // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4aaf2d078SSumanth Gundapaneni // See https://llvm.org/LICENSE.txt for license information. 5aaf2d078SSumanth Gundapaneni // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6aaf2d078SSumanth Gundapaneni // 7aaf2d078SSumanth Gundapaneni //===----------------------------------------------------------------------===// 8aaf2d078SSumanth Gundapaneni // This pass is to address a situation that appears after register allocaion 9aaf2d078SSumanth Gundapaneni // evey now and then, namely a register copy from a source that was defined 10aaf2d078SSumanth Gundapaneni // as an immediate value in the same block (usually just before the copy). 11aaf2d078SSumanth Gundapaneni // 12aaf2d078SSumanth Gundapaneni // Here is an example of actual code emitted that shows this problem: 13aaf2d078SSumanth Gundapaneni // 14aaf2d078SSumanth Gundapaneni // .LBB0_5: 15aaf2d078SSumanth Gundapaneni // { 16aaf2d078SSumanth Gundapaneni // r5 = zxtb(r8) 17aaf2d078SSumanth Gundapaneni // r6 = or(r6, ##12345) 18aaf2d078SSumanth Gundapaneni // } 19aaf2d078SSumanth Gundapaneni // { 20aaf2d078SSumanth Gundapaneni // r3 = xor(r1, r2) 21aaf2d078SSumanth Gundapaneni // r1 = #0 <-- r1 set to #0 22aaf2d078SSumanth Gundapaneni // } 23aaf2d078SSumanth Gundapaneni // { 24aaf2d078SSumanth Gundapaneni // r7 = r1 <-- r7 set to r1 25aaf2d078SSumanth Gundapaneni // r0 = zxtb(r3) 26aaf2d078SSumanth Gundapaneni // } 27aaf2d078SSumanth Gundapaneni 28aaf2d078SSumanth Gundapaneni #define DEBUG_TYPE "tfr-cleanup" 29aaf2d078SSumanth Gundapaneni #include "HexagonTargetMachine.h" 30aaf2d078SSumanth Gundapaneni 31aaf2d078SSumanth Gundapaneni #include "llvm/CodeGen/LiveIntervals.h" 32aaf2d078SSumanth Gundapaneni #include "llvm/CodeGen/MachineFunction.h" 33aaf2d078SSumanth Gundapaneni #include "llvm/CodeGen/MachineInstrBuilder.h" 34aaf2d078SSumanth Gundapaneni #include "llvm/CodeGen/Passes.h" 35aaf2d078SSumanth Gundapaneni #include "llvm/CodeGen/TargetInstrInfo.h" 36aaf2d078SSumanth Gundapaneni #include "llvm/CodeGen/TargetRegisterInfo.h" 37aaf2d078SSumanth Gundapaneni 38aaf2d078SSumanth Gundapaneni using namespace llvm; 39aaf2d078SSumanth Gundapaneni 40aaf2d078SSumanth Gundapaneni namespace llvm { 41aaf2d078SSumanth Gundapaneni FunctionPass *createHexagonTfrCleanup(); 42aaf2d078SSumanth Gundapaneni void initializeHexagonTfrCleanupPass(PassRegistry &); 43aaf2d078SSumanth Gundapaneni } // namespace llvm 44aaf2d078SSumanth Gundapaneni 45aaf2d078SSumanth Gundapaneni namespace { 46aaf2d078SSumanth Gundapaneni class HexagonTfrCleanup : public MachineFunctionPass { 47aaf2d078SSumanth Gundapaneni public: 48aaf2d078SSumanth Gundapaneni static char ID; 49aaf2d078SSumanth Gundapaneni HexagonTfrCleanup() : MachineFunctionPass(ID), HII(0), TRI(0) { 50aaf2d078SSumanth Gundapaneni PassRegistry &R = *PassRegistry::getPassRegistry(); 51aaf2d078SSumanth Gundapaneni initializeHexagonTfrCleanupPass(R); 52aaf2d078SSumanth Gundapaneni } 53aaf2d078SSumanth Gundapaneni StringRef getPassName() const override { return "Hexagon TFR Cleanup"; } 54aaf2d078SSumanth Gundapaneni void getAnalysisUsage(AnalysisUsage &AU) const override { 55aaf2d078SSumanth Gundapaneni AU.setPreservesAll(); 56aaf2d078SSumanth Gundapaneni MachineFunctionPass::getAnalysisUsage(AU); 57aaf2d078SSumanth Gundapaneni } 58aaf2d078SSumanth Gundapaneni bool runOnMachineFunction(MachineFunction &MF) override; 59aaf2d078SSumanth Gundapaneni 60aaf2d078SSumanth Gundapaneni private: 61aaf2d078SSumanth Gundapaneni const HexagonInstrInfo *HII; 62aaf2d078SSumanth Gundapaneni const TargetRegisterInfo *TRI; 63aaf2d078SSumanth Gundapaneni 64aaf2d078SSumanth Gundapaneni typedef DenseMap<unsigned, uint64_t> ImmediateMap; 65aaf2d078SSumanth Gundapaneni 66aaf2d078SSumanth Gundapaneni bool isIntReg(unsigned Reg, bool &Is32); 67aaf2d078SSumanth Gundapaneni void setReg(unsigned R32, uint32_t V32, ImmediateMap &IMap); 68aaf2d078SSumanth Gundapaneni bool getReg(unsigned Reg, uint64_t &Val, ImmediateMap &IMap); 69aaf2d078SSumanth Gundapaneni bool updateImmMap(MachineInstr *MI, ImmediateMap &IMap); 70aaf2d078SSumanth Gundapaneni bool rewriteIfImm(MachineInstr *MI, ImmediateMap &IMap, SlotIndexes *Indexes); 71aaf2d078SSumanth Gundapaneni bool eraseIfRedundant(MachineInstr *MI, SlotIndexes *Indexes); 72aaf2d078SSumanth Gundapaneni }; 73aaf2d078SSumanth Gundapaneni } // namespace 74aaf2d078SSumanth Gundapaneni 75aaf2d078SSumanth Gundapaneni char HexagonTfrCleanup::ID = 0; 76aaf2d078SSumanth Gundapaneni 77aaf2d078SSumanth Gundapaneni namespace llvm { 78aaf2d078SSumanth Gundapaneni char &HexagonTfrCleanupID = HexagonTfrCleanup::ID; 79aaf2d078SSumanth Gundapaneni } 80aaf2d078SSumanth Gundapaneni 81aaf2d078SSumanth Gundapaneni bool HexagonTfrCleanup::isIntReg(unsigned Reg, bool &Is32) { 82aaf2d078SSumanth Gundapaneni Is32 = Hexagon::IntRegsRegClass.contains(Reg); 83aaf2d078SSumanth Gundapaneni return Is32 || Hexagon::DoubleRegsRegClass.contains(Reg); 84aaf2d078SSumanth Gundapaneni } 85aaf2d078SSumanth Gundapaneni 86aaf2d078SSumanth Gundapaneni // Assign given value V32 to the specified the register R32 in the map. Only 87aaf2d078SSumanth Gundapaneni // 32-bit registers are valid arguments. 88aaf2d078SSumanth Gundapaneni void HexagonTfrCleanup::setReg(unsigned R32, uint32_t V32, ImmediateMap &IMap) { 89*f5b7c109SKazu Hirata IMap[R32] = V32; 90aaf2d078SSumanth Gundapaneni } 91aaf2d078SSumanth Gundapaneni 92aaf2d078SSumanth Gundapaneni // Retrieve a value of the provided register Reg and store it into Val. 93aaf2d078SSumanth Gundapaneni // Return "true" if a value was found, "false" otherwise. 94aaf2d078SSumanth Gundapaneni bool HexagonTfrCleanup::getReg(unsigned Reg, uint64_t &Val, 95aaf2d078SSumanth Gundapaneni ImmediateMap &IMap) { 96aaf2d078SSumanth Gundapaneni bool Is32; 97aaf2d078SSumanth Gundapaneni if (!isIntReg(Reg, Is32)) 98aaf2d078SSumanth Gundapaneni return false; 99aaf2d078SSumanth Gundapaneni 100aaf2d078SSumanth Gundapaneni if (Is32) { 101aaf2d078SSumanth Gundapaneni ImmediateMap::iterator F = IMap.find(Reg); 102aaf2d078SSumanth Gundapaneni if (F == IMap.end()) 103aaf2d078SSumanth Gundapaneni return false; 104aaf2d078SSumanth Gundapaneni Val = F->second; 105aaf2d078SSumanth Gundapaneni return true; 106aaf2d078SSumanth Gundapaneni } 107aaf2d078SSumanth Gundapaneni 108aaf2d078SSumanth Gundapaneni // For 64-bit registers, compose the value from the values of its 109aaf2d078SSumanth Gundapaneni // subregisters. 110aaf2d078SSumanth Gundapaneni unsigned SubL = TRI->getSubReg(Reg, Hexagon::isub_lo); 111aaf2d078SSumanth Gundapaneni unsigned SubH = TRI->getSubReg(Reg, Hexagon::isub_hi); 112aaf2d078SSumanth Gundapaneni ImmediateMap::iterator FL = IMap.find(SubL), FH = IMap.find(SubH); 113aaf2d078SSumanth Gundapaneni if (FL == IMap.end() || FH == IMap.end()) 114aaf2d078SSumanth Gundapaneni return false; 115aaf2d078SSumanth Gundapaneni Val = (FH->second << 32) | FL->second; 116aaf2d078SSumanth Gundapaneni return true; 117aaf2d078SSumanth Gundapaneni } 118aaf2d078SSumanth Gundapaneni 119aaf2d078SSumanth Gundapaneni // Process an instruction and record the relevant information in the imme- 120aaf2d078SSumanth Gundapaneni // diate map. 121aaf2d078SSumanth Gundapaneni bool HexagonTfrCleanup::updateImmMap(MachineInstr *MI, ImmediateMap &IMap) { 122aaf2d078SSumanth Gundapaneni using namespace Hexagon; 123aaf2d078SSumanth Gundapaneni 124aaf2d078SSumanth Gundapaneni if (MI->isCall()) { 125aaf2d078SSumanth Gundapaneni IMap.clear(); 126aaf2d078SSumanth Gundapaneni return true; 127aaf2d078SSumanth Gundapaneni } 128aaf2d078SSumanth Gundapaneni 129aaf2d078SSumanth Gundapaneni // If this is an instruction that loads a constant into a register, 130aaf2d078SSumanth Gundapaneni // record this information in IMap. 131aaf2d078SSumanth Gundapaneni unsigned Opc = MI->getOpcode(); 132aaf2d078SSumanth Gundapaneni if (Opc == A2_tfrsi || Opc == A2_tfrpi) { 133aaf2d078SSumanth Gundapaneni unsigned DefR = MI->getOperand(0).getReg(); 134aaf2d078SSumanth Gundapaneni bool Is32; 135aaf2d078SSumanth Gundapaneni if (!isIntReg(DefR, Is32)) 136aaf2d078SSumanth Gundapaneni return false; 137aaf2d078SSumanth Gundapaneni if (!MI->getOperand(1).isImm()) { 138aaf2d078SSumanth Gundapaneni if (!Is32) { 139aaf2d078SSumanth Gundapaneni IMap.erase(TRI->getSubReg(DefR, isub_lo)); 140aaf2d078SSumanth Gundapaneni IMap.erase(TRI->getSubReg(DefR, isub_hi)); 141aaf2d078SSumanth Gundapaneni } else { 142aaf2d078SSumanth Gundapaneni IMap.erase(DefR); 143aaf2d078SSumanth Gundapaneni } 144aaf2d078SSumanth Gundapaneni return false; 145aaf2d078SSumanth Gundapaneni } 146aaf2d078SSumanth Gundapaneni uint64_t Val = MI->getOperand(1).getImm(); 147aaf2d078SSumanth Gundapaneni // If it's a 64-bit register, break it up into subregisters. 148aaf2d078SSumanth Gundapaneni if (!Is32) { 149aaf2d078SSumanth Gundapaneni uint32_t VH = (Val >> 32), VL = (Val & 0xFFFFFFFFU); 150aaf2d078SSumanth Gundapaneni setReg(TRI->getSubReg(DefR, isub_lo), VL, IMap); 151aaf2d078SSumanth Gundapaneni setReg(TRI->getSubReg(DefR, isub_hi), VH, IMap); 152aaf2d078SSumanth Gundapaneni } else { 153aaf2d078SSumanth Gundapaneni setReg(DefR, Val, IMap); 154aaf2d078SSumanth Gundapaneni } 155aaf2d078SSumanth Gundapaneni return true; 156aaf2d078SSumanth Gundapaneni } 157aaf2d078SSumanth Gundapaneni 158aaf2d078SSumanth Gundapaneni // Not a A2_tfr[sp]i. Invalidate all modified registers in IMap. 159aaf2d078SSumanth Gundapaneni for (MachineInstr::mop_iterator Mo = MI->operands_begin(), 160aaf2d078SSumanth Gundapaneni E = MI->operands_end(); 161aaf2d078SSumanth Gundapaneni Mo != E; ++Mo) { 162aaf2d078SSumanth Gundapaneni if (Mo->isRegMask()) { 163aaf2d078SSumanth Gundapaneni IMap.clear(); 164aaf2d078SSumanth Gundapaneni return true; 165aaf2d078SSumanth Gundapaneni } 166aaf2d078SSumanth Gundapaneni if (!Mo->isReg() || !Mo->isDef()) 167aaf2d078SSumanth Gundapaneni continue; 168aaf2d078SSumanth Gundapaneni unsigned R = Mo->getReg(); 169aaf2d078SSumanth Gundapaneni for (MCRegAliasIterator AR(R, TRI, true); AR.isValid(); ++AR) { 170aaf2d078SSumanth Gundapaneni ImmediateMap::iterator F = IMap.find(*AR); 171aaf2d078SSumanth Gundapaneni if (F != IMap.end()) 172aaf2d078SSumanth Gundapaneni IMap.erase(F); 173aaf2d078SSumanth Gundapaneni } 174aaf2d078SSumanth Gundapaneni } 175aaf2d078SSumanth Gundapaneni return true; 176aaf2d078SSumanth Gundapaneni } 177aaf2d078SSumanth Gundapaneni 178aaf2d078SSumanth Gundapaneni // Rewrite the instruction as A2_tfrsi/A2_tfrpi, it is a copy of a source that 179aaf2d078SSumanth Gundapaneni // has a known constant value. 180aaf2d078SSumanth Gundapaneni bool HexagonTfrCleanup::rewriteIfImm(MachineInstr *MI, ImmediateMap &IMap, 181aaf2d078SSumanth Gundapaneni SlotIndexes *Indexes) { 182aaf2d078SSumanth Gundapaneni using namespace Hexagon; 183aaf2d078SSumanth Gundapaneni unsigned Opc = MI->getOpcode(); 184aaf2d078SSumanth Gundapaneni switch (Opc) { 185aaf2d078SSumanth Gundapaneni case A2_tfr: 186aaf2d078SSumanth Gundapaneni case A2_tfrp: 187aaf2d078SSumanth Gundapaneni case COPY: 188aaf2d078SSumanth Gundapaneni break; 189aaf2d078SSumanth Gundapaneni default: 190aaf2d078SSumanth Gundapaneni return false; 191aaf2d078SSumanth Gundapaneni } 192aaf2d078SSumanth Gundapaneni 193aaf2d078SSumanth Gundapaneni unsigned DstR = MI->getOperand(0).getReg(); 194aaf2d078SSumanth Gundapaneni unsigned SrcR = MI->getOperand(1).getReg(); 195aaf2d078SSumanth Gundapaneni bool Tmp, Is32; 196aaf2d078SSumanth Gundapaneni if (!isIntReg(DstR, Is32) || !isIntReg(SrcR, Tmp)) 197aaf2d078SSumanth Gundapaneni return false; 198aaf2d078SSumanth Gundapaneni assert(Tmp == Is32 && "Register size mismatch"); 199aaf2d078SSumanth Gundapaneni uint64_t Val; 200aaf2d078SSumanth Gundapaneni bool Found = getReg(SrcR, Val, IMap); 201aaf2d078SSumanth Gundapaneni if (!Found) 202aaf2d078SSumanth Gundapaneni return false; 203aaf2d078SSumanth Gundapaneni 204aaf2d078SSumanth Gundapaneni MachineBasicBlock &B = *MI->getParent(); 205aaf2d078SSumanth Gundapaneni DebugLoc DL = MI->getDebugLoc(); 206aaf2d078SSumanth Gundapaneni int64_t SVal = Is32 ? int32_t(Val) : Val; 207aaf2d078SSumanth Gundapaneni auto &HST = B.getParent()->getSubtarget<HexagonSubtarget>(); 208aaf2d078SSumanth Gundapaneni MachineInstr *NewMI; 209aaf2d078SSumanth Gundapaneni if (Is32) 210aaf2d078SSumanth Gundapaneni NewMI = BuildMI(B, MI, DL, HII->get(A2_tfrsi), DstR).addImm(SVal); 211aaf2d078SSumanth Gundapaneni else if (isInt<8>(SVal)) 212aaf2d078SSumanth Gundapaneni NewMI = BuildMI(B, MI, DL, HII->get(A2_tfrpi), DstR).addImm(SVal); 213aaf2d078SSumanth Gundapaneni else if (isInt<8>(SVal >> 32) && isInt<8>(int32_t(Val & 0xFFFFFFFFLL))) 214aaf2d078SSumanth Gundapaneni NewMI = BuildMI(B, MI, DL, HII->get(A2_combineii), DstR) 215aaf2d078SSumanth Gundapaneni .addImm(int32_t(SVal >> 32)) 216aaf2d078SSumanth Gundapaneni .addImm(int32_t(Val & 0xFFFFFFFFLL)); 217aaf2d078SSumanth Gundapaneni else if (HST.isTinyCore()) 218aaf2d078SSumanth Gundapaneni // Disable generating CONST64 since it requires load resource. 219aaf2d078SSumanth Gundapaneni return false; 220aaf2d078SSumanth Gundapaneni else 221aaf2d078SSumanth Gundapaneni NewMI = BuildMI(B, MI, DL, HII->get(CONST64), DstR).addImm(Val); 222aaf2d078SSumanth Gundapaneni 223aaf2d078SSumanth Gundapaneni // Replace the MI to reuse the same slot index 224aaf2d078SSumanth Gundapaneni if (Indexes) 225aaf2d078SSumanth Gundapaneni Indexes->replaceMachineInstrInMaps(*MI, *NewMI); 226aaf2d078SSumanth Gundapaneni MI->eraseFromParent(); 227aaf2d078SSumanth Gundapaneni return true; 228aaf2d078SSumanth Gundapaneni } 229aaf2d078SSumanth Gundapaneni 230aaf2d078SSumanth Gundapaneni // Remove the instruction if it is a self-assignment. 231aaf2d078SSumanth Gundapaneni bool HexagonTfrCleanup::eraseIfRedundant(MachineInstr *MI, 232aaf2d078SSumanth Gundapaneni SlotIndexes *Indexes) { 233aaf2d078SSumanth Gundapaneni unsigned Opc = MI->getOpcode(); 234aaf2d078SSumanth Gundapaneni unsigned DefR, SrcR; 235aaf2d078SSumanth Gundapaneni bool IsUndef = false; 236aaf2d078SSumanth Gundapaneni switch (Opc) { 237aaf2d078SSumanth Gundapaneni case Hexagon::A2_tfr: 238aaf2d078SSumanth Gundapaneni // Rd = Rd 239aaf2d078SSumanth Gundapaneni DefR = MI->getOperand(0).getReg(); 240aaf2d078SSumanth Gundapaneni SrcR = MI->getOperand(1).getReg(); 241aaf2d078SSumanth Gundapaneni IsUndef = MI->getOperand(1).isUndef(); 242aaf2d078SSumanth Gundapaneni break; 243aaf2d078SSumanth Gundapaneni case Hexagon::A2_tfrt: 244aaf2d078SSumanth Gundapaneni case Hexagon::A2_tfrf: 245aaf2d078SSumanth Gundapaneni // if ([!]Pu) Rd = Rd 246aaf2d078SSumanth Gundapaneni DefR = MI->getOperand(0).getReg(); 247aaf2d078SSumanth Gundapaneni SrcR = MI->getOperand(2).getReg(); 248aaf2d078SSumanth Gundapaneni IsUndef = MI->getOperand(2).isUndef(); 249aaf2d078SSumanth Gundapaneni break; 250aaf2d078SSumanth Gundapaneni default: 251aaf2d078SSumanth Gundapaneni return false; 252aaf2d078SSumanth Gundapaneni } 253aaf2d078SSumanth Gundapaneni if (DefR != SrcR) 254aaf2d078SSumanth Gundapaneni return false; 255aaf2d078SSumanth Gundapaneni if (IsUndef) { 256aaf2d078SSumanth Gundapaneni MachineBasicBlock &B = *MI->getParent(); 257aaf2d078SSumanth Gundapaneni DebugLoc DL = MI->getDebugLoc(); 258aaf2d078SSumanth Gundapaneni auto DefI = BuildMI(B, MI, DL, HII->get(TargetOpcode::IMPLICIT_DEF), DefR); 259aaf2d078SSumanth Gundapaneni for (auto &Op : MI->operands()) 260aaf2d078SSumanth Gundapaneni if (Op.isReg() && Op.isDef() && Op.isImplicit()) 261aaf2d078SSumanth Gundapaneni DefI->addOperand(Op); 262aaf2d078SSumanth Gundapaneni } 263aaf2d078SSumanth Gundapaneni 264aaf2d078SSumanth Gundapaneni if (Indexes) 265aaf2d078SSumanth Gundapaneni Indexes->removeMachineInstrFromMaps(*MI); 266aaf2d078SSumanth Gundapaneni MI->eraseFromParent(); 267aaf2d078SSumanth Gundapaneni return true; 268aaf2d078SSumanth Gundapaneni } 269aaf2d078SSumanth Gundapaneni 270aaf2d078SSumanth Gundapaneni bool HexagonTfrCleanup::runOnMachineFunction(MachineFunction &MF) { 271aaf2d078SSumanth Gundapaneni bool Changed = false; 272aaf2d078SSumanth Gundapaneni // Map: 32-bit register -> immediate value. 273aaf2d078SSumanth Gundapaneni // 64-bit registers are stored through their subregisters. 274aaf2d078SSumanth Gundapaneni ImmediateMap IMap; 2754010f894Spaperchalice auto *SIWrapper = getAnalysisIfAvailable<SlotIndexesWrapperPass>(); 2764010f894Spaperchalice SlotIndexes *Indexes = SIWrapper ? &SIWrapper->getSI() : nullptr; 277aaf2d078SSumanth Gundapaneni 278aaf2d078SSumanth Gundapaneni auto &HST = MF.getSubtarget<HexagonSubtarget>(); 279aaf2d078SSumanth Gundapaneni HII = HST.getInstrInfo(); 280aaf2d078SSumanth Gundapaneni TRI = HST.getRegisterInfo(); 281aaf2d078SSumanth Gundapaneni 2825e22a536SKazu Hirata for (MachineBasicBlock &B : MF) { 283aaf2d078SSumanth Gundapaneni MachineBasicBlock::iterator J, F, NextJ; 284aaf2d078SSumanth Gundapaneni IMap.clear(); 285aaf2d078SSumanth Gundapaneni bool Inserted = false, Erased = false; 286aaf2d078SSumanth Gundapaneni for (J = B.begin(), F = B.end(); J != F; J = NextJ) { 287aaf2d078SSumanth Gundapaneni NextJ = std::next(J); 288aaf2d078SSumanth Gundapaneni MachineInstr *MI = &*J; 289aaf2d078SSumanth Gundapaneni bool E = eraseIfRedundant(MI, Indexes); 290aaf2d078SSumanth Gundapaneni Erased |= E; 291aaf2d078SSumanth Gundapaneni if (E) 292aaf2d078SSumanth Gundapaneni continue; 293aaf2d078SSumanth Gundapaneni Inserted |= rewriteIfImm(MI, IMap, Indexes); 294aaf2d078SSumanth Gundapaneni MachineBasicBlock::iterator NewJ = std::prev(NextJ); 295aaf2d078SSumanth Gundapaneni updateImmMap(&*NewJ, IMap); 296aaf2d078SSumanth Gundapaneni } 297aaf2d078SSumanth Gundapaneni bool BlockC = Inserted | Erased; 298aaf2d078SSumanth Gundapaneni Changed |= BlockC; 299aaf2d078SSumanth Gundapaneni if (BlockC && Indexes) 300aaf2d078SSumanth Gundapaneni Indexes->repairIndexesInRange(&B, B.begin(), B.end()); 301aaf2d078SSumanth Gundapaneni } 302aaf2d078SSumanth Gundapaneni 303aaf2d078SSumanth Gundapaneni return Changed; 304aaf2d078SSumanth Gundapaneni } 305aaf2d078SSumanth Gundapaneni 306aaf2d078SSumanth Gundapaneni //===----------------------------------------------------------------------===// 307aaf2d078SSumanth Gundapaneni // Public Constructor Functions 308aaf2d078SSumanth Gundapaneni //===----------------------------------------------------------------------===// 309aaf2d078SSumanth Gundapaneni INITIALIZE_PASS(HexagonTfrCleanup, "tfr-cleanup", "Hexagon TFR Cleanup", false, 310aaf2d078SSumanth Gundapaneni false) 311aaf2d078SSumanth Gundapaneni 312aaf2d078SSumanth Gundapaneni FunctionPass *llvm::createHexagonTfrCleanup() { 313aaf2d078SSumanth Gundapaneni return new HexagonTfrCleanup(); 314aaf2d078SSumanth Gundapaneni } 315