diff --git a/llvm/include/llvm/CodeGen/MachineRegisterInfo.h b/llvm/include/llvm/CodeGen/MachineRegisterInfo.h --- a/llvm/include/llvm/CodeGen/MachineRegisterInfo.h +++ b/llvm/include/llvm/CodeGen/MachineRegisterInfo.h @@ -140,6 +140,13 @@ /// Target-specific flags associated with a virtual register. IndexedMap VRegFlags; + /// Map a physical register into the virtual register it currently represents. + /// This field is relevant only during RegAllocFast and will be reset to zero + /// all other times. It is needed while spilling a physical register via the + /// target hooks. Targets might want to access the virtual register flags + /// (VRegFlags) during the spill insertion. + Register PhysRegToCurrentVReg; + /// Keep track of the physical registers that are live in to the function. /// Live in values are typically arguments in registers. LiveIn values are /// allowed to have virtual registers associated with them, stored in the @@ -764,6 +771,8 @@ /// Returns true if \p Flag is set for \p Reg bool checkFlag(Register Reg, uint8_t Flag) const; + void updatePhysRegToCurrentVReg(Register Reg) { PhysRegToCurrentVReg = Reg; } + /// Remove all types associated to virtual registers (after instruction /// selection and constraining of all generic virtual registers). void clearVirtRegTypes(); diff --git a/llvm/lib/CodeGen/LiveIntervals.cpp b/llvm/lib/CodeGen/LiveIntervals.cpp --- a/llvm/lib/CodeGen/LiveIntervals.cpp +++ b/llvm/lib/CodeGen/LiveIntervals.cpp @@ -1743,9 +1743,8 @@ return; LLVM_DEBUG(dbgs() << " Split " << NumComp << " components: " << LI << '\n'); Register Reg = LI.reg(); - const TargetRegisterClass *RegClass = MRI->getRegClass(Reg); for (unsigned I = 1; I < NumComp; ++I) { - Register NewVReg = MRI->createVirtualRegister(RegClass); + Register NewVReg = MRI->cloneVirtualRegister(Reg); LiveInterval &NewLI = createEmptyInterval(NewVReg); SplitLIs.push_back(&NewLI); } diff --git a/llvm/lib/CodeGen/LiveRangeEdit.cpp b/llvm/lib/CodeGen/LiveRangeEdit.cpp --- a/llvm/lib/CodeGen/LiveRangeEdit.cpp +++ b/llvm/lib/CodeGen/LiveRangeEdit.cpp @@ -32,7 +32,7 @@ LiveInterval &LiveRangeEdit::createEmptyIntervalFrom(Register OldReg, bool createSubRanges) { - Register VReg = MRI.createVirtualRegister(MRI.getRegClass(OldReg)); + Register VReg = MRI.cloneVirtualRegister(OldReg); if (VRM) VRM->setIsSplitFromReg(VReg, VRM->getOriginal(OldReg)); @@ -52,7 +52,7 @@ } Register LiveRangeEdit::createFrom(Register OldReg) { - Register VReg = MRI.createVirtualRegister(MRI.getRegClass(OldReg)); + Register VReg = MRI.cloneVirtualRegister(OldReg); if (VRM) { VRM->setIsSplitFromReg(VReg, VRM->getOriginal(OldReg)); } diff --git a/llvm/lib/CodeGen/MachineRegisterInfo.cpp b/llvm/lib/CodeGen/MachineRegisterInfo.cpp --- a/llvm/lib/CodeGen/MachineRegisterInfo.cpp +++ b/llvm/lib/CodeGen/MachineRegisterInfo.cpp @@ -195,7 +195,10 @@ if (Register::isVirtualRegister(Reg)) return VRegFlags.inBounds(Reg) && VRegFlags[Reg] & ((uint8_t)1 << Flag); - return false; + // If a physical register, map to the virtual register it was currently + // assigned for. + return PhysRegToCurrentVReg && + VRegFlags[PhysRegToCurrentVReg] & ((uint8_t)1 << Flag); } Register diff --git a/llvm/lib/CodeGen/RegAllocFast.cpp b/llvm/lib/CodeGen/RegAllocFast.cpp --- a/llvm/lib/CodeGen/RegAllocFast.cpp +++ b/llvm/lib/CodeGen/RegAllocFast.cpp @@ -434,6 +434,7 @@ int FI = getStackSpaceFor(VirtReg); LLVM_DEBUG(dbgs() << " to stack slot #" << FI << '\n'); + MRI->updatePhysRegToCurrentVReg(VirtReg); const TargetRegisterClass &RC = *MRI->getRegClass(VirtReg); TII->storeRegToStackSlot(*MBB, Before, AssignedReg, Kill, FI, &RC, TRI); ++NumStores; @@ -488,6 +489,7 @@ LLVM_DEBUG(dbgs() << "Reloading " << printReg(VirtReg, TRI) << " into " << printReg(PhysReg, TRI) << '\n'); int FI = getStackSpaceFor(VirtReg); + MRI->updatePhysRegToCurrentVReg(VirtReg); const TargetRegisterClass &RC = *MRI->getRegClass(VirtReg); TII->loadRegFromStackSlot(*MBB, Before, PhysReg, FI, &RC, TRI); ++NumLoads; @@ -1605,6 +1607,9 @@ MRI->clearVirtRegs(); } + // Invalidate the physreg to current virtreg mapping. + MRI->updatePhysRegToCurrentVReg(Register()); + StackSlotForVirtReg.clear(); LiveDbgValueMap.clear(); return true;