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