xref: /src/contrib/llvm-project/llvm/lib/CodeGen/MachineRegisterInfo.cpp (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
171d5a254SDimitry Andric //===- lib/Codegen/MachineRegisterInfo.cpp --------------------------------===//
2009b1c42SEd Schouten //
3e6d15924SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4e6d15924SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5e6d15924SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6009b1c42SEd Schouten //
7009b1c42SEd Schouten //===----------------------------------------------------------------------===//
8009b1c42SEd Schouten //
9009b1c42SEd Schouten // Implementation of the MachineRegisterInfo class.
10009b1c42SEd Schouten //
11009b1c42SEd Schouten //===----------------------------------------------------------------------===//
12009b1c42SEd Schouten 
137ab83427SDimitry Andric #include "llvm/CodeGen/MachineRegisterInfo.h"
1471d5a254SDimitry Andric #include "llvm/ADT/iterator_range.h"
1571d5a254SDimitry Andric #include "llvm/CodeGen/MachineBasicBlock.h"
1671d5a254SDimitry Andric #include "llvm/CodeGen/MachineFunction.h"
1771d5a254SDimitry Andric #include "llvm/CodeGen/MachineInstr.h"
18d7f7719eSRoman Divacky #include "llvm/CodeGen/MachineInstrBuilder.h"
1971d5a254SDimitry Andric #include "llvm/CodeGen/MachineOperand.h"
20044eb2f6SDimitry Andric #include "llvm/CodeGen/TargetInstrInfo.h"
21044eb2f6SDimitry Andric #include "llvm/CodeGen/TargetRegisterInfo.h"
22044eb2f6SDimitry Andric #include "llvm/CodeGen/TargetSubtargetInfo.h"
23eb11fae6SDimitry Andric #include "llvm/Config/llvm-config.h"
2471d5a254SDimitry Andric #include "llvm/IR/Attributes.h"
2571d5a254SDimitry Andric #include "llvm/IR/DebugLoc.h"
26ee8648bdSDimitry Andric #include "llvm/IR/Function.h"
2771d5a254SDimitry Andric #include "llvm/MC/MCRegisterInfo.h"
2871d5a254SDimitry Andric #include "llvm/Support/Casting.h"
2971d5a254SDimitry Andric #include "llvm/Support/CommandLine.h"
3071d5a254SDimitry Andric #include "llvm/Support/Compiler.h"
3171d5a254SDimitry Andric #include "llvm/Support/ErrorHandling.h"
3271d5a254SDimitry Andric #include "llvm/Support/raw_ostream.h"
3371d5a254SDimitry Andric #include <cassert>
3459d6cff9SDimitry Andric 
35009b1c42SEd Schouten using namespace llvm;
36009b1c42SEd Schouten 
37b915e9e0SDimitry Andric static cl::opt<bool> EnableSubRegLiveness("enable-subreg-liveness", cl::Hidden,
38b915e9e0SDimitry Andric   cl::init(true), cl::desc("Enable subregister liveness tracking."));
39b915e9e0SDimitry Andric 
40f8af5cf6SDimitry Andric // Pin the vtable to this file.
anchor()41f8af5cf6SDimitry Andric void MachineRegisterInfo::Delegate::anchor() {}
42f8af5cf6SDimitry Andric 
MachineRegisterInfo(MachineFunction * MF)4301095a5dSDimitry Andric MachineRegisterInfo::MachineRegisterInfo(MachineFunction *MF)
44ac9a064cSDimitry Andric     : MF(MF),
45ac9a064cSDimitry Andric       TracksSubRegLiveness(EnableSubRegLiveness.getNumOccurrences()
46ac9a064cSDimitry Andric                                ? EnableSubRegLiveness
47ac9a064cSDimitry Andric                                : MF->getSubtarget().enableSubRegLiveness()) {
48dd58ef01SDimitry Andric   unsigned NumRegs = getTargetRegisterInfo()->getNumRegs();
49009b1c42SEd Schouten   VRegInfo.reserve(256);
50b2f21fb0SEd Schouten   RegAllocHints.reserve(256);
51dd58ef01SDimitry Andric   UsedPhysRegMask.resize(NumRegs);
52dd58ef01SDimitry Andric   PhysRegUseDefLists.reset(new MachineOperand*[NumRegs]());
53e3b55780SDimitry Andric   TheDelegates.clear();
54009b1c42SEd Schouten }
55009b1c42SEd Schouten 
56009b1c42SEd Schouten /// setRegClass - Set the register class of the specified virtual register.
57009b1c42SEd Schouten ///
58009b1c42SEd Schouten void
setRegClass(Register Reg,const TargetRegisterClass * RC)59cfca06d7SDimitry Andric MachineRegisterInfo::setRegClass(Register Reg, const TargetRegisterClass *RC) {
604a16efa3SDimitry Andric   assert(RC && RC->isAllocatable() && "Invalid RC for virtual register");
61009b1c42SEd Schouten   VRegInfo[Reg].first = RC;
62cf099d11SDimitry Andric }
63cf099d11SDimitry Andric 
setRegBank(Register Reg,const RegisterBank & RegBank)64cfca06d7SDimitry Andric void MachineRegisterInfo::setRegBank(Register Reg,
6501095a5dSDimitry Andric                                      const RegisterBank &RegBank) {
6601095a5dSDimitry Andric   VRegInfo[Reg].first = &RegBank;
6701095a5dSDimitry Andric }
6801095a5dSDimitry Andric 
69eb11fae6SDimitry Andric static const TargetRegisterClass *
constrainRegClass(MachineRegisterInfo & MRI,Register Reg,const TargetRegisterClass * OldRC,const TargetRegisterClass * RC,unsigned MinNumRegs)70cfca06d7SDimitry Andric constrainRegClass(MachineRegisterInfo &MRI, Register Reg,
71eb11fae6SDimitry Andric                   const TargetRegisterClass *OldRC,
72eb11fae6SDimitry Andric                   const TargetRegisterClass *RC, unsigned MinNumRegs) {
73cf099d11SDimitry Andric   if (OldRC == RC)
74cf099d11SDimitry Andric     return RC;
75f8af5cf6SDimitry Andric   const TargetRegisterClass *NewRC =
76eb11fae6SDimitry Andric       MRI.getTargetRegisterInfo()->getCommonSubClass(OldRC, RC);
7730815c53SDimitry Andric   if (!NewRC || NewRC == OldRC)
7830815c53SDimitry Andric     return NewRC;
7930815c53SDimitry Andric   if (NewRC->getNumRegs() < MinNumRegs)
805ca98fd9SDimitry Andric     return nullptr;
81eb11fae6SDimitry Andric   MRI.setRegClass(Reg, NewRC);
82cf099d11SDimitry Andric   return NewRC;
83009b1c42SEd Schouten }
84009b1c42SEd Schouten 
constrainRegClass(Register Reg,const TargetRegisterClass * RC,unsigned MinNumRegs)85e3b55780SDimitry Andric const TargetRegisterClass *MachineRegisterInfo::constrainRegClass(
86e3b55780SDimitry Andric     Register Reg, const TargetRegisterClass *RC, unsigned MinNumRegs) {
87e3b55780SDimitry Andric   if (Reg.isPhysical())
88e3b55780SDimitry Andric     return nullptr;
89eb11fae6SDimitry Andric   return ::constrainRegClass(*this, Reg, getRegClass(Reg), RC, MinNumRegs);
90eb11fae6SDimitry Andric }
91eb11fae6SDimitry Andric 
92eb11fae6SDimitry Andric bool
constrainRegAttrs(Register Reg,Register ConstrainingReg,unsigned MinNumRegs)93cfca06d7SDimitry Andric MachineRegisterInfo::constrainRegAttrs(Register Reg,
94cfca06d7SDimitry Andric                                        Register ConstrainingReg,
95eb11fae6SDimitry Andric                                        unsigned MinNumRegs) {
96d8e91e46SDimitry Andric   const LLT RegTy = getType(Reg);
97d8e91e46SDimitry Andric   const LLT ConstrainingRegTy = getType(ConstrainingReg);
98d8e91e46SDimitry Andric   if (RegTy.isValid() && ConstrainingRegTy.isValid() &&
99d8e91e46SDimitry Andric       RegTy != ConstrainingRegTy)
100eb11fae6SDimitry Andric     return false;
101b1c73532SDimitry Andric   const auto &ConstrainingRegCB = getRegClassOrRegBank(ConstrainingReg);
102d8e91e46SDimitry Andric   if (!ConstrainingRegCB.isNull()) {
103b1c73532SDimitry Andric     const auto &RegCB = getRegClassOrRegBank(Reg);
104d8e91e46SDimitry Andric     if (RegCB.isNull())
105d8e91e46SDimitry Andric       setRegClassOrRegBank(Reg, ConstrainingRegCB);
1067fa27ce4SDimitry Andric     else if (isa<const TargetRegisterClass *>(RegCB) !=
1077fa27ce4SDimitry Andric              isa<const TargetRegisterClass *>(ConstrainingRegCB))
108eb11fae6SDimitry Andric       return false;
1097fa27ce4SDimitry Andric     else if (isa<const TargetRegisterClass *>(RegCB)) {
110d8e91e46SDimitry Andric       if (!::constrainRegClass(
1117fa27ce4SDimitry Andric               *this, Reg, cast<const TargetRegisterClass *>(RegCB),
1127fa27ce4SDimitry Andric               cast<const TargetRegisterClass *>(ConstrainingRegCB), MinNumRegs))
113d8e91e46SDimitry Andric         return false;
114d8e91e46SDimitry Andric     } else if (RegCB != ConstrainingRegCB)
115d8e91e46SDimitry Andric       return false;
116d8e91e46SDimitry Andric   }
117d8e91e46SDimitry Andric   if (ConstrainingRegTy.isValid())
118d8e91e46SDimitry Andric     setType(Reg, ConstrainingRegTy);
119eb11fae6SDimitry Andric   return true;
120eb11fae6SDimitry Andric }
121eb11fae6SDimitry Andric 
12230815c53SDimitry Andric bool
recomputeRegClass(Register Reg)123cfca06d7SDimitry Andric MachineRegisterInfo::recomputeRegClass(Register Reg) {
1245a5ac124SDimitry Andric   const TargetInstrInfo *TII = MF->getSubtarget().getInstrInfo();
12530815c53SDimitry Andric   const TargetRegisterClass *OldRC = getRegClass(Reg);
126f8af5cf6SDimitry Andric   const TargetRegisterClass *NewRC =
1275a5ac124SDimitry Andric       getTargetRegisterInfo()->getLargestLegalSuperClass(OldRC, *MF);
12830815c53SDimitry Andric 
12930815c53SDimitry Andric   // Stop early if there is no room to grow.
13030815c53SDimitry Andric   if (NewRC == OldRC)
13130815c53SDimitry Andric     return false;
13230815c53SDimitry Andric 
13330815c53SDimitry Andric   // Accumulate constraints from all uses.
1345ca98fd9SDimitry Andric   for (MachineOperand &MO : reg_nodbg_operands(Reg)) {
1355ca98fd9SDimitry Andric     // Apply the effect of the given operand to NewRC.
1365ca98fd9SDimitry Andric     MachineInstr *MI = MO.getParent();
1375ca98fd9SDimitry Andric     unsigned OpNo = &MO - &MI->getOperand(0);
1385ca98fd9SDimitry Andric     NewRC = MI->getRegClassConstraintEffect(OpNo, NewRC, TII,
139f8af5cf6SDimitry Andric                                             getTargetRegisterInfo());
14030815c53SDimitry Andric     if (!NewRC || NewRC == OldRC)
14130815c53SDimitry Andric       return false;
14230815c53SDimitry Andric   }
14330815c53SDimitry Andric   setRegClass(Reg, NewRC);
14430815c53SDimitry Andric   return true;
14530815c53SDimitry Andric }
14630815c53SDimitry Andric 
createIncompleteVirtualRegister(StringRef Name)147cfca06d7SDimitry Andric Register MachineRegisterInfo::createIncompleteVirtualRegister(StringRef Name) {
148cfca06d7SDimitry Andric   Register Reg = Register::index2VirtReg(getNumVirtRegs());
149b915e9e0SDimitry Andric   VRegInfo.grow(Reg);
150b915e9e0SDimitry Andric   RegAllocHints.grow(Reg);
151eb11fae6SDimitry Andric   insertVRegByName(Name, Reg);
152b915e9e0SDimitry Andric   return Reg;
153b915e9e0SDimitry Andric }
154b915e9e0SDimitry Andric 
155009b1c42SEd Schouten /// createVirtualRegister - Create and return a new virtual register in the
156009b1c42SEd Schouten /// function with the specified register class.
157009b1c42SEd Schouten ///
158e6d15924SDimitry Andric Register
createVirtualRegister(const TargetRegisterClass * RegClass,StringRef Name)159eb11fae6SDimitry Andric MachineRegisterInfo::createVirtualRegister(const TargetRegisterClass *RegClass,
160eb11fae6SDimitry Andric                                            StringRef Name) {
161009b1c42SEd Schouten   assert(RegClass && "Cannot create register without RegClass!");
16256fe8f14SDimitry Andric   assert(RegClass->isAllocatable() &&
16356fe8f14SDimitry Andric          "Virtual register RegClass must be allocatable.");
164009b1c42SEd Schouten 
165cf099d11SDimitry Andric   // New virtual register number.
166cfca06d7SDimitry Andric   Register Reg = createIncompleteVirtualRegister(Name);
167cf099d11SDimitry Andric   VRegInfo[Reg].first = RegClass;
168e3b55780SDimitry Andric   noteNewVirtualRegister(Reg);
169cf099d11SDimitry Andric   return Reg;
170009b1c42SEd Schouten }
171009b1c42SEd Schouten 
createVirtualRegister(VRegAttrs RegAttr,StringRef Name)172ac9a064cSDimitry Andric Register MachineRegisterInfo::createVirtualRegister(VRegAttrs RegAttr,
173ac9a064cSDimitry Andric                                                     StringRef Name) {
174ac9a064cSDimitry Andric   Register Reg = createIncompleteVirtualRegister(Name);
175ac9a064cSDimitry Andric   VRegInfo[Reg].first = RegAttr.RCOrRB;
176ac9a064cSDimitry Andric   setType(Reg, RegAttr.Ty);
177ac9a064cSDimitry Andric   noteNewVirtualRegister(Reg);
178ac9a064cSDimitry Andric   return Reg;
179ac9a064cSDimitry Andric }
180ac9a064cSDimitry Andric 
cloneVirtualRegister(Register VReg,StringRef Name)181e6d15924SDimitry Andric Register MachineRegisterInfo::cloneVirtualRegister(Register VReg,
182d8e91e46SDimitry Andric                                                    StringRef Name) {
183cfca06d7SDimitry Andric   Register Reg = createIncompleteVirtualRegister(Name);
184d8e91e46SDimitry Andric   VRegInfo[Reg].first = VRegInfo[VReg].first;
185d8e91e46SDimitry Andric   setType(Reg, getType(VReg));
186e3b55780SDimitry Andric   noteCloneVirtualRegister(Reg, VReg);
187d8e91e46SDimitry Andric   return Reg;
188d8e91e46SDimitry Andric }
189d8e91e46SDimitry Andric 
setType(Register VReg,LLT Ty)190cfca06d7SDimitry Andric void MachineRegisterInfo::setType(Register VReg, LLT Ty) {
191eb11fae6SDimitry Andric   VRegToType.grow(VReg);
192eb11fae6SDimitry Andric   VRegToType[VReg] = Ty;
19301095a5dSDimitry Andric }
19401095a5dSDimitry Andric 
195e6d15924SDimitry Andric Register
createGenericVirtualRegister(LLT Ty,StringRef Name)196eb11fae6SDimitry Andric MachineRegisterInfo::createGenericVirtualRegister(LLT Ty, StringRef Name) {
19701095a5dSDimitry Andric   // New virtual register number.
198cfca06d7SDimitry Andric   Register Reg = createIncompleteVirtualRegister(Name);
19901095a5dSDimitry Andric   // FIXME: Should we use a dummy register class?
200b915e9e0SDimitry Andric   VRegInfo[Reg].first = static_cast<RegisterBank *>(nullptr);
201eb11fae6SDimitry Andric   setType(Reg, Ty);
202e3b55780SDimitry Andric   noteNewVirtualRegister(Reg);
20301095a5dSDimitry Andric   return Reg;
20401095a5dSDimitry Andric }
20501095a5dSDimitry Andric 
clearVirtRegTypes()206eb11fae6SDimitry Andric void MachineRegisterInfo::clearVirtRegTypes() { VRegToType.clear(); }
207b915e9e0SDimitry Andric 
20863faed5bSDimitry Andric /// clearVirtRegs - Remove all virtual registers (after physreg assignment).
clearVirtRegs()20963faed5bSDimitry Andric void MachineRegisterInfo::clearVirtRegs() {
21063faed5bSDimitry Andric #ifndef NDEBUG
21159d6cff9SDimitry Andric   for (unsigned i = 0, e = getNumVirtRegs(); i != e; ++i) {
212cfca06d7SDimitry Andric     Register Reg = Register::index2VirtReg(i);
21359d6cff9SDimitry Andric     if (!VRegInfo[Reg].second)
21459d6cff9SDimitry Andric       continue;
21559d6cff9SDimitry Andric     verifyUseList(Reg);
216e3b55780SDimitry Andric     errs() << "Remaining virtual register "
217e3b55780SDimitry Andric            << printReg(Reg, getTargetRegisterInfo()) << "...\n";
218e3b55780SDimitry Andric     for (MachineInstr &MI : reg_instructions(Reg))
219e3b55780SDimitry Andric       errs() << "...in instruction: " << MI << "\n";
220e3b55780SDimitry Andric     std::abort();
22159d6cff9SDimitry Andric   }
22263faed5bSDimitry Andric #endif
22363faed5bSDimitry Andric   VRegInfo.clear();
224dd58ef01SDimitry Andric   for (auto &I : LiveIns)
225dd58ef01SDimitry Andric     I.second = 0;
22663faed5bSDimitry Andric }
22763faed5bSDimitry Andric 
verifyUseList(Register Reg) const228cfca06d7SDimitry Andric void MachineRegisterInfo::verifyUseList(Register Reg) const {
22959d6cff9SDimitry Andric #ifndef NDEBUG
23059d6cff9SDimitry Andric   bool Valid = true;
2315ca98fd9SDimitry Andric   for (MachineOperand &M : reg_operands(Reg)) {
2325ca98fd9SDimitry Andric     MachineOperand *MO = &M;
23359d6cff9SDimitry Andric     MachineInstr *MI = MO->getParent();
23459d6cff9SDimitry Andric     if (!MI) {
235044eb2f6SDimitry Andric       errs() << printReg(Reg, getTargetRegisterInfo())
236f8af5cf6SDimitry Andric              << " use list MachineOperand " << MO
23759d6cff9SDimitry Andric              << " has no parent instruction.\n";
23859d6cff9SDimitry Andric       Valid = false;
23967c32a98SDimitry Andric       continue;
24059d6cff9SDimitry Andric     }
24159d6cff9SDimitry Andric     MachineOperand *MO0 = &MI->getOperand(0);
24259d6cff9SDimitry Andric     unsigned NumOps = MI->getNumOperands();
24359d6cff9SDimitry Andric     if (!(MO >= MO0 && MO < MO0+NumOps)) {
244044eb2f6SDimitry Andric       errs() << printReg(Reg, getTargetRegisterInfo())
245f8af5cf6SDimitry Andric              << " use list MachineOperand " << MO
24659d6cff9SDimitry Andric              << " doesn't belong to parent MI: " << *MI;
24759d6cff9SDimitry Andric       Valid = false;
24859d6cff9SDimitry Andric     }
24959d6cff9SDimitry Andric     if (!MO->isReg()) {
250044eb2f6SDimitry Andric       errs() << printReg(Reg, getTargetRegisterInfo())
251f8af5cf6SDimitry Andric              << " MachineOperand " << MO << ": " << *MO
25259d6cff9SDimitry Andric              << " is not a register\n";
25359d6cff9SDimitry Andric       Valid = false;
25459d6cff9SDimitry Andric     }
25559d6cff9SDimitry Andric     if (MO->getReg() != Reg) {
256044eb2f6SDimitry Andric       errs() << printReg(Reg, getTargetRegisterInfo())
257f8af5cf6SDimitry Andric              << " use-list MachineOperand " << MO << ": "
25859d6cff9SDimitry Andric              << *MO << " is the wrong register\n";
25959d6cff9SDimitry Andric       Valid = false;
26059d6cff9SDimitry Andric     }
26159d6cff9SDimitry Andric   }
26259d6cff9SDimitry Andric   assert(Valid && "Invalid use list");
26359d6cff9SDimitry Andric #endif
26459d6cff9SDimitry Andric }
26559d6cff9SDimitry Andric 
verifyUseLists() const26659d6cff9SDimitry Andric void MachineRegisterInfo::verifyUseLists() const {
26759d6cff9SDimitry Andric #ifndef NDEBUG
26859d6cff9SDimitry Andric   for (unsigned i = 0, e = getNumVirtRegs(); i != e; ++i)
2691d5ae102SDimitry Andric     verifyUseList(Register::index2VirtReg(i));
270f8af5cf6SDimitry Andric   for (unsigned i = 1, e = getTargetRegisterInfo()->getNumRegs(); i != e; ++i)
27159d6cff9SDimitry Andric     verifyUseList(i);
27259d6cff9SDimitry Andric #endif
27359d6cff9SDimitry Andric }
27459d6cff9SDimitry Andric 
27558b69754SDimitry Andric /// Add MO to the linked list of operands for its register.
addRegOperandToUseList(MachineOperand * MO)27658b69754SDimitry Andric void MachineRegisterInfo::addRegOperandToUseList(MachineOperand *MO) {
27758b69754SDimitry Andric   assert(!MO->isOnRegUseList() && "Already on list");
27858b69754SDimitry Andric   MachineOperand *&HeadRef = getRegUseDefListHead(MO->getReg());
27958b69754SDimitry Andric   MachineOperand *const Head = HeadRef;
28058b69754SDimitry Andric 
28158b69754SDimitry Andric   // Head points to the first list element.
28258b69754SDimitry Andric   // Next is NULL on the last list element.
28358b69754SDimitry Andric   // Prev pointers are circular, so Head->Prev == Last.
28458b69754SDimitry Andric 
28558b69754SDimitry Andric   // Head is NULL for an empty list.
28658b69754SDimitry Andric   if (!Head) {
28758b69754SDimitry Andric     MO->Contents.Reg.Prev = MO;
2885ca98fd9SDimitry Andric     MO->Contents.Reg.Next = nullptr;
28958b69754SDimitry Andric     HeadRef = MO;
29058b69754SDimitry Andric     return;
291009b1c42SEd Schouten   }
29258b69754SDimitry Andric   assert(MO->getReg() == Head->getReg() && "Different regs on the same list!");
29358b69754SDimitry Andric 
29458b69754SDimitry Andric   // Insert MO between Last and Head in the circular Prev chain.
29558b69754SDimitry Andric   MachineOperand *Last = Head->Contents.Reg.Prev;
29658b69754SDimitry Andric   assert(Last && "Inconsistent use list");
29758b69754SDimitry Andric   assert(MO->getReg() == Last->getReg() && "Different regs on the same list!");
29858b69754SDimitry Andric   Head->Contents.Reg.Prev = MO;
29958b69754SDimitry Andric   MO->Contents.Reg.Prev = Last;
30058b69754SDimitry Andric 
30158b69754SDimitry Andric   // Def operands always precede uses. This allows def_iterator to stop early.
30258b69754SDimitry Andric   // Insert def operands at the front, and use operands at the back.
30358b69754SDimitry Andric   if (MO->isDef()) {
30458b69754SDimitry Andric     // Insert def at the front.
30558b69754SDimitry Andric     MO->Contents.Reg.Next = Head;
30658b69754SDimitry Andric     HeadRef = MO;
30758b69754SDimitry Andric   } else {
30858b69754SDimitry Andric     // Insert use at the end.
3095ca98fd9SDimitry Andric     MO->Contents.Reg.Next = nullptr;
31058b69754SDimitry Andric     Last->Contents.Reg.Next = MO;
31158b69754SDimitry Andric   }
31258b69754SDimitry Andric }
31358b69754SDimitry Andric 
31458b69754SDimitry Andric /// Remove MO from its use-def list.
removeRegOperandFromUseList(MachineOperand * MO)31558b69754SDimitry Andric void MachineRegisterInfo::removeRegOperandFromUseList(MachineOperand *MO) {
31658b69754SDimitry Andric   assert(MO->isOnRegUseList() && "Operand not on use list");
31758b69754SDimitry Andric   MachineOperand *&HeadRef = getRegUseDefListHead(MO->getReg());
31858b69754SDimitry Andric   MachineOperand *const Head = HeadRef;
31958b69754SDimitry Andric   assert(Head && "List already empty");
32058b69754SDimitry Andric 
32158b69754SDimitry Andric   // Unlink this from the doubly linked list of operands.
32258b69754SDimitry Andric   MachineOperand *Next = MO->Contents.Reg.Next;
32358b69754SDimitry Andric   MachineOperand *Prev = MO->Contents.Reg.Prev;
32458b69754SDimitry Andric 
32558b69754SDimitry Andric   // Prev links are circular, next link is NULL instead of looping back to Head.
32658b69754SDimitry Andric   if (MO == Head)
32758b69754SDimitry Andric     HeadRef = Next;
32858b69754SDimitry Andric   else
32958b69754SDimitry Andric     Prev->Contents.Reg.Next = Next;
33058b69754SDimitry Andric 
33158b69754SDimitry Andric   (Next ? Next : Head)->Contents.Reg.Prev = Prev;
33258b69754SDimitry Andric 
3335ca98fd9SDimitry Andric   MO->Contents.Reg.Prev = nullptr;
3345ca98fd9SDimitry Andric   MO->Contents.Reg.Next = nullptr;
335009b1c42SEd Schouten }
336009b1c42SEd Schouten 
3374a16efa3SDimitry Andric /// Move NumOps operands from Src to Dst, updating use-def lists as needed.
3384a16efa3SDimitry Andric ///
3394a16efa3SDimitry Andric /// The Dst range is assumed to be uninitialized memory. (Or it may contain
3404a16efa3SDimitry Andric /// operands that won't be destroyed, which is OK because the MO destructor is
3414a16efa3SDimitry Andric /// trivial anyway).
3424a16efa3SDimitry Andric ///
3434a16efa3SDimitry Andric /// The Src and Dst ranges may overlap.
moveOperands(MachineOperand * Dst,MachineOperand * Src,unsigned NumOps)3444a16efa3SDimitry Andric void MachineRegisterInfo::moveOperands(MachineOperand *Dst,
3454a16efa3SDimitry Andric                                        MachineOperand *Src,
3464a16efa3SDimitry Andric                                        unsigned NumOps) {
3474a16efa3SDimitry Andric   assert(Src != Dst && NumOps && "Noop moveOperands");
3484a16efa3SDimitry Andric 
3494a16efa3SDimitry Andric   // Copy backwards if Dst is within the Src range.
3504a16efa3SDimitry Andric   int Stride = 1;
3514a16efa3SDimitry Andric   if (Dst >= Src && Dst < Src + NumOps) {
3524a16efa3SDimitry Andric     Stride = -1;
3534a16efa3SDimitry Andric     Dst += NumOps - 1;
3544a16efa3SDimitry Andric     Src += NumOps - 1;
3554a16efa3SDimitry Andric   }
3564a16efa3SDimitry Andric 
3574a16efa3SDimitry Andric   // Copy one operand at a time.
3584a16efa3SDimitry Andric   do {
3594a16efa3SDimitry Andric     new (Dst) MachineOperand(*Src);
3604a16efa3SDimitry Andric 
3614a16efa3SDimitry Andric     // Dst takes Src's place in the use-def chain.
3624a16efa3SDimitry Andric     if (Src->isReg()) {
3634a16efa3SDimitry Andric       MachineOperand *&Head = getRegUseDefListHead(Src->getReg());
3644a16efa3SDimitry Andric       MachineOperand *Prev = Src->Contents.Reg.Prev;
3654a16efa3SDimitry Andric       MachineOperand *Next = Src->Contents.Reg.Next;
3664a16efa3SDimitry Andric       assert(Head && "List empty, but operand is chained");
3674a16efa3SDimitry Andric       assert(Prev && "Operand was not on use-def list");
3684a16efa3SDimitry Andric 
3694a16efa3SDimitry Andric       // Prev links are circular, next link is NULL instead of looping back to
3704a16efa3SDimitry Andric       // Head.
3714a16efa3SDimitry Andric       if (Src == Head)
3724a16efa3SDimitry Andric         Head = Dst;
3734a16efa3SDimitry Andric       else
3744a16efa3SDimitry Andric         Prev->Contents.Reg.Next = Dst;
3754a16efa3SDimitry Andric 
3764a16efa3SDimitry Andric       // Update Prev pointer. This also works when Src was pointing to itself
3774a16efa3SDimitry Andric       // in a 1-element list. In that case Head == Dst.
3784a16efa3SDimitry Andric       (Next ? Next : Head)->Contents.Reg.Prev = Dst;
3794a16efa3SDimitry Andric     }
3804a16efa3SDimitry Andric 
3814a16efa3SDimitry Andric     Dst += Stride;
3824a16efa3SDimitry Andric     Src += Stride;
3834a16efa3SDimitry Andric   } while (--NumOps);
3844a16efa3SDimitry Andric }
3854a16efa3SDimitry Andric 
386009b1c42SEd Schouten /// replaceRegWith - Replace all instances of FromReg with ToReg in the
387009b1c42SEd Schouten /// machine function.  This is like llvm-level X->replaceAllUsesWith(Y),
388009b1c42SEd Schouten /// except that it also changes any definitions of the register as well.
38967c32a98SDimitry Andric /// If ToReg is a physical register we apply the sub register to obtain the
39067c32a98SDimitry Andric /// final/proper physical register.
replaceRegWith(Register FromReg,Register ToReg)391cfca06d7SDimitry Andric void MachineRegisterInfo::replaceRegWith(Register FromReg, Register ToReg) {
392009b1c42SEd Schouten   assert(FromReg != ToReg && "Cannot replace a reg with itself");
393009b1c42SEd Schouten 
39467c32a98SDimitry Andric   const TargetRegisterInfo *TRI = getTargetRegisterInfo();
39567c32a98SDimitry Andric 
396009b1c42SEd Schouten   // TODO: This could be more efficient by bulk changing the operands.
397c0981da4SDimitry Andric   for (MachineOperand &O : llvm::make_early_inc_range(reg_operands(FromReg))) {
398e3b55780SDimitry Andric     if (ToReg.isPhysical()) {
39967c32a98SDimitry Andric       O.substPhysReg(ToReg, *TRI);
40067c32a98SDimitry Andric     } else {
401009b1c42SEd Schouten       O.setReg(ToReg);
402009b1c42SEd Schouten     }
403009b1c42SEd Schouten   }
40467c32a98SDimitry Andric }
405009b1c42SEd Schouten 
406009b1c42SEd Schouten /// getVRegDef - Return the machine instr that defines the specified virtual
407009b1c42SEd Schouten /// register or null if none is found.  This assumes that the code is in SSA
408009b1c42SEd Schouten /// form, so there should only be one definition.
getVRegDef(Register Reg) const409cfca06d7SDimitry Andric MachineInstr *MachineRegisterInfo::getVRegDef(Register Reg) const {
41059850d08SRoman Divacky   // Since we are in SSA form, we can use the first definition.
4115ca98fd9SDimitry Andric   def_instr_iterator I = def_instr_begin(Reg);
4125ca98fd9SDimitry Andric   assert((I.atEnd() || std::next(I) == def_instr_end()) &&
41358b69754SDimitry Andric          "getVRegDef assumes a single definition or no definition");
4145ca98fd9SDimitry Andric   return !I.atEnd() ? &*I : nullptr;
415009b1c42SEd Schouten }
416009b1c42SEd Schouten 
41758b69754SDimitry Andric /// getUniqueVRegDef - Return the unique machine instr that defines the
41858b69754SDimitry Andric /// specified virtual register or null if none is found.  If there are
41958b69754SDimitry Andric /// multiple definitions or no definition, return null.
getUniqueVRegDef(Register Reg) const420cfca06d7SDimitry Andric MachineInstr *MachineRegisterInfo::getUniqueVRegDef(Register Reg) const {
4215ca98fd9SDimitry Andric   if (def_empty(Reg)) return nullptr;
4225ca98fd9SDimitry Andric   def_instr_iterator I = def_instr_begin(Reg);
4235ca98fd9SDimitry Andric   if (std::next(I) != def_instr_end())
4245ca98fd9SDimitry Andric     return nullptr;
42558b69754SDimitry Andric   return &*I;
426f5a3459aSRoman Divacky }
427f5a3459aSRoman Divacky 
hasOneNonDBGUse(Register RegNo) const428cfca06d7SDimitry Andric bool MachineRegisterInfo::hasOneNonDBGUse(Register RegNo) const {
429b60736ecSDimitry Andric   return hasSingleElement(use_nodbg_operands(RegNo));
430f5a3459aSRoman Divacky }
431009b1c42SEd Schouten 
hasOneNonDBGUser(Register RegNo) const432cfca06d7SDimitry Andric bool MachineRegisterInfo::hasOneNonDBGUser(Register RegNo) const {
433b60736ecSDimitry Andric   return hasSingleElement(use_nodbg_instructions(RegNo));
434e6d15924SDimitry Andric }
435e6d15924SDimitry Andric 
hasAtMostUserInstrs(Register Reg,unsigned MaxUsers) const436e3b55780SDimitry Andric bool MachineRegisterInfo::hasAtMostUserInstrs(Register Reg,
437e3b55780SDimitry Andric                                               unsigned MaxUsers) const {
438e3b55780SDimitry Andric   return hasNItemsOrLess(use_instr_nodbg_begin(Reg), use_instr_nodbg_end(),
439e3b55780SDimitry Andric                          MaxUsers);
440e3b55780SDimitry Andric }
441e3b55780SDimitry Andric 
442abdf259dSRoman Divacky /// clearKillFlags - Iterate over all the uses of the given register and
443abdf259dSRoman Divacky /// clear the kill flag from the MachineOperand. This function is used by
444abdf259dSRoman Divacky /// optimization passes which extend register lifetimes and need only
445abdf259dSRoman Divacky /// preserve conservative kill flag information.
clearKillFlags(Register Reg) const446cfca06d7SDimitry Andric void MachineRegisterInfo::clearKillFlags(Register Reg) const {
4475ca98fd9SDimitry Andric   for (MachineOperand &MO : use_operands(Reg))
4485ca98fd9SDimitry Andric     MO.setIsKill(false);
449abdf259dSRoman Divacky }
450abdf259dSRoman Divacky 
isLiveIn(Register Reg) const451cfca06d7SDimitry Andric bool MachineRegisterInfo::isLiveIn(Register Reg) const {
452344a3780SDimitry Andric   for (const std::pair<MCRegister, Register> &LI : liveins())
453344a3780SDimitry Andric     if ((Register)LI.first == Reg || LI.second == Reg)
454d7f7719eSRoman Divacky       return true;
455d7f7719eSRoman Divacky   return false;
456d7f7719eSRoman Divacky }
457d7f7719eSRoman Divacky 
458d7f7719eSRoman Divacky /// getLiveInPhysReg - If VReg is a live-in virtual register, return the
459d7f7719eSRoman Divacky /// corresponding live-in physical register.
getLiveInPhysReg(Register VReg) const460cfca06d7SDimitry Andric MCRegister MachineRegisterInfo::getLiveInPhysReg(Register VReg) const {
461344a3780SDimitry Andric   for (const std::pair<MCRegister, Register> &LI : liveins())
462344a3780SDimitry Andric     if (LI.second == VReg)
463344a3780SDimitry Andric       return LI.first;
464cfca06d7SDimitry Andric   return MCRegister();
465d7f7719eSRoman Divacky }
466d7f7719eSRoman Divacky 
467abdf259dSRoman Divacky /// getLiveInVirtReg - If PReg is a live-in physical register, return the
468abdf259dSRoman Divacky /// corresponding live-in physical register.
getLiveInVirtReg(MCRegister PReg) const469cfca06d7SDimitry Andric Register MachineRegisterInfo::getLiveInVirtReg(MCRegister PReg) const {
470344a3780SDimitry Andric   for (const std::pair<MCRegister, Register> &LI : liveins())
471344a3780SDimitry Andric     if (LI.first == PReg)
472344a3780SDimitry Andric       return LI.second;
473cfca06d7SDimitry Andric   return Register();
474abdf259dSRoman Divacky }
475abdf259dSRoman Divacky 
476d7f7719eSRoman Divacky /// EmitLiveInCopies - Emit copies to initialize livein virtual registers
477d7f7719eSRoman Divacky /// into the given entry block.
478d7f7719eSRoman Divacky void
EmitLiveInCopies(MachineBasicBlock * EntryMBB,const TargetRegisterInfo & TRI,const TargetInstrInfo & TII)479d7f7719eSRoman Divacky MachineRegisterInfo::EmitLiveInCopies(MachineBasicBlock *EntryMBB,
480d7f7719eSRoman Divacky                                       const TargetRegisterInfo &TRI,
481d7f7719eSRoman Divacky                                       const TargetInstrInfo &TII) {
48266e41e3cSRoman Divacky   // Emit the copies into the top of the block.
48366e41e3cSRoman Divacky   for (unsigned i = 0, e = LiveIns.size(); i != e; ++i)
48466e41e3cSRoman Divacky     if (LiveIns[i].second) {
485044eb2f6SDimitry Andric       if (use_nodbg_empty(LiveIns[i].second)) {
486044eb2f6SDimitry Andric         // The livein has no non-dbg uses. Drop it.
48766e41e3cSRoman Divacky         //
48866e41e3cSRoman Divacky         // It would be preferable to have isel avoid creating live-in
48966e41e3cSRoman Divacky         // records for unused arguments in the first place, but it's
49066e41e3cSRoman Divacky         // complicated by the debug info code for arguments.
49166e41e3cSRoman Divacky         LiveIns.erase(LiveIns.begin() + i);
49266e41e3cSRoman Divacky         --i; --e;
49366e41e3cSRoman Divacky       } else {
49466e41e3cSRoman Divacky         // Emit a copy.
495d0e4e96dSDimitry Andric         BuildMI(*EntryMBB, EntryMBB->begin(), DebugLoc(),
49666e41e3cSRoman Divacky                 TII.get(TargetOpcode::COPY), LiveIns[i].second)
49766e41e3cSRoman Divacky           .addReg(LiveIns[i].first);
49866e41e3cSRoman Divacky 
49966e41e3cSRoman Divacky         // Add the register to the entry block live-in set.
50066e41e3cSRoman Divacky         EntryMBB->addLiveIn(LiveIns[i].first);
501d7f7719eSRoman Divacky       }
502d7f7719eSRoman Divacky     } else {
50366e41e3cSRoman Divacky       // Add the register to the entry block live-in set.
50466e41e3cSRoman Divacky       EntryMBB->addLiveIn(LiveIns[i].first);
505d7f7719eSRoman Divacky     }
506d7f7719eSRoman Divacky }
507d7f7719eSRoman Divacky 
getMaxLaneMaskForVReg(Register Reg) const508cfca06d7SDimitry Andric LaneBitmask MachineRegisterInfo::getMaxLaneMaskForVReg(Register Reg) const {
50967c32a98SDimitry Andric   // Lane masks are only defined for vregs.
510e3b55780SDimitry Andric   assert(Reg.isVirtual());
51167c32a98SDimitry Andric   const TargetRegisterClass &TRC = *getRegClass(Reg);
51267c32a98SDimitry Andric   return TRC.getLaneMask();
51367c32a98SDimitry Andric }
51467c32a98SDimitry Andric 
51571d5a254SDimitry Andric #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
dumpUses(Register Reg) const516cfca06d7SDimitry Andric LLVM_DUMP_METHOD void MachineRegisterInfo::dumpUses(Register Reg) const {
5175ca98fd9SDimitry Andric   for (MachineInstr &I : use_instructions(Reg))
5185ca98fd9SDimitry Andric     I.dump();
519009b1c42SEd Schouten }
520009b1c42SEd Schouten #endif
52163faed5bSDimitry Andric 
freezeReservedRegs()522ac9a064cSDimitry Andric void MachineRegisterInfo::freezeReservedRegs() {
523ac9a064cSDimitry Andric   ReservedRegs = getTargetRegisterInfo()->getReservedRegs(*MF);
524f8af5cf6SDimitry Andric   assert(ReservedRegs.size() == getTargetRegisterInfo()->getNumRegs() &&
525522600a2SDimitry Andric          "Invalid ReservedRegs vector from target");
52663faed5bSDimitry Andric }
52763faed5bSDimitry Andric 
isConstantPhysReg(MCRegister PhysReg) const528cfca06d7SDimitry Andric bool MachineRegisterInfo::isConstantPhysReg(MCRegister PhysReg) const {
5291d5ae102SDimitry Andric   assert(Register::isPhysicalRegister(PhysReg));
53063faed5bSDimitry Andric 
531b915e9e0SDimitry Andric   const TargetRegisterInfo *TRI = getTargetRegisterInfo();
532b915e9e0SDimitry Andric   if (TRI->isConstantPhysReg(PhysReg))
533b915e9e0SDimitry Andric     return true;
534b915e9e0SDimitry Andric 
535522600a2SDimitry Andric   // Check if any overlapping register is modified, or allocatable so it may be
536522600a2SDimitry Andric   // used later.
537b915e9e0SDimitry Andric   for (MCRegAliasIterator AI(PhysReg, TRI, true);
538f8af5cf6SDimitry Andric        AI.isValid(); ++AI)
539522600a2SDimitry Andric     if (!def_empty(*AI) || isAllocatable(*AI))
54063faed5bSDimitry Andric       return false;
54163faed5bSDimitry Andric   return true;
54263faed5bSDimitry Andric }
5435ca98fd9SDimitry Andric 
5445ca98fd9SDimitry Andric /// markUsesInDebugValueAsUndef - Mark every DBG_VALUE referencing the
5455ca98fd9SDimitry Andric /// specified register as undefined which causes the DBG_VALUE to be
5465ca98fd9SDimitry Andric /// deleted during LiveDebugVariables analysis.
markUsesInDebugValueAsUndef(Register Reg) const547cfca06d7SDimitry Andric void MachineRegisterInfo::markUsesInDebugValueAsUndef(Register Reg) const {
548344a3780SDimitry Andric   // Mark any DBG_VALUE* that uses Reg as undef (but don't delete it.)
549344a3780SDimitry Andric   // We use make_early_inc_range because setReg invalidates the iterator.
550344a3780SDimitry Andric   for (MachineInstr &UseMI : llvm::make_early_inc_range(use_instructions(Reg))) {
551344a3780SDimitry Andric     if (UseMI.isDebugValue() && UseMI.hasDebugOperandForReg(Reg))
552344a3780SDimitry Andric       UseMI.setDebugValueUndef();
5535ca98fd9SDimitry Andric   }
5545ca98fd9SDimitry Andric }
555ee8648bdSDimitry Andric 
getCalledFunction(const MachineInstr & MI)556ee8648bdSDimitry Andric static const Function *getCalledFunction(const MachineInstr &MI) {
557ee8648bdSDimitry Andric   for (const MachineOperand &MO : MI.operands()) {
558ee8648bdSDimitry Andric     if (!MO.isGlobal())
559ee8648bdSDimitry Andric       continue;
560ee8648bdSDimitry Andric     const Function *Func = dyn_cast<Function>(MO.getGlobal());
561ee8648bdSDimitry Andric     if (Func != nullptr)
562ee8648bdSDimitry Andric       return Func;
563ee8648bdSDimitry Andric   }
564ee8648bdSDimitry Andric   return nullptr;
565ee8648bdSDimitry Andric }
566ee8648bdSDimitry Andric 
isNoReturnDef(const MachineOperand & MO)567ee8648bdSDimitry Andric static bool isNoReturnDef(const MachineOperand &MO) {
568ee8648bdSDimitry Andric   // Anything which is not a noreturn function is a real def.
569ee8648bdSDimitry Andric   const MachineInstr &MI = *MO.getParent();
570ee8648bdSDimitry Andric   if (!MI.isCall())
571ee8648bdSDimitry Andric     return false;
572ee8648bdSDimitry Andric   const MachineBasicBlock &MBB = *MI.getParent();
573ee8648bdSDimitry Andric   if (!MBB.succ_empty())
574ee8648bdSDimitry Andric     return false;
575ee8648bdSDimitry Andric   const MachineFunction &MF = *MBB.getParent();
576ee8648bdSDimitry Andric   // We need to keep correct unwind information even if the function will
577ee8648bdSDimitry Andric   // not return, since the runtime may need it.
578044eb2f6SDimitry Andric   if (MF.getFunction().hasFnAttribute(Attribute::UWTable))
579ee8648bdSDimitry Andric     return false;
580ee8648bdSDimitry Andric   const Function *Called = getCalledFunction(MI);
581dd58ef01SDimitry Andric   return !(Called == nullptr || !Called->hasFnAttribute(Attribute::NoReturn) ||
582dd58ef01SDimitry Andric            !Called->hasFnAttribute(Attribute::NoUnwind));
583ee8648bdSDimitry Andric }
584ee8648bdSDimitry Andric 
isPhysRegModified(MCRegister PhysReg,bool SkipNoReturnDef) const585cfca06d7SDimitry Andric bool MachineRegisterInfo::isPhysRegModified(MCRegister PhysReg,
58601095a5dSDimitry Andric                                             bool SkipNoReturnDef) const {
587ee8648bdSDimitry Andric   if (UsedPhysRegMask.test(PhysReg))
588ee8648bdSDimitry Andric     return true;
589ee8648bdSDimitry Andric   const TargetRegisterInfo *TRI = getTargetRegisterInfo();
590ee8648bdSDimitry Andric   for (MCRegAliasIterator AI(PhysReg, TRI, true); AI.isValid(); ++AI) {
591ee8648bdSDimitry Andric     for (const MachineOperand &MO : make_range(def_begin(*AI), def_end())) {
59201095a5dSDimitry Andric       if (!SkipNoReturnDef && isNoReturnDef(MO))
593ee8648bdSDimitry Andric         continue;
594ee8648bdSDimitry Andric       return true;
595ee8648bdSDimitry Andric     }
596ee8648bdSDimitry Andric   }
597ee8648bdSDimitry Andric   return false;
598ee8648bdSDimitry Andric }
599dd58ef01SDimitry Andric 
isPhysRegUsed(MCRegister PhysReg,bool SkipRegMaskTest) const600344a3780SDimitry Andric bool MachineRegisterInfo::isPhysRegUsed(MCRegister PhysReg,
601344a3780SDimitry Andric                                         bool SkipRegMaskTest) const {
602344a3780SDimitry Andric   if (!SkipRegMaskTest && UsedPhysRegMask.test(PhysReg))
603dd58ef01SDimitry Andric     return true;
604dd58ef01SDimitry Andric   const TargetRegisterInfo *TRI = getTargetRegisterInfo();
605dd58ef01SDimitry Andric   for (MCRegAliasIterator AliasReg(PhysReg, TRI, true); AliasReg.isValid();
606dd58ef01SDimitry Andric        ++AliasReg) {
607dd58ef01SDimitry Andric     if (!reg_nodbg_empty(*AliasReg))
608dd58ef01SDimitry Andric       return true;
609dd58ef01SDimitry Andric   }
610dd58ef01SDimitry Andric   return false;
611dd58ef01SDimitry Andric }
61271d5a254SDimitry Andric 
disableCalleeSavedRegister(MCRegister Reg)613cfca06d7SDimitry Andric void MachineRegisterInfo::disableCalleeSavedRegister(MCRegister Reg) {
61471d5a254SDimitry Andric 
61571d5a254SDimitry Andric   const TargetRegisterInfo *TRI = getTargetRegisterInfo();
61671d5a254SDimitry Andric   assert(Reg && (Reg < TRI->getNumRegs()) &&
61771d5a254SDimitry Andric          "Trying to disable an invalid register");
61871d5a254SDimitry Andric 
61971d5a254SDimitry Andric   if (!IsUpdatedCSRsInitialized) {
62071d5a254SDimitry Andric     const MCPhysReg *CSR = TRI->getCalleeSavedRegs(MF);
62171d5a254SDimitry Andric     for (const MCPhysReg *I = CSR; *I; ++I)
62271d5a254SDimitry Andric       UpdatedCSRs.push_back(*I);
62371d5a254SDimitry Andric 
62471d5a254SDimitry Andric     // Zero value represents the end of the register list
62571d5a254SDimitry Andric     // (no more registers should be pushed).
62671d5a254SDimitry Andric     UpdatedCSRs.push_back(0);
62771d5a254SDimitry Andric 
62871d5a254SDimitry Andric     IsUpdatedCSRsInitialized = true;
62971d5a254SDimitry Andric   }
63071d5a254SDimitry Andric 
63171d5a254SDimitry Andric   // Remove the register (and its aliases from the list).
63271d5a254SDimitry Andric   for (MCRegAliasIterator AI(Reg, TRI, true); AI.isValid(); ++AI)
633b1c73532SDimitry Andric     llvm::erase(UpdatedCSRs, *AI);
63471d5a254SDimitry Andric }
63571d5a254SDimitry Andric 
getCalleeSavedRegs() const63671d5a254SDimitry Andric const MCPhysReg *MachineRegisterInfo::getCalleeSavedRegs() const {
63771d5a254SDimitry Andric   if (IsUpdatedCSRsInitialized)
63871d5a254SDimitry Andric     return UpdatedCSRs.data();
63971d5a254SDimitry Andric 
64071d5a254SDimitry Andric   return getTargetRegisterInfo()->getCalleeSavedRegs(MF);
64171d5a254SDimitry Andric }
64271d5a254SDimitry Andric 
setCalleeSavedRegs(ArrayRef<MCPhysReg> CSRs)64371d5a254SDimitry Andric void MachineRegisterInfo::setCalleeSavedRegs(ArrayRef<MCPhysReg> CSRs) {
64471d5a254SDimitry Andric   if (IsUpdatedCSRsInitialized)
64571d5a254SDimitry Andric     UpdatedCSRs.clear();
64671d5a254SDimitry Andric 
647b60736ecSDimitry Andric   append_range(UpdatedCSRs, CSRs);
64871d5a254SDimitry Andric 
64971d5a254SDimitry Andric   // Zero value represents the end of the register list
65071d5a254SDimitry Andric   // (no more registers should be pushed).
65171d5a254SDimitry Andric   UpdatedCSRs.push_back(0);
65271d5a254SDimitry Andric   IsUpdatedCSRsInitialized = true;
65371d5a254SDimitry Andric }
654edad5bcbSDimitry Andric 
isReservedRegUnit(unsigned Unit) const655edad5bcbSDimitry Andric bool MachineRegisterInfo::isReservedRegUnit(unsigned Unit) const {
656edad5bcbSDimitry Andric   const TargetRegisterInfo *TRI = getTargetRegisterInfo();
657edad5bcbSDimitry Andric   for (MCRegUnitRootIterator Root(Unit, TRI); Root.isValid(); ++Root) {
6587fa27ce4SDimitry Andric     if (all_of(TRI->superregs_inclusive(*Root),
6597fa27ce4SDimitry Andric                [&](MCPhysReg Super) { return isReserved(Super); }))
660edad5bcbSDimitry Andric       return true;
661edad5bcbSDimitry Andric   }
662edad5bcbSDimitry Andric   return false;
663edad5bcbSDimitry Andric }
664