xref: /freebsd-src/contrib/llvm-project/llvm/lib/CodeGen/MachineRegisterInfo.cpp (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
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/MachineBasicBlock.h"
160b57cec5SDimitry Andric #include "llvm/CodeGen/MachineFunction.h"
170b57cec5SDimitry Andric #include "llvm/CodeGen/MachineInstr.h"
180b57cec5SDimitry Andric #include "llvm/CodeGen/MachineInstrBuilder.h"
190b57cec5SDimitry Andric #include "llvm/CodeGen/MachineOperand.h"
200b57cec5SDimitry Andric #include "llvm/CodeGen/TargetInstrInfo.h"
210b57cec5SDimitry Andric #include "llvm/CodeGen/TargetRegisterInfo.h"
220b57cec5SDimitry Andric #include "llvm/CodeGen/TargetSubtargetInfo.h"
230b57cec5SDimitry Andric #include "llvm/Config/llvm-config.h"
240b57cec5SDimitry Andric #include "llvm/IR/Attributes.h"
250b57cec5SDimitry Andric #include "llvm/IR/DebugLoc.h"
260b57cec5SDimitry Andric #include "llvm/IR/Function.h"
270b57cec5SDimitry Andric #include "llvm/MC/MCRegisterInfo.h"
280b57cec5SDimitry Andric #include "llvm/Support/Casting.h"
290b57cec5SDimitry Andric #include "llvm/Support/CommandLine.h"
300b57cec5SDimitry Andric #include "llvm/Support/Compiler.h"
310b57cec5SDimitry Andric #include "llvm/Support/ErrorHandling.h"
320b57cec5SDimitry Andric #include "llvm/Support/raw_ostream.h"
330b57cec5SDimitry Andric #include <cassert>
340b57cec5SDimitry Andric 
350b57cec5SDimitry Andric using namespace llvm;
360b57cec5SDimitry Andric 
370b57cec5SDimitry Andric static cl::opt<bool> EnableSubRegLiveness("enable-subreg-liveness", cl::Hidden,
380b57cec5SDimitry Andric   cl::init(true), cl::desc("Enable subregister liveness tracking."));
390b57cec5SDimitry Andric 
400b57cec5SDimitry Andric // Pin the vtable to this file.
410b57cec5SDimitry Andric void MachineRegisterInfo::Delegate::anchor() {}
420b57cec5SDimitry Andric 
430b57cec5SDimitry Andric MachineRegisterInfo::MachineRegisterInfo(MachineFunction *MF)
44*0fca6ea1SDimitry Andric     : MF(MF),
45*0fca6ea1SDimitry Andric       TracksSubRegLiveness(EnableSubRegLiveness.getNumOccurrences()
46*0fca6ea1SDimitry Andric                                ? EnableSubRegLiveness
47*0fca6ea1SDimitry Andric                                : MF->getSubtarget().enableSubRegLiveness()) {
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]());
53bdd1243dSDimitry Andric   TheDelegates.clear();
540b57cec5SDimitry Andric }
550b57cec5SDimitry Andric 
560b57cec5SDimitry Andric /// setRegClass - Set the register class of the specified virtual register.
570b57cec5SDimitry Andric ///
580b57cec5SDimitry Andric void
595ffd83dbSDimitry Andric MachineRegisterInfo::setRegClass(Register Reg, const TargetRegisterClass *RC) {
600b57cec5SDimitry Andric   assert(RC && RC->isAllocatable() && "Invalid RC for virtual register");
610b57cec5SDimitry Andric   VRegInfo[Reg].first = RC;
620b57cec5SDimitry Andric }
630b57cec5SDimitry Andric 
645ffd83dbSDimitry Andric void MachineRegisterInfo::setRegBank(Register Reg,
650b57cec5SDimitry Andric                                      const RegisterBank &RegBank) {
660b57cec5SDimitry Andric   VRegInfo[Reg].first = &RegBank;
670b57cec5SDimitry Andric }
680b57cec5SDimitry Andric 
690b57cec5SDimitry Andric static const TargetRegisterClass *
705ffd83dbSDimitry Andric constrainRegClass(MachineRegisterInfo &MRI, Register Reg,
710b57cec5SDimitry Andric                   const TargetRegisterClass *OldRC,
720b57cec5SDimitry Andric                   const TargetRegisterClass *RC, unsigned MinNumRegs) {
730b57cec5SDimitry Andric   if (OldRC == RC)
740b57cec5SDimitry Andric     return RC;
750b57cec5SDimitry Andric   const TargetRegisterClass *NewRC =
760b57cec5SDimitry Andric       MRI.getTargetRegisterInfo()->getCommonSubClass(OldRC, RC);
770b57cec5SDimitry Andric   if (!NewRC || NewRC == OldRC)
780b57cec5SDimitry Andric     return NewRC;
790b57cec5SDimitry Andric   if (NewRC->getNumRegs() < MinNumRegs)
800b57cec5SDimitry Andric     return nullptr;
810b57cec5SDimitry Andric   MRI.setRegClass(Reg, NewRC);
820b57cec5SDimitry Andric   return NewRC;
830b57cec5SDimitry Andric }
840b57cec5SDimitry Andric 
85bdd1243dSDimitry Andric const TargetRegisterClass *MachineRegisterInfo::constrainRegClass(
86bdd1243dSDimitry Andric     Register Reg, const TargetRegisterClass *RC, unsigned MinNumRegs) {
87bdd1243dSDimitry Andric   if (Reg.isPhysical())
88bdd1243dSDimitry Andric     return nullptr;
890b57cec5SDimitry Andric   return ::constrainRegClass(*this, Reg, getRegClass(Reg), RC, MinNumRegs);
900b57cec5SDimitry Andric }
910b57cec5SDimitry Andric 
920b57cec5SDimitry Andric bool
935ffd83dbSDimitry Andric MachineRegisterInfo::constrainRegAttrs(Register Reg,
945ffd83dbSDimitry Andric                                        Register ConstrainingReg,
950b57cec5SDimitry Andric                                        unsigned MinNumRegs) {
960b57cec5SDimitry Andric   const LLT RegTy = getType(Reg);
970b57cec5SDimitry Andric   const LLT ConstrainingRegTy = getType(ConstrainingReg);
980b57cec5SDimitry Andric   if (RegTy.isValid() && ConstrainingRegTy.isValid() &&
990b57cec5SDimitry Andric       RegTy != ConstrainingRegTy)
1000b57cec5SDimitry Andric     return false;
1015f757f3fSDimitry Andric   const auto &ConstrainingRegCB = getRegClassOrRegBank(ConstrainingReg);
1020b57cec5SDimitry Andric   if (!ConstrainingRegCB.isNull()) {
1035f757f3fSDimitry Andric     const auto &RegCB = getRegClassOrRegBank(Reg);
1040b57cec5SDimitry Andric     if (RegCB.isNull())
1050b57cec5SDimitry Andric       setRegClassOrRegBank(Reg, ConstrainingRegCB);
10606c3fb27SDimitry Andric     else if (isa<const TargetRegisterClass *>(RegCB) !=
10706c3fb27SDimitry Andric              isa<const TargetRegisterClass *>(ConstrainingRegCB))
1080b57cec5SDimitry Andric       return false;
10906c3fb27SDimitry Andric     else if (isa<const TargetRegisterClass *>(RegCB)) {
1100b57cec5SDimitry Andric       if (!::constrainRegClass(
11106c3fb27SDimitry Andric               *this, Reg, cast<const TargetRegisterClass *>(RegCB),
11206c3fb27SDimitry Andric               cast<const TargetRegisterClass *>(ConstrainingRegCB), MinNumRegs))
1130b57cec5SDimitry Andric         return false;
1140b57cec5SDimitry Andric     } else if (RegCB != ConstrainingRegCB)
1150b57cec5SDimitry Andric       return false;
1160b57cec5SDimitry Andric   }
1170b57cec5SDimitry Andric   if (ConstrainingRegTy.isValid())
1180b57cec5SDimitry Andric     setType(Reg, ConstrainingRegTy);
1190b57cec5SDimitry Andric   return true;
1200b57cec5SDimitry Andric }
1210b57cec5SDimitry Andric 
1220b57cec5SDimitry Andric bool
1235ffd83dbSDimitry Andric MachineRegisterInfo::recomputeRegClass(Register Reg) {
1240b57cec5SDimitry Andric   const TargetInstrInfo *TII = MF->getSubtarget().getInstrInfo();
1250b57cec5SDimitry Andric   const TargetRegisterClass *OldRC = getRegClass(Reg);
1260b57cec5SDimitry Andric   const TargetRegisterClass *NewRC =
1270b57cec5SDimitry Andric       getTargetRegisterInfo()->getLargestLegalSuperClass(OldRC, *MF);
1280b57cec5SDimitry Andric 
1290b57cec5SDimitry Andric   // Stop early if there is no room to grow.
1300b57cec5SDimitry Andric   if (NewRC == OldRC)
1310b57cec5SDimitry Andric     return false;
1320b57cec5SDimitry Andric 
1330b57cec5SDimitry Andric   // Accumulate constraints from all uses.
1340b57cec5SDimitry Andric   for (MachineOperand &MO : reg_nodbg_operands(Reg)) {
1350b57cec5SDimitry Andric     // Apply the effect of the given operand to NewRC.
1360b57cec5SDimitry Andric     MachineInstr *MI = MO.getParent();
1370b57cec5SDimitry Andric     unsigned OpNo = &MO - &MI->getOperand(0);
1380b57cec5SDimitry Andric     NewRC = MI->getRegClassConstraintEffect(OpNo, NewRC, TII,
1390b57cec5SDimitry Andric                                             getTargetRegisterInfo());
1400b57cec5SDimitry Andric     if (!NewRC || NewRC == OldRC)
1410b57cec5SDimitry Andric       return false;
1420b57cec5SDimitry Andric   }
1430b57cec5SDimitry Andric   setRegClass(Reg, NewRC);
1440b57cec5SDimitry Andric   return true;
1450b57cec5SDimitry Andric }
1460b57cec5SDimitry Andric 
1475ffd83dbSDimitry Andric Register MachineRegisterInfo::createIncompleteVirtualRegister(StringRef Name) {
1485ffd83dbSDimitry Andric   Register Reg = Register::index2VirtReg(getNumVirtRegs());
1490b57cec5SDimitry Andric   VRegInfo.grow(Reg);
1500b57cec5SDimitry Andric   RegAllocHints.grow(Reg);
1510b57cec5SDimitry Andric   insertVRegByName(Name, Reg);
1520b57cec5SDimitry Andric   return Reg;
1530b57cec5SDimitry Andric }
1540b57cec5SDimitry Andric 
1550b57cec5SDimitry Andric /// createVirtualRegister - Create and return a new virtual register in the
1560b57cec5SDimitry Andric /// function with the specified register class.
1570b57cec5SDimitry Andric ///
1580b57cec5SDimitry Andric Register
1590b57cec5SDimitry Andric MachineRegisterInfo::createVirtualRegister(const TargetRegisterClass *RegClass,
1600b57cec5SDimitry Andric                                            StringRef Name) {
1610b57cec5SDimitry Andric   assert(RegClass && "Cannot create register without RegClass!");
1620b57cec5SDimitry Andric   assert(RegClass->isAllocatable() &&
1630b57cec5SDimitry Andric          "Virtual register RegClass must be allocatable.");
1640b57cec5SDimitry Andric 
1650b57cec5SDimitry Andric   // New virtual register number.
1665ffd83dbSDimitry Andric   Register Reg = createIncompleteVirtualRegister(Name);
1670b57cec5SDimitry Andric   VRegInfo[Reg].first = RegClass;
168bdd1243dSDimitry Andric   noteNewVirtualRegister(Reg);
1690b57cec5SDimitry Andric   return Reg;
1700b57cec5SDimitry Andric }
1710b57cec5SDimitry Andric 
172*0fca6ea1SDimitry Andric Register MachineRegisterInfo::createVirtualRegister(VRegAttrs RegAttr,
173*0fca6ea1SDimitry Andric                                                     StringRef Name) {
174*0fca6ea1SDimitry Andric   Register Reg = createIncompleteVirtualRegister(Name);
175*0fca6ea1SDimitry Andric   VRegInfo[Reg].first = RegAttr.RCOrRB;
176*0fca6ea1SDimitry Andric   setType(Reg, RegAttr.Ty);
177*0fca6ea1SDimitry Andric   noteNewVirtualRegister(Reg);
178*0fca6ea1SDimitry Andric   return Reg;
179*0fca6ea1SDimitry Andric }
180*0fca6ea1SDimitry Andric 
1810b57cec5SDimitry Andric Register MachineRegisterInfo::cloneVirtualRegister(Register VReg,
1820b57cec5SDimitry Andric                                                    StringRef Name) {
1835ffd83dbSDimitry Andric   Register Reg = createIncompleteVirtualRegister(Name);
1840b57cec5SDimitry Andric   VRegInfo[Reg].first = VRegInfo[VReg].first;
1850b57cec5SDimitry Andric   setType(Reg, getType(VReg));
186bdd1243dSDimitry Andric   noteCloneVirtualRegister(Reg, VReg);
1870b57cec5SDimitry Andric   return Reg;
1880b57cec5SDimitry Andric }
1890b57cec5SDimitry Andric 
1905ffd83dbSDimitry Andric void MachineRegisterInfo::setType(Register VReg, LLT Ty) {
1910b57cec5SDimitry Andric   VRegToType.grow(VReg);
1920b57cec5SDimitry Andric   VRegToType[VReg] = Ty;
1930b57cec5SDimitry Andric }
1940b57cec5SDimitry Andric 
1950b57cec5SDimitry Andric Register
1960b57cec5SDimitry Andric MachineRegisterInfo::createGenericVirtualRegister(LLT Ty, StringRef Name) {
1970b57cec5SDimitry Andric   // New virtual register number.
1985ffd83dbSDimitry Andric   Register Reg = createIncompleteVirtualRegister(Name);
1990b57cec5SDimitry Andric   // FIXME: Should we use a dummy register class?
2000b57cec5SDimitry Andric   VRegInfo[Reg].first = static_cast<RegisterBank *>(nullptr);
2010b57cec5SDimitry Andric   setType(Reg, Ty);
202bdd1243dSDimitry Andric   noteNewVirtualRegister(Reg);
2030b57cec5SDimitry Andric   return Reg;
2040b57cec5SDimitry Andric }
2050b57cec5SDimitry Andric 
2060b57cec5SDimitry Andric void MachineRegisterInfo::clearVirtRegTypes() { VRegToType.clear(); }
2070b57cec5SDimitry Andric 
2080b57cec5SDimitry Andric /// clearVirtRegs - Remove all virtual registers (after physreg assignment).
2090b57cec5SDimitry Andric void MachineRegisterInfo::clearVirtRegs() {
2100b57cec5SDimitry Andric #ifndef NDEBUG
2110b57cec5SDimitry Andric   for (unsigned i = 0, e = getNumVirtRegs(); i != e; ++i) {
2125ffd83dbSDimitry Andric     Register Reg = Register::index2VirtReg(i);
2130b57cec5SDimitry Andric     if (!VRegInfo[Reg].second)
2140b57cec5SDimitry Andric       continue;
2150b57cec5SDimitry Andric     verifyUseList(Reg);
216bdd1243dSDimitry Andric     errs() << "Remaining virtual register "
217bdd1243dSDimitry Andric            << printReg(Reg, getTargetRegisterInfo()) << "...\n";
218bdd1243dSDimitry Andric     for (MachineInstr &MI : reg_instructions(Reg))
219bdd1243dSDimitry Andric       errs() << "...in instruction: " << MI << "\n";
220bdd1243dSDimitry Andric     std::abort();
2210b57cec5SDimitry Andric   }
2220b57cec5SDimitry Andric #endif
2230b57cec5SDimitry Andric   VRegInfo.clear();
2240b57cec5SDimitry Andric   for (auto &I : LiveIns)
2250b57cec5SDimitry Andric     I.second = 0;
2260b57cec5SDimitry Andric }
2270b57cec5SDimitry Andric 
2285ffd83dbSDimitry Andric void MachineRegisterInfo::verifyUseList(Register Reg) const {
2290b57cec5SDimitry Andric #ifndef NDEBUG
2300b57cec5SDimitry Andric   bool Valid = true;
2310b57cec5SDimitry Andric   for (MachineOperand &M : reg_operands(Reg)) {
2320b57cec5SDimitry Andric     MachineOperand *MO = &M;
2330b57cec5SDimitry Andric     MachineInstr *MI = MO->getParent();
2340b57cec5SDimitry Andric     if (!MI) {
2350b57cec5SDimitry Andric       errs() << printReg(Reg, getTargetRegisterInfo())
2360b57cec5SDimitry Andric              << " use list MachineOperand " << MO
2370b57cec5SDimitry Andric              << " has no parent instruction.\n";
2380b57cec5SDimitry Andric       Valid = false;
2390b57cec5SDimitry Andric       continue;
2400b57cec5SDimitry Andric     }
2410b57cec5SDimitry Andric     MachineOperand *MO0 = &MI->getOperand(0);
2420b57cec5SDimitry Andric     unsigned NumOps = MI->getNumOperands();
2430b57cec5SDimitry Andric     if (!(MO >= MO0 && MO < MO0+NumOps)) {
2440b57cec5SDimitry Andric       errs() << printReg(Reg, getTargetRegisterInfo())
2450b57cec5SDimitry Andric              << " use list MachineOperand " << MO
2460b57cec5SDimitry Andric              << " doesn't belong to parent MI: " << *MI;
2470b57cec5SDimitry Andric       Valid = false;
2480b57cec5SDimitry Andric     }
2490b57cec5SDimitry Andric     if (!MO->isReg()) {
2500b57cec5SDimitry Andric       errs() << printReg(Reg, getTargetRegisterInfo())
2510b57cec5SDimitry Andric              << " MachineOperand " << MO << ": " << *MO
2520b57cec5SDimitry Andric              << " is not a register\n";
2530b57cec5SDimitry Andric       Valid = false;
2540b57cec5SDimitry Andric     }
2550b57cec5SDimitry Andric     if (MO->getReg() != Reg) {
2560b57cec5SDimitry Andric       errs() << printReg(Reg, getTargetRegisterInfo())
2570b57cec5SDimitry Andric              << " use-list MachineOperand " << MO << ": "
2580b57cec5SDimitry Andric              << *MO << " is the wrong register\n";
2590b57cec5SDimitry Andric       Valid = false;
2600b57cec5SDimitry Andric     }
2610b57cec5SDimitry Andric   }
2620b57cec5SDimitry Andric   assert(Valid && "Invalid use list");
2630b57cec5SDimitry Andric #endif
2640b57cec5SDimitry Andric }
2650b57cec5SDimitry Andric 
2660b57cec5SDimitry Andric void MachineRegisterInfo::verifyUseLists() const {
2670b57cec5SDimitry Andric #ifndef NDEBUG
2680b57cec5SDimitry Andric   for (unsigned i = 0, e = getNumVirtRegs(); i != e; ++i)
2698bcb0991SDimitry Andric     verifyUseList(Register::index2VirtReg(i));
2700b57cec5SDimitry Andric   for (unsigned i = 1, e = getTargetRegisterInfo()->getNumRegs(); i != e; ++i)
2710b57cec5SDimitry Andric     verifyUseList(i);
2720b57cec5SDimitry Andric #endif
2730b57cec5SDimitry Andric }
2740b57cec5SDimitry Andric 
2750b57cec5SDimitry Andric /// Add MO to the linked list of operands for its register.
2760b57cec5SDimitry Andric void MachineRegisterInfo::addRegOperandToUseList(MachineOperand *MO) {
2770b57cec5SDimitry Andric   assert(!MO->isOnRegUseList() && "Already on list");
2780b57cec5SDimitry Andric   MachineOperand *&HeadRef = getRegUseDefListHead(MO->getReg());
2790b57cec5SDimitry Andric   MachineOperand *const Head = HeadRef;
2800b57cec5SDimitry Andric 
2810b57cec5SDimitry Andric   // Head points to the first list element.
2820b57cec5SDimitry Andric   // Next is NULL on the last list element.
2830b57cec5SDimitry Andric   // Prev pointers are circular, so Head->Prev == Last.
2840b57cec5SDimitry Andric 
2850b57cec5SDimitry Andric   // Head is NULL for an empty list.
2860b57cec5SDimitry Andric   if (!Head) {
2870b57cec5SDimitry Andric     MO->Contents.Reg.Prev = MO;
2880b57cec5SDimitry Andric     MO->Contents.Reg.Next = nullptr;
2890b57cec5SDimitry Andric     HeadRef = MO;
2900b57cec5SDimitry Andric     return;
2910b57cec5SDimitry Andric   }
2920b57cec5SDimitry Andric   assert(MO->getReg() == Head->getReg() && "Different regs on the same list!");
2930b57cec5SDimitry Andric 
2940b57cec5SDimitry Andric   // Insert MO between Last and Head in the circular Prev chain.
2950b57cec5SDimitry Andric   MachineOperand *Last = Head->Contents.Reg.Prev;
2960b57cec5SDimitry Andric   assert(Last && "Inconsistent use list");
2970b57cec5SDimitry Andric   assert(MO->getReg() == Last->getReg() && "Different regs on the same list!");
2980b57cec5SDimitry Andric   Head->Contents.Reg.Prev = MO;
2990b57cec5SDimitry Andric   MO->Contents.Reg.Prev = Last;
3000b57cec5SDimitry Andric 
3010b57cec5SDimitry Andric   // Def operands always precede uses. This allows def_iterator to stop early.
3020b57cec5SDimitry Andric   // Insert def operands at the front, and use operands at the back.
3030b57cec5SDimitry Andric   if (MO->isDef()) {
3040b57cec5SDimitry Andric     // Insert def at the front.
3050b57cec5SDimitry Andric     MO->Contents.Reg.Next = Head;
3060b57cec5SDimitry Andric     HeadRef = MO;
3070b57cec5SDimitry Andric   } else {
3080b57cec5SDimitry Andric     // Insert use at the end.
3090b57cec5SDimitry Andric     MO->Contents.Reg.Next = nullptr;
3100b57cec5SDimitry Andric     Last->Contents.Reg.Next = MO;
3110b57cec5SDimitry Andric   }
3120b57cec5SDimitry Andric }
3130b57cec5SDimitry Andric 
3140b57cec5SDimitry Andric /// Remove MO from its use-def list.
3150b57cec5SDimitry Andric void MachineRegisterInfo::removeRegOperandFromUseList(MachineOperand *MO) {
3160b57cec5SDimitry Andric   assert(MO->isOnRegUseList() && "Operand not on use list");
3170b57cec5SDimitry Andric   MachineOperand *&HeadRef = getRegUseDefListHead(MO->getReg());
3180b57cec5SDimitry Andric   MachineOperand *const Head = HeadRef;
3190b57cec5SDimitry Andric   assert(Head && "List already empty");
3200b57cec5SDimitry Andric 
3210b57cec5SDimitry Andric   // Unlink this from the doubly linked list of operands.
3220b57cec5SDimitry Andric   MachineOperand *Next = MO->Contents.Reg.Next;
3230b57cec5SDimitry Andric   MachineOperand *Prev = MO->Contents.Reg.Prev;
3240b57cec5SDimitry Andric 
3250b57cec5SDimitry Andric   // Prev links are circular, next link is NULL instead of looping back to Head.
3260b57cec5SDimitry Andric   if (MO == Head)
3270b57cec5SDimitry Andric     HeadRef = Next;
3280b57cec5SDimitry Andric   else
3290b57cec5SDimitry Andric     Prev->Contents.Reg.Next = Next;
3300b57cec5SDimitry Andric 
3310b57cec5SDimitry Andric   (Next ? Next : Head)->Contents.Reg.Prev = Prev;
3320b57cec5SDimitry Andric 
3330b57cec5SDimitry Andric   MO->Contents.Reg.Prev = nullptr;
3340b57cec5SDimitry Andric   MO->Contents.Reg.Next = nullptr;
3350b57cec5SDimitry Andric }
3360b57cec5SDimitry Andric 
3370b57cec5SDimitry Andric /// Move NumOps operands from Src to Dst, updating use-def lists as needed.
3380b57cec5SDimitry Andric ///
3390b57cec5SDimitry Andric /// The Dst range is assumed to be uninitialized memory. (Or it may contain
3400b57cec5SDimitry Andric /// operands that won't be destroyed, which is OK because the MO destructor is
3410b57cec5SDimitry Andric /// trivial anyway).
3420b57cec5SDimitry Andric ///
3430b57cec5SDimitry Andric /// The Src and Dst ranges may overlap.
3440b57cec5SDimitry Andric void MachineRegisterInfo::moveOperands(MachineOperand *Dst,
3450b57cec5SDimitry Andric                                        MachineOperand *Src,
3460b57cec5SDimitry Andric                                        unsigned NumOps) {
3470b57cec5SDimitry Andric   assert(Src != Dst && NumOps && "Noop moveOperands");
3480b57cec5SDimitry Andric 
3490b57cec5SDimitry Andric   // Copy backwards if Dst is within the Src range.
3500b57cec5SDimitry Andric   int Stride = 1;
3510b57cec5SDimitry Andric   if (Dst >= Src && Dst < Src + NumOps) {
3520b57cec5SDimitry Andric     Stride = -1;
3530b57cec5SDimitry Andric     Dst += NumOps - 1;
3540b57cec5SDimitry Andric     Src += NumOps - 1;
3550b57cec5SDimitry Andric   }
3560b57cec5SDimitry Andric 
3570b57cec5SDimitry Andric   // Copy one operand at a time.
3580b57cec5SDimitry Andric   do {
3590b57cec5SDimitry Andric     new (Dst) MachineOperand(*Src);
3600b57cec5SDimitry Andric 
3610b57cec5SDimitry Andric     // Dst takes Src's place in the use-def chain.
3620b57cec5SDimitry Andric     if (Src->isReg()) {
3630b57cec5SDimitry Andric       MachineOperand *&Head = getRegUseDefListHead(Src->getReg());
3640b57cec5SDimitry Andric       MachineOperand *Prev = Src->Contents.Reg.Prev;
3650b57cec5SDimitry Andric       MachineOperand *Next = Src->Contents.Reg.Next;
3660b57cec5SDimitry Andric       assert(Head && "List empty, but operand is chained");
3670b57cec5SDimitry Andric       assert(Prev && "Operand was not on use-def list");
3680b57cec5SDimitry Andric 
3690b57cec5SDimitry Andric       // Prev links are circular, next link is NULL instead of looping back to
3700b57cec5SDimitry Andric       // Head.
3710b57cec5SDimitry Andric       if (Src == Head)
3720b57cec5SDimitry Andric         Head = Dst;
3730b57cec5SDimitry Andric       else
3740b57cec5SDimitry Andric         Prev->Contents.Reg.Next = Dst;
3750b57cec5SDimitry Andric 
3760b57cec5SDimitry Andric       // Update Prev pointer. This also works when Src was pointing to itself
3770b57cec5SDimitry Andric       // in a 1-element list. In that case Head == Dst.
3780b57cec5SDimitry Andric       (Next ? Next : Head)->Contents.Reg.Prev = Dst;
3790b57cec5SDimitry Andric     }
3800b57cec5SDimitry Andric 
3810b57cec5SDimitry Andric     Dst += Stride;
3820b57cec5SDimitry Andric     Src += Stride;
3830b57cec5SDimitry Andric   } while (--NumOps);
3840b57cec5SDimitry Andric }
3850b57cec5SDimitry Andric 
3860b57cec5SDimitry Andric /// replaceRegWith - Replace all instances of FromReg with ToReg in the
3870b57cec5SDimitry Andric /// machine function.  This is like llvm-level X->replaceAllUsesWith(Y),
3880b57cec5SDimitry Andric /// except that it also changes any definitions of the register as well.
3890b57cec5SDimitry Andric /// If ToReg is a physical register we apply the sub register to obtain the
3900b57cec5SDimitry Andric /// final/proper physical register.
3915ffd83dbSDimitry Andric void MachineRegisterInfo::replaceRegWith(Register FromReg, Register ToReg) {
3920b57cec5SDimitry Andric   assert(FromReg != ToReg && "Cannot replace a reg with itself");
3930b57cec5SDimitry Andric 
3940b57cec5SDimitry Andric   const TargetRegisterInfo *TRI = getTargetRegisterInfo();
3950b57cec5SDimitry Andric 
3960b57cec5SDimitry Andric   // TODO: This could be more efficient by bulk changing the operands.
397349cc55cSDimitry Andric   for (MachineOperand &O : llvm::make_early_inc_range(reg_operands(FromReg))) {
398bdd1243dSDimitry Andric     if (ToReg.isPhysical()) {
3990b57cec5SDimitry Andric       O.substPhysReg(ToReg, *TRI);
4000b57cec5SDimitry Andric     } else {
4010b57cec5SDimitry Andric       O.setReg(ToReg);
4020b57cec5SDimitry Andric     }
4030b57cec5SDimitry Andric   }
4040b57cec5SDimitry Andric }
4050b57cec5SDimitry Andric 
4060b57cec5SDimitry Andric /// getVRegDef - Return the machine instr that defines the specified virtual
4070b57cec5SDimitry Andric /// register or null if none is found.  This assumes that the code is in SSA
4080b57cec5SDimitry Andric /// form, so there should only be one definition.
4095ffd83dbSDimitry Andric MachineInstr *MachineRegisterInfo::getVRegDef(Register Reg) const {
4100b57cec5SDimitry Andric   // Since we are in SSA form, we can use the first definition.
4110b57cec5SDimitry Andric   def_instr_iterator I = def_instr_begin(Reg);
4120b57cec5SDimitry Andric   assert((I.atEnd() || std::next(I) == def_instr_end()) &&
4130b57cec5SDimitry Andric          "getVRegDef assumes a single definition or no definition");
4140b57cec5SDimitry Andric   return !I.atEnd() ? &*I : nullptr;
4150b57cec5SDimitry Andric }
4160b57cec5SDimitry Andric 
4170b57cec5SDimitry Andric /// getUniqueVRegDef - Return the unique machine instr that defines the
4180b57cec5SDimitry Andric /// specified virtual register or null if none is found.  If there are
4190b57cec5SDimitry Andric /// multiple definitions or no definition, return null.
4205ffd83dbSDimitry Andric MachineInstr *MachineRegisterInfo::getUniqueVRegDef(Register Reg) const {
4210b57cec5SDimitry Andric   if (def_empty(Reg)) return nullptr;
4220b57cec5SDimitry Andric   def_instr_iterator I = def_instr_begin(Reg);
4230b57cec5SDimitry Andric   if (std::next(I) != def_instr_end())
4240b57cec5SDimitry Andric     return nullptr;
4250b57cec5SDimitry Andric   return &*I;
4260b57cec5SDimitry Andric }
4270b57cec5SDimitry Andric 
4285ffd83dbSDimitry Andric bool MachineRegisterInfo::hasOneNonDBGUse(Register RegNo) const {
429e8d8bef9SDimitry Andric   return hasSingleElement(use_nodbg_operands(RegNo));
4300b57cec5SDimitry Andric }
4310b57cec5SDimitry Andric 
4325ffd83dbSDimitry Andric bool MachineRegisterInfo::hasOneNonDBGUser(Register RegNo) const {
433e8d8bef9SDimitry Andric   return hasSingleElement(use_nodbg_instructions(RegNo));
4340b57cec5SDimitry Andric }
4350b57cec5SDimitry Andric 
436bdd1243dSDimitry Andric bool MachineRegisterInfo::hasAtMostUserInstrs(Register Reg,
437bdd1243dSDimitry Andric                                               unsigned MaxUsers) const {
438bdd1243dSDimitry Andric   return hasNItemsOrLess(use_instr_nodbg_begin(Reg), use_instr_nodbg_end(),
439bdd1243dSDimitry Andric                          MaxUsers);
440bdd1243dSDimitry Andric }
441bdd1243dSDimitry Andric 
4420b57cec5SDimitry Andric /// clearKillFlags - Iterate over all the uses of the given register and
4430b57cec5SDimitry Andric /// clear the kill flag from the MachineOperand. This function is used by
4440b57cec5SDimitry Andric /// optimization passes which extend register lifetimes and need only
4450b57cec5SDimitry Andric /// preserve conservative kill flag information.
4465ffd83dbSDimitry Andric void MachineRegisterInfo::clearKillFlags(Register Reg) const {
4470b57cec5SDimitry Andric   for (MachineOperand &MO : use_operands(Reg))
4480b57cec5SDimitry Andric     MO.setIsKill(false);
4490b57cec5SDimitry Andric }
4500b57cec5SDimitry Andric 
4515ffd83dbSDimitry Andric bool MachineRegisterInfo::isLiveIn(Register Reg) const {
452fe6060f1SDimitry Andric   for (const std::pair<MCRegister, Register> &LI : liveins())
453fe6060f1SDimitry Andric     if ((Register)LI.first == Reg || LI.second == Reg)
4540b57cec5SDimitry Andric       return true;
4550b57cec5SDimitry Andric   return false;
4560b57cec5SDimitry Andric }
4570b57cec5SDimitry Andric 
4580b57cec5SDimitry Andric /// getLiveInPhysReg - If VReg is a live-in virtual register, return the
4590b57cec5SDimitry Andric /// corresponding live-in physical register.
4605ffd83dbSDimitry Andric MCRegister MachineRegisterInfo::getLiveInPhysReg(Register VReg) const {
461fe6060f1SDimitry Andric   for (const std::pair<MCRegister, Register> &LI : liveins())
462fe6060f1SDimitry Andric     if (LI.second == VReg)
463fe6060f1SDimitry Andric       return LI.first;
4645ffd83dbSDimitry Andric   return MCRegister();
4650b57cec5SDimitry Andric }
4660b57cec5SDimitry Andric 
4670b57cec5SDimitry Andric /// getLiveInVirtReg - If PReg is a live-in physical register, return the
4680b57cec5SDimitry Andric /// corresponding live-in physical register.
4695ffd83dbSDimitry Andric Register MachineRegisterInfo::getLiveInVirtReg(MCRegister PReg) const {
470fe6060f1SDimitry Andric   for (const std::pair<MCRegister, Register> &LI : liveins())
471fe6060f1SDimitry Andric     if (LI.first == PReg)
472fe6060f1SDimitry Andric       return LI.second;
4735ffd83dbSDimitry Andric   return Register();
4740b57cec5SDimitry Andric }
4750b57cec5SDimitry Andric 
4760b57cec5SDimitry Andric /// EmitLiveInCopies - Emit copies to initialize livein virtual registers
4770b57cec5SDimitry Andric /// into the given entry block.
4780b57cec5SDimitry Andric void
4790b57cec5SDimitry Andric MachineRegisterInfo::EmitLiveInCopies(MachineBasicBlock *EntryMBB,
4800b57cec5SDimitry Andric                                       const TargetRegisterInfo &TRI,
4810b57cec5SDimitry Andric                                       const TargetInstrInfo &TII) {
4820b57cec5SDimitry Andric   // Emit the copies into the top of the block.
4830b57cec5SDimitry Andric   for (unsigned i = 0, e = LiveIns.size(); i != e; ++i)
4840b57cec5SDimitry Andric     if (LiveIns[i].second) {
4850b57cec5SDimitry Andric       if (use_nodbg_empty(LiveIns[i].second)) {
4860b57cec5SDimitry Andric         // The livein has no non-dbg uses. Drop it.
4870b57cec5SDimitry Andric         //
4880b57cec5SDimitry Andric         // It would be preferable to have isel avoid creating live-in
4890b57cec5SDimitry Andric         // records for unused arguments in the first place, but it's
4900b57cec5SDimitry Andric         // complicated by the debug info code for arguments.
4910b57cec5SDimitry Andric         LiveIns.erase(LiveIns.begin() + i);
4920b57cec5SDimitry Andric         --i; --e;
4930b57cec5SDimitry Andric       } else {
4940b57cec5SDimitry Andric         // Emit a copy.
4950b57cec5SDimitry Andric         BuildMI(*EntryMBB, EntryMBB->begin(), DebugLoc(),
4960b57cec5SDimitry Andric                 TII.get(TargetOpcode::COPY), LiveIns[i].second)
4970b57cec5SDimitry Andric           .addReg(LiveIns[i].first);
4980b57cec5SDimitry Andric 
4990b57cec5SDimitry Andric         // Add the register to the entry block live-in set.
5000b57cec5SDimitry Andric         EntryMBB->addLiveIn(LiveIns[i].first);
5010b57cec5SDimitry Andric       }
5020b57cec5SDimitry Andric     } else {
5030b57cec5SDimitry Andric       // Add the register to the entry block live-in set.
5040b57cec5SDimitry Andric       EntryMBB->addLiveIn(LiveIns[i].first);
5050b57cec5SDimitry Andric     }
5060b57cec5SDimitry Andric }
5070b57cec5SDimitry Andric 
5085ffd83dbSDimitry Andric LaneBitmask MachineRegisterInfo::getMaxLaneMaskForVReg(Register Reg) const {
5090b57cec5SDimitry Andric   // Lane masks are only defined for vregs.
510bdd1243dSDimitry Andric   assert(Reg.isVirtual());
5110b57cec5SDimitry Andric   const TargetRegisterClass &TRC = *getRegClass(Reg);
5120b57cec5SDimitry Andric   return TRC.getLaneMask();
5130b57cec5SDimitry Andric }
5140b57cec5SDimitry Andric 
5150b57cec5SDimitry Andric #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
5165ffd83dbSDimitry Andric LLVM_DUMP_METHOD void MachineRegisterInfo::dumpUses(Register Reg) const {
5170b57cec5SDimitry Andric   for (MachineInstr &I : use_instructions(Reg))
5180b57cec5SDimitry Andric     I.dump();
5190b57cec5SDimitry Andric }
5200b57cec5SDimitry Andric #endif
5210b57cec5SDimitry Andric 
522*0fca6ea1SDimitry Andric void MachineRegisterInfo::freezeReservedRegs() {
523*0fca6ea1SDimitry Andric   ReservedRegs = getTargetRegisterInfo()->getReservedRegs(*MF);
5240b57cec5SDimitry Andric   assert(ReservedRegs.size() == getTargetRegisterInfo()->getNumRegs() &&
5250b57cec5SDimitry Andric          "Invalid ReservedRegs vector from target");
5260b57cec5SDimitry Andric }
5270b57cec5SDimitry Andric 
5285ffd83dbSDimitry Andric bool MachineRegisterInfo::isConstantPhysReg(MCRegister PhysReg) const {
5298bcb0991SDimitry Andric   assert(Register::isPhysicalRegister(PhysReg));
5300b57cec5SDimitry Andric 
5310b57cec5SDimitry Andric   const TargetRegisterInfo *TRI = getTargetRegisterInfo();
5320b57cec5SDimitry Andric   if (TRI->isConstantPhysReg(PhysReg))
5330b57cec5SDimitry Andric     return true;
5340b57cec5SDimitry Andric 
5350b57cec5SDimitry Andric   // Check if any overlapping register is modified, or allocatable so it may be
5360b57cec5SDimitry Andric   // used later.
5370b57cec5SDimitry Andric   for (MCRegAliasIterator AI(PhysReg, TRI, true);
5380b57cec5SDimitry Andric        AI.isValid(); ++AI)
5390b57cec5SDimitry Andric     if (!def_empty(*AI) || isAllocatable(*AI))
5400b57cec5SDimitry Andric       return false;
5410b57cec5SDimitry Andric   return true;
5420b57cec5SDimitry Andric }
5430b57cec5SDimitry Andric 
5440b57cec5SDimitry Andric /// markUsesInDebugValueAsUndef - Mark every DBG_VALUE referencing the
5450b57cec5SDimitry Andric /// specified register as undefined which causes the DBG_VALUE to be
5460b57cec5SDimitry Andric /// deleted during LiveDebugVariables analysis.
5475ffd83dbSDimitry Andric void MachineRegisterInfo::markUsesInDebugValueAsUndef(Register Reg) const {
548fe6060f1SDimitry Andric   // Mark any DBG_VALUE* that uses Reg as undef (but don't delete it.)
549fe6060f1SDimitry Andric   // We use make_early_inc_range because setReg invalidates the iterator.
550fe6060f1SDimitry Andric   for (MachineInstr &UseMI : llvm::make_early_inc_range(use_instructions(Reg))) {
551fe6060f1SDimitry Andric     if (UseMI.isDebugValue() && UseMI.hasDebugOperandForReg(Reg))
552fe6060f1SDimitry Andric       UseMI.setDebugValueUndef();
5530b57cec5SDimitry Andric   }
5540b57cec5SDimitry Andric }
5550b57cec5SDimitry Andric 
5560b57cec5SDimitry Andric static const Function *getCalledFunction(const MachineInstr &MI) {
5570b57cec5SDimitry Andric   for (const MachineOperand &MO : MI.operands()) {
5580b57cec5SDimitry Andric     if (!MO.isGlobal())
5590b57cec5SDimitry Andric       continue;
5600b57cec5SDimitry Andric     const Function *Func = dyn_cast<Function>(MO.getGlobal());
5610b57cec5SDimitry Andric     if (Func != nullptr)
5620b57cec5SDimitry Andric       return Func;
5630b57cec5SDimitry Andric   }
5640b57cec5SDimitry Andric   return nullptr;
5650b57cec5SDimitry Andric }
5660b57cec5SDimitry Andric 
5670b57cec5SDimitry Andric static bool isNoReturnDef(const MachineOperand &MO) {
5680b57cec5SDimitry Andric   // Anything which is not a noreturn function is a real def.
5690b57cec5SDimitry Andric   const MachineInstr &MI = *MO.getParent();
5700b57cec5SDimitry Andric   if (!MI.isCall())
5710b57cec5SDimitry Andric     return false;
5720b57cec5SDimitry Andric   const MachineBasicBlock &MBB = *MI.getParent();
5730b57cec5SDimitry Andric   if (!MBB.succ_empty())
5740b57cec5SDimitry Andric     return false;
5750b57cec5SDimitry Andric   const MachineFunction &MF = *MBB.getParent();
5760b57cec5SDimitry Andric   // We need to keep correct unwind information even if the function will
5770b57cec5SDimitry Andric   // not return, since the runtime may need it.
5780b57cec5SDimitry Andric   if (MF.getFunction().hasFnAttribute(Attribute::UWTable))
5790b57cec5SDimitry Andric     return false;
5800b57cec5SDimitry Andric   const Function *Called = getCalledFunction(MI);
5810b57cec5SDimitry Andric   return !(Called == nullptr || !Called->hasFnAttribute(Attribute::NoReturn) ||
5820b57cec5SDimitry Andric            !Called->hasFnAttribute(Attribute::NoUnwind));
5830b57cec5SDimitry Andric }
5840b57cec5SDimitry Andric 
5855ffd83dbSDimitry Andric bool MachineRegisterInfo::isPhysRegModified(MCRegister PhysReg,
5860b57cec5SDimitry Andric                                             bool SkipNoReturnDef) const {
5870b57cec5SDimitry Andric   if (UsedPhysRegMask.test(PhysReg))
5880b57cec5SDimitry Andric     return true;
5890b57cec5SDimitry Andric   const TargetRegisterInfo *TRI = getTargetRegisterInfo();
5900b57cec5SDimitry Andric   for (MCRegAliasIterator AI(PhysReg, TRI, true); AI.isValid(); ++AI) {
5910b57cec5SDimitry Andric     for (const MachineOperand &MO : make_range(def_begin(*AI), def_end())) {
5920b57cec5SDimitry Andric       if (!SkipNoReturnDef && isNoReturnDef(MO))
5930b57cec5SDimitry Andric         continue;
5940b57cec5SDimitry Andric       return true;
5950b57cec5SDimitry Andric     }
5960b57cec5SDimitry Andric   }
5970b57cec5SDimitry Andric   return false;
5980b57cec5SDimitry Andric }
5990b57cec5SDimitry Andric 
600fe6060f1SDimitry Andric bool MachineRegisterInfo::isPhysRegUsed(MCRegister PhysReg,
601fe6060f1SDimitry Andric                                         bool SkipRegMaskTest) const {
602fe6060f1SDimitry Andric   if (!SkipRegMaskTest && UsedPhysRegMask.test(PhysReg))
6030b57cec5SDimitry Andric     return true;
6040b57cec5SDimitry Andric   const TargetRegisterInfo *TRI = getTargetRegisterInfo();
6050b57cec5SDimitry Andric   for (MCRegAliasIterator AliasReg(PhysReg, TRI, true); AliasReg.isValid();
6060b57cec5SDimitry Andric        ++AliasReg) {
6070b57cec5SDimitry Andric     if (!reg_nodbg_empty(*AliasReg))
6080b57cec5SDimitry Andric       return true;
6090b57cec5SDimitry Andric   }
6100b57cec5SDimitry Andric   return false;
6110b57cec5SDimitry Andric }
6120b57cec5SDimitry Andric 
6135ffd83dbSDimitry Andric void MachineRegisterInfo::disableCalleeSavedRegister(MCRegister Reg) {
6140b57cec5SDimitry Andric 
6150b57cec5SDimitry Andric   const TargetRegisterInfo *TRI = getTargetRegisterInfo();
6160b57cec5SDimitry Andric   assert(Reg && (Reg < TRI->getNumRegs()) &&
6170b57cec5SDimitry Andric          "Trying to disable an invalid register");
6180b57cec5SDimitry Andric 
6190b57cec5SDimitry Andric   if (!IsUpdatedCSRsInitialized) {
6200b57cec5SDimitry Andric     const MCPhysReg *CSR = TRI->getCalleeSavedRegs(MF);
6210b57cec5SDimitry Andric     for (const MCPhysReg *I = CSR; *I; ++I)
6220b57cec5SDimitry Andric       UpdatedCSRs.push_back(*I);
6230b57cec5SDimitry Andric 
6240b57cec5SDimitry Andric     // Zero value represents the end of the register list
6250b57cec5SDimitry Andric     // (no more registers should be pushed).
6260b57cec5SDimitry Andric     UpdatedCSRs.push_back(0);
6270b57cec5SDimitry Andric 
6280b57cec5SDimitry Andric     IsUpdatedCSRsInitialized = true;
6290b57cec5SDimitry Andric   }
6300b57cec5SDimitry Andric 
6310b57cec5SDimitry Andric   // Remove the register (and its aliases from the list).
6320b57cec5SDimitry Andric   for (MCRegAliasIterator AI(Reg, TRI, true); AI.isValid(); ++AI)
6335f757f3fSDimitry Andric     llvm::erase(UpdatedCSRs, *AI);
6340b57cec5SDimitry Andric }
6350b57cec5SDimitry Andric 
6360b57cec5SDimitry Andric const MCPhysReg *MachineRegisterInfo::getCalleeSavedRegs() const {
6370b57cec5SDimitry Andric   if (IsUpdatedCSRsInitialized)
6380b57cec5SDimitry Andric     return UpdatedCSRs.data();
6390b57cec5SDimitry Andric 
6400b57cec5SDimitry Andric   return getTargetRegisterInfo()->getCalleeSavedRegs(MF);
6410b57cec5SDimitry Andric }
6420b57cec5SDimitry Andric 
6430b57cec5SDimitry Andric void MachineRegisterInfo::setCalleeSavedRegs(ArrayRef<MCPhysReg> CSRs) {
6440b57cec5SDimitry Andric   if (IsUpdatedCSRsInitialized)
6450b57cec5SDimitry Andric     UpdatedCSRs.clear();
6460b57cec5SDimitry Andric 
647e8d8bef9SDimitry Andric   append_range(UpdatedCSRs, CSRs);
6480b57cec5SDimitry Andric 
6490b57cec5SDimitry Andric   // Zero value represents the end of the register list
6500b57cec5SDimitry Andric   // (no more registers should be pushed).
6510b57cec5SDimitry Andric   UpdatedCSRs.push_back(0);
6520b57cec5SDimitry Andric   IsUpdatedCSRsInitialized = true;
6530b57cec5SDimitry Andric }
6540b57cec5SDimitry Andric 
6550b57cec5SDimitry Andric bool MachineRegisterInfo::isReservedRegUnit(unsigned Unit) const {
6560b57cec5SDimitry Andric   const TargetRegisterInfo *TRI = getTargetRegisterInfo();
6570b57cec5SDimitry Andric   for (MCRegUnitRootIterator Root(Unit, TRI); Root.isValid(); ++Root) {
65806c3fb27SDimitry Andric     if (all_of(TRI->superregs_inclusive(*Root),
65906c3fb27SDimitry Andric                [&](MCPhysReg Super) { return isReserved(Super); }))
6600b57cec5SDimitry Andric       return true;
6610b57cec5SDimitry Andric   }
6620b57cec5SDimitry Andric   return false;
6630b57cec5SDimitry Andric }
664