181ad6265SDimitry Andric //===-- GCNNSAReassign.cpp - Reassign registers in NSA instructions -------===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric // 90b57cec5SDimitry Andric /// \file 100b57cec5SDimitry Andric /// \brief Try to reassign registers on GFX10+ from non-sequential to sequential 1181ad6265SDimitry Andric /// in NSA image instructions. Later SIShrinkInstructions pass will replace NSA 120b57cec5SDimitry Andric /// with sequential versions where possible. 130b57cec5SDimitry Andric /// 140b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 150b57cec5SDimitry Andric 160b57cec5SDimitry Andric #include "AMDGPU.h" 17e8d8bef9SDimitry Andric #include "GCNSubtarget.h" 180b57cec5SDimitry Andric #include "SIMachineFunctionInfo.h" 1981ad6265SDimitry Andric #include "SIRegisterInfo.h" 200b57cec5SDimitry Andric #include "llvm/ADT/Statistic.h" 210b57cec5SDimitry Andric #include "llvm/CodeGen/LiveIntervals.h" 220b57cec5SDimitry Andric #include "llvm/CodeGen/LiveRegMatrix.h" 230b57cec5SDimitry Andric #include "llvm/CodeGen/MachineFunctionPass.h" 2481ad6265SDimitry Andric #include "llvm/CodeGen/VirtRegMap.h" 25480093f4SDimitry Andric #include "llvm/InitializePasses.h" 260b57cec5SDimitry Andric 270b57cec5SDimitry Andric using namespace llvm; 280b57cec5SDimitry Andric 290b57cec5SDimitry Andric #define DEBUG_TYPE "amdgpu-nsa-reassign" 300b57cec5SDimitry Andric 310b57cec5SDimitry Andric STATISTIC(NumNSAInstructions, 320b57cec5SDimitry Andric "Number of NSA instructions with non-sequential address found"); 330b57cec5SDimitry Andric STATISTIC(NumNSAConverted, 340b57cec5SDimitry Andric "Number of NSA instructions changed to sequential"); 350b57cec5SDimitry Andric 360b57cec5SDimitry Andric namespace { 370b57cec5SDimitry Andric 380b57cec5SDimitry Andric class GCNNSAReassign : public MachineFunctionPass { 390b57cec5SDimitry Andric public: 400b57cec5SDimitry Andric static char ID; 410b57cec5SDimitry Andric 420b57cec5SDimitry Andric GCNNSAReassign() : MachineFunctionPass(ID) { 430b57cec5SDimitry Andric initializeGCNNSAReassignPass(*PassRegistry::getPassRegistry()); 440b57cec5SDimitry Andric } 450b57cec5SDimitry Andric 460b57cec5SDimitry Andric bool runOnMachineFunction(MachineFunction &MF) override; 470b57cec5SDimitry Andric 480b57cec5SDimitry Andric StringRef getPassName() const override { return "GCN NSA Reassign"; } 490b57cec5SDimitry Andric 500b57cec5SDimitry Andric void getAnalysisUsage(AnalysisUsage &AU) const override { 51*0fca6ea1SDimitry Andric AU.addRequired<LiveIntervalsWrapperPass>(); 520b57cec5SDimitry Andric AU.addRequired<VirtRegMap>(); 530b57cec5SDimitry Andric AU.addRequired<LiveRegMatrix>(); 540b57cec5SDimitry Andric AU.setPreservesAll(); 550b57cec5SDimitry Andric MachineFunctionPass::getAnalysisUsage(AU); 560b57cec5SDimitry Andric } 570b57cec5SDimitry Andric 580b57cec5SDimitry Andric private: 59*0fca6ea1SDimitry Andric using NSA_Status = enum { 600b57cec5SDimitry Andric NOT_NSA, // Not an NSA instruction 610b57cec5SDimitry Andric FIXED, // NSA which we cannot modify 620b57cec5SDimitry Andric NON_CONTIGUOUS, // NSA with non-sequential address which we can try 630b57cec5SDimitry Andric // to optimize. 640b57cec5SDimitry Andric CONTIGUOUS // NSA with all sequential address registers 65*0fca6ea1SDimitry Andric }; 660b57cec5SDimitry Andric 670b57cec5SDimitry Andric const GCNSubtarget *ST; 680b57cec5SDimitry Andric 690b57cec5SDimitry Andric const MachineRegisterInfo *MRI; 700b57cec5SDimitry Andric 710b57cec5SDimitry Andric const SIRegisterInfo *TRI; 720b57cec5SDimitry Andric 730b57cec5SDimitry Andric VirtRegMap *VRM; 740b57cec5SDimitry Andric 750b57cec5SDimitry Andric LiveRegMatrix *LRM; 760b57cec5SDimitry Andric 770b57cec5SDimitry Andric LiveIntervals *LIS; 780b57cec5SDimitry Andric 790b57cec5SDimitry Andric unsigned MaxNumVGPRs; 800b57cec5SDimitry Andric 810b57cec5SDimitry Andric const MCPhysReg *CSRegs; 820b57cec5SDimitry Andric 830b57cec5SDimitry Andric NSA_Status CheckNSA(const MachineInstr &MI, bool Fast = false) const; 840b57cec5SDimitry Andric 850b57cec5SDimitry Andric bool tryAssignRegisters(SmallVectorImpl<LiveInterval *> &Intervals, 860b57cec5SDimitry Andric unsigned StartReg) const; 870b57cec5SDimitry Andric 880b57cec5SDimitry Andric bool canAssign(unsigned StartReg, unsigned NumRegs) const; 890b57cec5SDimitry Andric 900b57cec5SDimitry Andric bool scavengeRegs(SmallVectorImpl<LiveInterval *> &Intervals) const; 910b57cec5SDimitry Andric }; 920b57cec5SDimitry Andric 930b57cec5SDimitry Andric } // End anonymous namespace. 940b57cec5SDimitry Andric 950b57cec5SDimitry Andric INITIALIZE_PASS_BEGIN(GCNNSAReassign, DEBUG_TYPE, "GCN NSA Reassign", 960b57cec5SDimitry Andric false, false) 97*0fca6ea1SDimitry Andric INITIALIZE_PASS_DEPENDENCY(LiveIntervalsWrapperPass) 980b57cec5SDimitry Andric INITIALIZE_PASS_DEPENDENCY(VirtRegMap) 990b57cec5SDimitry Andric INITIALIZE_PASS_DEPENDENCY(LiveRegMatrix) 1000b57cec5SDimitry Andric INITIALIZE_PASS_END(GCNNSAReassign, DEBUG_TYPE, "GCN NSA Reassign", 1010b57cec5SDimitry Andric false, false) 1020b57cec5SDimitry Andric 1030b57cec5SDimitry Andric 1040b57cec5SDimitry Andric char GCNNSAReassign::ID = 0; 1050b57cec5SDimitry Andric 1060b57cec5SDimitry Andric char &llvm::GCNNSAReassignID = GCNNSAReassign::ID; 1070b57cec5SDimitry Andric 1080b57cec5SDimitry Andric bool 1090b57cec5SDimitry Andric GCNNSAReassign::tryAssignRegisters(SmallVectorImpl<LiveInterval *> &Intervals, 1100b57cec5SDimitry Andric unsigned StartReg) const { 1110b57cec5SDimitry Andric unsigned NumRegs = Intervals.size(); 1120b57cec5SDimitry Andric 1130b57cec5SDimitry Andric for (unsigned N = 0; N < NumRegs; ++N) 114e8d8bef9SDimitry Andric if (VRM->hasPhys(Intervals[N]->reg())) 1150b57cec5SDimitry Andric LRM->unassign(*Intervals[N]); 1160b57cec5SDimitry Andric 1170b57cec5SDimitry Andric for (unsigned N = 0; N < NumRegs; ++N) 118e8d8bef9SDimitry Andric if (LRM->checkInterference(*Intervals[N], MCRegister::from(StartReg + N))) 1190b57cec5SDimitry Andric return false; 1200b57cec5SDimitry Andric 1210b57cec5SDimitry Andric for (unsigned N = 0; N < NumRegs; ++N) 122e8d8bef9SDimitry Andric LRM->assign(*Intervals[N], MCRegister::from(StartReg + N)); 1230b57cec5SDimitry Andric 1240b57cec5SDimitry Andric return true; 1250b57cec5SDimitry Andric } 1260b57cec5SDimitry Andric 1270b57cec5SDimitry Andric bool GCNNSAReassign::canAssign(unsigned StartReg, unsigned NumRegs) const { 1280b57cec5SDimitry Andric for (unsigned N = 0; N < NumRegs; ++N) { 1290b57cec5SDimitry Andric unsigned Reg = StartReg + N; 1300b57cec5SDimitry Andric if (!MRI->isAllocatable(Reg)) 1310b57cec5SDimitry Andric return false; 1320b57cec5SDimitry Andric 1330b57cec5SDimitry Andric for (unsigned I = 0; CSRegs[I]; ++I) 1340b57cec5SDimitry Andric if (TRI->isSubRegisterEq(Reg, CSRegs[I]) && 1350b57cec5SDimitry Andric !LRM->isPhysRegUsed(CSRegs[I])) 1360b57cec5SDimitry Andric return false; 1370b57cec5SDimitry Andric } 1380b57cec5SDimitry Andric 1390b57cec5SDimitry Andric return true; 1400b57cec5SDimitry Andric } 1410b57cec5SDimitry Andric 1420b57cec5SDimitry Andric bool 1430b57cec5SDimitry Andric GCNNSAReassign::scavengeRegs(SmallVectorImpl<LiveInterval *> &Intervals) const { 1440b57cec5SDimitry Andric unsigned NumRegs = Intervals.size(); 1450b57cec5SDimitry Andric 1460b57cec5SDimitry Andric if (NumRegs > MaxNumVGPRs) 1470b57cec5SDimitry Andric return false; 1480b57cec5SDimitry Andric unsigned MaxReg = MaxNumVGPRs - NumRegs + AMDGPU::VGPR0; 1490b57cec5SDimitry Andric 1500b57cec5SDimitry Andric for (unsigned Reg = AMDGPU::VGPR0; Reg <= MaxReg; ++Reg) { 1510b57cec5SDimitry Andric if (!canAssign(Reg, NumRegs)) 1520b57cec5SDimitry Andric continue; 1530b57cec5SDimitry Andric 1540b57cec5SDimitry Andric if (tryAssignRegisters(Intervals, Reg)) 1550b57cec5SDimitry Andric return true; 1560b57cec5SDimitry Andric } 1570b57cec5SDimitry Andric 1580b57cec5SDimitry Andric return false; 1590b57cec5SDimitry Andric } 1600b57cec5SDimitry Andric 1610b57cec5SDimitry Andric GCNNSAReassign::NSA_Status 1620b57cec5SDimitry Andric GCNNSAReassign::CheckNSA(const MachineInstr &MI, bool Fast) const { 1630b57cec5SDimitry Andric const AMDGPU::MIMGInfo *Info = AMDGPU::getMIMGInfo(MI.getOpcode()); 16481ad6265SDimitry Andric if (!Info) 1650b57cec5SDimitry Andric return NSA_Status::NOT_NSA; 1660b57cec5SDimitry Andric 16781ad6265SDimitry Andric switch (Info->MIMGEncoding) { 16881ad6265SDimitry Andric case AMDGPU::MIMGEncGfx10NSA: 16981ad6265SDimitry Andric case AMDGPU::MIMGEncGfx11NSA: 17081ad6265SDimitry Andric break; 17181ad6265SDimitry Andric default: 17281ad6265SDimitry Andric return NSA_Status::NOT_NSA; 17381ad6265SDimitry Andric } 17481ad6265SDimitry Andric 1750b57cec5SDimitry Andric int VAddr0Idx = 1760b57cec5SDimitry Andric AMDGPU::getNamedOperandIdx(MI.getOpcode(), AMDGPU::OpName::vaddr0); 1770b57cec5SDimitry Andric 1780b57cec5SDimitry Andric unsigned VgprBase = 0; 1790b57cec5SDimitry Andric bool NSA = false; 18081ad6265SDimitry Andric for (unsigned I = 0; I < Info->VAddrOperands; ++I) { 1810b57cec5SDimitry Andric const MachineOperand &Op = MI.getOperand(VAddr0Idx + I); 1828bcb0991SDimitry Andric Register Reg = Op.getReg(); 183e8d8bef9SDimitry Andric if (Reg.isPhysical() || !VRM->isAssignedReg(Reg)) 1840b57cec5SDimitry Andric return NSA_Status::FIXED; 1850b57cec5SDimitry Andric 1868bcb0991SDimitry Andric Register PhysReg = VRM->getPhys(Reg); 1870b57cec5SDimitry Andric 1880b57cec5SDimitry Andric if (!Fast) { 1890b57cec5SDimitry Andric if (!PhysReg) 1900b57cec5SDimitry Andric return NSA_Status::FIXED; 1910b57cec5SDimitry Andric 19281ad6265SDimitry Andric // TODO: address the below limitation to handle GFX11 BVH instructions 1930b57cec5SDimitry Andric // Bail if address is not a VGPR32. That should be possible to extend the 1940b57cec5SDimitry Andric // optimization to work with subregs of a wider register tuples, but the 1950b57cec5SDimitry Andric // logic to find free registers will be much more complicated with much 1960b57cec5SDimitry Andric // less chances for success. That seems reasonable to assume that in most 1970b57cec5SDimitry Andric // cases a tuple is used because a vector variable contains different 19881ad6265SDimitry Andric // parts of an address and it is either already consecutive or cannot 1990b57cec5SDimitry Andric // be reassigned if not. If needed it is better to rely on register 2000b57cec5SDimitry Andric // coalescer to process such address tuples. 20181ad6265SDimitry Andric if (TRI->getRegSizeInBits(*MRI->getRegClass(Reg)) != 32 || Op.getSubReg()) 2020b57cec5SDimitry Andric return NSA_Status::FIXED; 2030b57cec5SDimitry Andric 204fe6060f1SDimitry Andric // InlineSpiller does not call LRM::assign() after an LI split leaving 205fe6060f1SDimitry Andric // it in an inconsistent state, so we cannot call LRM::unassign(). 206fe6060f1SDimitry Andric // See llvm bug #48911. 207fe6060f1SDimitry Andric // Skip reassign if a register has originated from such split. 208fe6060f1SDimitry Andric // FIXME: Remove the workaround when bug #48911 is fixed. 209fe6060f1SDimitry Andric if (VRM->getPreSplitReg(Reg)) 210fe6060f1SDimitry Andric return NSA_Status::FIXED; 211fe6060f1SDimitry Andric 2120b57cec5SDimitry Andric const MachineInstr *Def = MRI->getUniqueVRegDef(Reg); 2130b57cec5SDimitry Andric 2140b57cec5SDimitry Andric if (Def && Def->isCopy() && Def->getOperand(1).getReg() == PhysReg) 2150b57cec5SDimitry Andric return NSA_Status::FIXED; 2160b57cec5SDimitry Andric 2170b57cec5SDimitry Andric for (auto U : MRI->use_nodbg_operands(Reg)) { 2180b57cec5SDimitry Andric if (U.isImplicit()) 2190b57cec5SDimitry Andric return NSA_Status::FIXED; 2200b57cec5SDimitry Andric const MachineInstr *UseInst = U.getParent(); 2210b57cec5SDimitry Andric if (UseInst->isCopy() && UseInst->getOperand(0).getReg() == PhysReg) 2220b57cec5SDimitry Andric return NSA_Status::FIXED; 2230b57cec5SDimitry Andric } 2240b57cec5SDimitry Andric 2250b57cec5SDimitry Andric if (!LIS->hasInterval(Reg)) 2260b57cec5SDimitry Andric return NSA_Status::FIXED; 2270b57cec5SDimitry Andric } 2280b57cec5SDimitry Andric 2290b57cec5SDimitry Andric if (I == 0) 2300b57cec5SDimitry Andric VgprBase = PhysReg; 2310b57cec5SDimitry Andric else if (VgprBase + I != PhysReg) 2320b57cec5SDimitry Andric NSA = true; 2330b57cec5SDimitry Andric } 2340b57cec5SDimitry Andric 2350b57cec5SDimitry Andric return NSA ? NSA_Status::NON_CONTIGUOUS : NSA_Status::CONTIGUOUS; 2360b57cec5SDimitry Andric } 2370b57cec5SDimitry Andric 2380b57cec5SDimitry Andric bool GCNNSAReassign::runOnMachineFunction(MachineFunction &MF) { 2390b57cec5SDimitry Andric ST = &MF.getSubtarget<GCNSubtarget>(); 2407a6dacacSDimitry Andric if (!ST->hasNSAEncoding() || !ST->hasNonNSAEncoding()) 2410b57cec5SDimitry Andric return false; 2420b57cec5SDimitry Andric 2430b57cec5SDimitry Andric MRI = &MF.getRegInfo(); 2440b57cec5SDimitry Andric TRI = ST->getRegisterInfo(); 2450b57cec5SDimitry Andric VRM = &getAnalysis<VirtRegMap>(); 2460b57cec5SDimitry Andric LRM = &getAnalysis<LiveRegMatrix>(); 247*0fca6ea1SDimitry Andric LIS = &getAnalysis<LiveIntervalsWrapperPass>().getLIS(); 2480b57cec5SDimitry Andric 2490b57cec5SDimitry Andric const SIMachineFunctionInfo *MFI = MF.getInfo<SIMachineFunctionInfo>(); 2500b57cec5SDimitry Andric MaxNumVGPRs = ST->getMaxNumVGPRs(MF); 2510b57cec5SDimitry Andric MaxNumVGPRs = std::min(ST->getMaxNumVGPRs(MFI->getOccupancy()), MaxNumVGPRs); 2520b57cec5SDimitry Andric CSRegs = MRI->getCalleeSavedRegs(); 2530b57cec5SDimitry Andric 2540b57cec5SDimitry Andric using Candidate = std::pair<const MachineInstr*, bool>; 2550b57cec5SDimitry Andric SmallVector<Candidate, 32> Candidates; 2560b57cec5SDimitry Andric for (const MachineBasicBlock &MBB : MF) { 2570b57cec5SDimitry Andric for (const MachineInstr &MI : MBB) { 2580b57cec5SDimitry Andric switch (CheckNSA(MI)) { 2590b57cec5SDimitry Andric default: 2600b57cec5SDimitry Andric continue; 2610b57cec5SDimitry Andric case NSA_Status::CONTIGUOUS: 262bdd1243dSDimitry Andric Candidates.push_back(std::pair(&MI, true)); 2630b57cec5SDimitry Andric break; 2640b57cec5SDimitry Andric case NSA_Status::NON_CONTIGUOUS: 265bdd1243dSDimitry Andric Candidates.push_back(std::pair(&MI, false)); 2660b57cec5SDimitry Andric ++NumNSAInstructions; 2670b57cec5SDimitry Andric break; 2680b57cec5SDimitry Andric } 2690b57cec5SDimitry Andric } 2700b57cec5SDimitry Andric } 2710b57cec5SDimitry Andric 2720b57cec5SDimitry Andric bool Changed = false; 2730b57cec5SDimitry Andric for (auto &C : Candidates) { 2740b57cec5SDimitry Andric if (C.second) 2750b57cec5SDimitry Andric continue; 2760b57cec5SDimitry Andric 2770b57cec5SDimitry Andric const MachineInstr *MI = C.first; 2780b57cec5SDimitry Andric if (CheckNSA(*MI, true) == NSA_Status::CONTIGUOUS) { 2790b57cec5SDimitry Andric // Already happen to be fixed. 2800b57cec5SDimitry Andric C.second = true; 2810b57cec5SDimitry Andric ++NumNSAConverted; 2820b57cec5SDimitry Andric continue; 2830b57cec5SDimitry Andric } 2840b57cec5SDimitry Andric 2850b57cec5SDimitry Andric const AMDGPU::MIMGInfo *Info = AMDGPU::getMIMGInfo(MI->getOpcode()); 2860b57cec5SDimitry Andric int VAddr0Idx = 2870b57cec5SDimitry Andric AMDGPU::getNamedOperandIdx(MI->getOpcode(), AMDGPU::OpName::vaddr0); 2880b57cec5SDimitry Andric 2890b57cec5SDimitry Andric SmallVector<LiveInterval *, 16> Intervals; 290e8d8bef9SDimitry Andric SmallVector<MCRegister, 16> OrigRegs; 2910b57cec5SDimitry Andric SlotIndex MinInd, MaxInd; 29281ad6265SDimitry Andric for (unsigned I = 0; I < Info->VAddrOperands; ++I) { 2930b57cec5SDimitry Andric const MachineOperand &Op = MI->getOperand(VAddr0Idx + I); 2948bcb0991SDimitry Andric Register Reg = Op.getReg(); 2950b57cec5SDimitry Andric LiveInterval *LI = &LIS->getInterval(Reg); 296e8d8bef9SDimitry Andric if (llvm::is_contained(Intervals, LI)) { 2970b57cec5SDimitry Andric // Same register used, unable to make sequential 2980b57cec5SDimitry Andric Intervals.clear(); 2990b57cec5SDimitry Andric break; 3000b57cec5SDimitry Andric } 3010b57cec5SDimitry Andric Intervals.push_back(LI); 3020b57cec5SDimitry Andric OrigRegs.push_back(VRM->getPhys(Reg)); 3035ffd83dbSDimitry Andric if (LI->empty()) { 3045ffd83dbSDimitry Andric // The address input is undef, so it doesn't contribute to the relevant 3055ffd83dbSDimitry Andric // range. Seed a reasonable index range if required. 3065ffd83dbSDimitry Andric if (I == 0) 3075ffd83dbSDimitry Andric MinInd = MaxInd = LIS->getInstructionIndex(*MI); 3085ffd83dbSDimitry Andric continue; 3095ffd83dbSDimitry Andric } 3105ffd83dbSDimitry Andric MinInd = I != 0 ? std::min(MinInd, LI->beginIndex()) : LI->beginIndex(); 3115ffd83dbSDimitry Andric MaxInd = I != 0 ? std::max(MaxInd, LI->endIndex()) : LI->endIndex(); 3120b57cec5SDimitry Andric } 3130b57cec5SDimitry Andric 3140b57cec5SDimitry Andric if (Intervals.empty()) 3150b57cec5SDimitry Andric continue; 3160b57cec5SDimitry Andric 3170b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "Attempting to reassign NSA: " << *MI 3180b57cec5SDimitry Andric << "\tOriginal allocation:\t"; 319e8d8bef9SDimitry Andric for (auto *LI 320e8d8bef9SDimitry Andric : Intervals) dbgs() 321e8d8bef9SDimitry Andric << " " << llvm::printReg((VRM->getPhys(LI->reg())), TRI); 3220b57cec5SDimitry Andric dbgs() << '\n'); 3230b57cec5SDimitry Andric 3240b57cec5SDimitry Andric bool Success = scavengeRegs(Intervals); 3250b57cec5SDimitry Andric if (!Success) { 3260b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "\tCannot reallocate.\n"); 327e8d8bef9SDimitry Andric if (VRM->hasPhys(Intervals.back()->reg())) // Did not change allocation. 3280b57cec5SDimitry Andric continue; 3290b57cec5SDimitry Andric } else { 3300b57cec5SDimitry Andric // Check we did not make it worse for other instructions. 3310b57cec5SDimitry Andric auto I = std::lower_bound(Candidates.begin(), &C, MinInd, 3320b57cec5SDimitry Andric [this](const Candidate &C, SlotIndex I) { 3330b57cec5SDimitry Andric return LIS->getInstructionIndex(*C.first) < I; 3340b57cec5SDimitry Andric }); 3350b57cec5SDimitry Andric for (auto E = Candidates.end(); Success && I != E && 3360b57cec5SDimitry Andric LIS->getInstructionIndex(*I->first) < MaxInd; ++I) { 3370b57cec5SDimitry Andric if (I->second && CheckNSA(*I->first, true) < NSA_Status::CONTIGUOUS) { 3380b57cec5SDimitry Andric Success = false; 3390b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "\tNSA conversion conflict with " << *I->first); 3400b57cec5SDimitry Andric } 3410b57cec5SDimitry Andric } 3420b57cec5SDimitry Andric } 3430b57cec5SDimitry Andric 3440b57cec5SDimitry Andric if (!Success) { 34581ad6265SDimitry Andric for (unsigned I = 0; I < Info->VAddrOperands; ++I) 346e8d8bef9SDimitry Andric if (VRM->hasPhys(Intervals[I]->reg())) 3470b57cec5SDimitry Andric LRM->unassign(*Intervals[I]); 3480b57cec5SDimitry Andric 34981ad6265SDimitry Andric for (unsigned I = 0; I < Info->VAddrOperands; ++I) 3500b57cec5SDimitry Andric LRM->assign(*Intervals[I], OrigRegs[I]); 3510b57cec5SDimitry Andric 3520b57cec5SDimitry Andric continue; 3530b57cec5SDimitry Andric } 3540b57cec5SDimitry Andric 3550b57cec5SDimitry Andric C.second = true; 3560b57cec5SDimitry Andric ++NumNSAConverted; 357e8d8bef9SDimitry Andric LLVM_DEBUG( 358e8d8bef9SDimitry Andric dbgs() << "\tNew allocation:\t\t [" 359e8d8bef9SDimitry Andric << llvm::printReg((VRM->getPhys(Intervals.front()->reg())), TRI) 3600b57cec5SDimitry Andric << " : " 361e8d8bef9SDimitry Andric << llvm::printReg((VRM->getPhys(Intervals.back()->reg())), TRI) 3620b57cec5SDimitry Andric << "]\n"); 3630b57cec5SDimitry Andric Changed = true; 3640b57cec5SDimitry Andric } 3650b57cec5SDimitry Andric 3660b57cec5SDimitry Andric return Changed; 3670b57cec5SDimitry Andric } 368