17a7e6055SDimitry Andric //===- lib/Codegen/MachineRegisterInfo.cpp --------------------------------===//
2f22ef01cSRoman Divacky //
3f22ef01cSRoman Divacky //                     The LLVM Compiler Infrastructure
4f22ef01cSRoman Divacky //
5f22ef01cSRoman Divacky // This file is distributed under the University of Illinois Open Source
6f22ef01cSRoman Divacky // License. See LICENSE.TXT for details.
7f22ef01cSRoman Divacky //
8f22ef01cSRoman Divacky //===----------------------------------------------------------------------===//
9f22ef01cSRoman Divacky //
10f22ef01cSRoman Divacky // Implementation of the MachineRegisterInfo class.
11f22ef01cSRoman Divacky //
12f22ef01cSRoman Divacky //===----------------------------------------------------------------------===//
13f22ef01cSRoman Divacky 
14db17bf38SDimitry Andric #include "llvm/CodeGen/MachineRegisterInfo.h"
157a7e6055SDimitry Andric #include "llvm/ADT/iterator_range.h"
167a7e6055SDimitry Andric #include "llvm/CodeGen/LowLevelType.h"
177a7e6055SDimitry Andric #include "llvm/CodeGen/MachineBasicBlock.h"
187a7e6055SDimitry Andric #include "llvm/CodeGen/MachineFunction.h"
197a7e6055SDimitry Andric #include "llvm/CodeGen/MachineInstr.h"
20f22ef01cSRoman Divacky #include "llvm/CodeGen/MachineInstrBuilder.h"
217a7e6055SDimitry Andric #include "llvm/CodeGen/MachineOperand.h"
222cab237bSDimitry Andric #include "llvm/CodeGen/TargetInstrInfo.h"
232cab237bSDimitry Andric #include "llvm/CodeGen/TargetRegisterInfo.h"
242cab237bSDimitry Andric #include "llvm/CodeGen/TargetSubtargetInfo.h"
254ba319b5SDimitry Andric #include "llvm/Config/llvm-config.h"
267a7e6055SDimitry Andric #include "llvm/IR/Attributes.h"
277a7e6055SDimitry Andric #include "llvm/IR/DebugLoc.h"
28875ed548SDimitry Andric #include "llvm/IR/Function.h"
297a7e6055SDimitry Andric #include "llvm/MC/MCRegisterInfo.h"
307a7e6055SDimitry Andric #include "llvm/Support/Casting.h"
317a7e6055SDimitry Andric #include "llvm/Support/CommandLine.h"
327a7e6055SDimitry Andric #include "llvm/Support/Compiler.h"
337a7e6055SDimitry Andric #include "llvm/Support/ErrorHandling.h"
347a7e6055SDimitry Andric #include "llvm/Support/raw_ostream.h"
357a7e6055SDimitry Andric #include <cassert>
36284c1978SDimitry Andric 
37f22ef01cSRoman Divacky using namespace llvm;
38f22ef01cSRoman Divacky 
39d88c1a5aSDimitry Andric static cl::opt<bool> EnableSubRegLiveness("enable-subreg-liveness", cl::Hidden,
40d88c1a5aSDimitry Andric   cl::init(true), cl::desc("Enable subregister liveness tracking."));
41d88c1a5aSDimitry Andric 
42f785676fSDimitry Andric // Pin the vtable to this file.
anchor()43f785676fSDimitry Andric void MachineRegisterInfo::Delegate::anchor() {}
44f785676fSDimitry Andric 
MachineRegisterInfo(MachineFunction * MF)453ca95b02SDimitry Andric MachineRegisterInfo::MachineRegisterInfo(MachineFunction *MF)
467a7e6055SDimitry Andric     : MF(MF), TracksSubRegLiveness(MF->getSubtarget().enableSubRegLiveness() &&
477a7e6055SDimitry Andric                                    EnableSubRegLiveness),
487a7e6055SDimitry Andric       IsUpdatedCSRsInitialized(false) {
497d523365SDimitry Andric   unsigned NumRegs = getTargetRegisterInfo()->getNumRegs();
50f22ef01cSRoman Divacky   VRegInfo.reserve(256);
51f22ef01cSRoman Divacky   RegAllocHints.reserve(256);
527d523365SDimitry Andric   UsedPhysRegMask.resize(NumRegs);
537d523365SDimitry Andric   PhysRegUseDefLists.reset(new MachineOperand*[NumRegs]());
54f22ef01cSRoman Divacky }
55f22ef01cSRoman Divacky 
56f22ef01cSRoman Divacky /// setRegClass - Set the register class of the specified virtual register.
57f22ef01cSRoman Divacky ///
58f22ef01cSRoman Divacky void
setRegClass(unsigned Reg,const TargetRegisterClass * RC)59f22ef01cSRoman Divacky MachineRegisterInfo::setRegClass(unsigned Reg, const TargetRegisterClass *RC) {
60139f7f9bSDimitry Andric   assert(RC && RC->isAllocatable() && "Invalid RC for virtual register");
61f22ef01cSRoman Divacky   VRegInfo[Reg].first = RC;
622754fe60SDimitry Andric }
632754fe60SDimitry Andric 
setRegBank(unsigned Reg,const RegisterBank & RegBank)643ca95b02SDimitry Andric void MachineRegisterInfo::setRegBank(unsigned Reg,
653ca95b02SDimitry Andric                                      const RegisterBank &RegBank) {
663ca95b02SDimitry Andric   VRegInfo[Reg].first = &RegBank;
673ca95b02SDimitry Andric }
683ca95b02SDimitry Andric 
694ba319b5SDimitry Andric static const TargetRegisterClass *
constrainRegClass(MachineRegisterInfo & MRI,unsigned Reg,const TargetRegisterClass * OldRC,const TargetRegisterClass * RC,unsigned MinNumRegs)704ba319b5SDimitry Andric constrainRegClass(MachineRegisterInfo &MRI, unsigned Reg,
714ba319b5SDimitry Andric                   const TargetRegisterClass *OldRC,
724ba319b5SDimitry Andric                   const TargetRegisterClass *RC, unsigned MinNumRegs) {
732754fe60SDimitry Andric   if (OldRC == RC)
742754fe60SDimitry Andric     return RC;
75f785676fSDimitry Andric   const TargetRegisterClass *NewRC =
764ba319b5SDimitry Andric       MRI.getTargetRegisterInfo()->getCommonSubClass(OldRC, RC);
776122f3e6SDimitry Andric   if (!NewRC || NewRC == OldRC)
786122f3e6SDimitry Andric     return NewRC;
796122f3e6SDimitry Andric   if (NewRC->getNumRegs() < MinNumRegs)
8091bc56edSDimitry Andric     return nullptr;
814ba319b5SDimitry Andric   MRI.setRegClass(Reg, NewRC);
822754fe60SDimitry Andric   return NewRC;
83f22ef01cSRoman Divacky }
84f22ef01cSRoman Divacky 
854ba319b5SDimitry Andric const TargetRegisterClass *
constrainRegClass(unsigned Reg,const TargetRegisterClass * RC,unsigned MinNumRegs)864ba319b5SDimitry Andric MachineRegisterInfo::constrainRegClass(unsigned Reg,
874ba319b5SDimitry Andric                                        const TargetRegisterClass *RC,
884ba319b5SDimitry Andric                                        unsigned MinNumRegs) {
894ba319b5SDimitry Andric   return ::constrainRegClass(*this, Reg, getRegClass(Reg), RC, MinNumRegs);
904ba319b5SDimitry Andric }
914ba319b5SDimitry Andric 
924ba319b5SDimitry Andric bool
constrainRegAttrs(unsigned Reg,unsigned ConstrainingReg,unsigned MinNumRegs)934ba319b5SDimitry Andric MachineRegisterInfo::constrainRegAttrs(unsigned Reg,
944ba319b5SDimitry Andric                                        unsigned ConstrainingReg,
954ba319b5SDimitry Andric                                        unsigned MinNumRegs) {
96*b5893f02SDimitry Andric   const LLT RegTy = getType(Reg);
97*b5893f02SDimitry Andric   const LLT ConstrainingRegTy = getType(ConstrainingReg);
98*b5893f02SDimitry Andric   if (RegTy.isValid() && ConstrainingRegTy.isValid() &&
99*b5893f02SDimitry Andric       RegTy != ConstrainingRegTy)
1004ba319b5SDimitry Andric     return false;
101*b5893f02SDimitry Andric   const auto ConstrainingRegCB = getRegClassOrRegBank(ConstrainingReg);
102*b5893f02SDimitry Andric   if (!ConstrainingRegCB.isNull()) {
103*b5893f02SDimitry Andric     const auto RegCB = getRegClassOrRegBank(Reg);
104*b5893f02SDimitry Andric     if (RegCB.isNull())
105*b5893f02SDimitry Andric       setRegClassOrRegBank(Reg, ConstrainingRegCB);
106*b5893f02SDimitry Andric     else if (RegCB.is<const TargetRegisterClass *>() !=
107*b5893f02SDimitry Andric              ConstrainingRegCB.is<const TargetRegisterClass *>())
1084ba319b5SDimitry Andric       return false;
109*b5893f02SDimitry Andric     else if (RegCB.is<const TargetRegisterClass *>()) {
110*b5893f02SDimitry Andric       if (!::constrainRegClass(
111*b5893f02SDimitry Andric               *this, Reg, RegCB.get<const TargetRegisterClass *>(),
112*b5893f02SDimitry Andric               ConstrainingRegCB.get<const TargetRegisterClass *>(), MinNumRegs))
113*b5893f02SDimitry Andric         return false;
114*b5893f02SDimitry Andric     } else if (RegCB != ConstrainingRegCB)
115*b5893f02SDimitry Andric       return false;
116*b5893f02SDimitry Andric   }
117*b5893f02SDimitry Andric   if (ConstrainingRegTy.isValid())
118*b5893f02SDimitry Andric     setType(Reg, ConstrainingRegTy);
1194ba319b5SDimitry Andric   return true;
1204ba319b5SDimitry Andric }
1214ba319b5SDimitry Andric 
1226122f3e6SDimitry Andric bool
recomputeRegClass(unsigned Reg)123ff0cc061SDimitry Andric MachineRegisterInfo::recomputeRegClass(unsigned Reg) {
124ff0cc061SDimitry Andric   const TargetInstrInfo *TII = MF->getSubtarget().getInstrInfo();
1256122f3e6SDimitry Andric   const TargetRegisterClass *OldRC = getRegClass(Reg);
126f785676fSDimitry Andric   const TargetRegisterClass *NewRC =
127ff0cc061SDimitry Andric       getTargetRegisterInfo()->getLargestLegalSuperClass(OldRC, *MF);
1286122f3e6SDimitry Andric 
1296122f3e6SDimitry Andric   // Stop early if there is no room to grow.
1306122f3e6SDimitry Andric   if (NewRC == OldRC)
1316122f3e6SDimitry Andric     return false;
1326122f3e6SDimitry Andric 
1336122f3e6SDimitry Andric   // Accumulate constraints from all uses.
13491bc56edSDimitry Andric   for (MachineOperand &MO : reg_nodbg_operands(Reg)) {
13591bc56edSDimitry Andric     // Apply the effect of the given operand to NewRC.
13691bc56edSDimitry Andric     MachineInstr *MI = MO.getParent();
13791bc56edSDimitry Andric     unsigned OpNo = &MO - &MI->getOperand(0);
13891bc56edSDimitry Andric     NewRC = MI->getRegClassConstraintEffect(OpNo, NewRC, TII,
139f785676fSDimitry Andric                                             getTargetRegisterInfo());
1406122f3e6SDimitry Andric     if (!NewRC || NewRC == OldRC)
1416122f3e6SDimitry Andric       return false;
1426122f3e6SDimitry Andric   }
1436122f3e6SDimitry Andric   setRegClass(Reg, NewRC);
1446122f3e6SDimitry Andric   return true;
1456122f3e6SDimitry Andric }
1466122f3e6SDimitry Andric 
createIncompleteVirtualRegister(StringRef Name)1474ba319b5SDimitry Andric unsigned MachineRegisterInfo::createIncompleteVirtualRegister(StringRef Name) {
148d88c1a5aSDimitry Andric   unsigned Reg = TargetRegisterInfo::index2VirtReg(getNumVirtRegs());
149d88c1a5aSDimitry Andric   VRegInfo.grow(Reg);
150d88c1a5aSDimitry Andric   RegAllocHints.grow(Reg);
1514ba319b5SDimitry Andric   insertVRegByName(Name, Reg);
152d88c1a5aSDimitry Andric   return Reg;
153d88c1a5aSDimitry Andric }
154d88c1a5aSDimitry Andric 
155f22ef01cSRoman Divacky /// createVirtualRegister - Create and return a new virtual register in the
156f22ef01cSRoman Divacky /// function with the specified register class.
157f22ef01cSRoman Divacky ///
158f22ef01cSRoman Divacky unsigned
createVirtualRegister(const TargetRegisterClass * RegClass,StringRef Name)1594ba319b5SDimitry Andric MachineRegisterInfo::createVirtualRegister(const TargetRegisterClass *RegClass,
1604ba319b5SDimitry Andric                                            StringRef Name) {
161f22ef01cSRoman Divacky   assert(RegClass && "Cannot create register without RegClass!");
162bd5abe19SDimitry Andric   assert(RegClass->isAllocatable() &&
163bd5abe19SDimitry Andric          "Virtual register RegClass must be allocatable.");
164f22ef01cSRoman Divacky 
1652754fe60SDimitry Andric   // New virtual register number.
1664ba319b5SDimitry Andric   unsigned Reg = createIncompleteVirtualRegister(Name);
1672754fe60SDimitry Andric   VRegInfo[Reg].first = RegClass;
168f785676fSDimitry Andric   if (TheDelegate)
169f785676fSDimitry Andric     TheDelegate->MRI_NoteNewVirtualRegister(Reg);
1702754fe60SDimitry Andric   return Reg;
171f22ef01cSRoman Divacky }
172f22ef01cSRoman Divacky 
cloneVirtualRegister(unsigned VReg,StringRef Name)173*b5893f02SDimitry Andric unsigned MachineRegisterInfo::cloneVirtualRegister(unsigned VReg,
174*b5893f02SDimitry Andric                                                    StringRef Name) {
175*b5893f02SDimitry Andric   unsigned Reg = createIncompleteVirtualRegister(Name);
176*b5893f02SDimitry Andric   VRegInfo[Reg].first = VRegInfo[VReg].first;
177*b5893f02SDimitry Andric   setType(Reg, getType(VReg));
178*b5893f02SDimitry Andric   if (TheDelegate)
179*b5893f02SDimitry Andric     TheDelegate->MRI_NoteNewVirtualRegister(Reg);
180*b5893f02SDimitry Andric   return Reg;
181*b5893f02SDimitry Andric }
182*b5893f02SDimitry Andric 
setType(unsigned VReg,LLT Ty)183d88c1a5aSDimitry Andric void MachineRegisterInfo::setType(unsigned VReg, LLT Ty) {
1844ba319b5SDimitry Andric   VRegToType.grow(VReg);
1854ba319b5SDimitry Andric   VRegToType[VReg] = Ty;
1863ca95b02SDimitry Andric }
1873ca95b02SDimitry Andric 
1883ca95b02SDimitry Andric unsigned
createGenericVirtualRegister(LLT Ty,StringRef Name)1894ba319b5SDimitry Andric MachineRegisterInfo::createGenericVirtualRegister(LLT Ty, StringRef Name) {
1903ca95b02SDimitry Andric   // New virtual register number.
1914ba319b5SDimitry Andric   unsigned Reg = createIncompleteVirtualRegister(Name);
1923ca95b02SDimitry Andric   // FIXME: Should we use a dummy register class?
193d88c1a5aSDimitry Andric   VRegInfo[Reg].first = static_cast<RegisterBank *>(nullptr);
1944ba319b5SDimitry Andric   setType(Reg, Ty);
1953ca95b02SDimitry Andric   if (TheDelegate)
1963ca95b02SDimitry Andric     TheDelegate->MRI_NoteNewVirtualRegister(Reg);
1973ca95b02SDimitry Andric   return Reg;
1983ca95b02SDimitry Andric }
1993ca95b02SDimitry Andric 
clearVirtRegTypes()2004ba319b5SDimitry Andric void MachineRegisterInfo::clearVirtRegTypes() { VRegToType.clear(); }
201d88c1a5aSDimitry Andric 
202dff0c46cSDimitry Andric /// clearVirtRegs - Remove all virtual registers (after physreg assignment).
clearVirtRegs()203dff0c46cSDimitry Andric void MachineRegisterInfo::clearVirtRegs() {
204dff0c46cSDimitry Andric #ifndef NDEBUG
205284c1978SDimitry Andric   for (unsigned i = 0, e = getNumVirtRegs(); i != e; ++i) {
206284c1978SDimitry Andric     unsigned Reg = TargetRegisterInfo::index2VirtReg(i);
207284c1978SDimitry Andric     if (!VRegInfo[Reg].second)
208284c1978SDimitry Andric       continue;
209284c1978SDimitry Andric     verifyUseList(Reg);
210284c1978SDimitry Andric     llvm_unreachable("Remaining virtual register operands");
211284c1978SDimitry Andric   }
212dff0c46cSDimitry Andric #endif
213dff0c46cSDimitry Andric   VRegInfo.clear();
2147d523365SDimitry Andric   for (auto &I : LiveIns)
2157d523365SDimitry Andric     I.second = 0;
216dff0c46cSDimitry Andric }
217dff0c46cSDimitry Andric 
verifyUseList(unsigned Reg) const218284c1978SDimitry Andric void MachineRegisterInfo::verifyUseList(unsigned Reg) const {
219284c1978SDimitry Andric #ifndef NDEBUG
220284c1978SDimitry Andric   bool Valid = true;
22191bc56edSDimitry Andric   for (MachineOperand &M : reg_operands(Reg)) {
22291bc56edSDimitry Andric     MachineOperand *MO = &M;
223284c1978SDimitry Andric     MachineInstr *MI = MO->getParent();
224284c1978SDimitry Andric     if (!MI) {
2252cab237bSDimitry Andric       errs() << printReg(Reg, getTargetRegisterInfo())
226f785676fSDimitry Andric              << " use list MachineOperand " << MO
227284c1978SDimitry Andric              << " has no parent instruction.\n";
228284c1978SDimitry Andric       Valid = false;
22939d628a0SDimitry Andric       continue;
230284c1978SDimitry Andric     }
231284c1978SDimitry Andric     MachineOperand *MO0 = &MI->getOperand(0);
232284c1978SDimitry Andric     unsigned NumOps = MI->getNumOperands();
233284c1978SDimitry Andric     if (!(MO >= MO0 && MO < MO0+NumOps)) {
2342cab237bSDimitry Andric       errs() << printReg(Reg, getTargetRegisterInfo())
235f785676fSDimitry Andric              << " use list MachineOperand " << MO
236284c1978SDimitry Andric              << " doesn't belong to parent MI: " << *MI;
237284c1978SDimitry Andric       Valid = false;
238284c1978SDimitry Andric     }
239284c1978SDimitry Andric     if (!MO->isReg()) {
2402cab237bSDimitry Andric       errs() << printReg(Reg, getTargetRegisterInfo())
241f785676fSDimitry Andric              << " MachineOperand " << MO << ": " << *MO
242284c1978SDimitry Andric              << " is not a register\n";
243284c1978SDimitry Andric       Valid = false;
244284c1978SDimitry Andric     }
245284c1978SDimitry Andric     if (MO->getReg() != Reg) {
2462cab237bSDimitry Andric       errs() << printReg(Reg, getTargetRegisterInfo())
247f785676fSDimitry Andric              << " use-list MachineOperand " << MO << ": "
248284c1978SDimitry Andric              << *MO << " is the wrong register\n";
249284c1978SDimitry Andric       Valid = false;
250284c1978SDimitry Andric     }
251284c1978SDimitry Andric   }
252284c1978SDimitry Andric   assert(Valid && "Invalid use list");
253284c1978SDimitry Andric #endif
254284c1978SDimitry Andric }
255284c1978SDimitry Andric 
verifyUseLists() const256284c1978SDimitry Andric void MachineRegisterInfo::verifyUseLists() const {
257284c1978SDimitry Andric #ifndef NDEBUG
258284c1978SDimitry Andric   for (unsigned i = 0, e = getNumVirtRegs(); i != e; ++i)
259284c1978SDimitry Andric     verifyUseList(TargetRegisterInfo::index2VirtReg(i));
260f785676fSDimitry Andric   for (unsigned i = 1, e = getTargetRegisterInfo()->getNumRegs(); i != e; ++i)
261284c1978SDimitry Andric     verifyUseList(i);
262284c1978SDimitry Andric #endif
263284c1978SDimitry Andric }
264284c1978SDimitry Andric 
2657ae0e2c9SDimitry Andric /// Add MO to the linked list of operands for its register.
addRegOperandToUseList(MachineOperand * MO)2667ae0e2c9SDimitry Andric void MachineRegisterInfo::addRegOperandToUseList(MachineOperand *MO) {
2677ae0e2c9SDimitry Andric   assert(!MO->isOnRegUseList() && "Already on list");
2687ae0e2c9SDimitry Andric   MachineOperand *&HeadRef = getRegUseDefListHead(MO->getReg());
2697ae0e2c9SDimitry Andric   MachineOperand *const Head = HeadRef;
2707ae0e2c9SDimitry Andric 
2717ae0e2c9SDimitry Andric   // Head points to the first list element.
2727ae0e2c9SDimitry Andric   // Next is NULL on the last list element.
2737ae0e2c9SDimitry Andric   // Prev pointers are circular, so Head->Prev == Last.
2747ae0e2c9SDimitry Andric 
2757ae0e2c9SDimitry Andric   // Head is NULL for an empty list.
2767ae0e2c9SDimitry Andric   if (!Head) {
2777ae0e2c9SDimitry Andric     MO->Contents.Reg.Prev = MO;
27891bc56edSDimitry Andric     MO->Contents.Reg.Next = nullptr;
2797ae0e2c9SDimitry Andric     HeadRef = MO;
2807ae0e2c9SDimitry Andric     return;
281f22ef01cSRoman Divacky   }
2827ae0e2c9SDimitry Andric   assert(MO->getReg() == Head->getReg() && "Different regs on the same list!");
2837ae0e2c9SDimitry Andric 
2847ae0e2c9SDimitry Andric   // Insert MO between Last and Head in the circular Prev chain.
2857ae0e2c9SDimitry Andric   MachineOperand *Last = Head->Contents.Reg.Prev;
2867ae0e2c9SDimitry Andric   assert(Last && "Inconsistent use list");
2877ae0e2c9SDimitry Andric   assert(MO->getReg() == Last->getReg() && "Different regs on the same list!");
2887ae0e2c9SDimitry Andric   Head->Contents.Reg.Prev = MO;
2897ae0e2c9SDimitry Andric   MO->Contents.Reg.Prev = Last;
2907ae0e2c9SDimitry Andric 
2917ae0e2c9SDimitry Andric   // Def operands always precede uses. This allows def_iterator to stop early.
2927ae0e2c9SDimitry Andric   // Insert def operands at the front, and use operands at the back.
2937ae0e2c9SDimitry Andric   if (MO->isDef()) {
2947ae0e2c9SDimitry Andric     // Insert def at the front.
2957ae0e2c9SDimitry Andric     MO->Contents.Reg.Next = Head;
2967ae0e2c9SDimitry Andric     HeadRef = MO;
2977ae0e2c9SDimitry Andric   } else {
2987ae0e2c9SDimitry Andric     // Insert use at the end.
29991bc56edSDimitry Andric     MO->Contents.Reg.Next = nullptr;
3007ae0e2c9SDimitry Andric     Last->Contents.Reg.Next = MO;
3017ae0e2c9SDimitry Andric   }
3027ae0e2c9SDimitry Andric }
3037ae0e2c9SDimitry Andric 
3047ae0e2c9SDimitry Andric /// Remove MO from its use-def list.
removeRegOperandFromUseList(MachineOperand * MO)3057ae0e2c9SDimitry Andric void MachineRegisterInfo::removeRegOperandFromUseList(MachineOperand *MO) {
3067ae0e2c9SDimitry Andric   assert(MO->isOnRegUseList() && "Operand not on use list");
3077ae0e2c9SDimitry Andric   MachineOperand *&HeadRef = getRegUseDefListHead(MO->getReg());
3087ae0e2c9SDimitry Andric   MachineOperand *const Head = HeadRef;
3097ae0e2c9SDimitry Andric   assert(Head && "List already empty");
3107ae0e2c9SDimitry Andric 
3117ae0e2c9SDimitry Andric   // Unlink this from the doubly linked list of operands.
3127ae0e2c9SDimitry Andric   MachineOperand *Next = MO->Contents.Reg.Next;
3137ae0e2c9SDimitry Andric   MachineOperand *Prev = MO->Contents.Reg.Prev;
3147ae0e2c9SDimitry Andric 
3157ae0e2c9SDimitry Andric   // Prev links are circular, next link is NULL instead of looping back to Head.
3167ae0e2c9SDimitry Andric   if (MO == Head)
3177ae0e2c9SDimitry Andric     HeadRef = Next;
3187ae0e2c9SDimitry Andric   else
3197ae0e2c9SDimitry Andric     Prev->Contents.Reg.Next = Next;
3207ae0e2c9SDimitry Andric 
3217ae0e2c9SDimitry Andric   (Next ? Next : Head)->Contents.Reg.Prev = Prev;
3227ae0e2c9SDimitry Andric 
32391bc56edSDimitry Andric   MO->Contents.Reg.Prev = nullptr;
32491bc56edSDimitry Andric   MO->Contents.Reg.Next = nullptr;
325f22ef01cSRoman Divacky }
326f22ef01cSRoman Divacky 
327139f7f9bSDimitry Andric /// Move NumOps operands from Src to Dst, updating use-def lists as needed.
328139f7f9bSDimitry Andric ///
329139f7f9bSDimitry Andric /// The Dst range is assumed to be uninitialized memory. (Or it may contain
330139f7f9bSDimitry Andric /// operands that won't be destroyed, which is OK because the MO destructor is
331139f7f9bSDimitry Andric /// trivial anyway).
332139f7f9bSDimitry Andric ///
333139f7f9bSDimitry Andric /// The Src and Dst ranges may overlap.
moveOperands(MachineOperand * Dst,MachineOperand * Src,unsigned NumOps)334139f7f9bSDimitry Andric void MachineRegisterInfo::moveOperands(MachineOperand *Dst,
335139f7f9bSDimitry Andric                                        MachineOperand *Src,
336139f7f9bSDimitry Andric                                        unsigned NumOps) {
337139f7f9bSDimitry Andric   assert(Src != Dst && NumOps && "Noop moveOperands");
338139f7f9bSDimitry Andric 
339139f7f9bSDimitry Andric   // Copy backwards if Dst is within the Src range.
340139f7f9bSDimitry Andric   int Stride = 1;
341139f7f9bSDimitry Andric   if (Dst >= Src && Dst < Src + NumOps) {
342139f7f9bSDimitry Andric     Stride = -1;
343139f7f9bSDimitry Andric     Dst += NumOps - 1;
344139f7f9bSDimitry Andric     Src += NumOps - 1;
345139f7f9bSDimitry Andric   }
346139f7f9bSDimitry Andric 
347139f7f9bSDimitry Andric   // Copy one operand at a time.
348139f7f9bSDimitry Andric   do {
349139f7f9bSDimitry Andric     new (Dst) MachineOperand(*Src);
350139f7f9bSDimitry Andric 
351139f7f9bSDimitry Andric     // Dst takes Src's place in the use-def chain.
352139f7f9bSDimitry Andric     if (Src->isReg()) {
353139f7f9bSDimitry Andric       MachineOperand *&Head = getRegUseDefListHead(Src->getReg());
354139f7f9bSDimitry Andric       MachineOperand *Prev = Src->Contents.Reg.Prev;
355139f7f9bSDimitry Andric       MachineOperand *Next = Src->Contents.Reg.Next;
356139f7f9bSDimitry Andric       assert(Head && "List empty, but operand is chained");
357139f7f9bSDimitry Andric       assert(Prev && "Operand was not on use-def list");
358139f7f9bSDimitry Andric 
359139f7f9bSDimitry Andric       // Prev links are circular, next link is NULL instead of looping back to
360139f7f9bSDimitry Andric       // Head.
361139f7f9bSDimitry Andric       if (Src == Head)
362139f7f9bSDimitry Andric         Head = Dst;
363139f7f9bSDimitry Andric       else
364139f7f9bSDimitry Andric         Prev->Contents.Reg.Next = Dst;
365139f7f9bSDimitry Andric 
366139f7f9bSDimitry Andric       // Update Prev pointer. This also works when Src was pointing to itself
367139f7f9bSDimitry Andric       // in a 1-element list. In that case Head == Dst.
368139f7f9bSDimitry Andric       (Next ? Next : Head)->Contents.Reg.Prev = Dst;
369139f7f9bSDimitry Andric     }
370139f7f9bSDimitry Andric 
371139f7f9bSDimitry Andric     Dst += Stride;
372139f7f9bSDimitry Andric     Src += Stride;
373139f7f9bSDimitry Andric   } while (--NumOps);
374139f7f9bSDimitry Andric }
375139f7f9bSDimitry Andric 
376f22ef01cSRoman Divacky /// replaceRegWith - Replace all instances of FromReg with ToReg in the
377f22ef01cSRoman Divacky /// machine function.  This is like llvm-level X->replaceAllUsesWith(Y),
378f22ef01cSRoman Divacky /// except that it also changes any definitions of the register as well.
37939d628a0SDimitry Andric /// If ToReg is a physical register we apply the sub register to obtain the
38039d628a0SDimitry Andric /// final/proper physical register.
replaceRegWith(unsigned FromReg,unsigned ToReg)381f22ef01cSRoman Divacky void MachineRegisterInfo::replaceRegWith(unsigned FromReg, unsigned ToReg) {
382f22ef01cSRoman Divacky   assert(FromReg != ToReg && "Cannot replace a reg with itself");
383f22ef01cSRoman Divacky 
38439d628a0SDimitry Andric   const TargetRegisterInfo *TRI = getTargetRegisterInfo();
38539d628a0SDimitry Andric 
386f22ef01cSRoman Divacky   // TODO: This could be more efficient by bulk changing the operands.
387f22ef01cSRoman Divacky   for (reg_iterator I = reg_begin(FromReg), E = reg_end(); I != E; ) {
38891bc56edSDimitry Andric     MachineOperand &O = *I;
389f22ef01cSRoman Divacky     ++I;
39039d628a0SDimitry Andric     if (TargetRegisterInfo::isPhysicalRegister(ToReg)) {
39139d628a0SDimitry Andric       O.substPhysReg(ToReg, *TRI);
39239d628a0SDimitry Andric     } else {
393f22ef01cSRoman Divacky       O.setReg(ToReg);
394f22ef01cSRoman Divacky     }
395f22ef01cSRoman Divacky   }
39639d628a0SDimitry Andric }
397f22ef01cSRoman Divacky 
398f22ef01cSRoman Divacky /// getVRegDef - Return the machine instr that defines the specified virtual
399f22ef01cSRoman Divacky /// register or null if none is found.  This assumes that the code is in SSA
400f22ef01cSRoman Divacky /// form, so there should only be one definition.
getVRegDef(unsigned Reg) const401f22ef01cSRoman Divacky MachineInstr *MachineRegisterInfo::getVRegDef(unsigned Reg) const {
402f22ef01cSRoman Divacky   // Since we are in SSA form, we can use the first definition.
40391bc56edSDimitry Andric   def_instr_iterator I = def_instr_begin(Reg);
40491bc56edSDimitry Andric   assert((I.atEnd() || std::next(I) == def_instr_end()) &&
4057ae0e2c9SDimitry Andric          "getVRegDef assumes a single definition or no definition");
40691bc56edSDimitry Andric   return !I.atEnd() ? &*I : nullptr;
407f22ef01cSRoman Divacky }
408f22ef01cSRoman Divacky 
4097ae0e2c9SDimitry Andric /// getUniqueVRegDef - Return the unique machine instr that defines the
4107ae0e2c9SDimitry Andric /// specified virtual register or null if none is found.  If there are
4117ae0e2c9SDimitry Andric /// multiple definitions or no definition, return null.
getUniqueVRegDef(unsigned Reg) const4127ae0e2c9SDimitry Andric MachineInstr *MachineRegisterInfo::getUniqueVRegDef(unsigned Reg) const {
41391bc56edSDimitry Andric   if (def_empty(Reg)) return nullptr;
41491bc56edSDimitry Andric   def_instr_iterator I = def_instr_begin(Reg);
41591bc56edSDimitry Andric   if (std::next(I) != def_instr_end())
41691bc56edSDimitry Andric     return nullptr;
4177ae0e2c9SDimitry Andric   return &*I;
418f22ef01cSRoman Divacky }
419f22ef01cSRoman Divacky 
hasOneNonDBGUse(unsigned RegNo) const420f22ef01cSRoman Divacky bool MachineRegisterInfo::hasOneNonDBGUse(unsigned RegNo) const {
421f22ef01cSRoman Divacky   use_nodbg_iterator UI = use_nodbg_begin(RegNo);
422f22ef01cSRoman Divacky   if (UI == use_nodbg_end())
423f22ef01cSRoman Divacky     return false;
424f22ef01cSRoman Divacky   return ++UI == use_nodbg_end();
425f22ef01cSRoman Divacky }
426f22ef01cSRoman Divacky 
427f22ef01cSRoman Divacky /// clearKillFlags - Iterate over all the uses of the given register and
428f22ef01cSRoman Divacky /// clear the kill flag from the MachineOperand. This function is used by
429f22ef01cSRoman Divacky /// optimization passes which extend register lifetimes and need only
430f22ef01cSRoman Divacky /// preserve conservative kill flag information.
clearKillFlags(unsigned Reg) const431f22ef01cSRoman Divacky void MachineRegisterInfo::clearKillFlags(unsigned Reg) const {
43291bc56edSDimitry Andric   for (MachineOperand &MO : use_operands(Reg))
43391bc56edSDimitry Andric     MO.setIsKill(false);
434f22ef01cSRoman Divacky }
435f22ef01cSRoman Divacky 
isLiveIn(unsigned Reg) const436f22ef01cSRoman Divacky bool MachineRegisterInfo::isLiveIn(unsigned Reg) const {
437f22ef01cSRoman Divacky   for (livein_iterator I = livein_begin(), E = livein_end(); I != E; ++I)
438f22ef01cSRoman Divacky     if (I->first == Reg || I->second == Reg)
439f22ef01cSRoman Divacky       return true;
440f22ef01cSRoman Divacky   return false;
441f22ef01cSRoman Divacky }
442f22ef01cSRoman Divacky 
443f22ef01cSRoman Divacky /// getLiveInPhysReg - If VReg is a live-in virtual register, return the
444f22ef01cSRoman Divacky /// corresponding live-in physical register.
getLiveInPhysReg(unsigned VReg) const445f22ef01cSRoman Divacky unsigned MachineRegisterInfo::getLiveInPhysReg(unsigned VReg) const {
446f22ef01cSRoman Divacky   for (livein_iterator I = livein_begin(), E = livein_end(); I != E; ++I)
447f22ef01cSRoman Divacky     if (I->second == VReg)
448f22ef01cSRoman Divacky       return I->first;
449f22ef01cSRoman Divacky   return 0;
450f22ef01cSRoman Divacky }
451f22ef01cSRoman Divacky 
452f22ef01cSRoman Divacky /// getLiveInVirtReg - If PReg is a live-in physical register, return the
453f22ef01cSRoman Divacky /// corresponding live-in physical register.
getLiveInVirtReg(unsigned PReg) const454f22ef01cSRoman Divacky unsigned MachineRegisterInfo::getLiveInVirtReg(unsigned PReg) const {
455f22ef01cSRoman Divacky   for (livein_iterator I = livein_begin(), E = livein_end(); I != E; ++I)
456f22ef01cSRoman Divacky     if (I->first == PReg)
457f22ef01cSRoman Divacky       return I->second;
458f22ef01cSRoman Divacky   return 0;
459f22ef01cSRoman Divacky }
460f22ef01cSRoman Divacky 
461f22ef01cSRoman Divacky /// EmitLiveInCopies - Emit copies to initialize livein virtual registers
462f22ef01cSRoman Divacky /// into the given entry block.
463f22ef01cSRoman Divacky void
EmitLiveInCopies(MachineBasicBlock * EntryMBB,const TargetRegisterInfo & TRI,const TargetInstrInfo & TII)464f22ef01cSRoman Divacky MachineRegisterInfo::EmitLiveInCopies(MachineBasicBlock *EntryMBB,
465f22ef01cSRoman Divacky                                       const TargetRegisterInfo &TRI,
466f22ef01cSRoman Divacky                                       const TargetInstrInfo &TII) {
467ffd1746dSEd Schouten   // Emit the copies into the top of the block.
468ffd1746dSEd Schouten   for (unsigned i = 0, e = LiveIns.size(); i != e; ++i)
469ffd1746dSEd Schouten     if (LiveIns[i].second) {
4702cab237bSDimitry Andric       if (use_nodbg_empty(LiveIns[i].second)) {
4712cab237bSDimitry Andric         // The livein has no non-dbg uses. Drop it.
472ffd1746dSEd Schouten         //
473ffd1746dSEd Schouten         // It would be preferable to have isel avoid creating live-in
474ffd1746dSEd Schouten         // records for unused arguments in the first place, but it's
475ffd1746dSEd Schouten         // complicated by the debug info code for arguments.
476ffd1746dSEd Schouten         LiveIns.erase(LiveIns.begin() + i);
477ffd1746dSEd Schouten         --i; --e;
478ffd1746dSEd Schouten       } else {
479ffd1746dSEd Schouten         // Emit a copy.
480dd6029ffSDimitry Andric         BuildMI(*EntryMBB, EntryMBB->begin(), DebugLoc(),
481ffd1746dSEd Schouten                 TII.get(TargetOpcode::COPY), LiveIns[i].second)
482ffd1746dSEd Schouten           .addReg(LiveIns[i].first);
483ffd1746dSEd Schouten 
484ffd1746dSEd Schouten         // Add the register to the entry block live-in set.
485ffd1746dSEd Schouten         EntryMBB->addLiveIn(LiveIns[i].first);
486f22ef01cSRoman Divacky       }
487f22ef01cSRoman Divacky     } else {
488ffd1746dSEd Schouten       // Add the register to the entry block live-in set.
489ffd1746dSEd Schouten       EntryMBB->addLiveIn(LiveIns[i].first);
490f22ef01cSRoman Divacky     }
491f22ef01cSRoman Divacky }
492f22ef01cSRoman Divacky 
getMaxLaneMaskForVReg(unsigned Reg) const4937d523365SDimitry Andric LaneBitmask MachineRegisterInfo::getMaxLaneMaskForVReg(unsigned Reg) const {
49439d628a0SDimitry Andric   // Lane masks are only defined for vregs.
49539d628a0SDimitry Andric   assert(TargetRegisterInfo::isVirtualRegister(Reg));
49639d628a0SDimitry Andric   const TargetRegisterClass &TRC = *getRegClass(Reg);
49739d628a0SDimitry Andric   return TRC.getLaneMask();
49839d628a0SDimitry Andric }
49939d628a0SDimitry Andric 
5007a7e6055SDimitry Andric #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
dumpUses(unsigned Reg) const5017a7e6055SDimitry Andric LLVM_DUMP_METHOD void MachineRegisterInfo::dumpUses(unsigned Reg) const {
50291bc56edSDimitry Andric   for (MachineInstr &I : use_instructions(Reg))
50391bc56edSDimitry Andric     I.dump();
504f22ef01cSRoman Divacky }
505f22ef01cSRoman Divacky #endif
506dff0c46cSDimitry Andric 
freezeReservedRegs(const MachineFunction & MF)507dff0c46cSDimitry Andric void MachineRegisterInfo::freezeReservedRegs(const MachineFunction &MF) {
508f785676fSDimitry Andric   ReservedRegs = getTargetRegisterInfo()->getReservedRegs(MF);
509f785676fSDimitry Andric   assert(ReservedRegs.size() == getTargetRegisterInfo()->getNumRegs() &&
5103861d79fSDimitry Andric          "Invalid ReservedRegs vector from target");
511dff0c46cSDimitry Andric }
512dff0c46cSDimitry Andric 
isConstantPhysReg(unsigned PhysReg) const513d88c1a5aSDimitry Andric bool MachineRegisterInfo::isConstantPhysReg(unsigned PhysReg) const {
514dff0c46cSDimitry Andric   assert(TargetRegisterInfo::isPhysicalRegister(PhysReg));
515dff0c46cSDimitry Andric 
516d88c1a5aSDimitry Andric   const TargetRegisterInfo *TRI = getTargetRegisterInfo();
517d88c1a5aSDimitry Andric   if (TRI->isConstantPhysReg(PhysReg))
518d88c1a5aSDimitry Andric     return true;
519d88c1a5aSDimitry Andric 
5203861d79fSDimitry Andric   // Check if any overlapping register is modified, or allocatable so it may be
5213861d79fSDimitry Andric   // used later.
522d88c1a5aSDimitry Andric   for (MCRegAliasIterator AI(PhysReg, TRI, true);
523f785676fSDimitry Andric        AI.isValid(); ++AI)
5243861d79fSDimitry Andric     if (!def_empty(*AI) || isAllocatable(*AI))
525dff0c46cSDimitry Andric       return false;
526dff0c46cSDimitry Andric   return true;
527dff0c46cSDimitry Andric }
52891bc56edSDimitry Andric 
5292cab237bSDimitry Andric bool
isCallerPreservedOrConstPhysReg(unsigned PhysReg) const5302cab237bSDimitry Andric MachineRegisterInfo::isCallerPreservedOrConstPhysReg(unsigned PhysReg) const {
5312cab237bSDimitry Andric   const TargetRegisterInfo *TRI = getTargetRegisterInfo();
5322cab237bSDimitry Andric   return isConstantPhysReg(PhysReg) ||
5332cab237bSDimitry Andric       TRI->isCallerPreservedPhysReg(PhysReg, *MF);
5342cab237bSDimitry Andric }
5352cab237bSDimitry Andric 
53691bc56edSDimitry Andric /// markUsesInDebugValueAsUndef - Mark every DBG_VALUE referencing the
53791bc56edSDimitry Andric /// specified register as undefined which causes the DBG_VALUE to be
53891bc56edSDimitry Andric /// deleted during LiveDebugVariables analysis.
markUsesInDebugValueAsUndef(unsigned Reg) const53991bc56edSDimitry Andric void MachineRegisterInfo::markUsesInDebugValueAsUndef(unsigned Reg) const {
54091bc56edSDimitry Andric   // Mark any DBG_VALUE that uses Reg as undef (but don't delete it.)
54191bc56edSDimitry Andric   MachineRegisterInfo::use_instr_iterator nextI;
54291bc56edSDimitry Andric   for (use_instr_iterator I = use_instr_begin(Reg), E = use_instr_end();
54391bc56edSDimitry Andric        I != E; I = nextI) {
54491bc56edSDimitry Andric     nextI = std::next(I);  // I is invalidated by the setReg
54591bc56edSDimitry Andric     MachineInstr *UseMI = &*I;
54691bc56edSDimitry Andric     if (UseMI->isDebugValue())
54791bc56edSDimitry Andric       UseMI->getOperand(0).setReg(0U);
54891bc56edSDimitry Andric   }
54991bc56edSDimitry Andric }
550875ed548SDimitry Andric 
getCalledFunction(const MachineInstr & MI)551875ed548SDimitry Andric static const Function *getCalledFunction(const MachineInstr &MI) {
552875ed548SDimitry Andric   for (const MachineOperand &MO : MI.operands()) {
553875ed548SDimitry Andric     if (!MO.isGlobal())
554875ed548SDimitry Andric       continue;
555875ed548SDimitry Andric     const Function *Func = dyn_cast<Function>(MO.getGlobal());
556875ed548SDimitry Andric     if (Func != nullptr)
557875ed548SDimitry Andric       return Func;
558875ed548SDimitry Andric   }
559875ed548SDimitry Andric   return nullptr;
560875ed548SDimitry Andric }
561875ed548SDimitry Andric 
isNoReturnDef(const MachineOperand & MO)562875ed548SDimitry Andric static bool isNoReturnDef(const MachineOperand &MO) {
563875ed548SDimitry Andric   // Anything which is not a noreturn function is a real def.
564875ed548SDimitry Andric   const MachineInstr &MI = *MO.getParent();
565875ed548SDimitry Andric   if (!MI.isCall())
566875ed548SDimitry Andric     return false;
567875ed548SDimitry Andric   const MachineBasicBlock &MBB = *MI.getParent();
568875ed548SDimitry Andric   if (!MBB.succ_empty())
569875ed548SDimitry Andric     return false;
570875ed548SDimitry Andric   const MachineFunction &MF = *MBB.getParent();
571875ed548SDimitry Andric   // We need to keep correct unwind information even if the function will
572875ed548SDimitry Andric   // not return, since the runtime may need it.
5732cab237bSDimitry Andric   if (MF.getFunction().hasFnAttribute(Attribute::UWTable))
574875ed548SDimitry Andric     return false;
575875ed548SDimitry Andric   const Function *Called = getCalledFunction(MI);
5767d523365SDimitry Andric   return !(Called == nullptr || !Called->hasFnAttribute(Attribute::NoReturn) ||
5777d523365SDimitry Andric            !Called->hasFnAttribute(Attribute::NoUnwind));
578875ed548SDimitry Andric }
579875ed548SDimitry Andric 
isPhysRegModified(unsigned PhysReg,bool SkipNoReturnDef) const5803ca95b02SDimitry Andric bool MachineRegisterInfo::isPhysRegModified(unsigned PhysReg,
5813ca95b02SDimitry Andric                                             bool SkipNoReturnDef) const {
582875ed548SDimitry Andric   if (UsedPhysRegMask.test(PhysReg))
583875ed548SDimitry Andric     return true;
584875ed548SDimitry Andric   const TargetRegisterInfo *TRI = getTargetRegisterInfo();
585875ed548SDimitry Andric   for (MCRegAliasIterator AI(PhysReg, TRI, true); AI.isValid(); ++AI) {
586875ed548SDimitry Andric     for (const MachineOperand &MO : make_range(def_begin(*AI), def_end())) {
5873ca95b02SDimitry Andric       if (!SkipNoReturnDef && isNoReturnDef(MO))
588875ed548SDimitry Andric         continue;
589875ed548SDimitry Andric       return true;
590875ed548SDimitry Andric     }
591875ed548SDimitry Andric   }
592875ed548SDimitry Andric   return false;
593875ed548SDimitry Andric }
5947d523365SDimitry Andric 
isPhysRegUsed(unsigned PhysReg) const5957d523365SDimitry Andric bool MachineRegisterInfo::isPhysRegUsed(unsigned PhysReg) const {
5967d523365SDimitry Andric   if (UsedPhysRegMask.test(PhysReg))
5977d523365SDimitry Andric     return true;
5987d523365SDimitry Andric   const TargetRegisterInfo *TRI = getTargetRegisterInfo();
5997d523365SDimitry Andric   for (MCRegAliasIterator AliasReg(PhysReg, TRI, true); AliasReg.isValid();
6007d523365SDimitry Andric        ++AliasReg) {
6017d523365SDimitry Andric     if (!reg_nodbg_empty(*AliasReg))
6027d523365SDimitry Andric       return true;
6037d523365SDimitry Andric   }
6047d523365SDimitry Andric   return false;
6057d523365SDimitry Andric }
6067a7e6055SDimitry Andric 
disableCalleeSavedRegister(unsigned Reg)6077a7e6055SDimitry Andric void MachineRegisterInfo::disableCalleeSavedRegister(unsigned Reg) {
6087a7e6055SDimitry Andric 
6097a7e6055SDimitry Andric   const TargetRegisterInfo *TRI = getTargetRegisterInfo();
6107a7e6055SDimitry Andric   assert(Reg && (Reg < TRI->getNumRegs()) &&
6117a7e6055SDimitry Andric          "Trying to disable an invalid register");
6127a7e6055SDimitry Andric 
6137a7e6055SDimitry Andric   if (!IsUpdatedCSRsInitialized) {
6147a7e6055SDimitry Andric     const MCPhysReg *CSR = TRI->getCalleeSavedRegs(MF);
6157a7e6055SDimitry Andric     for (const MCPhysReg *I = CSR; *I; ++I)
6167a7e6055SDimitry Andric       UpdatedCSRs.push_back(*I);
6177a7e6055SDimitry Andric 
6187a7e6055SDimitry Andric     // Zero value represents the end of the register list
6197a7e6055SDimitry Andric     // (no more registers should be pushed).
6207a7e6055SDimitry Andric     UpdatedCSRs.push_back(0);
6217a7e6055SDimitry Andric 
6227a7e6055SDimitry Andric     IsUpdatedCSRsInitialized = true;
6237a7e6055SDimitry Andric   }
6247a7e6055SDimitry Andric 
6257a7e6055SDimitry Andric   // Remove the register (and its aliases from the list).
6267a7e6055SDimitry Andric   for (MCRegAliasIterator AI(Reg, TRI, true); AI.isValid(); ++AI)
6277a7e6055SDimitry Andric     UpdatedCSRs.erase(std::remove(UpdatedCSRs.begin(), UpdatedCSRs.end(), *AI),
6287a7e6055SDimitry Andric                       UpdatedCSRs.end());
6297a7e6055SDimitry Andric }
6307a7e6055SDimitry Andric 
getCalleeSavedRegs() const6317a7e6055SDimitry Andric const MCPhysReg *MachineRegisterInfo::getCalleeSavedRegs() const {
6327a7e6055SDimitry Andric   if (IsUpdatedCSRsInitialized)
6337a7e6055SDimitry Andric     return UpdatedCSRs.data();
6347a7e6055SDimitry Andric 
6357a7e6055SDimitry Andric   return getTargetRegisterInfo()->getCalleeSavedRegs(MF);
6367a7e6055SDimitry Andric }
6377a7e6055SDimitry Andric 
setCalleeSavedRegs(ArrayRef<MCPhysReg> CSRs)6387a7e6055SDimitry Andric void MachineRegisterInfo::setCalleeSavedRegs(ArrayRef<MCPhysReg> CSRs) {
6397a7e6055SDimitry Andric   if (IsUpdatedCSRsInitialized)
6407a7e6055SDimitry Andric     UpdatedCSRs.clear();
6417a7e6055SDimitry Andric 
6427a7e6055SDimitry Andric   for (MCPhysReg Reg : CSRs)
6437a7e6055SDimitry Andric     UpdatedCSRs.push_back(Reg);
6447a7e6055SDimitry Andric 
6457a7e6055SDimitry Andric   // Zero value represents the end of the register list
6467a7e6055SDimitry Andric   // (no more registers should be pushed).
6477a7e6055SDimitry Andric   UpdatedCSRs.push_back(0);
6487a7e6055SDimitry Andric   IsUpdatedCSRsInitialized = true;
6497a7e6055SDimitry Andric }
650d4419f6fSDimitry Andric 
isReservedRegUnit(unsigned Unit) const651d4419f6fSDimitry Andric bool MachineRegisterInfo::isReservedRegUnit(unsigned Unit) const {
652d4419f6fSDimitry Andric   const TargetRegisterInfo *TRI = getTargetRegisterInfo();
653d4419f6fSDimitry Andric   for (MCRegUnitRootIterator Root(Unit, TRI); Root.isValid(); ++Root) {
654d4419f6fSDimitry Andric     bool IsRootReserved = true;
655d4419f6fSDimitry Andric     for (MCSuperRegIterator Super(*Root, TRI, /*IncludeSelf=*/true);
656d4419f6fSDimitry Andric          Super.isValid(); ++Super) {
657d4419f6fSDimitry Andric       unsigned Reg = *Super;
658d4419f6fSDimitry Andric       if (!isReserved(Reg)) {
659d4419f6fSDimitry Andric         IsRootReserved = false;
660d4419f6fSDimitry Andric         break;
661d4419f6fSDimitry Andric       }
662d4419f6fSDimitry Andric     }
663d4419f6fSDimitry Andric     if (IsRootReserved)
664d4419f6fSDimitry Andric       return true;
665d4419f6fSDimitry Andric   }
666d4419f6fSDimitry Andric   return false;
667d4419f6fSDimitry Andric }
668