xref: /aosp_15_r20/external/llvm/lib/CodeGen/VirtRegMap.cpp (revision 9880d6810fe72a1726cb53787c6711e909410d58)
1*9880d681SAndroid Build Coastguard Worker //===-- llvm/CodeGen/VirtRegMap.cpp - Virtual Register Map ----------------===//
2*9880d681SAndroid Build Coastguard Worker //
3*9880d681SAndroid Build Coastguard Worker //                     The LLVM Compiler Infrastructure
4*9880d681SAndroid Build Coastguard Worker //
5*9880d681SAndroid Build Coastguard Worker // This file is distributed under the University of Illinois Open Source
6*9880d681SAndroid Build Coastguard Worker // License. See LICENSE.TXT for details.
7*9880d681SAndroid Build Coastguard Worker //
8*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
9*9880d681SAndroid Build Coastguard Worker //
10*9880d681SAndroid Build Coastguard Worker // This file implements the VirtRegMap class.
11*9880d681SAndroid Build Coastguard Worker //
12*9880d681SAndroid Build Coastguard Worker // It also contains implementations of the Spiller interface, which, given a
13*9880d681SAndroid Build Coastguard Worker // virtual register map and a machine function, eliminates all virtual
14*9880d681SAndroid Build Coastguard Worker // references by replacing them with physical register references - adding spill
15*9880d681SAndroid Build Coastguard Worker // code as necessary.
16*9880d681SAndroid Build Coastguard Worker //
17*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
18*9880d681SAndroid Build Coastguard Worker 
19*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/VirtRegMap.h"
20*9880d681SAndroid Build Coastguard Worker #include "LiveDebugVariables.h"
21*9880d681SAndroid Build Coastguard Worker #include "llvm/ADT/STLExtras.h"
22*9880d681SAndroid Build Coastguard Worker #include "llvm/ADT/Statistic.h"
23*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/LiveIntervalAnalysis.h"
24*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/LiveStackAnalysis.h"
25*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/MachineFrameInfo.h"
26*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/MachineFunction.h"
27*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/MachineInstrBuilder.h"
28*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/MachineRegisterInfo.h"
29*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/Passes.h"
30*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/Function.h"
31*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/Compiler.h"
32*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/Debug.h"
33*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/raw_ostream.h"
34*9880d681SAndroid Build Coastguard Worker #include "llvm/Target/TargetInstrInfo.h"
35*9880d681SAndroid Build Coastguard Worker #include "llvm/Target/TargetMachine.h"
36*9880d681SAndroid Build Coastguard Worker #include "llvm/Target/TargetRegisterInfo.h"
37*9880d681SAndroid Build Coastguard Worker #include "llvm/Target/TargetSubtargetInfo.h"
38*9880d681SAndroid Build Coastguard Worker #include <algorithm>
39*9880d681SAndroid Build Coastguard Worker using namespace llvm;
40*9880d681SAndroid Build Coastguard Worker 
41*9880d681SAndroid Build Coastguard Worker #define DEBUG_TYPE "regalloc"
42*9880d681SAndroid Build Coastguard Worker 
43*9880d681SAndroid Build Coastguard Worker STATISTIC(NumSpillSlots, "Number of spill slots allocated");
44*9880d681SAndroid Build Coastguard Worker STATISTIC(NumIdCopies,   "Number of identity moves eliminated after rewriting");
45*9880d681SAndroid Build Coastguard Worker 
46*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
47*9880d681SAndroid Build Coastguard Worker //  VirtRegMap implementation
48*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
49*9880d681SAndroid Build Coastguard Worker 
50*9880d681SAndroid Build Coastguard Worker char VirtRegMap::ID = 0;
51*9880d681SAndroid Build Coastguard Worker 
52*9880d681SAndroid Build Coastguard Worker INITIALIZE_PASS(VirtRegMap, "virtregmap", "Virtual Register Map", false, false)
53*9880d681SAndroid Build Coastguard Worker 
runOnMachineFunction(MachineFunction & mf)54*9880d681SAndroid Build Coastguard Worker bool VirtRegMap::runOnMachineFunction(MachineFunction &mf) {
55*9880d681SAndroid Build Coastguard Worker   MRI = &mf.getRegInfo();
56*9880d681SAndroid Build Coastguard Worker   TII = mf.getSubtarget().getInstrInfo();
57*9880d681SAndroid Build Coastguard Worker   TRI = mf.getSubtarget().getRegisterInfo();
58*9880d681SAndroid Build Coastguard Worker   MF = &mf;
59*9880d681SAndroid Build Coastguard Worker 
60*9880d681SAndroid Build Coastguard Worker   Virt2PhysMap.clear();
61*9880d681SAndroid Build Coastguard Worker   Virt2StackSlotMap.clear();
62*9880d681SAndroid Build Coastguard Worker   Virt2SplitMap.clear();
63*9880d681SAndroid Build Coastguard Worker 
64*9880d681SAndroid Build Coastguard Worker   grow();
65*9880d681SAndroid Build Coastguard Worker   return false;
66*9880d681SAndroid Build Coastguard Worker }
67*9880d681SAndroid Build Coastguard Worker 
grow()68*9880d681SAndroid Build Coastguard Worker void VirtRegMap::grow() {
69*9880d681SAndroid Build Coastguard Worker   unsigned NumRegs = MF->getRegInfo().getNumVirtRegs();
70*9880d681SAndroid Build Coastguard Worker   Virt2PhysMap.resize(NumRegs);
71*9880d681SAndroid Build Coastguard Worker   Virt2StackSlotMap.resize(NumRegs);
72*9880d681SAndroid Build Coastguard Worker   Virt2SplitMap.resize(NumRegs);
73*9880d681SAndroid Build Coastguard Worker }
74*9880d681SAndroid Build Coastguard Worker 
createSpillSlot(const TargetRegisterClass * RC)75*9880d681SAndroid Build Coastguard Worker unsigned VirtRegMap::createSpillSlot(const TargetRegisterClass *RC) {
76*9880d681SAndroid Build Coastguard Worker   int SS = MF->getFrameInfo()->CreateSpillStackObject(RC->getSize(),
77*9880d681SAndroid Build Coastguard Worker                                                       RC->getAlignment());
78*9880d681SAndroid Build Coastguard Worker   ++NumSpillSlots;
79*9880d681SAndroid Build Coastguard Worker   return SS;
80*9880d681SAndroid Build Coastguard Worker }
81*9880d681SAndroid Build Coastguard Worker 
hasPreferredPhys(unsigned VirtReg)82*9880d681SAndroid Build Coastguard Worker bool VirtRegMap::hasPreferredPhys(unsigned VirtReg) {
83*9880d681SAndroid Build Coastguard Worker   unsigned Hint = MRI->getSimpleHint(VirtReg);
84*9880d681SAndroid Build Coastguard Worker   if (!Hint)
85*9880d681SAndroid Build Coastguard Worker     return false;
86*9880d681SAndroid Build Coastguard Worker   if (TargetRegisterInfo::isVirtualRegister(Hint))
87*9880d681SAndroid Build Coastguard Worker     Hint = getPhys(Hint);
88*9880d681SAndroid Build Coastguard Worker   return getPhys(VirtReg) == Hint;
89*9880d681SAndroid Build Coastguard Worker }
90*9880d681SAndroid Build Coastguard Worker 
hasKnownPreference(unsigned VirtReg)91*9880d681SAndroid Build Coastguard Worker bool VirtRegMap::hasKnownPreference(unsigned VirtReg) {
92*9880d681SAndroid Build Coastguard Worker   std::pair<unsigned, unsigned> Hint = MRI->getRegAllocationHint(VirtReg);
93*9880d681SAndroid Build Coastguard Worker   if (TargetRegisterInfo::isPhysicalRegister(Hint.second))
94*9880d681SAndroid Build Coastguard Worker     return true;
95*9880d681SAndroid Build Coastguard Worker   if (TargetRegisterInfo::isVirtualRegister(Hint.second))
96*9880d681SAndroid Build Coastguard Worker     return hasPhys(Hint.second);
97*9880d681SAndroid Build Coastguard Worker   return false;
98*9880d681SAndroid Build Coastguard Worker }
99*9880d681SAndroid Build Coastguard Worker 
assignVirt2StackSlot(unsigned virtReg)100*9880d681SAndroid Build Coastguard Worker int VirtRegMap::assignVirt2StackSlot(unsigned virtReg) {
101*9880d681SAndroid Build Coastguard Worker   assert(TargetRegisterInfo::isVirtualRegister(virtReg));
102*9880d681SAndroid Build Coastguard Worker   assert(Virt2StackSlotMap[virtReg] == NO_STACK_SLOT &&
103*9880d681SAndroid Build Coastguard Worker          "attempt to assign stack slot to already spilled register");
104*9880d681SAndroid Build Coastguard Worker   const TargetRegisterClass* RC = MF->getRegInfo().getRegClass(virtReg);
105*9880d681SAndroid Build Coastguard Worker   return Virt2StackSlotMap[virtReg] = createSpillSlot(RC);
106*9880d681SAndroid Build Coastguard Worker }
107*9880d681SAndroid Build Coastguard Worker 
assignVirt2StackSlot(unsigned virtReg,int SS)108*9880d681SAndroid Build Coastguard Worker void VirtRegMap::assignVirt2StackSlot(unsigned virtReg, int SS) {
109*9880d681SAndroid Build Coastguard Worker   assert(TargetRegisterInfo::isVirtualRegister(virtReg));
110*9880d681SAndroid Build Coastguard Worker   assert(Virt2StackSlotMap[virtReg] == NO_STACK_SLOT &&
111*9880d681SAndroid Build Coastguard Worker          "attempt to assign stack slot to already spilled register");
112*9880d681SAndroid Build Coastguard Worker   assert((SS >= 0 ||
113*9880d681SAndroid Build Coastguard Worker           (SS >= MF->getFrameInfo()->getObjectIndexBegin())) &&
114*9880d681SAndroid Build Coastguard Worker          "illegal fixed frame index");
115*9880d681SAndroid Build Coastguard Worker   Virt2StackSlotMap[virtReg] = SS;
116*9880d681SAndroid Build Coastguard Worker }
117*9880d681SAndroid Build Coastguard Worker 
print(raw_ostream & OS,const Module *) const118*9880d681SAndroid Build Coastguard Worker void VirtRegMap::print(raw_ostream &OS, const Module*) const {
119*9880d681SAndroid Build Coastguard Worker   OS << "********** REGISTER MAP **********\n";
120*9880d681SAndroid Build Coastguard Worker   for (unsigned i = 0, e = MRI->getNumVirtRegs(); i != e; ++i) {
121*9880d681SAndroid Build Coastguard Worker     unsigned Reg = TargetRegisterInfo::index2VirtReg(i);
122*9880d681SAndroid Build Coastguard Worker     if (Virt2PhysMap[Reg] != (unsigned)VirtRegMap::NO_PHYS_REG) {
123*9880d681SAndroid Build Coastguard Worker       OS << '[' << PrintReg(Reg, TRI) << " -> "
124*9880d681SAndroid Build Coastguard Worker          << PrintReg(Virt2PhysMap[Reg], TRI) << "] "
125*9880d681SAndroid Build Coastguard Worker          << TRI->getRegClassName(MRI->getRegClass(Reg)) << "\n";
126*9880d681SAndroid Build Coastguard Worker     }
127*9880d681SAndroid Build Coastguard Worker   }
128*9880d681SAndroid Build Coastguard Worker 
129*9880d681SAndroid Build Coastguard Worker   for (unsigned i = 0, e = MRI->getNumVirtRegs(); i != e; ++i) {
130*9880d681SAndroid Build Coastguard Worker     unsigned Reg = TargetRegisterInfo::index2VirtReg(i);
131*9880d681SAndroid Build Coastguard Worker     if (Virt2StackSlotMap[Reg] != VirtRegMap::NO_STACK_SLOT) {
132*9880d681SAndroid Build Coastguard Worker       OS << '[' << PrintReg(Reg, TRI) << " -> fi#" << Virt2StackSlotMap[Reg]
133*9880d681SAndroid Build Coastguard Worker          << "] " << TRI->getRegClassName(MRI->getRegClass(Reg)) << "\n";
134*9880d681SAndroid Build Coastguard Worker     }
135*9880d681SAndroid Build Coastguard Worker   }
136*9880d681SAndroid Build Coastguard Worker   OS << '\n';
137*9880d681SAndroid Build Coastguard Worker }
138*9880d681SAndroid Build Coastguard Worker 
139*9880d681SAndroid Build Coastguard Worker #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
dump() const140*9880d681SAndroid Build Coastguard Worker LLVM_DUMP_METHOD void VirtRegMap::dump() const {
141*9880d681SAndroid Build Coastguard Worker   print(dbgs());
142*9880d681SAndroid Build Coastguard Worker }
143*9880d681SAndroid Build Coastguard Worker #endif
144*9880d681SAndroid Build Coastguard Worker 
145*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
146*9880d681SAndroid Build Coastguard Worker //                              VirtRegRewriter
147*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
148*9880d681SAndroid Build Coastguard Worker //
149*9880d681SAndroid Build Coastguard Worker // The VirtRegRewriter is the last of the register allocator passes.
150*9880d681SAndroid Build Coastguard Worker // It rewrites virtual registers to physical registers as specified in the
151*9880d681SAndroid Build Coastguard Worker // VirtRegMap analysis. It also updates live-in information on basic blocks
152*9880d681SAndroid Build Coastguard Worker // according to LiveIntervals.
153*9880d681SAndroid Build Coastguard Worker //
154*9880d681SAndroid Build Coastguard Worker namespace {
155*9880d681SAndroid Build Coastguard Worker class VirtRegRewriter : public MachineFunctionPass {
156*9880d681SAndroid Build Coastguard Worker   MachineFunction *MF;
157*9880d681SAndroid Build Coastguard Worker   const TargetMachine *TM;
158*9880d681SAndroid Build Coastguard Worker   const TargetRegisterInfo *TRI;
159*9880d681SAndroid Build Coastguard Worker   const TargetInstrInfo *TII;
160*9880d681SAndroid Build Coastguard Worker   MachineRegisterInfo *MRI;
161*9880d681SAndroid Build Coastguard Worker   SlotIndexes *Indexes;
162*9880d681SAndroid Build Coastguard Worker   LiveIntervals *LIS;
163*9880d681SAndroid Build Coastguard Worker   VirtRegMap *VRM;
164*9880d681SAndroid Build Coastguard Worker 
165*9880d681SAndroid Build Coastguard Worker   void rewrite();
166*9880d681SAndroid Build Coastguard Worker   void addMBBLiveIns();
167*9880d681SAndroid Build Coastguard Worker   bool readsUndefSubreg(const MachineOperand &MO) const;
168*9880d681SAndroid Build Coastguard Worker   void addLiveInsForSubRanges(const LiveInterval &LI, unsigned PhysReg) const;
169*9880d681SAndroid Build Coastguard Worker   void handleIdentityCopy(MachineInstr &MI) const;
170*9880d681SAndroid Build Coastguard Worker 
171*9880d681SAndroid Build Coastguard Worker public:
172*9880d681SAndroid Build Coastguard Worker   static char ID;
VirtRegRewriter()173*9880d681SAndroid Build Coastguard Worker   VirtRegRewriter() : MachineFunctionPass(ID) {}
174*9880d681SAndroid Build Coastguard Worker 
175*9880d681SAndroid Build Coastguard Worker   void getAnalysisUsage(AnalysisUsage &AU) const override;
176*9880d681SAndroid Build Coastguard Worker 
177*9880d681SAndroid Build Coastguard Worker   bool runOnMachineFunction(MachineFunction&) override;
getSetProperties() const178*9880d681SAndroid Build Coastguard Worker   MachineFunctionProperties getSetProperties() const override {
179*9880d681SAndroid Build Coastguard Worker     return MachineFunctionProperties().set(
180*9880d681SAndroid Build Coastguard Worker         MachineFunctionProperties::Property::AllVRegsAllocated);
181*9880d681SAndroid Build Coastguard Worker   }
182*9880d681SAndroid Build Coastguard Worker };
183*9880d681SAndroid Build Coastguard Worker } // end anonymous namespace
184*9880d681SAndroid Build Coastguard Worker 
185*9880d681SAndroid Build Coastguard Worker char &llvm::VirtRegRewriterID = VirtRegRewriter::ID;
186*9880d681SAndroid Build Coastguard Worker 
187*9880d681SAndroid Build Coastguard Worker INITIALIZE_PASS_BEGIN(VirtRegRewriter, "virtregrewriter",
188*9880d681SAndroid Build Coastguard Worker                       "Virtual Register Rewriter", false, false)
189*9880d681SAndroid Build Coastguard Worker INITIALIZE_PASS_DEPENDENCY(SlotIndexes)
190*9880d681SAndroid Build Coastguard Worker INITIALIZE_PASS_DEPENDENCY(LiveIntervals)
191*9880d681SAndroid Build Coastguard Worker INITIALIZE_PASS_DEPENDENCY(LiveDebugVariables)
192*9880d681SAndroid Build Coastguard Worker INITIALIZE_PASS_DEPENDENCY(LiveStacks)
193*9880d681SAndroid Build Coastguard Worker INITIALIZE_PASS_DEPENDENCY(VirtRegMap)
194*9880d681SAndroid Build Coastguard Worker INITIALIZE_PASS_END(VirtRegRewriter, "virtregrewriter",
195*9880d681SAndroid Build Coastguard Worker                     "Virtual Register Rewriter", false, false)
196*9880d681SAndroid Build Coastguard Worker 
197*9880d681SAndroid Build Coastguard Worker char VirtRegRewriter::ID = 0;
198*9880d681SAndroid Build Coastguard Worker 
getAnalysisUsage(AnalysisUsage & AU) const199*9880d681SAndroid Build Coastguard Worker void VirtRegRewriter::getAnalysisUsage(AnalysisUsage &AU) const {
200*9880d681SAndroid Build Coastguard Worker   AU.setPreservesCFG();
201*9880d681SAndroid Build Coastguard Worker   AU.addRequired<LiveIntervals>();
202*9880d681SAndroid Build Coastguard Worker   AU.addRequired<SlotIndexes>();
203*9880d681SAndroid Build Coastguard Worker   AU.addPreserved<SlotIndexes>();
204*9880d681SAndroid Build Coastguard Worker   AU.addRequired<LiveDebugVariables>();
205*9880d681SAndroid Build Coastguard Worker   AU.addRequired<LiveStacks>();
206*9880d681SAndroid Build Coastguard Worker   AU.addPreserved<LiveStacks>();
207*9880d681SAndroid Build Coastguard Worker   AU.addRequired<VirtRegMap>();
208*9880d681SAndroid Build Coastguard Worker   MachineFunctionPass::getAnalysisUsage(AU);
209*9880d681SAndroid Build Coastguard Worker }
210*9880d681SAndroid Build Coastguard Worker 
runOnMachineFunction(MachineFunction & fn)211*9880d681SAndroid Build Coastguard Worker bool VirtRegRewriter::runOnMachineFunction(MachineFunction &fn) {
212*9880d681SAndroid Build Coastguard Worker   MF = &fn;
213*9880d681SAndroid Build Coastguard Worker   TM = &MF->getTarget();
214*9880d681SAndroid Build Coastguard Worker   TRI = MF->getSubtarget().getRegisterInfo();
215*9880d681SAndroid Build Coastguard Worker   TII = MF->getSubtarget().getInstrInfo();
216*9880d681SAndroid Build Coastguard Worker   MRI = &MF->getRegInfo();
217*9880d681SAndroid Build Coastguard Worker   Indexes = &getAnalysis<SlotIndexes>();
218*9880d681SAndroid Build Coastguard Worker   LIS = &getAnalysis<LiveIntervals>();
219*9880d681SAndroid Build Coastguard Worker   VRM = &getAnalysis<VirtRegMap>();
220*9880d681SAndroid Build Coastguard Worker   DEBUG(dbgs() << "********** REWRITE VIRTUAL REGISTERS **********\n"
221*9880d681SAndroid Build Coastguard Worker                << "********** Function: "
222*9880d681SAndroid Build Coastguard Worker                << MF->getName() << '\n');
223*9880d681SAndroid Build Coastguard Worker   DEBUG(VRM->dump());
224*9880d681SAndroid Build Coastguard Worker 
225*9880d681SAndroid Build Coastguard Worker   // Add kill flags while we still have virtual registers.
226*9880d681SAndroid Build Coastguard Worker   LIS->addKillFlags(VRM);
227*9880d681SAndroid Build Coastguard Worker 
228*9880d681SAndroid Build Coastguard Worker   // Live-in lists on basic blocks are required for physregs.
229*9880d681SAndroid Build Coastguard Worker   addMBBLiveIns();
230*9880d681SAndroid Build Coastguard Worker 
231*9880d681SAndroid Build Coastguard Worker   // Rewrite virtual registers.
232*9880d681SAndroid Build Coastguard Worker   rewrite();
233*9880d681SAndroid Build Coastguard Worker 
234*9880d681SAndroid Build Coastguard Worker   // Write out new DBG_VALUE instructions.
235*9880d681SAndroid Build Coastguard Worker   getAnalysis<LiveDebugVariables>().emitDebugValues(VRM);
236*9880d681SAndroid Build Coastguard Worker 
237*9880d681SAndroid Build Coastguard Worker   // All machine operands and other references to virtual registers have been
238*9880d681SAndroid Build Coastguard Worker   // replaced. Remove the virtual registers and release all the transient data.
239*9880d681SAndroid Build Coastguard Worker   VRM->clearAllVirt();
240*9880d681SAndroid Build Coastguard Worker   MRI->clearVirtRegs();
241*9880d681SAndroid Build Coastguard Worker   return true;
242*9880d681SAndroid Build Coastguard Worker }
243*9880d681SAndroid Build Coastguard Worker 
addLiveInsForSubRanges(const LiveInterval & LI,unsigned PhysReg) const244*9880d681SAndroid Build Coastguard Worker void VirtRegRewriter::addLiveInsForSubRanges(const LiveInterval &LI,
245*9880d681SAndroid Build Coastguard Worker                                              unsigned PhysReg) const {
246*9880d681SAndroid Build Coastguard Worker   assert(!LI.empty());
247*9880d681SAndroid Build Coastguard Worker   assert(LI.hasSubRanges());
248*9880d681SAndroid Build Coastguard Worker 
249*9880d681SAndroid Build Coastguard Worker   typedef std::pair<const LiveInterval::SubRange *,
250*9880d681SAndroid Build Coastguard Worker                     LiveInterval::const_iterator> SubRangeIteratorPair;
251*9880d681SAndroid Build Coastguard Worker   SmallVector<SubRangeIteratorPair, 4> SubRanges;
252*9880d681SAndroid Build Coastguard Worker   SlotIndex First;
253*9880d681SAndroid Build Coastguard Worker   SlotIndex Last;
254*9880d681SAndroid Build Coastguard Worker   for (const LiveInterval::SubRange &SR : LI.subranges()) {
255*9880d681SAndroid Build Coastguard Worker     SubRanges.push_back(std::make_pair(&SR, SR.begin()));
256*9880d681SAndroid Build Coastguard Worker     if (!First.isValid() || SR.segments.front().start < First)
257*9880d681SAndroid Build Coastguard Worker       First = SR.segments.front().start;
258*9880d681SAndroid Build Coastguard Worker     if (!Last.isValid() || SR.segments.back().end > Last)
259*9880d681SAndroid Build Coastguard Worker       Last = SR.segments.back().end;
260*9880d681SAndroid Build Coastguard Worker   }
261*9880d681SAndroid Build Coastguard Worker 
262*9880d681SAndroid Build Coastguard Worker   // Check all mbb start positions between First and Last while
263*9880d681SAndroid Build Coastguard Worker   // simulatenously advancing an iterator for each subrange.
264*9880d681SAndroid Build Coastguard Worker   for (SlotIndexes::MBBIndexIterator MBBI = Indexes->findMBBIndex(First);
265*9880d681SAndroid Build Coastguard Worker        MBBI != Indexes->MBBIndexEnd() && MBBI->first <= Last; ++MBBI) {
266*9880d681SAndroid Build Coastguard Worker     SlotIndex MBBBegin = MBBI->first;
267*9880d681SAndroid Build Coastguard Worker     // Advance all subrange iterators so that their end position is just
268*9880d681SAndroid Build Coastguard Worker     // behind MBBBegin (or the iterator is at the end).
269*9880d681SAndroid Build Coastguard Worker     LaneBitmask LaneMask = 0;
270*9880d681SAndroid Build Coastguard Worker     for (auto &RangeIterPair : SubRanges) {
271*9880d681SAndroid Build Coastguard Worker       const LiveInterval::SubRange *SR = RangeIterPair.first;
272*9880d681SAndroid Build Coastguard Worker       LiveInterval::const_iterator &SRI = RangeIterPair.second;
273*9880d681SAndroid Build Coastguard Worker       while (SRI != SR->end() && SRI->end <= MBBBegin)
274*9880d681SAndroid Build Coastguard Worker         ++SRI;
275*9880d681SAndroid Build Coastguard Worker       if (SRI == SR->end())
276*9880d681SAndroid Build Coastguard Worker         continue;
277*9880d681SAndroid Build Coastguard Worker       if (SRI->start <= MBBBegin)
278*9880d681SAndroid Build Coastguard Worker         LaneMask |= SR->LaneMask;
279*9880d681SAndroid Build Coastguard Worker     }
280*9880d681SAndroid Build Coastguard Worker     if (LaneMask == 0)
281*9880d681SAndroid Build Coastguard Worker       continue;
282*9880d681SAndroid Build Coastguard Worker     MachineBasicBlock *MBB = MBBI->second;
283*9880d681SAndroid Build Coastguard Worker     MBB->addLiveIn(PhysReg, LaneMask);
284*9880d681SAndroid Build Coastguard Worker   }
285*9880d681SAndroid Build Coastguard Worker }
286*9880d681SAndroid Build Coastguard Worker 
287*9880d681SAndroid Build Coastguard Worker // Compute MBB live-in lists from virtual register live ranges and their
288*9880d681SAndroid Build Coastguard Worker // assignments.
addMBBLiveIns()289*9880d681SAndroid Build Coastguard Worker void VirtRegRewriter::addMBBLiveIns() {
290*9880d681SAndroid Build Coastguard Worker   for (unsigned Idx = 0, IdxE = MRI->getNumVirtRegs(); Idx != IdxE; ++Idx) {
291*9880d681SAndroid Build Coastguard Worker     unsigned VirtReg = TargetRegisterInfo::index2VirtReg(Idx);
292*9880d681SAndroid Build Coastguard Worker     if (MRI->reg_nodbg_empty(VirtReg))
293*9880d681SAndroid Build Coastguard Worker       continue;
294*9880d681SAndroid Build Coastguard Worker     LiveInterval &LI = LIS->getInterval(VirtReg);
295*9880d681SAndroid Build Coastguard Worker     if (LI.empty() || LIS->intervalIsInOneMBB(LI))
296*9880d681SAndroid Build Coastguard Worker       continue;
297*9880d681SAndroid Build Coastguard Worker     // This is a virtual register that is live across basic blocks. Its
298*9880d681SAndroid Build Coastguard Worker     // assigned PhysReg must be marked as live-in to those blocks.
299*9880d681SAndroid Build Coastguard Worker     unsigned PhysReg = VRM->getPhys(VirtReg);
300*9880d681SAndroid Build Coastguard Worker     assert(PhysReg != VirtRegMap::NO_PHYS_REG && "Unmapped virtual register.");
301*9880d681SAndroid Build Coastguard Worker 
302*9880d681SAndroid Build Coastguard Worker     if (LI.hasSubRanges()) {
303*9880d681SAndroid Build Coastguard Worker       addLiveInsForSubRanges(LI, PhysReg);
304*9880d681SAndroid Build Coastguard Worker     } else {
305*9880d681SAndroid Build Coastguard Worker       // Go over MBB begin positions and see if we have segments covering them.
306*9880d681SAndroid Build Coastguard Worker       // The following works because segments and the MBBIndex list are both
307*9880d681SAndroid Build Coastguard Worker       // sorted by slot indexes.
308*9880d681SAndroid Build Coastguard Worker       SlotIndexes::MBBIndexIterator I = Indexes->MBBIndexBegin();
309*9880d681SAndroid Build Coastguard Worker       for (const auto &Seg : LI) {
310*9880d681SAndroid Build Coastguard Worker         I = Indexes->advanceMBBIndex(I, Seg.start);
311*9880d681SAndroid Build Coastguard Worker         for (; I != Indexes->MBBIndexEnd() && I->first < Seg.end; ++I) {
312*9880d681SAndroid Build Coastguard Worker           MachineBasicBlock *MBB = I->second;
313*9880d681SAndroid Build Coastguard Worker           MBB->addLiveIn(PhysReg);
314*9880d681SAndroid Build Coastguard Worker         }
315*9880d681SAndroid Build Coastguard Worker       }
316*9880d681SAndroid Build Coastguard Worker     }
317*9880d681SAndroid Build Coastguard Worker   }
318*9880d681SAndroid Build Coastguard Worker 
319*9880d681SAndroid Build Coastguard Worker   // Sort and unique MBB LiveIns as we've not checked if SubReg/PhysReg were in
320*9880d681SAndroid Build Coastguard Worker   // each MBB's LiveIns set before calling addLiveIn on them.
321*9880d681SAndroid Build Coastguard Worker   for (MachineBasicBlock &MBB : *MF)
322*9880d681SAndroid Build Coastguard Worker     MBB.sortUniqueLiveIns();
323*9880d681SAndroid Build Coastguard Worker }
324*9880d681SAndroid Build Coastguard Worker 
325*9880d681SAndroid Build Coastguard Worker /// Returns true if the given machine operand \p MO only reads undefined lanes.
326*9880d681SAndroid Build Coastguard Worker /// The function only works for use operands with a subregister set.
readsUndefSubreg(const MachineOperand & MO) const327*9880d681SAndroid Build Coastguard Worker bool VirtRegRewriter::readsUndefSubreg(const MachineOperand &MO) const {
328*9880d681SAndroid Build Coastguard Worker   // Shortcut if the operand is already marked undef.
329*9880d681SAndroid Build Coastguard Worker   if (MO.isUndef())
330*9880d681SAndroid Build Coastguard Worker     return true;
331*9880d681SAndroid Build Coastguard Worker 
332*9880d681SAndroid Build Coastguard Worker   unsigned Reg = MO.getReg();
333*9880d681SAndroid Build Coastguard Worker   const LiveInterval &LI = LIS->getInterval(Reg);
334*9880d681SAndroid Build Coastguard Worker   const MachineInstr &MI = *MO.getParent();
335*9880d681SAndroid Build Coastguard Worker   SlotIndex BaseIndex = LIS->getInstructionIndex(MI);
336*9880d681SAndroid Build Coastguard Worker   // This code is only meant to handle reading undefined subregisters which
337*9880d681SAndroid Build Coastguard Worker   // we couldn't properly detect before.
338*9880d681SAndroid Build Coastguard Worker   assert(LI.liveAt(BaseIndex) &&
339*9880d681SAndroid Build Coastguard Worker          "Reads of completely dead register should be marked undef already");
340*9880d681SAndroid Build Coastguard Worker   unsigned SubRegIdx = MO.getSubReg();
341*9880d681SAndroid Build Coastguard Worker   LaneBitmask UseMask = TRI->getSubRegIndexLaneMask(SubRegIdx);
342*9880d681SAndroid Build Coastguard Worker   // See if any of the relevant subregister liveranges is defined at this point.
343*9880d681SAndroid Build Coastguard Worker   for (const LiveInterval::SubRange &SR : LI.subranges()) {
344*9880d681SAndroid Build Coastguard Worker     if ((SR.LaneMask & UseMask) != 0 && SR.liveAt(BaseIndex))
345*9880d681SAndroid Build Coastguard Worker       return false;
346*9880d681SAndroid Build Coastguard Worker   }
347*9880d681SAndroid Build Coastguard Worker   return true;
348*9880d681SAndroid Build Coastguard Worker }
349*9880d681SAndroid Build Coastguard Worker 
handleIdentityCopy(MachineInstr & MI) const350*9880d681SAndroid Build Coastguard Worker void VirtRegRewriter::handleIdentityCopy(MachineInstr &MI) const {
351*9880d681SAndroid Build Coastguard Worker   if (!MI.isIdentityCopy())
352*9880d681SAndroid Build Coastguard Worker     return;
353*9880d681SAndroid Build Coastguard Worker   DEBUG(dbgs() << "Identity copy: " << MI);
354*9880d681SAndroid Build Coastguard Worker   ++NumIdCopies;
355*9880d681SAndroid Build Coastguard Worker 
356*9880d681SAndroid Build Coastguard Worker   // Copies like:
357*9880d681SAndroid Build Coastguard Worker   //    %R0 = COPY %R0<undef>
358*9880d681SAndroid Build Coastguard Worker   //    %AL = COPY %AL, %EAX<imp-def>
359*9880d681SAndroid Build Coastguard Worker   // give us additional liveness information: The target (super-)register
360*9880d681SAndroid Build Coastguard Worker   // must not be valid before this point. Replace the COPY with a KILL
361*9880d681SAndroid Build Coastguard Worker   // instruction to maintain this information.
362*9880d681SAndroid Build Coastguard Worker   if (MI.getOperand(0).isUndef() || MI.getNumOperands() > 2) {
363*9880d681SAndroid Build Coastguard Worker     MI.setDesc(TII->get(TargetOpcode::KILL));
364*9880d681SAndroid Build Coastguard Worker     DEBUG(dbgs() << "  replace by: " << MI);
365*9880d681SAndroid Build Coastguard Worker     return;
366*9880d681SAndroid Build Coastguard Worker   }
367*9880d681SAndroid Build Coastguard Worker 
368*9880d681SAndroid Build Coastguard Worker   if (Indexes)
369*9880d681SAndroid Build Coastguard Worker     Indexes->removeMachineInstrFromMaps(MI);
370*9880d681SAndroid Build Coastguard Worker   MI.eraseFromParent();
371*9880d681SAndroid Build Coastguard Worker   DEBUG(dbgs() << "  deleted.\n");
372*9880d681SAndroid Build Coastguard Worker }
373*9880d681SAndroid Build Coastguard Worker 
rewrite()374*9880d681SAndroid Build Coastguard Worker void VirtRegRewriter::rewrite() {
375*9880d681SAndroid Build Coastguard Worker   bool NoSubRegLiveness = !MRI->subRegLivenessEnabled();
376*9880d681SAndroid Build Coastguard Worker   SmallVector<unsigned, 8> SuperDeads;
377*9880d681SAndroid Build Coastguard Worker   SmallVector<unsigned, 8> SuperDefs;
378*9880d681SAndroid Build Coastguard Worker   SmallVector<unsigned, 8> SuperKills;
379*9880d681SAndroid Build Coastguard Worker 
380*9880d681SAndroid Build Coastguard Worker   for (MachineFunction::iterator MBBI = MF->begin(), MBBE = MF->end();
381*9880d681SAndroid Build Coastguard Worker        MBBI != MBBE; ++MBBI) {
382*9880d681SAndroid Build Coastguard Worker     DEBUG(MBBI->print(dbgs(), Indexes));
383*9880d681SAndroid Build Coastguard Worker     for (MachineBasicBlock::instr_iterator
384*9880d681SAndroid Build Coastguard Worker            MII = MBBI->instr_begin(), MIE = MBBI->instr_end(); MII != MIE;) {
385*9880d681SAndroid Build Coastguard Worker       MachineInstr *MI = &*MII;
386*9880d681SAndroid Build Coastguard Worker       ++MII;
387*9880d681SAndroid Build Coastguard Worker 
388*9880d681SAndroid Build Coastguard Worker       for (MachineInstr::mop_iterator MOI = MI->operands_begin(),
389*9880d681SAndroid Build Coastguard Worker            MOE = MI->operands_end(); MOI != MOE; ++MOI) {
390*9880d681SAndroid Build Coastguard Worker         MachineOperand &MO = *MOI;
391*9880d681SAndroid Build Coastguard Worker 
392*9880d681SAndroid Build Coastguard Worker         // Make sure MRI knows about registers clobbered by regmasks.
393*9880d681SAndroid Build Coastguard Worker         if (MO.isRegMask())
394*9880d681SAndroid Build Coastguard Worker           MRI->addPhysRegsUsedFromRegMask(MO.getRegMask());
395*9880d681SAndroid Build Coastguard Worker 
396*9880d681SAndroid Build Coastguard Worker         if (!MO.isReg() || !TargetRegisterInfo::isVirtualRegister(MO.getReg()))
397*9880d681SAndroid Build Coastguard Worker           continue;
398*9880d681SAndroid Build Coastguard Worker         unsigned VirtReg = MO.getReg();
399*9880d681SAndroid Build Coastguard Worker         unsigned PhysReg = VRM->getPhys(VirtReg);
400*9880d681SAndroid Build Coastguard Worker         assert(PhysReg != VirtRegMap::NO_PHYS_REG &&
401*9880d681SAndroid Build Coastguard Worker                "Instruction uses unmapped VirtReg");
402*9880d681SAndroid Build Coastguard Worker         assert(!MRI->isReserved(PhysReg) && "Reserved register assignment");
403*9880d681SAndroid Build Coastguard Worker 
404*9880d681SAndroid Build Coastguard Worker         // Preserve semantics of sub-register operands.
405*9880d681SAndroid Build Coastguard Worker         unsigned SubReg = MO.getSubReg();
406*9880d681SAndroid Build Coastguard Worker         if (SubReg != 0) {
407*9880d681SAndroid Build Coastguard Worker           if (NoSubRegLiveness) {
408*9880d681SAndroid Build Coastguard Worker             // A virtual register kill refers to the whole register, so we may
409*9880d681SAndroid Build Coastguard Worker             // have to add <imp-use,kill> operands for the super-register.  A
410*9880d681SAndroid Build Coastguard Worker             // partial redef always kills and redefines the super-register.
411*9880d681SAndroid Build Coastguard Worker             if (MO.readsReg() && (MO.isDef() || MO.isKill()))
412*9880d681SAndroid Build Coastguard Worker               SuperKills.push_back(PhysReg);
413*9880d681SAndroid Build Coastguard Worker 
414*9880d681SAndroid Build Coastguard Worker             if (MO.isDef()) {
415*9880d681SAndroid Build Coastguard Worker               // Also add implicit defs for the super-register.
416*9880d681SAndroid Build Coastguard Worker               if (MO.isDead())
417*9880d681SAndroid Build Coastguard Worker                 SuperDeads.push_back(PhysReg);
418*9880d681SAndroid Build Coastguard Worker               else
419*9880d681SAndroid Build Coastguard Worker                 SuperDefs.push_back(PhysReg);
420*9880d681SAndroid Build Coastguard Worker             }
421*9880d681SAndroid Build Coastguard Worker           } else {
422*9880d681SAndroid Build Coastguard Worker             if (MO.isUse()) {
423*9880d681SAndroid Build Coastguard Worker               if (readsUndefSubreg(MO))
424*9880d681SAndroid Build Coastguard Worker                 // We need to add an <undef> flag if the subregister is
425*9880d681SAndroid Build Coastguard Worker                 // completely undefined (and we are not adding super-register
426*9880d681SAndroid Build Coastguard Worker                 // defs).
427*9880d681SAndroid Build Coastguard Worker                 MO.setIsUndef(true);
428*9880d681SAndroid Build Coastguard Worker             } else if (!MO.isDead()) {
429*9880d681SAndroid Build Coastguard Worker               assert(MO.isDef());
430*9880d681SAndroid Build Coastguard Worker             }
431*9880d681SAndroid Build Coastguard Worker           }
432*9880d681SAndroid Build Coastguard Worker 
433*9880d681SAndroid Build Coastguard Worker           // The <def,undef> flag only makes sense for sub-register defs, and
434*9880d681SAndroid Build Coastguard Worker           // we are substituting a full physreg.  An <imp-use,kill> operand
435*9880d681SAndroid Build Coastguard Worker           // from the SuperKills list will represent the partial read of the
436*9880d681SAndroid Build Coastguard Worker           // super-register.
437*9880d681SAndroid Build Coastguard Worker           if (MO.isDef())
438*9880d681SAndroid Build Coastguard Worker             MO.setIsUndef(false);
439*9880d681SAndroid Build Coastguard Worker 
440*9880d681SAndroid Build Coastguard Worker           // PhysReg operands cannot have subregister indexes.
441*9880d681SAndroid Build Coastguard Worker           PhysReg = TRI->getSubReg(PhysReg, SubReg);
442*9880d681SAndroid Build Coastguard Worker           assert(PhysReg && "Invalid SubReg for physical register");
443*9880d681SAndroid Build Coastguard Worker           MO.setSubReg(0);
444*9880d681SAndroid Build Coastguard Worker         }
445*9880d681SAndroid Build Coastguard Worker         // Rewrite. Note we could have used MachineOperand::substPhysReg(), but
446*9880d681SAndroid Build Coastguard Worker         // we need the inlining here.
447*9880d681SAndroid Build Coastguard Worker         MO.setReg(PhysReg);
448*9880d681SAndroid Build Coastguard Worker       }
449*9880d681SAndroid Build Coastguard Worker 
450*9880d681SAndroid Build Coastguard Worker       // Add any missing super-register kills after rewriting the whole
451*9880d681SAndroid Build Coastguard Worker       // instruction.
452*9880d681SAndroid Build Coastguard Worker       while (!SuperKills.empty())
453*9880d681SAndroid Build Coastguard Worker         MI->addRegisterKilled(SuperKills.pop_back_val(), TRI, true);
454*9880d681SAndroid Build Coastguard Worker 
455*9880d681SAndroid Build Coastguard Worker       while (!SuperDeads.empty())
456*9880d681SAndroid Build Coastguard Worker         MI->addRegisterDead(SuperDeads.pop_back_val(), TRI, true);
457*9880d681SAndroid Build Coastguard Worker 
458*9880d681SAndroid Build Coastguard Worker       while (!SuperDefs.empty())
459*9880d681SAndroid Build Coastguard Worker         MI->addRegisterDefined(SuperDefs.pop_back_val(), TRI);
460*9880d681SAndroid Build Coastguard Worker 
461*9880d681SAndroid Build Coastguard Worker       DEBUG(dbgs() << "> " << *MI);
462*9880d681SAndroid Build Coastguard Worker 
463*9880d681SAndroid Build Coastguard Worker       // We can remove identity copies right now.
464*9880d681SAndroid Build Coastguard Worker       handleIdentityCopy(*MI);
465*9880d681SAndroid Build Coastguard Worker     }
466*9880d681SAndroid Build Coastguard Worker   }
467*9880d681SAndroid Build Coastguard Worker }
468