xref: /llvm-project/llvm/lib/Target/Hexagon/HexagonTfrCleanup.cpp (revision 7e8bc5cf77bdda9e32b984b3fa91953361f24abb)
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