[ARM] MVE integer min and max
[llvm-complete.git] / lib / Target / SystemZ / SystemZRegisterInfo.cpp
blobe7cd6871dbb40125fd0594b9c75ea2b58df08587
1 //===-- SystemZRegisterInfo.cpp - SystemZ register information ------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
9 #include "SystemZRegisterInfo.h"
10 #include "SystemZInstrInfo.h"
11 #include "SystemZSubtarget.h"
12 #include "llvm/CodeGen/LiveIntervals.h"
13 #include "llvm/ADT/SmallSet.h"
14 #include "llvm/CodeGen/MachineInstrBuilder.h"
15 #include "llvm/CodeGen/MachineRegisterInfo.h"
16 #include "llvm/CodeGen/TargetFrameLowering.h"
17 #include "llvm/CodeGen/VirtRegMap.h"
19 using namespace llvm;
21 #define GET_REGINFO_TARGET_DESC
22 #include "SystemZGenRegisterInfo.inc"
24 SystemZRegisterInfo::SystemZRegisterInfo()
25 : SystemZGenRegisterInfo(SystemZ::R14D) {}
27 // Given that MO is a GRX32 operand, return either GR32 or GRH32 if MO
28 // somehow belongs in it. Otherwise, return GRX32.
29 static const TargetRegisterClass *getRC32(MachineOperand &MO,
30 const VirtRegMap *VRM,
31 const MachineRegisterInfo *MRI) {
32 const TargetRegisterClass *RC = MRI->getRegClass(MO.getReg());
34 if (SystemZ::GR32BitRegClass.hasSubClassEq(RC) ||
35 MO.getSubReg() == SystemZ::subreg_l32 ||
36 MO.getSubReg() == SystemZ::subreg_hl32)
37 return &SystemZ::GR32BitRegClass;
38 if (SystemZ::GRH32BitRegClass.hasSubClassEq(RC) ||
39 MO.getSubReg() == SystemZ::subreg_h32 ||
40 MO.getSubReg() == SystemZ::subreg_hh32)
41 return &SystemZ::GRH32BitRegClass;
43 if (VRM && VRM->hasPhys(MO.getReg())) {
44 unsigned PhysReg = VRM->getPhys(MO.getReg());
45 if (SystemZ::GR32BitRegClass.contains(PhysReg))
46 return &SystemZ::GR32BitRegClass;
47 assert (SystemZ::GRH32BitRegClass.contains(PhysReg) &&
48 "Phys reg not in GR32 or GRH32?");
49 return &SystemZ::GRH32BitRegClass;
52 assert (RC == &SystemZ::GRX32BitRegClass);
53 return RC;
56 // Pass the registers of RC as hints while making sure that if any of these
57 // registers are copy hints (and therefore already in Hints), hint them
58 // first.
59 static void addHints(ArrayRef<MCPhysReg> Order,
60 SmallVectorImpl<MCPhysReg> &Hints,
61 const TargetRegisterClass *RC,
62 const MachineRegisterInfo *MRI) {
63 SmallSet<unsigned, 4> CopyHints;
64 CopyHints.insert(Hints.begin(), Hints.end());
65 Hints.clear();
66 for (MCPhysReg Reg : Order)
67 if (CopyHints.count(Reg) &&
68 RC->contains(Reg) && !MRI->isReserved(Reg))
69 Hints.push_back(Reg);
70 for (MCPhysReg Reg : Order)
71 if (!CopyHints.count(Reg) &&
72 RC->contains(Reg) && !MRI->isReserved(Reg))
73 Hints.push_back(Reg);
76 bool
77 SystemZRegisterInfo::getRegAllocationHints(unsigned VirtReg,
78 ArrayRef<MCPhysReg> Order,
79 SmallVectorImpl<MCPhysReg> &Hints,
80 const MachineFunction &MF,
81 const VirtRegMap *VRM,
82 const LiveRegMatrix *Matrix) const {
83 const MachineRegisterInfo *MRI = &MF.getRegInfo();
84 const SystemZSubtarget &Subtarget = MF.getSubtarget<SystemZSubtarget>();
85 const TargetRegisterInfo *TRI = Subtarget.getRegisterInfo();
87 bool BaseImplRetVal = TargetRegisterInfo::getRegAllocationHints(
88 VirtReg, Order, Hints, MF, VRM, Matrix);
90 if (MRI->getRegClass(VirtReg) == &SystemZ::GRX32BitRegClass) {
91 SmallVector<unsigned, 8> Worklist;
92 SmallSet<unsigned, 4> DoneRegs;
93 Worklist.push_back(VirtReg);
94 while (Worklist.size()) {
95 unsigned Reg = Worklist.pop_back_val();
96 if (!DoneRegs.insert(Reg).second)
97 continue;
99 for (auto &Use : MRI->reg_instructions(Reg)) {
100 // For LOCRMux, see if the other operand is already a high or low
101 // register, and in that case give the corresponding hints for
102 // VirtReg. LOCR instructions need both operands in either high or
103 // low parts. Same handling for SELRMux.
104 if (Use.getOpcode() == SystemZ::LOCRMux ||
105 Use.getOpcode() == SystemZ::SELRMux) {
106 MachineOperand &TrueMO = Use.getOperand(1);
107 MachineOperand &FalseMO = Use.getOperand(2);
108 const TargetRegisterClass *RC =
109 TRI->getCommonSubClass(getRC32(FalseMO, VRM, MRI),
110 getRC32(TrueMO, VRM, MRI));
111 if (Use.getOpcode() == SystemZ::SELRMux)
112 RC = TRI->getCommonSubClass(RC,
113 getRC32(Use.getOperand(0), VRM, MRI));
114 if (RC && RC != &SystemZ::GRX32BitRegClass) {
115 addHints(Order, Hints, RC, MRI);
116 // Return true to make these hints the only regs available to
117 // RA. This may mean extra spilling but since the alternative is
118 // a jump sequence expansion of the LOCRMux, it is preferred.
119 return true;
122 // Add the other operand of the LOCRMux to the worklist.
123 unsigned OtherReg =
124 (TrueMO.getReg() == Reg ? FalseMO.getReg() : TrueMO.getReg());
125 if (MRI->getRegClass(OtherReg) == &SystemZ::GRX32BitRegClass)
126 Worklist.push_back(OtherReg);
127 } // end LOCRMux
128 else if (Use.getOpcode() == SystemZ::CHIMux ||
129 Use.getOpcode() == SystemZ::CFIMux) {
130 if (Use.getOperand(1).getImm() == 0) {
131 bool OnlyLMuxes = true;
132 for (MachineInstr &DefMI : MRI->def_instructions(VirtReg))
133 if (DefMI.getOpcode() != SystemZ::LMux)
134 OnlyLMuxes = false;
135 if (OnlyLMuxes) {
136 addHints(Order, Hints, &SystemZ::GR32BitRegClass, MRI);
137 // Return false to make these hints preferred but not obligatory.
138 return false;
141 } // end CHIMux / CFIMux
146 if (VRM == nullptr)
147 return BaseImplRetVal;
149 // Add any two address hints after any copy hints.
150 SmallSet<unsigned, 4> TwoAddrHints;
151 for (auto &Use : MRI->reg_nodbg_instructions(VirtReg))
152 if (SystemZ::getTwoOperandOpcode(Use.getOpcode()) != -1) {
153 const MachineOperand *VRRegMO = nullptr;
154 const MachineOperand *OtherMO = nullptr;
155 const MachineOperand *CommuMO = nullptr;
156 if (VirtReg == Use.getOperand(0).getReg()) {
157 VRRegMO = &Use.getOperand(0);
158 OtherMO = &Use.getOperand(1);
159 if (Use.isCommutable())
160 CommuMO = &Use.getOperand(2);
161 } else if (VirtReg == Use.getOperand(1).getReg()) {
162 VRRegMO = &Use.getOperand(1);
163 OtherMO = &Use.getOperand(0);
164 } else if (VirtReg == Use.getOperand(2).getReg() && Use.isCommutable()) {
165 VRRegMO = &Use.getOperand(2);
166 OtherMO = &Use.getOperand(0);
167 } else
168 continue;
170 auto tryAddHint = [&](const MachineOperand *MO) -> void {
171 Register Reg = MO->getReg();
172 Register PhysReg = isPhysicalRegister(Reg) ? Reg : VRM->getPhys(Reg);
173 if (PhysReg) {
174 if (MO->getSubReg())
175 PhysReg = getSubReg(PhysReg, MO->getSubReg());
176 if (VRRegMO->getSubReg())
177 PhysReg = getMatchingSuperReg(PhysReg, VRRegMO->getSubReg(),
178 MRI->getRegClass(VirtReg));
179 if (!MRI->isReserved(PhysReg) && !is_contained(Hints, PhysReg))
180 TwoAddrHints.insert(PhysReg);
183 tryAddHint(OtherMO);
184 if (CommuMO)
185 tryAddHint(CommuMO);
187 for (MCPhysReg OrderReg : Order)
188 if (TwoAddrHints.count(OrderReg))
189 Hints.push_back(OrderReg);
191 return BaseImplRetVal;
194 const MCPhysReg *
195 SystemZRegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const {
196 const SystemZSubtarget &Subtarget = MF->getSubtarget<SystemZSubtarget>();
197 if (MF->getFunction().getCallingConv() == CallingConv::AnyReg)
198 return Subtarget.hasVector()? CSR_SystemZ_AllRegs_Vector_SaveList
199 : CSR_SystemZ_AllRegs_SaveList;
200 if (MF->getSubtarget().getTargetLowering()->supportSwiftError() &&
201 MF->getFunction().getAttributes().hasAttrSomewhere(
202 Attribute::SwiftError))
203 return CSR_SystemZ_SwiftError_SaveList;
204 return CSR_SystemZ_SaveList;
207 const uint32_t *
208 SystemZRegisterInfo::getCallPreservedMask(const MachineFunction &MF,
209 CallingConv::ID CC) const {
210 const SystemZSubtarget &Subtarget = MF.getSubtarget<SystemZSubtarget>();
211 if (CC == CallingConv::AnyReg)
212 return Subtarget.hasVector()? CSR_SystemZ_AllRegs_Vector_RegMask
213 : CSR_SystemZ_AllRegs_RegMask;
214 if (MF.getSubtarget().getTargetLowering()->supportSwiftError() &&
215 MF.getFunction().getAttributes().hasAttrSomewhere(
216 Attribute::SwiftError))
217 return CSR_SystemZ_SwiftError_RegMask;
218 return CSR_SystemZ_RegMask;
221 BitVector
222 SystemZRegisterInfo::getReservedRegs(const MachineFunction &MF) const {
223 BitVector Reserved(getNumRegs());
224 const SystemZFrameLowering *TFI = getFrameLowering(MF);
226 if (TFI->hasFP(MF)) {
227 // R11D is the frame pointer. Reserve all aliases.
228 Reserved.set(SystemZ::R11D);
229 Reserved.set(SystemZ::R11L);
230 Reserved.set(SystemZ::R11H);
231 Reserved.set(SystemZ::R10Q);
234 // R15D is the stack pointer. Reserve all aliases.
235 Reserved.set(SystemZ::R15D);
236 Reserved.set(SystemZ::R15L);
237 Reserved.set(SystemZ::R15H);
238 Reserved.set(SystemZ::R14Q);
240 // A0 and A1 hold the thread pointer.
241 Reserved.set(SystemZ::A0);
242 Reserved.set(SystemZ::A1);
244 // FPC is the floating-point control register.
245 Reserved.set(SystemZ::FPC);
247 return Reserved;
250 void
251 SystemZRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator MI,
252 int SPAdj, unsigned FIOperandNum,
253 RegScavenger *RS) const {
254 assert(SPAdj == 0 && "Outgoing arguments should be part of the frame");
256 MachineBasicBlock &MBB = *MI->getParent();
257 MachineFunction &MF = *MBB.getParent();
258 auto *TII =
259 static_cast<const SystemZInstrInfo *>(MF.getSubtarget().getInstrInfo());
260 const SystemZFrameLowering *TFI = getFrameLowering(MF);
261 DebugLoc DL = MI->getDebugLoc();
263 // Decompose the frame index into a base and offset.
264 int FrameIndex = MI->getOperand(FIOperandNum).getIndex();
265 unsigned BasePtr;
266 int64_t Offset = (TFI->getFrameIndexReference(MF, FrameIndex, BasePtr) +
267 MI->getOperand(FIOperandNum + 1).getImm());
269 // Special handling of dbg_value instructions.
270 if (MI->isDebugValue()) {
271 MI->getOperand(FIOperandNum).ChangeToRegister(BasePtr, /*isDef*/ false);
272 MI->getOperand(FIOperandNum + 1).ChangeToImmediate(Offset);
273 return;
276 // See if the offset is in range, or if an equivalent instruction that
277 // accepts the offset exists.
278 unsigned Opcode = MI->getOpcode();
279 unsigned OpcodeForOffset = TII->getOpcodeForOffset(Opcode, Offset);
280 if (OpcodeForOffset) {
281 if (OpcodeForOffset == SystemZ::LE &&
282 MF.getSubtarget<SystemZSubtarget>().hasVector()) {
283 // If LE is ok for offset, use LDE instead on z13.
284 OpcodeForOffset = SystemZ::LDE32;
286 MI->getOperand(FIOperandNum).ChangeToRegister(BasePtr, false);
288 else {
289 // Create an anchor point that is in range. Start at 0xffff so that
290 // can use LLILH to load the immediate.
291 int64_t OldOffset = Offset;
292 int64_t Mask = 0xffff;
293 do {
294 Offset = OldOffset & Mask;
295 OpcodeForOffset = TII->getOpcodeForOffset(Opcode, Offset);
296 Mask >>= 1;
297 assert(Mask && "One offset must be OK");
298 } while (!OpcodeForOffset);
300 unsigned ScratchReg =
301 MF.getRegInfo().createVirtualRegister(&SystemZ::ADDR64BitRegClass);
302 int64_t HighOffset = OldOffset - Offset;
304 if (MI->getDesc().TSFlags & SystemZII::HasIndex
305 && MI->getOperand(FIOperandNum + 2).getReg() == 0) {
306 // Load the offset into the scratch register and use it as an index.
307 // The scratch register then dies here.
308 TII->loadImmediate(MBB, MI, ScratchReg, HighOffset);
309 MI->getOperand(FIOperandNum).ChangeToRegister(BasePtr, false);
310 MI->getOperand(FIOperandNum + 2).ChangeToRegister(ScratchReg,
311 false, false, true);
312 } else {
313 // Load the anchor address into a scratch register.
314 unsigned LAOpcode = TII->getOpcodeForOffset(SystemZ::LA, HighOffset);
315 if (LAOpcode)
316 BuildMI(MBB, MI, DL, TII->get(LAOpcode),ScratchReg)
317 .addReg(BasePtr).addImm(HighOffset).addReg(0);
318 else {
319 // Load the high offset into the scratch register and use it as
320 // an index.
321 TII->loadImmediate(MBB, MI, ScratchReg, HighOffset);
322 BuildMI(MBB, MI, DL, TII->get(SystemZ::AGR),ScratchReg)
323 .addReg(ScratchReg, RegState::Kill).addReg(BasePtr);
326 // Use the scratch register as the base. It then dies here.
327 MI->getOperand(FIOperandNum).ChangeToRegister(ScratchReg,
328 false, false, true);
331 MI->setDesc(TII->get(OpcodeForOffset));
332 MI->getOperand(FIOperandNum + 1).ChangeToImmediate(Offset);
335 bool SystemZRegisterInfo::shouldCoalesce(MachineInstr *MI,
336 const TargetRegisterClass *SrcRC,
337 unsigned SubReg,
338 const TargetRegisterClass *DstRC,
339 unsigned DstSubReg,
340 const TargetRegisterClass *NewRC,
341 LiveIntervals &LIS) const {
342 assert (MI->isCopy() && "Only expecting COPY instructions");
344 // Coalesce anything which is not a COPY involving a subreg to/from GR128.
345 if (!(NewRC->hasSuperClassEq(&SystemZ::GR128BitRegClass) &&
346 (getRegSizeInBits(*SrcRC) <= 64 || getRegSizeInBits(*DstRC) <= 64)))
347 return true;
349 // Allow coalescing of a GR128 subreg COPY only if the live ranges are small
350 // and local to one MBB with not too much interferring registers. Otherwise
351 // regalloc may run out of registers.
353 unsigned WideOpNo = (getRegSizeInBits(*SrcRC) == 128 ? 1 : 0);
354 unsigned GR128Reg = MI->getOperand(WideOpNo).getReg();
355 unsigned GRNarReg = MI->getOperand((WideOpNo == 1) ? 0 : 1).getReg();
356 LiveInterval &IntGR128 = LIS.getInterval(GR128Reg);
357 LiveInterval &IntGRNar = LIS.getInterval(GRNarReg);
359 // Check that the two virtual registers are local to MBB.
360 MachineBasicBlock *MBB = MI->getParent();
361 MachineInstr *FirstMI_GR128 =
362 LIS.getInstructionFromIndex(IntGR128.beginIndex());
363 MachineInstr *FirstMI_GRNar =
364 LIS.getInstructionFromIndex(IntGRNar.beginIndex());
365 MachineInstr *LastMI_GR128 = LIS.getInstructionFromIndex(IntGR128.endIndex());
366 MachineInstr *LastMI_GRNar = LIS.getInstructionFromIndex(IntGRNar.endIndex());
367 if ((!FirstMI_GR128 || FirstMI_GR128->getParent() != MBB) ||
368 (!FirstMI_GRNar || FirstMI_GRNar->getParent() != MBB) ||
369 (!LastMI_GR128 || LastMI_GR128->getParent() != MBB) ||
370 (!LastMI_GRNar || LastMI_GRNar->getParent() != MBB))
371 return false;
373 MachineBasicBlock::iterator MII = nullptr, MEE = nullptr;
374 if (WideOpNo == 1) {
375 MII = FirstMI_GR128;
376 MEE = LastMI_GRNar;
377 } else {
378 MII = FirstMI_GRNar;
379 MEE = LastMI_GR128;
382 // Check if coalescing seems safe by finding the set of clobbered physreg
383 // pairs in the region.
384 BitVector PhysClobbered(getNumRegs());
385 MEE++;
386 for (; MII != MEE; ++MII) {
387 for (const MachineOperand &MO : MII->operands())
388 if (MO.isReg() && isPhysicalRegister(MO.getReg())) {
389 for (MCSuperRegIterator SI(MO.getReg(), this, true/*IncludeSelf*/);
390 SI.isValid(); ++SI)
391 if (NewRC->contains(*SI)) {
392 PhysClobbered.set(*SI);
393 break;
398 // Demand an arbitrary margin of free regs.
399 unsigned const DemandedFreeGR128 = 3;
400 if (PhysClobbered.count() > (NewRC->getNumRegs() - DemandedFreeGR128))
401 return false;
403 return true;
406 Register
407 SystemZRegisterInfo::getFrameRegister(const MachineFunction &MF) const {
408 const SystemZFrameLowering *TFI = getFrameLowering(MF);
409 return TFI->hasFP(MF) ? SystemZ::R11D : SystemZ::R15D;
412 const TargetRegisterClass *
413 SystemZRegisterInfo::getCrossCopyRegClass(const TargetRegisterClass *RC) const {
414 if (RC == &SystemZ::CCRRegClass)
415 return &SystemZ::GR32BitRegClass;
416 return RC;