1*8bcb0991SDimitry Andric //===---------- MIRVRegNamerUtils.cpp - MIR VReg Renaming Utilities -------===// 2*8bcb0991SDimitry Andric // 3*8bcb0991SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*8bcb0991SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 5*8bcb0991SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6*8bcb0991SDimitry Andric // 7*8bcb0991SDimitry Andric //===----------------------------------------------------------------------===// 8*8bcb0991SDimitry Andric 9*8bcb0991SDimitry Andric #include "MIRVRegNamerUtils.h" 10*8bcb0991SDimitry Andric #include "llvm/Support/Debug.h" 11*8bcb0991SDimitry Andric 12*8bcb0991SDimitry Andric using namespace llvm; 13*8bcb0991SDimitry Andric 14*8bcb0991SDimitry Andric #define DEBUG_TYPE "mir-vregnamer-utils" 15*8bcb0991SDimitry Andric 16*8bcb0991SDimitry Andric namespace { 17*8bcb0991SDimitry Andric 18*8bcb0991SDimitry Andric // TypedVReg and VRType are used to tell the renamer what to do at points in a 19*8bcb0991SDimitry Andric // sequence of values to be renamed. A TypedVReg can either contain 20*8bcb0991SDimitry Andric // an actual VReg, a FrameIndex, or it could just be a barrier for the next 21*8bcb0991SDimitry Andric // candidate (side-effecting instruction). This tells the renamer to increment 22*8bcb0991SDimitry Andric // to the next vreg name, or to skip modulo some skip-gap value. 23*8bcb0991SDimitry Andric enum VRType { RSE_Reg = 0, RSE_FrameIndex, RSE_NewCandidate }; 24*8bcb0991SDimitry Andric class TypedVReg { 25*8bcb0991SDimitry Andric VRType Type; 26*8bcb0991SDimitry Andric Register Reg; 27*8bcb0991SDimitry Andric 28*8bcb0991SDimitry Andric public: 29*8bcb0991SDimitry Andric TypedVReg(Register Reg) : Type(RSE_Reg), Reg(Reg) {} 30*8bcb0991SDimitry Andric TypedVReg(VRType Type) : Type(Type), Reg(~0U) { 31*8bcb0991SDimitry Andric assert(Type != RSE_Reg && "Expected a non-Register Type."); 32*8bcb0991SDimitry Andric } 33*8bcb0991SDimitry Andric 34*8bcb0991SDimitry Andric bool isReg() const { return Type == RSE_Reg; } 35*8bcb0991SDimitry Andric bool isFrameIndex() const { return Type == RSE_FrameIndex; } 36*8bcb0991SDimitry Andric bool isCandidate() const { return Type == RSE_NewCandidate; } 37*8bcb0991SDimitry Andric 38*8bcb0991SDimitry Andric VRType getType() const { return Type; } 39*8bcb0991SDimitry Andric Register getReg() const { 40*8bcb0991SDimitry Andric assert(this->isReg() && "Expected a virtual or physical Register."); 41*8bcb0991SDimitry Andric return Reg; 42*8bcb0991SDimitry Andric } 43*8bcb0991SDimitry Andric }; 44*8bcb0991SDimitry Andric 45*8bcb0991SDimitry Andric /// Here we find our candidates. What makes an interesting candidate? 46*8bcb0991SDimitry Andric /// A candidate for a canonicalization tree root is normally any kind of 47*8bcb0991SDimitry Andric /// instruction that causes side effects such as a store to memory or a copy to 48*8bcb0991SDimitry Andric /// a physical register or a return instruction. We use these as an expression 49*8bcb0991SDimitry Andric /// tree root that we walk in order to build a canonical walk which should 50*8bcb0991SDimitry Andric /// result in canonical vreg renaming. 51*8bcb0991SDimitry Andric std::vector<MachineInstr *> populateCandidates(MachineBasicBlock *MBB) { 52*8bcb0991SDimitry Andric std::vector<MachineInstr *> Candidates; 53*8bcb0991SDimitry Andric MachineRegisterInfo &MRI = MBB->getParent()->getRegInfo(); 54*8bcb0991SDimitry Andric 55*8bcb0991SDimitry Andric for (auto II = MBB->begin(), IE = MBB->end(); II != IE; ++II) { 56*8bcb0991SDimitry Andric MachineInstr *MI = &*II; 57*8bcb0991SDimitry Andric 58*8bcb0991SDimitry Andric bool DoesMISideEffect = false; 59*8bcb0991SDimitry Andric 60*8bcb0991SDimitry Andric if (MI->getNumOperands() > 0 && MI->getOperand(0).isReg()) { 61*8bcb0991SDimitry Andric const Register Dst = MI->getOperand(0).getReg(); 62*8bcb0991SDimitry Andric DoesMISideEffect |= !Register::isVirtualRegister(Dst); 63*8bcb0991SDimitry Andric 64*8bcb0991SDimitry Andric for (auto UI = MRI.use_begin(Dst); UI != MRI.use_end(); ++UI) { 65*8bcb0991SDimitry Andric if (DoesMISideEffect) 66*8bcb0991SDimitry Andric break; 67*8bcb0991SDimitry Andric DoesMISideEffect |= (UI->getParent()->getParent() != MI->getParent()); 68*8bcb0991SDimitry Andric } 69*8bcb0991SDimitry Andric } 70*8bcb0991SDimitry Andric 71*8bcb0991SDimitry Andric if (!MI->mayStore() && !MI->isBranch() && !DoesMISideEffect) 72*8bcb0991SDimitry Andric continue; 73*8bcb0991SDimitry Andric 74*8bcb0991SDimitry Andric LLVM_DEBUG(dbgs() << "Found Candidate: "; MI->dump();); 75*8bcb0991SDimitry Andric Candidates.push_back(MI); 76*8bcb0991SDimitry Andric } 77*8bcb0991SDimitry Andric 78*8bcb0991SDimitry Andric return Candidates; 79*8bcb0991SDimitry Andric } 80*8bcb0991SDimitry Andric 81*8bcb0991SDimitry Andric void doCandidateWalk(std::vector<TypedVReg> &VRegs, 82*8bcb0991SDimitry Andric std::queue<TypedVReg> &RegQueue, 83*8bcb0991SDimitry Andric std::vector<MachineInstr *> &VisitedMIs, 84*8bcb0991SDimitry Andric const MachineBasicBlock *MBB) { 85*8bcb0991SDimitry Andric 86*8bcb0991SDimitry Andric const MachineFunction &MF = *MBB->getParent(); 87*8bcb0991SDimitry Andric const MachineRegisterInfo &MRI = MF.getRegInfo(); 88*8bcb0991SDimitry Andric 89*8bcb0991SDimitry Andric while (!RegQueue.empty()) { 90*8bcb0991SDimitry Andric 91*8bcb0991SDimitry Andric auto TReg = RegQueue.front(); 92*8bcb0991SDimitry Andric RegQueue.pop(); 93*8bcb0991SDimitry Andric 94*8bcb0991SDimitry Andric if (TReg.isFrameIndex()) { 95*8bcb0991SDimitry Andric LLVM_DEBUG(dbgs() << "Popping frame index.\n";); 96*8bcb0991SDimitry Andric VRegs.push_back(TypedVReg(RSE_FrameIndex)); 97*8bcb0991SDimitry Andric continue; 98*8bcb0991SDimitry Andric } 99*8bcb0991SDimitry Andric 100*8bcb0991SDimitry Andric assert(TReg.isReg() && "Expected vreg or physreg."); 101*8bcb0991SDimitry Andric Register Reg = TReg.getReg(); 102*8bcb0991SDimitry Andric 103*8bcb0991SDimitry Andric if (Register::isVirtualRegister(Reg)) { 104*8bcb0991SDimitry Andric LLVM_DEBUG({ 105*8bcb0991SDimitry Andric dbgs() << "Popping vreg "; 106*8bcb0991SDimitry Andric MRI.def_begin(Reg)->dump(); 107*8bcb0991SDimitry Andric dbgs() << "\n"; 108*8bcb0991SDimitry Andric }); 109*8bcb0991SDimitry Andric 110*8bcb0991SDimitry Andric if (!llvm::any_of(VRegs, [&](const TypedVReg &TR) { 111*8bcb0991SDimitry Andric return TR.isReg() && TR.getReg() == Reg; 112*8bcb0991SDimitry Andric })) { 113*8bcb0991SDimitry Andric VRegs.push_back(TypedVReg(Reg)); 114*8bcb0991SDimitry Andric } 115*8bcb0991SDimitry Andric } else { 116*8bcb0991SDimitry Andric LLVM_DEBUG(dbgs() << "Popping physreg.\n";); 117*8bcb0991SDimitry Andric VRegs.push_back(TypedVReg(Reg)); 118*8bcb0991SDimitry Andric continue; 119*8bcb0991SDimitry Andric } 120*8bcb0991SDimitry Andric 121*8bcb0991SDimitry Andric for (auto RI = MRI.def_begin(Reg), RE = MRI.def_end(); RI != RE; ++RI) { 122*8bcb0991SDimitry Andric MachineInstr *Def = RI->getParent(); 123*8bcb0991SDimitry Andric 124*8bcb0991SDimitry Andric if (Def->getParent() != MBB) 125*8bcb0991SDimitry Andric continue; 126*8bcb0991SDimitry Andric 127*8bcb0991SDimitry Andric if (llvm::any_of(VisitedMIs, 128*8bcb0991SDimitry Andric [&](const MachineInstr *VMI) { return Def == VMI; })) { 129*8bcb0991SDimitry Andric break; 130*8bcb0991SDimitry Andric } 131*8bcb0991SDimitry Andric 132*8bcb0991SDimitry Andric LLVM_DEBUG({ 133*8bcb0991SDimitry Andric dbgs() << "\n========================\n"; 134*8bcb0991SDimitry Andric dbgs() << "Visited MI: "; 135*8bcb0991SDimitry Andric Def->dump(); 136*8bcb0991SDimitry Andric dbgs() << "BB Name: " << Def->getParent()->getName() << "\n"; 137*8bcb0991SDimitry Andric dbgs() << "\n========================\n"; 138*8bcb0991SDimitry Andric }); 139*8bcb0991SDimitry Andric VisitedMIs.push_back(Def); 140*8bcb0991SDimitry Andric for (unsigned I = 1, E = Def->getNumOperands(); I != E; ++I) { 141*8bcb0991SDimitry Andric 142*8bcb0991SDimitry Andric MachineOperand &MO = Def->getOperand(I); 143*8bcb0991SDimitry Andric if (MO.isFI()) { 144*8bcb0991SDimitry Andric LLVM_DEBUG(dbgs() << "Pushing frame index.\n";); 145*8bcb0991SDimitry Andric RegQueue.push(TypedVReg(RSE_FrameIndex)); 146*8bcb0991SDimitry Andric } 147*8bcb0991SDimitry Andric 148*8bcb0991SDimitry Andric if (!MO.isReg()) 149*8bcb0991SDimitry Andric continue; 150*8bcb0991SDimitry Andric RegQueue.push(TypedVReg(MO.getReg())); 151*8bcb0991SDimitry Andric } 152*8bcb0991SDimitry Andric } 153*8bcb0991SDimitry Andric } 154*8bcb0991SDimitry Andric } 155*8bcb0991SDimitry Andric 156*8bcb0991SDimitry Andric std::map<unsigned, unsigned> 157*8bcb0991SDimitry Andric getVRegRenameMap(const std::vector<TypedVReg> &VRegs, 158*8bcb0991SDimitry Andric const std::vector<Register> &renamedInOtherBB, 159*8bcb0991SDimitry Andric MachineRegisterInfo &MRI, NamedVRegCursor &NVC) { 160*8bcb0991SDimitry Andric std::map<unsigned, unsigned> VRegRenameMap; 161*8bcb0991SDimitry Andric bool FirstCandidate = true; 162*8bcb0991SDimitry Andric 163*8bcb0991SDimitry Andric for (auto &vreg : VRegs) { 164*8bcb0991SDimitry Andric if (vreg.isFrameIndex()) { 165*8bcb0991SDimitry Andric // We skip one vreg for any frame index because there is a good chance 166*8bcb0991SDimitry Andric // (especially when comparing SelectionDAG to GlobalISel generated MIR) 167*8bcb0991SDimitry Andric // that in the other file we are just getting an incoming vreg that comes 168*8bcb0991SDimitry Andric // from a copy from a frame index. So it's safe to skip by one. 169*8bcb0991SDimitry Andric unsigned LastRenameReg = NVC.incrementVirtualVReg(); 170*8bcb0991SDimitry Andric (void)LastRenameReg; 171*8bcb0991SDimitry Andric LLVM_DEBUG(dbgs() << "Skipping rename for FI " << LastRenameReg << "\n";); 172*8bcb0991SDimitry Andric continue; 173*8bcb0991SDimitry Andric } else if (vreg.isCandidate()) { 174*8bcb0991SDimitry Andric 175*8bcb0991SDimitry Andric // After the first candidate, for every subsequent candidate, we skip mod 176*8bcb0991SDimitry Andric // 10 registers so that the candidates are more likely to start at the 177*8bcb0991SDimitry Andric // same vreg number making it more likely that the canonical walk from the 178*8bcb0991SDimitry Andric // candidate insruction. We don't need to skip from the first candidate of 179*8bcb0991SDimitry Andric // the BasicBlock because we already skip ahead several vregs for each BB. 180*8bcb0991SDimitry Andric unsigned LastRenameReg = NVC.getVirtualVReg(); 181*8bcb0991SDimitry Andric if (FirstCandidate) 182*8bcb0991SDimitry Andric NVC.incrementVirtualVReg(LastRenameReg % 10); 183*8bcb0991SDimitry Andric FirstCandidate = false; 184*8bcb0991SDimitry Andric continue; 185*8bcb0991SDimitry Andric } else if (!Register::isVirtualRegister(vreg.getReg())) { 186*8bcb0991SDimitry Andric unsigned LastRenameReg = NVC.incrementVirtualVReg(); 187*8bcb0991SDimitry Andric (void)LastRenameReg; 188*8bcb0991SDimitry Andric LLVM_DEBUG({ 189*8bcb0991SDimitry Andric dbgs() << "Skipping rename for Phys Reg " << LastRenameReg << "\n"; 190*8bcb0991SDimitry Andric }); 191*8bcb0991SDimitry Andric continue; 192*8bcb0991SDimitry Andric } 193*8bcb0991SDimitry Andric 194*8bcb0991SDimitry Andric auto Reg = vreg.getReg(); 195*8bcb0991SDimitry Andric if (llvm::find(renamedInOtherBB, Reg) != renamedInOtherBB.end()) { 196*8bcb0991SDimitry Andric LLVM_DEBUG(dbgs() << "Vreg " << Reg 197*8bcb0991SDimitry Andric << " already renamed in other BB.\n";); 198*8bcb0991SDimitry Andric continue; 199*8bcb0991SDimitry Andric } 200*8bcb0991SDimitry Andric 201*8bcb0991SDimitry Andric auto Rename = NVC.createVirtualRegister(Reg); 202*8bcb0991SDimitry Andric 203*8bcb0991SDimitry Andric if (VRegRenameMap.find(Reg) == VRegRenameMap.end()) { 204*8bcb0991SDimitry Andric LLVM_DEBUG(dbgs() << "Mapping vreg ";); 205*8bcb0991SDimitry Andric if (MRI.reg_begin(Reg) != MRI.reg_end()) { 206*8bcb0991SDimitry Andric LLVM_DEBUG(auto foo = &*MRI.reg_begin(Reg); foo->dump();); 207*8bcb0991SDimitry Andric } else { 208*8bcb0991SDimitry Andric LLVM_DEBUG(dbgs() << Reg;); 209*8bcb0991SDimitry Andric } 210*8bcb0991SDimitry Andric LLVM_DEBUG(dbgs() << " to ";); 211*8bcb0991SDimitry Andric if (MRI.reg_begin(Rename) != MRI.reg_end()) { 212*8bcb0991SDimitry Andric LLVM_DEBUG(auto foo = &*MRI.reg_begin(Rename); foo->dump();); 213*8bcb0991SDimitry Andric } else { 214*8bcb0991SDimitry Andric LLVM_DEBUG(dbgs() << Rename;); 215*8bcb0991SDimitry Andric } 216*8bcb0991SDimitry Andric LLVM_DEBUG(dbgs() << "\n";); 217*8bcb0991SDimitry Andric 218*8bcb0991SDimitry Andric VRegRenameMap.insert(std::pair<unsigned, unsigned>(Reg, Rename)); 219*8bcb0991SDimitry Andric } 220*8bcb0991SDimitry Andric } 221*8bcb0991SDimitry Andric 222*8bcb0991SDimitry Andric return VRegRenameMap; 223*8bcb0991SDimitry Andric } 224*8bcb0991SDimitry Andric 225*8bcb0991SDimitry Andric bool doVRegRenaming(std::vector<Register> &renamedInOtherBB, 226*8bcb0991SDimitry Andric const std::map<unsigned, unsigned> &VRegRenameMap, 227*8bcb0991SDimitry Andric MachineRegisterInfo &MRI) { 228*8bcb0991SDimitry Andric bool Changed = false; 229*8bcb0991SDimitry Andric for (auto I = VRegRenameMap.begin(), E = VRegRenameMap.end(); I != E; ++I) { 230*8bcb0991SDimitry Andric 231*8bcb0991SDimitry Andric auto VReg = I->first; 232*8bcb0991SDimitry Andric auto Rename = I->second; 233*8bcb0991SDimitry Andric 234*8bcb0991SDimitry Andric renamedInOtherBB.push_back(Rename); 235*8bcb0991SDimitry Andric 236*8bcb0991SDimitry Andric std::vector<MachineOperand *> RenameMOs; 237*8bcb0991SDimitry Andric for (auto &MO : MRI.reg_operands(VReg)) { 238*8bcb0991SDimitry Andric RenameMOs.push_back(&MO); 239*8bcb0991SDimitry Andric } 240*8bcb0991SDimitry Andric 241*8bcb0991SDimitry Andric for (auto *MO : RenameMOs) { 242*8bcb0991SDimitry Andric Changed = true; 243*8bcb0991SDimitry Andric MO->setReg(Rename); 244*8bcb0991SDimitry Andric 245*8bcb0991SDimitry Andric if (!MO->isDef()) 246*8bcb0991SDimitry Andric MO->setIsKill(false); 247*8bcb0991SDimitry Andric } 248*8bcb0991SDimitry Andric } 249*8bcb0991SDimitry Andric 250*8bcb0991SDimitry Andric return Changed; 251*8bcb0991SDimitry Andric } 252*8bcb0991SDimitry Andric 253*8bcb0991SDimitry Andric bool renameVRegs(MachineBasicBlock *MBB, 254*8bcb0991SDimitry Andric std::vector<Register> &renamedInOtherBB, 255*8bcb0991SDimitry Andric NamedVRegCursor &NVC) { 256*8bcb0991SDimitry Andric bool Changed = false; 257*8bcb0991SDimitry Andric MachineFunction &MF = *MBB->getParent(); 258*8bcb0991SDimitry Andric MachineRegisterInfo &MRI = MF.getRegInfo(); 259*8bcb0991SDimitry Andric 260*8bcb0991SDimitry Andric std::vector<MachineInstr *> Candidates = populateCandidates(MBB); 261*8bcb0991SDimitry Andric std::vector<MachineInstr *> VisitedMIs; 262*8bcb0991SDimitry Andric llvm::copy(Candidates, std::back_inserter(VisitedMIs)); 263*8bcb0991SDimitry Andric 264*8bcb0991SDimitry Andric std::vector<TypedVReg> VRegs; 265*8bcb0991SDimitry Andric for (auto candidate : Candidates) { 266*8bcb0991SDimitry Andric VRegs.push_back(TypedVReg(RSE_NewCandidate)); 267*8bcb0991SDimitry Andric 268*8bcb0991SDimitry Andric std::queue<TypedVReg> RegQueue; 269*8bcb0991SDimitry Andric 270*8bcb0991SDimitry Andric // Here we walk the vreg operands of a non-root node along our walk. 271*8bcb0991SDimitry Andric // The root nodes are the original candidates (stores normally). 272*8bcb0991SDimitry Andric // These are normally not the root nodes (except for the case of copies to 273*8bcb0991SDimitry Andric // physical registers). 274*8bcb0991SDimitry Andric for (unsigned i = 1; i < candidate->getNumOperands(); i++) { 275*8bcb0991SDimitry Andric if (candidate->mayStore() || candidate->isBranch()) 276*8bcb0991SDimitry Andric break; 277*8bcb0991SDimitry Andric 278*8bcb0991SDimitry Andric MachineOperand &MO = candidate->getOperand(i); 279*8bcb0991SDimitry Andric if (!(MO.isReg() && Register::isVirtualRegister(MO.getReg()))) 280*8bcb0991SDimitry Andric continue; 281*8bcb0991SDimitry Andric 282*8bcb0991SDimitry Andric LLVM_DEBUG(dbgs() << "Enqueue register"; MO.dump(); dbgs() << "\n";); 283*8bcb0991SDimitry Andric RegQueue.push(TypedVReg(MO.getReg())); 284*8bcb0991SDimitry Andric } 285*8bcb0991SDimitry Andric 286*8bcb0991SDimitry Andric // Here we walk the root candidates. We start from the 0th operand because 287*8bcb0991SDimitry Andric // the root is normally a store to a vreg. 288*8bcb0991SDimitry Andric for (unsigned i = 0; i < candidate->getNumOperands(); i++) { 289*8bcb0991SDimitry Andric 290*8bcb0991SDimitry Andric if (!candidate->mayStore() && !candidate->isBranch()) 291*8bcb0991SDimitry Andric break; 292*8bcb0991SDimitry Andric 293*8bcb0991SDimitry Andric MachineOperand &MO = candidate->getOperand(i); 294*8bcb0991SDimitry Andric 295*8bcb0991SDimitry Andric // TODO: Do we want to only add vregs here? 296*8bcb0991SDimitry Andric if (!MO.isReg() && !MO.isFI()) 297*8bcb0991SDimitry Andric continue; 298*8bcb0991SDimitry Andric 299*8bcb0991SDimitry Andric LLVM_DEBUG(dbgs() << "Enqueue Reg/FI"; MO.dump(); dbgs() << "\n";); 300*8bcb0991SDimitry Andric 301*8bcb0991SDimitry Andric RegQueue.push(MO.isReg() ? TypedVReg(MO.getReg()) 302*8bcb0991SDimitry Andric : TypedVReg(RSE_FrameIndex)); 303*8bcb0991SDimitry Andric } 304*8bcb0991SDimitry Andric 305*8bcb0991SDimitry Andric doCandidateWalk(VRegs, RegQueue, VisitedMIs, MBB); 306*8bcb0991SDimitry Andric } 307*8bcb0991SDimitry Andric 308*8bcb0991SDimitry Andric // If we have populated no vregs to rename then bail. 309*8bcb0991SDimitry Andric // The rest of this function does the vreg remaping. 310*8bcb0991SDimitry Andric if (VRegs.size() == 0) 311*8bcb0991SDimitry Andric return Changed; 312*8bcb0991SDimitry Andric 313*8bcb0991SDimitry Andric auto VRegRenameMap = getVRegRenameMap(VRegs, renamedInOtherBB, MRI, NVC); 314*8bcb0991SDimitry Andric Changed |= doVRegRenaming(renamedInOtherBB, VRegRenameMap, MRI); 315*8bcb0991SDimitry Andric return Changed; 316*8bcb0991SDimitry Andric } 317*8bcb0991SDimitry Andric } // anonymous namespace 318*8bcb0991SDimitry Andric 319*8bcb0991SDimitry Andric void NamedVRegCursor::skipVRegs() { 320*8bcb0991SDimitry Andric unsigned VRegGapIndex = 1; 321*8bcb0991SDimitry Andric if (!virtualVRegNumber) { 322*8bcb0991SDimitry Andric VRegGapIndex = 0; 323*8bcb0991SDimitry Andric virtualVRegNumber = MRI.createIncompleteVirtualRegister(); 324*8bcb0991SDimitry Andric } 325*8bcb0991SDimitry Andric const unsigned VR_GAP = (++VRegGapIndex * SkipGapSize); 326*8bcb0991SDimitry Andric 327*8bcb0991SDimitry Andric unsigned I = virtualVRegNumber; 328*8bcb0991SDimitry Andric const unsigned E = (((I + VR_GAP) / VR_GAP) + 1) * VR_GAP; 329*8bcb0991SDimitry Andric 330*8bcb0991SDimitry Andric virtualVRegNumber = E; 331*8bcb0991SDimitry Andric } 332*8bcb0991SDimitry Andric 333*8bcb0991SDimitry Andric unsigned NamedVRegCursor::createVirtualRegister(unsigned VReg) { 334*8bcb0991SDimitry Andric if (!virtualVRegNumber) 335*8bcb0991SDimitry Andric skipVRegs(); 336*8bcb0991SDimitry Andric std::string S; 337*8bcb0991SDimitry Andric raw_string_ostream OS(S); 338*8bcb0991SDimitry Andric OS << "namedVReg" << (virtualVRegNumber & ~0x80000000); 339*8bcb0991SDimitry Andric OS.flush(); 340*8bcb0991SDimitry Andric virtualVRegNumber++; 341*8bcb0991SDimitry Andric if (auto RC = MRI.getRegClassOrNull(VReg)) 342*8bcb0991SDimitry Andric return MRI.createVirtualRegister(RC, OS.str()); 343*8bcb0991SDimitry Andric return MRI.createGenericVirtualRegister(MRI.getType(VReg), OS.str()); 344*8bcb0991SDimitry Andric } 345*8bcb0991SDimitry Andric 346*8bcb0991SDimitry Andric bool NamedVRegCursor::renameVRegs(MachineBasicBlock *MBB) { 347*8bcb0991SDimitry Andric return ::renameVRegs(MBB, RenamedInOtherBB, *this); 348*8bcb0991SDimitry Andric } 349