1284c1978SDimitry Andric //===-- SystemZRegisterInfo.cpp - SystemZ register information ------------===//
2284c1978SDimitry Andric //
3284c1978SDimitry Andric //                     The LLVM Compiler Infrastructure
4284c1978SDimitry Andric //
5284c1978SDimitry Andric // This file is distributed under the University of Illinois Open Source
6284c1978SDimitry Andric // License. See LICENSE.TXT for details.
7284c1978SDimitry Andric //
8284c1978SDimitry Andric //===----------------------------------------------------------------------===//
9284c1978SDimitry Andric 
10284c1978SDimitry Andric #include "SystemZRegisterInfo.h"
11db17bf38SDimitry Andric #include "SystemZInstrInfo.h"
1291bc56edSDimitry Andric #include "SystemZSubtarget.h"
132cab237bSDimitry Andric #include "llvm/CodeGen/LiveIntervals.h"
142cab237bSDimitry Andric #include "llvm/ADT/SmallSet.h"
15284c1978SDimitry Andric #include "llvm/CodeGen/MachineInstrBuilder.h"
16284c1978SDimitry Andric #include "llvm/CodeGen/MachineRegisterInfo.h"
172cab237bSDimitry Andric #include "llvm/CodeGen/TargetFrameLowering.h"
182cab237bSDimitry Andric #include "llvm/CodeGen/VirtRegMap.h"
1991bc56edSDimitry Andric 
2091bc56edSDimitry Andric using namespace llvm;
21284c1978SDimitry Andric 
22284c1978SDimitry Andric #define GET_REGINFO_TARGET_DESC
23284c1978SDimitry Andric #include "SystemZGenRegisterInfo.inc"
24284c1978SDimitry Andric 
SystemZRegisterInfo()2591bc56edSDimitry Andric SystemZRegisterInfo::SystemZRegisterInfo()
2691bc56edSDimitry Andric     : SystemZGenRegisterInfo(SystemZ::R14D) {}
27284c1978SDimitry Andric 
282cab237bSDimitry Andric // Given that MO is a GRX32 operand, return either GR32 or GRH32 if MO
292cab237bSDimitry Andric // somehow belongs in it. Otherwise, return GRX32.
getRC32(MachineOperand & MO,const VirtRegMap * VRM,const MachineRegisterInfo * MRI)302cab237bSDimitry Andric static const TargetRegisterClass *getRC32(MachineOperand &MO,
312cab237bSDimitry Andric                                           const VirtRegMap *VRM,
322cab237bSDimitry Andric                                           const MachineRegisterInfo *MRI) {
332cab237bSDimitry Andric   const TargetRegisterClass *RC = MRI->getRegClass(MO.getReg());
342cab237bSDimitry Andric 
352cab237bSDimitry Andric   if (SystemZ::GR32BitRegClass.hasSubClassEq(RC) ||
362cab237bSDimitry Andric       MO.getSubReg() == SystemZ::subreg_l32 ||
372cab237bSDimitry Andric       MO.getSubReg() == SystemZ::subreg_hl32)
382cab237bSDimitry Andric     return &SystemZ::GR32BitRegClass;
392cab237bSDimitry Andric   if (SystemZ::GRH32BitRegClass.hasSubClassEq(RC) ||
402cab237bSDimitry Andric       MO.getSubReg() == SystemZ::subreg_h32 ||
412cab237bSDimitry Andric       MO.getSubReg() == SystemZ::subreg_hh32)
422cab237bSDimitry Andric     return &SystemZ::GRH32BitRegClass;
432cab237bSDimitry Andric 
442cab237bSDimitry Andric   if (VRM && VRM->hasPhys(MO.getReg())) {
452cab237bSDimitry Andric     unsigned PhysReg = VRM->getPhys(MO.getReg());
462cab237bSDimitry Andric     if (SystemZ::GR32BitRegClass.contains(PhysReg))
472cab237bSDimitry Andric       return &SystemZ::GR32BitRegClass;
482cab237bSDimitry Andric     assert (SystemZ::GRH32BitRegClass.contains(PhysReg) &&
492cab237bSDimitry Andric             "Phys reg not in GR32 or GRH32?");
502cab237bSDimitry Andric     return &SystemZ::GRH32BitRegClass;
512cab237bSDimitry Andric   }
522cab237bSDimitry Andric 
532cab237bSDimitry Andric   assert (RC == &SystemZ::GRX32BitRegClass);
542cab237bSDimitry Andric   return RC;
552cab237bSDimitry Andric }
562cab237bSDimitry Andric 
572cab237bSDimitry Andric bool
getRegAllocationHints(unsigned VirtReg,ArrayRef<MCPhysReg> Order,SmallVectorImpl<MCPhysReg> & Hints,const MachineFunction & MF,const VirtRegMap * VRM,const LiveRegMatrix * Matrix) const582cab237bSDimitry Andric SystemZRegisterInfo::getRegAllocationHints(unsigned VirtReg,
592cab237bSDimitry Andric                                            ArrayRef<MCPhysReg> Order,
602cab237bSDimitry Andric                                            SmallVectorImpl<MCPhysReg> &Hints,
612cab237bSDimitry Andric                                            const MachineFunction &MF,
622cab237bSDimitry Andric                                            const VirtRegMap *VRM,
632cab237bSDimitry Andric                                            const LiveRegMatrix *Matrix) const {
642cab237bSDimitry Andric   const MachineRegisterInfo *MRI = &MF.getRegInfo();
652cab237bSDimitry Andric   const TargetRegisterInfo *TRI = MF.getSubtarget().getRegisterInfo();
66*b5893f02SDimitry Andric 
67*b5893f02SDimitry Andric   bool BaseImplRetVal = TargetRegisterInfo::getRegAllocationHints(
68*b5893f02SDimitry Andric       VirtReg, Order, Hints, MF, VRM, Matrix);
69*b5893f02SDimitry Andric 
702cab237bSDimitry Andric   if (MRI->getRegClass(VirtReg) == &SystemZ::GRX32BitRegClass) {
712cab237bSDimitry Andric     SmallVector<unsigned, 8> Worklist;
722cab237bSDimitry Andric     SmallSet<unsigned, 4> DoneRegs;
732cab237bSDimitry Andric     Worklist.push_back(VirtReg);
742cab237bSDimitry Andric     while (Worklist.size()) {
752cab237bSDimitry Andric       unsigned Reg = Worklist.pop_back_val();
762cab237bSDimitry Andric       if (!DoneRegs.insert(Reg).second)
772cab237bSDimitry Andric         continue;
782cab237bSDimitry Andric 
792cab237bSDimitry Andric       for (auto &Use : MRI->use_instructions(Reg))
802cab237bSDimitry Andric         // For LOCRMux, see if the other operand is already a high or low
812cab237bSDimitry Andric         // register, and in that case give the correpsonding hints for
822cab237bSDimitry Andric         // VirtReg. LOCR instructions need both operands in either high or
832cab237bSDimitry Andric         // low parts.
842cab237bSDimitry Andric         if (Use.getOpcode() == SystemZ::LOCRMux) {
852cab237bSDimitry Andric           MachineOperand &TrueMO = Use.getOperand(1);
862cab237bSDimitry Andric           MachineOperand &FalseMO = Use.getOperand(2);
872cab237bSDimitry Andric           const TargetRegisterClass *RC =
882cab237bSDimitry Andric             TRI->getCommonSubClass(getRC32(FalseMO, VRM, MRI),
892cab237bSDimitry Andric                                    getRC32(TrueMO, VRM, MRI));
902cab237bSDimitry Andric           if (RC && RC != &SystemZ::GRX32BitRegClass) {
91*b5893f02SDimitry Andric             // Pass the registers of RC as hints while making sure that if
92*b5893f02SDimitry Andric             // any of these registers are copy hints, hint them first.
93*b5893f02SDimitry Andric             SmallSet<unsigned, 4> CopyHints;
94*b5893f02SDimitry Andric             CopyHints.insert(Hints.begin(), Hints.end());
95*b5893f02SDimitry Andric             Hints.clear();
962cab237bSDimitry Andric             for (MCPhysReg Reg : Order)
97*b5893f02SDimitry Andric               if (CopyHints.count(Reg) &&
98*b5893f02SDimitry Andric                   RC->contains(Reg) && !MRI->isReserved(Reg))
99*b5893f02SDimitry Andric                 Hints.push_back(Reg);
100*b5893f02SDimitry Andric             for (MCPhysReg Reg : Order)
101*b5893f02SDimitry Andric               if (!CopyHints.count(Reg) &&
102*b5893f02SDimitry Andric                   RC->contains(Reg) && !MRI->isReserved(Reg))
1032cab237bSDimitry Andric                 Hints.push_back(Reg);
1042cab237bSDimitry Andric             // Return true to make these hints the only regs available to
1052cab237bSDimitry Andric             // RA. This may mean extra spilling but since the alternative is
1062cab237bSDimitry Andric             // a jump sequence expansion of the LOCRMux, it is preferred.
1072cab237bSDimitry Andric             return true;
1082cab237bSDimitry Andric           }
1092cab237bSDimitry Andric 
1102cab237bSDimitry Andric           // Add the other operand of the LOCRMux to the worklist.
1112cab237bSDimitry Andric           unsigned OtherReg =
1122cab237bSDimitry Andric             (TrueMO.getReg() == Reg ? FalseMO.getReg() : TrueMO.getReg());
1132cab237bSDimitry Andric           if (MRI->getRegClass(OtherReg) == &SystemZ::GRX32BitRegClass)
1142cab237bSDimitry Andric             Worklist.push_back(OtherReg);
1152cab237bSDimitry Andric         }
1162cab237bSDimitry Andric     }
1172cab237bSDimitry Andric   }
1182cab237bSDimitry Andric 
119*b5893f02SDimitry Andric   return BaseImplRetVal;
1202cab237bSDimitry Andric }
1212cab237bSDimitry Andric 
12291bc56edSDimitry Andric const MCPhysReg *
getCalleeSavedRegs(const MachineFunction * MF) const123284c1978SDimitry Andric SystemZRegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const {
1244ba319b5SDimitry Andric   const SystemZSubtarget &Subtarget = MF->getSubtarget<SystemZSubtarget>();
1254ba319b5SDimitry Andric   if (MF->getFunction().getCallingConv() == CallingConv::AnyReg)
1264ba319b5SDimitry Andric     return Subtarget.hasVector()? CSR_SystemZ_AllRegs_Vector_SaveList
1274ba319b5SDimitry Andric                                 : CSR_SystemZ_AllRegs_SaveList;
1283ca95b02SDimitry Andric   if (MF->getSubtarget().getTargetLowering()->supportSwiftError() &&
1292cab237bSDimitry Andric       MF->getFunction().getAttributes().hasAttrSomewhere(
1303ca95b02SDimitry Andric           Attribute::SwiftError))
1313ca95b02SDimitry Andric     return CSR_SystemZ_SwiftError_SaveList;
13291bc56edSDimitry Andric   return CSR_SystemZ_SaveList;
13391bc56edSDimitry Andric }
134284c1978SDimitry Andric 
13591bc56edSDimitry Andric const uint32_t *
getCallPreservedMask(const MachineFunction & MF,CallingConv::ID CC) const136ff0cc061SDimitry Andric SystemZRegisterInfo::getCallPreservedMask(const MachineFunction &MF,
137ff0cc061SDimitry Andric                                           CallingConv::ID CC) const {
1384ba319b5SDimitry Andric   const SystemZSubtarget &Subtarget = MF.getSubtarget<SystemZSubtarget>();
1394ba319b5SDimitry Andric   if (CC == CallingConv::AnyReg)
1404ba319b5SDimitry Andric     return Subtarget.hasVector()? CSR_SystemZ_AllRegs_Vector_RegMask
1414ba319b5SDimitry Andric                                 : CSR_SystemZ_AllRegs_RegMask;
1423ca95b02SDimitry Andric   if (MF.getSubtarget().getTargetLowering()->supportSwiftError() &&
1432cab237bSDimitry Andric       MF.getFunction().getAttributes().hasAttrSomewhere(
1443ca95b02SDimitry Andric           Attribute::SwiftError))
1453ca95b02SDimitry Andric     return CSR_SystemZ_SwiftError_RegMask;
14691bc56edSDimitry Andric   return CSR_SystemZ_RegMask;
147284c1978SDimitry Andric }
148284c1978SDimitry Andric 
149284c1978SDimitry Andric BitVector
getReservedRegs(const MachineFunction & MF) const150284c1978SDimitry Andric SystemZRegisterInfo::getReservedRegs(const MachineFunction &MF) const {
151284c1978SDimitry Andric   BitVector Reserved(getNumRegs());
152875ed548SDimitry Andric   const SystemZFrameLowering *TFI = getFrameLowering(MF);
153284c1978SDimitry Andric 
154284c1978SDimitry Andric   if (TFI->hasFP(MF)) {
155284c1978SDimitry Andric     // R11D is the frame pointer.  Reserve all aliases.
156284c1978SDimitry Andric     Reserved.set(SystemZ::R11D);
157f785676fSDimitry Andric     Reserved.set(SystemZ::R11L);
158f785676fSDimitry Andric     Reserved.set(SystemZ::R11H);
159284c1978SDimitry Andric     Reserved.set(SystemZ::R10Q);
160284c1978SDimitry Andric   }
161284c1978SDimitry Andric 
162284c1978SDimitry Andric   // R15D is the stack pointer.  Reserve all aliases.
163284c1978SDimitry Andric   Reserved.set(SystemZ::R15D);
164f785676fSDimitry Andric   Reserved.set(SystemZ::R15L);
165f785676fSDimitry Andric   Reserved.set(SystemZ::R15H);
166284c1978SDimitry Andric   Reserved.set(SystemZ::R14Q);
167d88c1a5aSDimitry Andric 
168d88c1a5aSDimitry Andric   // A0 and A1 hold the thread pointer.
169d88c1a5aSDimitry Andric   Reserved.set(SystemZ::A0);
170d88c1a5aSDimitry Andric   Reserved.set(SystemZ::A1);
171d88c1a5aSDimitry Andric 
172284c1978SDimitry Andric   return Reserved;
173284c1978SDimitry Andric }
174284c1978SDimitry Andric 
175284c1978SDimitry Andric void
eliminateFrameIndex(MachineBasicBlock::iterator MI,int SPAdj,unsigned FIOperandNum,RegScavenger * RS) const176284c1978SDimitry Andric SystemZRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator MI,
177284c1978SDimitry Andric                                          int SPAdj, unsigned FIOperandNum,
178284c1978SDimitry Andric                                          RegScavenger *RS) const {
179284c1978SDimitry Andric   assert(SPAdj == 0 && "Outgoing arguments should be part of the frame");
180284c1978SDimitry Andric 
181284c1978SDimitry Andric   MachineBasicBlock &MBB = *MI->getParent();
182284c1978SDimitry Andric   MachineFunction &MF = *MBB.getParent();
18391bc56edSDimitry Andric   auto *TII =
18439d628a0SDimitry Andric       static_cast<const SystemZInstrInfo *>(MF.getSubtarget().getInstrInfo());
185875ed548SDimitry Andric   const SystemZFrameLowering *TFI = getFrameLowering(MF);
186284c1978SDimitry Andric   DebugLoc DL = MI->getDebugLoc();
187284c1978SDimitry Andric 
188284c1978SDimitry Andric   // Decompose the frame index into a base and offset.
189284c1978SDimitry Andric   int FrameIndex = MI->getOperand(FIOperandNum).getIndex();
1907d523365SDimitry Andric   unsigned BasePtr;
1917d523365SDimitry Andric   int64_t Offset = (TFI->getFrameIndexReference(MF, FrameIndex, BasePtr) +
192284c1978SDimitry Andric                     MI->getOperand(FIOperandNum + 1).getImm());
193284c1978SDimitry Andric 
194284c1978SDimitry Andric   // Special handling of dbg_value instructions.
195284c1978SDimitry Andric   if (MI->isDebugValue()) {
196284c1978SDimitry Andric     MI->getOperand(FIOperandNum).ChangeToRegister(BasePtr, /*isDef*/ false);
197284c1978SDimitry Andric     MI->getOperand(FIOperandNum + 1).ChangeToImmediate(Offset);
198284c1978SDimitry Andric     return;
199284c1978SDimitry Andric   }
200284c1978SDimitry Andric 
201284c1978SDimitry Andric   // See if the offset is in range, or if an equivalent instruction that
202284c1978SDimitry Andric   // accepts the offset exists.
203284c1978SDimitry Andric   unsigned Opcode = MI->getOpcode();
20491bc56edSDimitry Andric   unsigned OpcodeForOffset = TII->getOpcodeForOffset(Opcode, Offset);
2053ca95b02SDimitry Andric   if (OpcodeForOffset) {
2063ca95b02SDimitry Andric     if (OpcodeForOffset == SystemZ::LE &&
2073ca95b02SDimitry Andric         MF.getSubtarget<SystemZSubtarget>().hasVector()) {
2083ca95b02SDimitry Andric       // If LE is ok for offset, use LDE instead on z13.
2093ca95b02SDimitry Andric       OpcodeForOffset = SystemZ::LDE32;
2103ca95b02SDimitry Andric     }
211284c1978SDimitry Andric     MI->getOperand(FIOperandNum).ChangeToRegister(BasePtr, false);
2123ca95b02SDimitry Andric   }
213284c1978SDimitry Andric   else {
214284c1978SDimitry Andric     // Create an anchor point that is in range.  Start at 0xffff so that
215284c1978SDimitry Andric     // can use LLILH to load the immediate.
216284c1978SDimitry Andric     int64_t OldOffset = Offset;
217284c1978SDimitry Andric     int64_t Mask = 0xffff;
218284c1978SDimitry Andric     do {
219284c1978SDimitry Andric       Offset = OldOffset & Mask;
22091bc56edSDimitry Andric       OpcodeForOffset = TII->getOpcodeForOffset(Opcode, Offset);
221284c1978SDimitry Andric       Mask >>= 1;
222284c1978SDimitry Andric       assert(Mask && "One offset must be OK");
223284c1978SDimitry Andric     } while (!OpcodeForOffset);
224284c1978SDimitry Andric 
225284c1978SDimitry Andric     unsigned ScratchReg =
226284c1978SDimitry Andric       MF.getRegInfo().createVirtualRegister(&SystemZ::ADDR64BitRegClass);
227284c1978SDimitry Andric     int64_t HighOffset = OldOffset - Offset;
228284c1978SDimitry Andric 
229284c1978SDimitry Andric     if (MI->getDesc().TSFlags & SystemZII::HasIndex
230284c1978SDimitry Andric         && MI->getOperand(FIOperandNum + 2).getReg() == 0) {
231284c1978SDimitry Andric       // Load the offset into the scratch register and use it as an index.
232284c1978SDimitry Andric       // The scratch register then dies here.
23391bc56edSDimitry Andric       TII->loadImmediate(MBB, MI, ScratchReg, HighOffset);
234284c1978SDimitry Andric       MI->getOperand(FIOperandNum).ChangeToRegister(BasePtr, false);
235284c1978SDimitry Andric       MI->getOperand(FIOperandNum + 2).ChangeToRegister(ScratchReg,
236284c1978SDimitry Andric                                                         false, false, true);
237284c1978SDimitry Andric     } else {
238284c1978SDimitry Andric       // Load the anchor address into a scratch register.
23991bc56edSDimitry Andric       unsigned LAOpcode = TII->getOpcodeForOffset(SystemZ::LA, HighOffset);
240284c1978SDimitry Andric       if (LAOpcode)
24191bc56edSDimitry Andric         BuildMI(MBB, MI, DL, TII->get(LAOpcode),ScratchReg)
242284c1978SDimitry Andric           .addReg(BasePtr).addImm(HighOffset).addReg(0);
243284c1978SDimitry Andric       else {
244284c1978SDimitry Andric         // Load the high offset into the scratch register and use it as
245284c1978SDimitry Andric         // an index.
24691bc56edSDimitry Andric         TII->loadImmediate(MBB, MI, ScratchReg, HighOffset);
24791bc56edSDimitry Andric         BuildMI(MBB, MI, DL, TII->get(SystemZ::AGR),ScratchReg)
248284c1978SDimitry Andric           .addReg(ScratchReg, RegState::Kill).addReg(BasePtr);
249284c1978SDimitry Andric       }
250284c1978SDimitry Andric 
251284c1978SDimitry Andric       // Use the scratch register as the base.  It then dies here.
252284c1978SDimitry Andric       MI->getOperand(FIOperandNum).ChangeToRegister(ScratchReg,
253284c1978SDimitry Andric                                                     false, false, true);
254284c1978SDimitry Andric     }
255284c1978SDimitry Andric   }
25691bc56edSDimitry Andric   MI->setDesc(TII->get(OpcodeForOffset));
257284c1978SDimitry Andric   MI->getOperand(FIOperandNum + 1).ChangeToImmediate(Offset);
258284c1978SDimitry Andric }
259284c1978SDimitry Andric 
shouldCoalesce(MachineInstr * MI,const TargetRegisterClass * SrcRC,unsigned SubReg,const TargetRegisterClass * DstRC,unsigned DstSubReg,const TargetRegisterClass * NewRC,LiveIntervals & LIS) const2602cab237bSDimitry Andric bool SystemZRegisterInfo::shouldCoalesce(MachineInstr *MI,
2612cab237bSDimitry Andric                                   const TargetRegisterClass *SrcRC,
2622cab237bSDimitry Andric                                   unsigned SubReg,
2632cab237bSDimitry Andric                                   const TargetRegisterClass *DstRC,
2642cab237bSDimitry Andric                                   unsigned DstSubReg,
2652cab237bSDimitry Andric                                   const TargetRegisterClass *NewRC,
2662cab237bSDimitry Andric                                   LiveIntervals &LIS) const {
2672cab237bSDimitry Andric   assert (MI->isCopy() && "Only expecting COPY instructions");
2682cab237bSDimitry Andric 
2692cab237bSDimitry Andric   // Coalesce anything which is not a COPY involving a subreg to/from GR128.
2702cab237bSDimitry Andric   if (!(NewRC->hasSuperClassEq(&SystemZ::GR128BitRegClass) &&
2712cab237bSDimitry Andric         (getRegSizeInBits(*SrcRC) <= 64 || getRegSizeInBits(*DstRC) <= 64)))
2722cab237bSDimitry Andric     return true;
2732cab237bSDimitry Andric 
2742cab237bSDimitry Andric   // Allow coalescing of a GR128 subreg COPY only if the live ranges are small
2752cab237bSDimitry Andric   // and local to one MBB with not too much interferring registers. Otherwise
2762cab237bSDimitry Andric   // regalloc may run out of registers.
2772cab237bSDimitry Andric 
2782cab237bSDimitry Andric   unsigned WideOpNo = (getRegSizeInBits(*SrcRC) == 128 ? 1 : 0);
2792cab237bSDimitry Andric   unsigned GR128Reg = MI->getOperand(WideOpNo).getReg();
2802cab237bSDimitry Andric   unsigned GRNarReg = MI->getOperand((WideOpNo == 1) ? 0 : 1).getReg();
2812cab237bSDimitry Andric   LiveInterval &IntGR128 = LIS.getInterval(GR128Reg);
2822cab237bSDimitry Andric   LiveInterval &IntGRNar = LIS.getInterval(GRNarReg);
2832cab237bSDimitry Andric 
2842cab237bSDimitry Andric   // Check that the two virtual registers are local to MBB.
2852cab237bSDimitry Andric   MachineBasicBlock *MBB = MI->getParent();
286*b5893f02SDimitry Andric   MachineInstr *FirstMI_GR128 =
287*b5893f02SDimitry Andric     LIS.getInstructionFromIndex(IntGR128.beginIndex());
288*b5893f02SDimitry Andric   MachineInstr *FirstMI_GRNar =
289*b5893f02SDimitry Andric     LIS.getInstructionFromIndex(IntGRNar.beginIndex());
290*b5893f02SDimitry Andric   MachineInstr *LastMI_GR128 = LIS.getInstructionFromIndex(IntGR128.endIndex());
291*b5893f02SDimitry Andric   MachineInstr *LastMI_GRNar = LIS.getInstructionFromIndex(IntGRNar.endIndex());
292*b5893f02SDimitry Andric   if ((!FirstMI_GR128 || FirstMI_GR128->getParent() != MBB) ||
293*b5893f02SDimitry Andric       (!FirstMI_GRNar || FirstMI_GRNar->getParent() != MBB) ||
294*b5893f02SDimitry Andric       (!LastMI_GR128 || LastMI_GR128->getParent() != MBB) ||
295*b5893f02SDimitry Andric       (!LastMI_GRNar || LastMI_GRNar->getParent() != MBB))
2962cab237bSDimitry Andric     return false;
2972cab237bSDimitry Andric 
298*b5893f02SDimitry Andric   MachineBasicBlock::iterator MII = nullptr, MEE = nullptr;
2992cab237bSDimitry Andric   if (WideOpNo == 1) {
300*b5893f02SDimitry Andric     MII = FirstMI_GR128;
301*b5893f02SDimitry Andric     MEE = LastMI_GRNar;
3022cab237bSDimitry Andric   } else {
303*b5893f02SDimitry Andric     MII = FirstMI_GRNar;
304*b5893f02SDimitry Andric     MEE = LastMI_GR128;
3052cab237bSDimitry Andric   }
3062cab237bSDimitry Andric 
3072cab237bSDimitry Andric   // Check if coalescing seems safe by finding the set of clobbered physreg
3082cab237bSDimitry Andric   // pairs in the region.
3092cab237bSDimitry Andric   BitVector PhysClobbered(getNumRegs());
3102cab237bSDimitry Andric   MEE++;
3112cab237bSDimitry Andric   for (; MII != MEE; ++MII) {
3122cab237bSDimitry Andric     for (const MachineOperand &MO : MII->operands())
3132cab237bSDimitry Andric       if (MO.isReg() && isPhysicalRegister(MO.getReg())) {
3142cab237bSDimitry Andric         for (MCSuperRegIterator SI(MO.getReg(), this, true/*IncludeSelf*/);
3152cab237bSDimitry Andric              SI.isValid(); ++SI)
3162cab237bSDimitry Andric           if (NewRC->contains(*SI)) {
3172cab237bSDimitry Andric             PhysClobbered.set(*SI);
3182cab237bSDimitry Andric             break;
3192cab237bSDimitry Andric           }
3202cab237bSDimitry Andric       }
3212cab237bSDimitry Andric   }
3222cab237bSDimitry Andric 
3232cab237bSDimitry Andric   // Demand an arbitrary margin of free regs.
3242cab237bSDimitry Andric   unsigned const DemandedFreeGR128 = 3;
3252cab237bSDimitry Andric   if (PhysClobbered.count() > (NewRC->getNumRegs() - DemandedFreeGR128))
3262cab237bSDimitry Andric     return false;
3272cab237bSDimitry Andric 
3282cab237bSDimitry Andric   return true;
3292cab237bSDimitry Andric }
3302cab237bSDimitry Andric 
331284c1978SDimitry Andric unsigned
getFrameRegister(const MachineFunction & MF) const332284c1978SDimitry Andric SystemZRegisterInfo::getFrameRegister(const MachineFunction &MF) const {
333875ed548SDimitry Andric   const SystemZFrameLowering *TFI = getFrameLowering(MF);
334284c1978SDimitry Andric   return TFI->hasFP(MF) ? SystemZ::R11D : SystemZ::R15D;
335284c1978SDimitry Andric }
3364ba319b5SDimitry Andric 
3374ba319b5SDimitry Andric const TargetRegisterClass *
getCrossCopyRegClass(const TargetRegisterClass * RC) const3384ba319b5SDimitry Andric SystemZRegisterInfo::getCrossCopyRegClass(const TargetRegisterClass *RC) const {
3394ba319b5SDimitry Andric   if (RC == &SystemZ::CCRRegClass)
3404ba319b5SDimitry Andric     return &SystemZ::GR32BitRegClass;
3414ba319b5SDimitry Andric   return RC;
3424ba319b5SDimitry Andric }
3434ba319b5SDimitry Andric 
344