10b57cec5SDimitry Andric //===- lib/Codegen/MachineRegisterInfo.cpp --------------------------------===//
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 // Implementation of the MachineRegisterInfo class.
100b57cec5SDimitry Andric //
110b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
120b57cec5SDimitry Andric 
130b57cec5SDimitry Andric #include "llvm/CodeGen/MachineRegisterInfo.h"
140b57cec5SDimitry Andric #include "llvm/ADT/iterator_range.h"
150b57cec5SDimitry Andric #include "llvm/CodeGen/LowLevelType.h"
160b57cec5SDimitry Andric #include "llvm/CodeGen/MachineBasicBlock.h"
170b57cec5SDimitry Andric #include "llvm/CodeGen/MachineFunction.h"
180b57cec5SDimitry Andric #include "llvm/CodeGen/MachineInstr.h"
190b57cec5SDimitry Andric #include "llvm/CodeGen/MachineInstrBuilder.h"
200b57cec5SDimitry Andric #include "llvm/CodeGen/MachineOperand.h"
210b57cec5SDimitry Andric #include "llvm/CodeGen/TargetInstrInfo.h"
220b57cec5SDimitry Andric #include "llvm/CodeGen/TargetRegisterInfo.h"
230b57cec5SDimitry Andric #include "llvm/CodeGen/TargetSubtargetInfo.h"
240b57cec5SDimitry Andric #include "llvm/Config/llvm-config.h"
250b57cec5SDimitry Andric #include "llvm/IR/Attributes.h"
260b57cec5SDimitry Andric #include "llvm/IR/DebugLoc.h"
270b57cec5SDimitry Andric #include "llvm/IR/Function.h"
280b57cec5SDimitry Andric #include "llvm/MC/MCRegisterInfo.h"
290b57cec5SDimitry Andric #include "llvm/Support/Casting.h"
300b57cec5SDimitry Andric #include "llvm/Support/CommandLine.h"
310b57cec5SDimitry Andric #include "llvm/Support/Compiler.h"
320b57cec5SDimitry Andric #include "llvm/Support/ErrorHandling.h"
330b57cec5SDimitry Andric #include "llvm/Support/raw_ostream.h"
340b57cec5SDimitry Andric #include <cassert>
350b57cec5SDimitry Andric 
360b57cec5SDimitry Andric using namespace llvm;
370b57cec5SDimitry Andric 
380b57cec5SDimitry Andric static cl::opt<bool> EnableSubRegLiveness("enable-subreg-liveness", cl::Hidden,
390b57cec5SDimitry Andric   cl::init(true), cl::desc("Enable subregister liveness tracking."));
400b57cec5SDimitry Andric 
410b57cec5SDimitry Andric // Pin the vtable to this file.
anchor()420b57cec5SDimitry Andric void MachineRegisterInfo::Delegate::anchor() {}
430b57cec5SDimitry Andric 
MachineRegisterInfo(MachineFunction * MF)440b57cec5SDimitry Andric MachineRegisterInfo::MachineRegisterInfo(MachineFunction *MF)
450b57cec5SDimitry Andric     : MF(MF), TracksSubRegLiveness(MF->getSubtarget().enableSubRegLiveness() &&
460b57cec5SDimitry Andric                                    EnableSubRegLiveness),
470b57cec5SDimitry Andric       IsUpdatedCSRsInitialized(false) {
480b57cec5SDimitry Andric   unsigned NumRegs = getTargetRegisterInfo()->getNumRegs();
490b57cec5SDimitry Andric   VRegInfo.reserve(256);
500b57cec5SDimitry Andric   RegAllocHints.reserve(256);
510b57cec5SDimitry Andric   UsedPhysRegMask.resize(NumRegs);
520b57cec5SDimitry Andric   PhysRegUseDefLists.reset(new MachineOperand*[NumRegs]());
530b57cec5SDimitry Andric }
540b57cec5SDimitry Andric 
550b57cec5SDimitry Andric /// setRegClass - Set the register class of the specified virtual register.
560b57cec5SDimitry Andric ///
570b57cec5SDimitry Andric void
setRegClass(Register Reg,const TargetRegisterClass * RC)585ffd83dbSDimitry Andric MachineRegisterInfo::setRegClass(Register Reg, const TargetRegisterClass *RC) {
590b57cec5SDimitry Andric   assert(RC && RC->isAllocatable() && "Invalid RC for virtual register");
600b57cec5SDimitry Andric   VRegInfo[Reg].first = RC;
610b57cec5SDimitry Andric }
620b57cec5SDimitry Andric 
setRegBank(Register Reg,const RegisterBank & RegBank)635ffd83dbSDimitry Andric void MachineRegisterInfo::setRegBank(Register Reg,
640b57cec5SDimitry Andric                                      const RegisterBank &RegBank) {
650b57cec5SDimitry Andric   VRegInfo[Reg].first = &RegBank;
660b57cec5SDimitry Andric }
670b57cec5SDimitry Andric 
680b57cec5SDimitry Andric static const TargetRegisterClass *
constrainRegClass(MachineRegisterInfo & MRI,Register Reg,const TargetRegisterClass * OldRC,const TargetRegisterClass * RC,unsigned MinNumRegs)695ffd83dbSDimitry Andric constrainRegClass(MachineRegisterInfo &MRI, Register Reg,
700b57cec5SDimitry Andric                   const TargetRegisterClass *OldRC,
710b57cec5SDimitry Andric                   const TargetRegisterClass *RC, unsigned MinNumRegs) {
720b57cec5SDimitry Andric   if (OldRC == RC)
730b57cec5SDimitry Andric     return RC;
740b57cec5SDimitry Andric   const TargetRegisterClass *NewRC =
750b57cec5SDimitry Andric       MRI.getTargetRegisterInfo()->getCommonSubClass(OldRC, RC);
760b57cec5SDimitry Andric   if (!NewRC || NewRC == OldRC)
770b57cec5SDimitry Andric     return NewRC;
780b57cec5SDimitry Andric   if (NewRC->getNumRegs() < MinNumRegs)
790b57cec5SDimitry Andric     return nullptr;
800b57cec5SDimitry Andric   MRI.setRegClass(Reg, NewRC);
810b57cec5SDimitry Andric   return NewRC;
820b57cec5SDimitry Andric }
830b57cec5SDimitry Andric 
840b57cec5SDimitry Andric const TargetRegisterClass *
constrainRegClass(Register Reg,const TargetRegisterClass * RC,unsigned MinNumRegs)855ffd83dbSDimitry Andric MachineRegisterInfo::constrainRegClass(Register Reg,
860b57cec5SDimitry Andric                                        const TargetRegisterClass *RC,
870b57cec5SDimitry Andric                                        unsigned MinNumRegs) {
880b57cec5SDimitry Andric   return ::constrainRegClass(*this, Reg, getRegClass(Reg), RC, MinNumRegs);
890b57cec5SDimitry Andric }
900b57cec5SDimitry Andric 
910b57cec5SDimitry Andric bool
constrainRegAttrs(Register Reg,Register ConstrainingReg,unsigned MinNumRegs)925ffd83dbSDimitry Andric MachineRegisterInfo::constrainRegAttrs(Register Reg,
935ffd83dbSDimitry Andric                                        Register ConstrainingReg,
940b57cec5SDimitry Andric                                        unsigned MinNumRegs) {
950b57cec5SDimitry Andric   const LLT RegTy = getType(Reg);
960b57cec5SDimitry Andric   const LLT ConstrainingRegTy = getType(ConstrainingReg);
970b57cec5SDimitry Andric   if (RegTy.isValid() && ConstrainingRegTy.isValid() &&
980b57cec5SDimitry Andric       RegTy != ConstrainingRegTy)
990b57cec5SDimitry Andric     return false;
1000b57cec5SDimitry Andric   const auto ConstrainingRegCB = getRegClassOrRegBank(ConstrainingReg);
1010b57cec5SDimitry Andric   if (!ConstrainingRegCB.isNull()) {
1020b57cec5SDimitry Andric     const auto RegCB = getRegClassOrRegBank(Reg);
1030b57cec5SDimitry Andric     if (RegCB.isNull())
1040b57cec5SDimitry Andric       setRegClassOrRegBank(Reg, ConstrainingRegCB);
1050b57cec5SDimitry Andric     else if (RegCB.is<const TargetRegisterClass *>() !=
1060b57cec5SDimitry Andric              ConstrainingRegCB.is<const TargetRegisterClass *>())
1070b57cec5SDimitry Andric       return false;
1080b57cec5SDimitry Andric     else if (RegCB.is<const TargetRegisterClass *>()) {
1090b57cec5SDimitry Andric       if (!::constrainRegClass(
1100b57cec5SDimitry Andric               *this, Reg, RegCB.get<const TargetRegisterClass *>(),
1110b57cec5SDimitry Andric               ConstrainingRegCB.get<const TargetRegisterClass *>(), MinNumRegs))
1120b57cec5SDimitry Andric         return false;
1130b57cec5SDimitry Andric     } else if (RegCB != ConstrainingRegCB)
1140b57cec5SDimitry Andric       return false;
1150b57cec5SDimitry Andric   }
1160b57cec5SDimitry Andric   if (ConstrainingRegTy.isValid())
1170b57cec5SDimitry Andric     setType(Reg, ConstrainingRegTy);
1180b57cec5SDimitry Andric   return true;
1190b57cec5SDimitry Andric }
1200b57cec5SDimitry Andric 
1210b57cec5SDimitry Andric bool
recomputeRegClass(Register Reg)1225ffd83dbSDimitry Andric MachineRegisterInfo::recomputeRegClass(Register Reg) {
1230b57cec5SDimitry Andric   const TargetInstrInfo *TII = MF->getSubtarget().getInstrInfo();
1240b57cec5SDimitry Andric   const TargetRegisterClass *OldRC = getRegClass(Reg);
1250b57cec5SDimitry Andric   const TargetRegisterClass *NewRC =
1260b57cec5SDimitry Andric       getTargetRegisterInfo()->getLargestLegalSuperClass(OldRC, *MF);
1270b57cec5SDimitry Andric 
1280b57cec5SDimitry Andric   // Stop early if there is no room to grow.
1290b57cec5SDimitry Andric   if (NewRC == OldRC)
1300b57cec5SDimitry Andric     return false;
1310b57cec5SDimitry Andric 
1320b57cec5SDimitry Andric   // Accumulate constraints from all uses.
1330b57cec5SDimitry Andric   for (MachineOperand &MO : reg_nodbg_operands(Reg)) {
1340b57cec5SDimitry Andric     // Apply the effect of the given operand to NewRC.
1350b57cec5SDimitry Andric     MachineInstr *MI = MO.getParent();
1360b57cec5SDimitry Andric     unsigned OpNo = &MO - &MI->getOperand(0);
1370b57cec5SDimitry Andric     NewRC = MI->getRegClassConstraintEffect(OpNo, NewRC, TII,
1380b57cec5SDimitry Andric                                             getTargetRegisterInfo());
1390b57cec5SDimitry Andric     if (!NewRC || NewRC == OldRC)
1400b57cec5SDimitry Andric       return false;
1410b57cec5SDimitry Andric   }
1420b57cec5SDimitry Andric   setRegClass(Reg, NewRC);
1430b57cec5SDimitry Andric   return true;
1440b57cec5SDimitry Andric }
1450b57cec5SDimitry Andric 
createIncompleteVirtualRegister(StringRef Name)1465ffd83dbSDimitry Andric Register MachineRegisterInfo::createIncompleteVirtualRegister(StringRef Name) {
1475ffd83dbSDimitry Andric   Register Reg = Register::index2VirtReg(getNumVirtRegs());
1480b57cec5SDimitry Andric   VRegInfo.grow(Reg);
1490b57cec5SDimitry Andric   RegAllocHints.grow(Reg);
1500b57cec5SDimitry Andric   insertVRegByName(Name, Reg);
1510b57cec5SDimitry Andric   return Reg;
1520b57cec5SDimitry Andric }
1530b57cec5SDimitry Andric 
1540b57cec5SDimitry Andric /// createVirtualRegister - Create and return a new virtual register in the
1550b57cec5SDimitry Andric /// function with the specified register class.
1560b57cec5SDimitry Andric ///
1570b57cec5SDimitry Andric Register
createVirtualRegister(const TargetRegisterClass * RegClass,StringRef Name)1580b57cec5SDimitry Andric MachineRegisterInfo::createVirtualRegister(const TargetRegisterClass *RegClass,
1590b57cec5SDimitry Andric                                            StringRef Name) {
1600b57cec5SDimitry Andric   assert(RegClass && "Cannot create register without RegClass!");
1610b57cec5SDimitry Andric   assert(RegClass->isAllocatable() &&
1620b57cec5SDimitry Andric          "Virtual register RegClass must be allocatable.");
1630b57cec5SDimitry Andric 
1640b57cec5SDimitry Andric   // New virtual register number.
1655ffd83dbSDimitry Andric   Register Reg = createIncompleteVirtualRegister(Name);
1660b57cec5SDimitry Andric   VRegInfo[Reg].first = RegClass;
1670b57cec5SDimitry Andric   if (TheDelegate)
1680b57cec5SDimitry Andric     TheDelegate->MRI_NoteNewVirtualRegister(Reg);
1690b57cec5SDimitry Andric   return Reg;
1700b57cec5SDimitry Andric }
1710b57cec5SDimitry Andric 
cloneVirtualRegister(Register VReg,StringRef Name)1720b57cec5SDimitry Andric Register MachineRegisterInfo::cloneVirtualRegister(Register VReg,
1730b57cec5SDimitry Andric                                                    StringRef Name) {
1745ffd83dbSDimitry Andric   Register Reg = createIncompleteVirtualRegister(Name);
1750b57cec5SDimitry Andric   VRegInfo[Reg].first = VRegInfo[VReg].first;
1760b57cec5SDimitry Andric   setType(Reg, getType(VReg));
1770b57cec5SDimitry Andric   if (TheDelegate)
1780b57cec5SDimitry Andric     TheDelegate->MRI_NoteNewVirtualRegister(Reg);
1790b57cec5SDimitry Andric   return Reg;
1800b57cec5SDimitry Andric }
1810b57cec5SDimitry Andric 
setType(Register VReg,LLT Ty)1825ffd83dbSDimitry Andric void MachineRegisterInfo::setType(Register VReg, LLT Ty) {
1830b57cec5SDimitry Andric   VRegToType.grow(VReg);
1840b57cec5SDimitry Andric   VRegToType[VReg] = Ty;
1850b57cec5SDimitry Andric }
1860b57cec5SDimitry Andric 
1870b57cec5SDimitry Andric Register
createGenericVirtualRegister(LLT Ty,StringRef Name)1880b57cec5SDimitry Andric MachineRegisterInfo::createGenericVirtualRegister(LLT Ty, StringRef Name) {
1890b57cec5SDimitry Andric   // New virtual register number.
1905ffd83dbSDimitry Andric   Register Reg = createIncompleteVirtualRegister(Name);
1910b57cec5SDimitry Andric   // FIXME: Should we use a dummy register class?
1920b57cec5SDimitry Andric   VRegInfo[Reg].first = static_cast<RegisterBank *>(nullptr);
1930b57cec5SDimitry Andric   setType(Reg, Ty);
1940b57cec5SDimitry Andric   if (TheDelegate)
1950b57cec5SDimitry Andric     TheDelegate->MRI_NoteNewVirtualRegister(Reg);
1960b57cec5SDimitry Andric   return Reg;
1970b57cec5SDimitry Andric }
1980b57cec5SDimitry Andric 
clearVirtRegTypes()1990b57cec5SDimitry Andric void MachineRegisterInfo::clearVirtRegTypes() { VRegToType.clear(); }
2000b57cec5SDimitry Andric 
2010b57cec5SDimitry Andric /// clearVirtRegs - Remove all virtual registers (after physreg assignment).
clearVirtRegs()2020b57cec5SDimitry Andric void MachineRegisterInfo::clearVirtRegs() {
2030b57cec5SDimitry Andric #ifndef NDEBUG
2040b57cec5SDimitry Andric   for (unsigned i = 0, e = getNumVirtRegs(); i != e; ++i) {
2055ffd83dbSDimitry Andric     Register Reg = Register::index2VirtReg(i);
2060b57cec5SDimitry Andric     if (!VRegInfo[Reg].second)
2070b57cec5SDimitry Andric       continue;
2080b57cec5SDimitry Andric     verifyUseList(Reg);
2090b57cec5SDimitry Andric     llvm_unreachable("Remaining virtual register operands");
2100b57cec5SDimitry Andric   }
2110b57cec5SDimitry Andric #endif
2120b57cec5SDimitry Andric   VRegInfo.clear();
2130b57cec5SDimitry Andric   for (auto &I : LiveIns)
2140b57cec5SDimitry Andric     I.second = 0;
2150b57cec5SDimitry Andric }
2160b57cec5SDimitry Andric 
verifyUseList(Register Reg) const2175ffd83dbSDimitry Andric void MachineRegisterInfo::verifyUseList(Register Reg) const {
2180b57cec5SDimitry Andric #ifndef NDEBUG
2190b57cec5SDimitry Andric   bool Valid = true;
2200b57cec5SDimitry Andric   for (MachineOperand &M : reg_operands(Reg)) {
2210b57cec5SDimitry Andric     MachineOperand *MO = &M;
2220b57cec5SDimitry Andric     MachineInstr *MI = MO->getParent();
2230b57cec5SDimitry Andric     if (!MI) {
2240b57cec5SDimitry Andric       errs() << printReg(Reg, getTargetRegisterInfo())
2250b57cec5SDimitry Andric              << " use list MachineOperand " << MO
2260b57cec5SDimitry Andric              << " has no parent instruction.\n";
2270b57cec5SDimitry Andric       Valid = false;
2280b57cec5SDimitry Andric       continue;
2290b57cec5SDimitry Andric     }
2300b57cec5SDimitry Andric     MachineOperand *MO0 = &MI->getOperand(0);
2310b57cec5SDimitry Andric     unsigned NumOps = MI->getNumOperands();
2320b57cec5SDimitry Andric     if (!(MO >= MO0 && MO < MO0+NumOps)) {
2330b57cec5SDimitry Andric       errs() << printReg(Reg, getTargetRegisterInfo())
2340b57cec5SDimitry Andric              << " use list MachineOperand " << MO
2350b57cec5SDimitry Andric              << " doesn't belong to parent MI: " << *MI;
2360b57cec5SDimitry Andric       Valid = false;
2370b57cec5SDimitry Andric     }
2380b57cec5SDimitry Andric     if (!MO->isReg()) {
2390b57cec5SDimitry Andric       errs() << printReg(Reg, getTargetRegisterInfo())
2400b57cec5SDimitry Andric              << " MachineOperand " << MO << ": " << *MO
2410b57cec5SDimitry Andric              << " is not a register\n";
2420b57cec5SDimitry Andric       Valid = false;
2430b57cec5SDimitry Andric     }
2440b57cec5SDimitry Andric     if (MO->getReg() != Reg) {
2450b57cec5SDimitry Andric       errs() << printReg(Reg, getTargetRegisterInfo())
2460b57cec5SDimitry Andric              << " use-list MachineOperand " << MO << ": "
2470b57cec5SDimitry Andric              << *MO << " is the wrong register\n";
2480b57cec5SDimitry Andric       Valid = false;
2490b57cec5SDimitry Andric     }
2500b57cec5SDimitry Andric   }
2510b57cec5SDimitry Andric   assert(Valid && "Invalid use list");
2520b57cec5SDimitry Andric #endif
2530b57cec5SDimitry Andric }
2540b57cec5SDimitry Andric 
verifyUseLists() const2550b57cec5SDimitry Andric void MachineRegisterInfo::verifyUseLists() const {
2560b57cec5SDimitry Andric #ifndef NDEBUG
2570b57cec5SDimitry Andric   for (unsigned i = 0, e = getNumVirtRegs(); i != e; ++i)
2588bcb0991SDimitry Andric     verifyUseList(Register::index2VirtReg(i));
2590b57cec5SDimitry Andric   for (unsigned i = 1, e = getTargetRegisterInfo()->getNumRegs(); i != e; ++i)
2600b57cec5SDimitry Andric     verifyUseList(i);
2610b57cec5SDimitry Andric #endif
2620b57cec5SDimitry Andric }
2630b57cec5SDimitry Andric 
2640b57cec5SDimitry Andric /// Add MO to the linked list of operands for its register.
addRegOperandToUseList(MachineOperand * MO)2650b57cec5SDimitry Andric void MachineRegisterInfo::addRegOperandToUseList(MachineOperand *MO) {
2660b57cec5SDimitry Andric   assert(!MO->isOnRegUseList() && "Already on list");
2670b57cec5SDimitry Andric   MachineOperand *&HeadRef = getRegUseDefListHead(MO->getReg());
2680b57cec5SDimitry Andric   MachineOperand *const Head = HeadRef;
2690b57cec5SDimitry Andric 
2700b57cec5SDimitry Andric   // Head points to the first list element.
2710b57cec5SDimitry Andric   // Next is NULL on the last list element.
2720b57cec5SDimitry Andric   // Prev pointers are circular, so Head->Prev == Last.
2730b57cec5SDimitry Andric 
2740b57cec5SDimitry Andric   // Head is NULL for an empty list.
2750b57cec5SDimitry Andric   if (!Head) {
2760b57cec5SDimitry Andric     MO->Contents.Reg.Prev = MO;
2770b57cec5SDimitry Andric     MO->Contents.Reg.Next = nullptr;
2780b57cec5SDimitry Andric     HeadRef = MO;
2790b57cec5SDimitry Andric     return;
2800b57cec5SDimitry Andric   }
2810b57cec5SDimitry Andric   assert(MO->getReg() == Head->getReg() && "Different regs on the same list!");
2820b57cec5SDimitry Andric 
2830b57cec5SDimitry Andric   // Insert MO between Last and Head in the circular Prev chain.
2840b57cec5SDimitry Andric   MachineOperand *Last = Head->Contents.Reg.Prev;
2850b57cec5SDimitry Andric   assert(Last && "Inconsistent use list");
2860b57cec5SDimitry Andric   assert(MO->getReg() == Last->getReg() && "Different regs on the same list!");
2870b57cec5SDimitry Andric   Head->Contents.Reg.Prev = MO;
2880b57cec5SDimitry Andric   MO->Contents.Reg.Prev = Last;
2890b57cec5SDimitry Andric 
2900b57cec5SDimitry Andric   // Def operands always precede uses. This allows def_iterator to stop early.
2910b57cec5SDimitry Andric   // Insert def operands at the front, and use operands at the back.
2920b57cec5SDimitry Andric   if (MO->isDef()) {
2930b57cec5SDimitry Andric     // Insert def at the front.
2940b57cec5SDimitry Andric     MO->Contents.Reg.Next = Head;
2950b57cec5SDimitry Andric     HeadRef = MO;
2960b57cec5SDimitry Andric   } else {
2970b57cec5SDimitry Andric     // Insert use at the end.
2980b57cec5SDimitry Andric     MO->Contents.Reg.Next = nullptr;
2990b57cec5SDimitry Andric     Last->Contents.Reg.Next = MO;
3000b57cec5SDimitry Andric   }
3010b57cec5SDimitry Andric }
3020b57cec5SDimitry Andric 
3030b57cec5SDimitry Andric /// Remove MO from its use-def list.
removeRegOperandFromUseList(MachineOperand * MO)3040b57cec5SDimitry Andric void MachineRegisterInfo::removeRegOperandFromUseList(MachineOperand *MO) {
3050b57cec5SDimitry Andric   assert(MO->isOnRegUseList() && "Operand not on use list");
3060b57cec5SDimitry Andric   MachineOperand *&HeadRef = getRegUseDefListHead(MO->getReg());
3070b57cec5SDimitry Andric   MachineOperand *const Head = HeadRef;
3080b57cec5SDimitry Andric   assert(Head && "List already empty");
3090b57cec5SDimitry Andric 
3100b57cec5SDimitry Andric   // Unlink this from the doubly linked list of operands.
3110b57cec5SDimitry Andric   MachineOperand *Next = MO->Contents.Reg.Next;
3120b57cec5SDimitry Andric   MachineOperand *Prev = MO->Contents.Reg.Prev;
3130b57cec5SDimitry Andric 
3140b57cec5SDimitry Andric   // Prev links are circular, next link is NULL instead of looping back to Head.
3150b57cec5SDimitry Andric   if (MO == Head)
3160b57cec5SDimitry Andric     HeadRef = Next;
3170b57cec5SDimitry Andric   else
3180b57cec5SDimitry Andric     Prev->Contents.Reg.Next = Next;
3190b57cec5SDimitry Andric 
3200b57cec5SDimitry Andric   (Next ? Next : Head)->Contents.Reg.Prev = Prev;
3210b57cec5SDimitry Andric 
3220b57cec5SDimitry Andric   MO->Contents.Reg.Prev = nullptr;
3230b57cec5SDimitry Andric   MO->Contents.Reg.Next = nullptr;
3240b57cec5SDimitry Andric }
3250b57cec5SDimitry Andric 
3260b57cec5SDimitry Andric /// Move NumOps operands from Src to Dst, updating use-def lists as needed.
3270b57cec5SDimitry Andric ///
3280b57cec5SDimitry Andric /// The Dst range is assumed to be uninitialized memory. (Or it may contain
3290b57cec5SDimitry Andric /// operands that won't be destroyed, which is OK because the MO destructor is
3300b57cec5SDimitry Andric /// trivial anyway).
3310b57cec5SDimitry Andric ///
3320b57cec5SDimitry Andric /// The Src and Dst ranges may overlap.
moveOperands(MachineOperand * Dst,MachineOperand * Src,unsigned NumOps)3330b57cec5SDimitry Andric void MachineRegisterInfo::moveOperands(MachineOperand *Dst,
3340b57cec5SDimitry Andric                                        MachineOperand *Src,
3350b57cec5SDimitry Andric                                        unsigned NumOps) {
3360b57cec5SDimitry Andric   assert(Src != Dst && NumOps && "Noop moveOperands");
3370b57cec5SDimitry Andric 
3380b57cec5SDimitry Andric   // Copy backwards if Dst is within the Src range.
3390b57cec5SDimitry Andric   int Stride = 1;
3400b57cec5SDimitry Andric   if (Dst >= Src && Dst < Src + NumOps) {
3410b57cec5SDimitry Andric     Stride = -1;
3420b57cec5SDimitry Andric     Dst += NumOps - 1;
3430b57cec5SDimitry Andric     Src += NumOps - 1;
3440b57cec5SDimitry Andric   }
3450b57cec5SDimitry Andric 
3460b57cec5SDimitry Andric   // Copy one operand at a time.
3470b57cec5SDimitry Andric   do {
3480b57cec5SDimitry Andric     new (Dst) MachineOperand(*Src);
3490b57cec5SDimitry Andric 
3500b57cec5SDimitry Andric     // Dst takes Src's place in the use-def chain.
3510b57cec5SDimitry Andric     if (Src->isReg()) {
3520b57cec5SDimitry Andric       MachineOperand *&Head = getRegUseDefListHead(Src->getReg());
3530b57cec5SDimitry Andric       MachineOperand *Prev = Src->Contents.Reg.Prev;
3540b57cec5SDimitry Andric       MachineOperand *Next = Src->Contents.Reg.Next;
3550b57cec5SDimitry Andric       assert(Head && "List empty, but operand is chained");
3560b57cec5SDimitry Andric       assert(Prev && "Operand was not on use-def list");
3570b57cec5SDimitry Andric 
3580b57cec5SDimitry Andric       // Prev links are circular, next link is NULL instead of looping back to
3590b57cec5SDimitry Andric       // Head.
3600b57cec5SDimitry Andric       if (Src == Head)
3610b57cec5SDimitry Andric         Head = Dst;
3620b57cec5SDimitry Andric       else
3630b57cec5SDimitry Andric         Prev->Contents.Reg.Next = Dst;
3640b57cec5SDimitry Andric 
3650b57cec5SDimitry Andric       // Update Prev pointer. This also works when Src was pointing to itself
3660b57cec5SDimitry Andric       // in a 1-element list. In that case Head == Dst.
3670b57cec5SDimitry Andric       (Next ? Next : Head)->Contents.Reg.Prev = Dst;
3680b57cec5SDimitry Andric     }
3690b57cec5SDimitry Andric 
3700b57cec5SDimitry Andric     Dst += Stride;
3710b57cec5SDimitry Andric     Src += Stride;
3720b57cec5SDimitry Andric   } while (--NumOps);
3730b57cec5SDimitry Andric }
3740b57cec5SDimitry Andric 
3750b57cec5SDimitry Andric /// replaceRegWith - Replace all instances of FromReg with ToReg in the
3760b57cec5SDimitry Andric /// machine function.  This is like llvm-level X->replaceAllUsesWith(Y),
3770b57cec5SDimitry Andric /// except that it also changes any definitions of the register as well.
3780b57cec5SDimitry Andric /// If ToReg is a physical register we apply the sub register to obtain the
3790b57cec5SDimitry Andric /// final/proper physical register.
replaceRegWith(Register FromReg,Register ToReg)3805ffd83dbSDimitry Andric void MachineRegisterInfo::replaceRegWith(Register FromReg, Register ToReg) {
3810b57cec5SDimitry Andric   assert(FromReg != ToReg && "Cannot replace a reg with itself");
3820b57cec5SDimitry Andric 
3830b57cec5SDimitry Andric   const TargetRegisterInfo *TRI = getTargetRegisterInfo();
3840b57cec5SDimitry Andric 
3850b57cec5SDimitry Andric   // TODO: This could be more efficient by bulk changing the operands.
3860b57cec5SDimitry Andric   for (reg_iterator I = reg_begin(FromReg), E = reg_end(); I != E; ) {
3870b57cec5SDimitry Andric     MachineOperand &O = *I;
3880b57cec5SDimitry Andric     ++I;
3898bcb0991SDimitry Andric     if (Register::isPhysicalRegister(ToReg)) {
3900b57cec5SDimitry Andric       O.substPhysReg(ToReg, *TRI);
3910b57cec5SDimitry Andric     } else {
3920b57cec5SDimitry Andric       O.setReg(ToReg);
3930b57cec5SDimitry Andric     }
3940b57cec5SDimitry Andric   }
3950b57cec5SDimitry Andric }
3960b57cec5SDimitry Andric 
3970b57cec5SDimitry Andric /// getVRegDef - Return the machine instr that defines the specified virtual
3980b57cec5SDimitry Andric /// register or null if none is found.  This assumes that the code is in SSA
3990b57cec5SDimitry Andric /// form, so there should only be one definition.
getVRegDef(Register Reg) const4005ffd83dbSDimitry Andric MachineInstr *MachineRegisterInfo::getVRegDef(Register Reg) const {
4010b57cec5SDimitry Andric   // Since we are in SSA form, we can use the first definition.
4020b57cec5SDimitry Andric   def_instr_iterator I = def_instr_begin(Reg);
4030b57cec5SDimitry Andric   assert((I.atEnd() || std::next(I) == def_instr_end()) &&
4040b57cec5SDimitry Andric          "getVRegDef assumes a single definition or no definition");
4050b57cec5SDimitry Andric   return !I.atEnd() ? &*I : nullptr;
4060b57cec5SDimitry Andric }
4070b57cec5SDimitry Andric 
4080b57cec5SDimitry Andric /// getUniqueVRegDef - Return the unique machine instr that defines the
4090b57cec5SDimitry Andric /// specified virtual register or null if none is found.  If there are
4100b57cec5SDimitry Andric /// multiple definitions or no definition, return null.
getUniqueVRegDef(Register Reg) const4115ffd83dbSDimitry Andric MachineInstr *MachineRegisterInfo::getUniqueVRegDef(Register Reg) const {
4120b57cec5SDimitry Andric   if (def_empty(Reg)) return nullptr;
4130b57cec5SDimitry Andric   def_instr_iterator I = def_instr_begin(Reg);
4140b57cec5SDimitry Andric   if (std::next(I) != def_instr_end())
4150b57cec5SDimitry Andric     return nullptr;
4160b57cec5SDimitry Andric   return &*I;
4170b57cec5SDimitry Andric }
4180b57cec5SDimitry Andric 
hasOneNonDBGUse(Register RegNo) const4195ffd83dbSDimitry Andric bool MachineRegisterInfo::hasOneNonDBGUse(Register RegNo) const {
420af732203SDimitry Andric   return hasSingleElement(use_nodbg_operands(RegNo));
4210b57cec5SDimitry Andric }
4220b57cec5SDimitry Andric 
hasOneNonDBGUser(Register RegNo) const4235ffd83dbSDimitry Andric bool MachineRegisterInfo::hasOneNonDBGUser(Register RegNo) const {
424af732203SDimitry Andric   return hasSingleElement(use_nodbg_instructions(RegNo));
4250b57cec5SDimitry Andric }
4260b57cec5SDimitry Andric 
4270b57cec5SDimitry Andric /// clearKillFlags - Iterate over all the uses of the given register and
4280b57cec5SDimitry Andric /// clear the kill flag from the MachineOperand. This function is used by
4290b57cec5SDimitry Andric /// optimization passes which extend register lifetimes and need only
4300b57cec5SDimitry Andric /// preserve conservative kill flag information.
clearKillFlags(Register Reg) const4315ffd83dbSDimitry Andric void MachineRegisterInfo::clearKillFlags(Register Reg) const {
4320b57cec5SDimitry Andric   for (MachineOperand &MO : use_operands(Reg))
4330b57cec5SDimitry Andric     MO.setIsKill(false);
4340b57cec5SDimitry Andric }
4350b57cec5SDimitry Andric 
isLiveIn(Register Reg) const4365ffd83dbSDimitry Andric bool MachineRegisterInfo::isLiveIn(Register Reg) const {
437*5f7ddb14SDimitry Andric   for (const std::pair<MCRegister, Register> &LI : liveins())
438*5f7ddb14SDimitry Andric     if ((Register)LI.first == Reg || LI.second == Reg)
4390b57cec5SDimitry Andric       return true;
4400b57cec5SDimitry Andric   return false;
4410b57cec5SDimitry Andric }
4420b57cec5SDimitry Andric 
4430b57cec5SDimitry Andric /// getLiveInPhysReg - If VReg is a live-in virtual register, return the
4440b57cec5SDimitry Andric /// corresponding live-in physical register.
getLiveInPhysReg(Register VReg) const4455ffd83dbSDimitry Andric MCRegister MachineRegisterInfo::getLiveInPhysReg(Register VReg) const {
446*5f7ddb14SDimitry Andric   for (const std::pair<MCRegister, Register> &LI : liveins())
447*5f7ddb14SDimitry Andric     if (LI.second == VReg)
448*5f7ddb14SDimitry Andric       return LI.first;
4495ffd83dbSDimitry Andric   return MCRegister();
4500b57cec5SDimitry Andric }
4510b57cec5SDimitry Andric 
4520b57cec5SDimitry Andric /// getLiveInVirtReg - If PReg is a live-in physical register, return the
4530b57cec5SDimitry Andric /// corresponding live-in physical register.
getLiveInVirtReg(MCRegister PReg) const4545ffd83dbSDimitry Andric Register MachineRegisterInfo::getLiveInVirtReg(MCRegister PReg) const {
455*5f7ddb14SDimitry Andric   for (const std::pair<MCRegister, Register> &LI : liveins())
456*5f7ddb14SDimitry Andric     if (LI.first == PReg)
457*5f7ddb14SDimitry Andric       return LI.second;
4585ffd83dbSDimitry Andric   return Register();
4590b57cec5SDimitry Andric }
4600b57cec5SDimitry Andric 
4610b57cec5SDimitry Andric /// EmitLiveInCopies - Emit copies to initialize livein virtual registers
4620b57cec5SDimitry Andric /// into the given entry block.
4630b57cec5SDimitry Andric void
EmitLiveInCopies(MachineBasicBlock * EntryMBB,const TargetRegisterInfo & TRI,const TargetInstrInfo & TII)4640b57cec5SDimitry Andric MachineRegisterInfo::EmitLiveInCopies(MachineBasicBlock *EntryMBB,
4650b57cec5SDimitry Andric                                       const TargetRegisterInfo &TRI,
4660b57cec5SDimitry Andric                                       const TargetInstrInfo &TII) {
4670b57cec5SDimitry Andric   // Emit the copies into the top of the block.
4680b57cec5SDimitry Andric   for (unsigned i = 0, e = LiveIns.size(); i != e; ++i)
4690b57cec5SDimitry Andric     if (LiveIns[i].second) {
4700b57cec5SDimitry Andric       if (use_nodbg_empty(LiveIns[i].second)) {
4710b57cec5SDimitry Andric         // The livein has no non-dbg uses. Drop it.
4720b57cec5SDimitry Andric         //
4730b57cec5SDimitry Andric         // It would be preferable to have isel avoid creating live-in
4740b57cec5SDimitry Andric         // records for unused arguments in the first place, but it's
4750b57cec5SDimitry Andric         // complicated by the debug info code for arguments.
4760b57cec5SDimitry Andric         LiveIns.erase(LiveIns.begin() + i);
4770b57cec5SDimitry Andric         --i; --e;
4780b57cec5SDimitry Andric       } else {
4790b57cec5SDimitry Andric         // Emit a copy.
4800b57cec5SDimitry Andric         BuildMI(*EntryMBB, EntryMBB->begin(), DebugLoc(),
4810b57cec5SDimitry Andric                 TII.get(TargetOpcode::COPY), LiveIns[i].second)
4820b57cec5SDimitry Andric           .addReg(LiveIns[i].first);
4830b57cec5SDimitry Andric 
4840b57cec5SDimitry Andric         // Add the register to the entry block live-in set.
4850b57cec5SDimitry Andric         EntryMBB->addLiveIn(LiveIns[i].first);
4860b57cec5SDimitry Andric       }
4870b57cec5SDimitry Andric     } else {
4880b57cec5SDimitry Andric       // Add the register to the entry block live-in set.
4890b57cec5SDimitry Andric       EntryMBB->addLiveIn(LiveIns[i].first);
4900b57cec5SDimitry Andric     }
4910b57cec5SDimitry Andric }
4920b57cec5SDimitry Andric 
getMaxLaneMaskForVReg(Register Reg) const4935ffd83dbSDimitry Andric LaneBitmask MachineRegisterInfo::getMaxLaneMaskForVReg(Register Reg) const {
4940b57cec5SDimitry Andric   // Lane masks are only defined for vregs.
4958bcb0991SDimitry Andric   assert(Register::isVirtualRegister(Reg));
4960b57cec5SDimitry Andric   const TargetRegisterClass &TRC = *getRegClass(Reg);
4970b57cec5SDimitry Andric   return TRC.getLaneMask();
4980b57cec5SDimitry Andric }
4990b57cec5SDimitry Andric 
5000b57cec5SDimitry Andric #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
dumpUses(Register Reg) const5015ffd83dbSDimitry Andric LLVM_DUMP_METHOD void MachineRegisterInfo::dumpUses(Register Reg) const {
5020b57cec5SDimitry Andric   for (MachineInstr &I : use_instructions(Reg))
5030b57cec5SDimitry Andric     I.dump();
5040b57cec5SDimitry Andric }
5050b57cec5SDimitry Andric #endif
5060b57cec5SDimitry Andric 
freezeReservedRegs(const MachineFunction & MF)5070b57cec5SDimitry Andric void MachineRegisterInfo::freezeReservedRegs(const MachineFunction &MF) {
5080b57cec5SDimitry Andric   ReservedRegs = getTargetRegisterInfo()->getReservedRegs(MF);
5090b57cec5SDimitry Andric   assert(ReservedRegs.size() == getTargetRegisterInfo()->getNumRegs() &&
5100b57cec5SDimitry Andric          "Invalid ReservedRegs vector from target");
5110b57cec5SDimitry Andric }
5120b57cec5SDimitry Andric 
isConstantPhysReg(MCRegister PhysReg) const5135ffd83dbSDimitry Andric bool MachineRegisterInfo::isConstantPhysReg(MCRegister PhysReg) const {
5148bcb0991SDimitry Andric   assert(Register::isPhysicalRegister(PhysReg));
5150b57cec5SDimitry Andric 
5160b57cec5SDimitry Andric   const TargetRegisterInfo *TRI = getTargetRegisterInfo();
5170b57cec5SDimitry Andric   if (TRI->isConstantPhysReg(PhysReg))
5180b57cec5SDimitry Andric     return true;
5190b57cec5SDimitry Andric 
5200b57cec5SDimitry Andric   // Check if any overlapping register is modified, or allocatable so it may be
5210b57cec5SDimitry Andric   // used later.
5220b57cec5SDimitry Andric   for (MCRegAliasIterator AI(PhysReg, TRI, true);
5230b57cec5SDimitry Andric        AI.isValid(); ++AI)
5240b57cec5SDimitry Andric     if (!def_empty(*AI) || isAllocatable(*AI))
5250b57cec5SDimitry Andric       return false;
5260b57cec5SDimitry Andric   return true;
5270b57cec5SDimitry Andric }
5280b57cec5SDimitry Andric 
5290b57cec5SDimitry Andric /// markUsesInDebugValueAsUndef - Mark every DBG_VALUE referencing the
5300b57cec5SDimitry Andric /// specified register as undefined which causes the DBG_VALUE to be
5310b57cec5SDimitry Andric /// deleted during LiveDebugVariables analysis.
markUsesInDebugValueAsUndef(Register Reg) const5325ffd83dbSDimitry Andric void MachineRegisterInfo::markUsesInDebugValueAsUndef(Register Reg) const {
533*5f7ddb14SDimitry Andric   // Mark any DBG_VALUE* that uses Reg as undef (but don't delete it.)
534*5f7ddb14SDimitry Andric   // We use make_early_inc_range because setReg invalidates the iterator.
535*5f7ddb14SDimitry Andric   for (MachineInstr &UseMI : llvm::make_early_inc_range(use_instructions(Reg))) {
536*5f7ddb14SDimitry Andric     if (UseMI.isDebugValue() && UseMI.hasDebugOperandForReg(Reg))
537*5f7ddb14SDimitry Andric       UseMI.setDebugValueUndef();
5380b57cec5SDimitry Andric   }
5390b57cec5SDimitry Andric }
5400b57cec5SDimitry Andric 
getCalledFunction(const MachineInstr & MI)5410b57cec5SDimitry Andric static const Function *getCalledFunction(const MachineInstr &MI) {
5420b57cec5SDimitry Andric   for (const MachineOperand &MO : MI.operands()) {
5430b57cec5SDimitry Andric     if (!MO.isGlobal())
5440b57cec5SDimitry Andric       continue;
5450b57cec5SDimitry Andric     const Function *Func = dyn_cast<Function>(MO.getGlobal());
5460b57cec5SDimitry Andric     if (Func != nullptr)
5470b57cec5SDimitry Andric       return Func;
5480b57cec5SDimitry Andric   }
5490b57cec5SDimitry Andric   return nullptr;
5500b57cec5SDimitry Andric }
5510b57cec5SDimitry Andric 
isNoReturnDef(const MachineOperand & MO)5520b57cec5SDimitry Andric static bool isNoReturnDef(const MachineOperand &MO) {
5530b57cec5SDimitry Andric   // Anything which is not a noreturn function is a real def.
5540b57cec5SDimitry Andric   const MachineInstr &MI = *MO.getParent();
5550b57cec5SDimitry Andric   if (!MI.isCall())
5560b57cec5SDimitry Andric     return false;
5570b57cec5SDimitry Andric   const MachineBasicBlock &MBB = *MI.getParent();
5580b57cec5SDimitry Andric   if (!MBB.succ_empty())
5590b57cec5SDimitry Andric     return false;
5600b57cec5SDimitry Andric   const MachineFunction &MF = *MBB.getParent();
5610b57cec5SDimitry Andric   // We need to keep correct unwind information even if the function will
5620b57cec5SDimitry Andric   // not return, since the runtime may need it.
5630b57cec5SDimitry Andric   if (MF.getFunction().hasFnAttribute(Attribute::UWTable))
5640b57cec5SDimitry Andric     return false;
5650b57cec5SDimitry Andric   const Function *Called = getCalledFunction(MI);
5660b57cec5SDimitry Andric   return !(Called == nullptr || !Called->hasFnAttribute(Attribute::NoReturn) ||
5670b57cec5SDimitry Andric            !Called->hasFnAttribute(Attribute::NoUnwind));
5680b57cec5SDimitry Andric }
5690b57cec5SDimitry Andric 
isPhysRegModified(MCRegister PhysReg,bool SkipNoReturnDef) const5705ffd83dbSDimitry Andric bool MachineRegisterInfo::isPhysRegModified(MCRegister PhysReg,
5710b57cec5SDimitry Andric                                             bool SkipNoReturnDef) const {
5720b57cec5SDimitry Andric   if (UsedPhysRegMask.test(PhysReg))
5730b57cec5SDimitry Andric     return true;
5740b57cec5SDimitry Andric   const TargetRegisterInfo *TRI = getTargetRegisterInfo();
5750b57cec5SDimitry Andric   for (MCRegAliasIterator AI(PhysReg, TRI, true); AI.isValid(); ++AI) {
5760b57cec5SDimitry Andric     for (const MachineOperand &MO : make_range(def_begin(*AI), def_end())) {
5770b57cec5SDimitry Andric       if (!SkipNoReturnDef && isNoReturnDef(MO))
5780b57cec5SDimitry Andric         continue;
5790b57cec5SDimitry Andric       return true;
5800b57cec5SDimitry Andric     }
5810b57cec5SDimitry Andric   }
5820b57cec5SDimitry Andric   return false;
5830b57cec5SDimitry Andric }
5840b57cec5SDimitry Andric 
isPhysRegUsed(MCRegister PhysReg,bool SkipRegMaskTest) const585*5f7ddb14SDimitry Andric bool MachineRegisterInfo::isPhysRegUsed(MCRegister PhysReg,
586*5f7ddb14SDimitry Andric                                         bool SkipRegMaskTest) const {
587*5f7ddb14SDimitry Andric   if (!SkipRegMaskTest && UsedPhysRegMask.test(PhysReg))
5880b57cec5SDimitry Andric     return true;
5890b57cec5SDimitry Andric   const TargetRegisterInfo *TRI = getTargetRegisterInfo();
5900b57cec5SDimitry Andric   for (MCRegAliasIterator AliasReg(PhysReg, TRI, true); AliasReg.isValid();
5910b57cec5SDimitry Andric        ++AliasReg) {
5920b57cec5SDimitry Andric     if (!reg_nodbg_empty(*AliasReg))
5930b57cec5SDimitry Andric       return true;
5940b57cec5SDimitry Andric   }
5950b57cec5SDimitry Andric   return false;
5960b57cec5SDimitry Andric }
5970b57cec5SDimitry Andric 
disableCalleeSavedRegister(MCRegister Reg)5985ffd83dbSDimitry Andric void MachineRegisterInfo::disableCalleeSavedRegister(MCRegister Reg) {
5990b57cec5SDimitry Andric 
6000b57cec5SDimitry Andric   const TargetRegisterInfo *TRI = getTargetRegisterInfo();
6010b57cec5SDimitry Andric   assert(Reg && (Reg < TRI->getNumRegs()) &&
6020b57cec5SDimitry Andric          "Trying to disable an invalid register");
6030b57cec5SDimitry Andric 
6040b57cec5SDimitry Andric   if (!IsUpdatedCSRsInitialized) {
6050b57cec5SDimitry Andric     const MCPhysReg *CSR = TRI->getCalleeSavedRegs(MF);
6060b57cec5SDimitry Andric     for (const MCPhysReg *I = CSR; *I; ++I)
6070b57cec5SDimitry Andric       UpdatedCSRs.push_back(*I);
6080b57cec5SDimitry Andric 
6090b57cec5SDimitry Andric     // Zero value represents the end of the register list
6100b57cec5SDimitry Andric     // (no more registers should be pushed).
6110b57cec5SDimitry Andric     UpdatedCSRs.push_back(0);
6120b57cec5SDimitry Andric 
6130b57cec5SDimitry Andric     IsUpdatedCSRsInitialized = true;
6140b57cec5SDimitry Andric   }
6150b57cec5SDimitry Andric 
6160b57cec5SDimitry Andric   // Remove the register (and its aliases from the list).
6170b57cec5SDimitry Andric   for (MCRegAliasIterator AI(Reg, TRI, true); AI.isValid(); ++AI)
618af732203SDimitry Andric     llvm::erase_value(UpdatedCSRs, *AI);
6190b57cec5SDimitry Andric }
6200b57cec5SDimitry Andric 
getCalleeSavedRegs() const6210b57cec5SDimitry Andric const MCPhysReg *MachineRegisterInfo::getCalleeSavedRegs() const {
6220b57cec5SDimitry Andric   if (IsUpdatedCSRsInitialized)
6230b57cec5SDimitry Andric     return UpdatedCSRs.data();
6240b57cec5SDimitry Andric 
6250b57cec5SDimitry Andric   return getTargetRegisterInfo()->getCalleeSavedRegs(MF);
6260b57cec5SDimitry Andric }
6270b57cec5SDimitry Andric 
setCalleeSavedRegs(ArrayRef<MCPhysReg> CSRs)6280b57cec5SDimitry Andric void MachineRegisterInfo::setCalleeSavedRegs(ArrayRef<MCPhysReg> CSRs) {
6290b57cec5SDimitry Andric   if (IsUpdatedCSRsInitialized)
6300b57cec5SDimitry Andric     UpdatedCSRs.clear();
6310b57cec5SDimitry Andric 
632af732203SDimitry Andric   append_range(UpdatedCSRs, CSRs);
6330b57cec5SDimitry Andric 
6340b57cec5SDimitry Andric   // Zero value represents the end of the register list
6350b57cec5SDimitry Andric   // (no more registers should be pushed).
6360b57cec5SDimitry Andric   UpdatedCSRs.push_back(0);
6370b57cec5SDimitry Andric   IsUpdatedCSRsInitialized = true;
6380b57cec5SDimitry Andric }
6390b57cec5SDimitry Andric 
isReservedRegUnit(unsigned Unit) const6400b57cec5SDimitry Andric bool MachineRegisterInfo::isReservedRegUnit(unsigned Unit) const {
6410b57cec5SDimitry Andric   const TargetRegisterInfo *TRI = getTargetRegisterInfo();
6420b57cec5SDimitry Andric   for (MCRegUnitRootIterator Root(Unit, TRI); Root.isValid(); ++Root) {
6430b57cec5SDimitry Andric     bool IsRootReserved = true;
6440b57cec5SDimitry Andric     for (MCSuperRegIterator Super(*Root, TRI, /*IncludeSelf=*/true);
6450b57cec5SDimitry Andric          Super.isValid(); ++Super) {
646af732203SDimitry Andric       MCRegister Reg = *Super;
6470b57cec5SDimitry Andric       if (!isReserved(Reg)) {
6480b57cec5SDimitry Andric         IsRootReserved = false;
6490b57cec5SDimitry Andric         break;
6500b57cec5SDimitry Andric       }
6510b57cec5SDimitry Andric     }
6520b57cec5SDimitry Andric     if (IsRootReserved)
6530b57cec5SDimitry Andric       return true;
6540b57cec5SDimitry Andric   }
6550b57cec5SDimitry Andric   return false;
6560b57cec5SDimitry Andric }
657