1 //===-- HexagonRegisterInfo.cpp - Hexagon Register Information ------------===//
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
7 //===----------------------------------------------------------------------===//
9 // This file contains the Hexagon implementation of the TargetRegisterInfo
12 //===----------------------------------------------------------------------===//
14 #include "HexagonRegisterInfo.h"
16 #include "HexagonMachineFunctionInfo.h"
17 #include "HexagonSubtarget.h"
18 #include "HexagonTargetMachine.h"
19 #include "llvm/ADT/BitVector.h"
20 #include "llvm/ADT/SmallSet.h"
21 #include "llvm/ADT/STLExtras.h"
22 #include "llvm/CodeGen/LiveIntervals.h"
23 #include "llvm/CodeGen/LiveRegUnits.h"
24 #include "llvm/CodeGen/MachineFrameInfo.h"
25 #include "llvm/CodeGen/MachineFunction.h"
26 #include "llvm/CodeGen/MachineFunctionPass.h"
27 #include "llvm/CodeGen/MachineInstrBuilder.h"
28 #include "llvm/CodeGen/MachineRegisterInfo.h"
29 #include "llvm/CodeGen/PseudoSourceValue.h"
30 #include "llvm/CodeGen/RegisterScavenging.h"
31 #include "llvm/CodeGen/TargetInstrInfo.h"
32 #include "llvm/IR/Function.h"
33 #include "llvm/IR/Type.h"
34 #include "llvm/MC/MachineLocation.h"
35 #include "llvm/Support/CommandLine.h"
36 #include "llvm/Support/Debug.h"
37 #include "llvm/Support/ErrorHandling.h"
38 #include "llvm/Support/raw_ostream.h"
39 #include "llvm/Target/TargetMachine.h"
40 #include "llvm/Target/TargetOptions.h"
42 #define GET_REGINFO_TARGET_DESC
43 #include "HexagonGenRegisterInfo.inc"
47 static cl::opt
<unsigned> FrameIndexSearchRange(
48 "hexagon-frame-index-search-range", cl::init(32), cl::Hidden
,
49 cl::desc("Limit on instruction search range in frame index elimination"));
51 static cl::opt
<unsigned> FrameIndexReuseLimit(
52 "hexagon-frame-index-reuse-limit", cl::init(~0), cl::Hidden
,
53 cl::desc("Limit on the number of reused registers in frame index "
56 HexagonRegisterInfo::HexagonRegisterInfo(unsigned HwMode
)
57 : HexagonGenRegisterInfo(Hexagon::R31
, 0/*DwarfFlavor*/, 0/*EHFlavor*/,
61 bool HexagonRegisterInfo::isEHReturnCalleeSaveReg(unsigned R
) const {
62 return R
== Hexagon::R0
|| R
== Hexagon::R1
|| R
== Hexagon::R2
||
63 R
== Hexagon::R3
|| R
== Hexagon::D0
|| R
== Hexagon::D1
;
67 HexagonRegisterInfo::getCallerSavedRegs(const MachineFunction
*MF
,
68 const TargetRegisterClass
*RC
) const {
69 using namespace Hexagon
;
71 static const MCPhysReg Int32
[] = {
72 R0
, R1
, R2
, R3
, R4
, R5
, R6
, R7
, R8
, R9
, R10
, R11
, R12
, R13
, R14
, R15
, 0
74 static const MCPhysReg Int64
[] = {
75 D0
, D1
, D2
, D3
, D4
, D5
, D6
, D7
, 0
77 static const MCPhysReg Pred
[] = {
80 static const MCPhysReg VecSgl
[] = {
81 V0
, V1
, V2
, V3
, V4
, V5
, V6
, V7
, V8
, V9
, V10
, V11
, V12
, V13
,
82 V14
, V15
, V16
, V17
, V18
, V19
, V20
, V21
, V22
, V23
, V24
, V25
, V26
, V27
,
85 static const MCPhysReg VecDbl
[] = {
86 W0
, W1
, W2
, W3
, W4
, W5
, W6
, W7
, W8
, W9
, W10
, W11
, W12
, W13
, W14
, W15
, 0
88 static const MCPhysReg VecPred
[] = {
92 switch (RC
->getID()) {
93 case IntRegsRegClassID
:
95 case DoubleRegsRegClassID
:
97 case PredRegsRegClassID
:
101 case HvxWRRegClassID
:
103 case HvxQRRegClassID
:
109 static const MCPhysReg Empty
[] = { 0 };
111 dbgs() << "Register class: " << getRegClassName(RC
) << "\n";
113 llvm_unreachable("Unexpected register class");
119 HexagonRegisterInfo::getCalleeSavedRegs(const MachineFunction
*MF
) const {
120 static const MCPhysReg CalleeSavedRegsV3
[] = {
121 Hexagon::R16
, Hexagon::R17
, Hexagon::R18
, Hexagon::R19
,
122 Hexagon::R20
, Hexagon::R21
, Hexagon::R22
, Hexagon::R23
,
123 Hexagon::R24
, Hexagon::R25
, Hexagon::R26
, Hexagon::R27
, 0
126 // Functions that contain a call to __builtin_eh_return also save the first 4
127 // parameter registers.
128 static const MCPhysReg CalleeSavedRegsV3EHReturn
[] = {
129 Hexagon::R0
, Hexagon::R1
, Hexagon::R2
, Hexagon::R3
,
130 Hexagon::R16
, Hexagon::R17
, Hexagon::R18
, Hexagon::R19
,
131 Hexagon::R20
, Hexagon::R21
, Hexagon::R22
, Hexagon::R23
,
132 Hexagon::R24
, Hexagon::R25
, Hexagon::R26
, Hexagon::R27
, 0
135 bool HasEHReturn
= MF
->getInfo
<HexagonMachineFunctionInfo
>()->hasEHReturn();
137 return HasEHReturn
? CalleeSavedRegsV3EHReturn
: CalleeSavedRegsV3
;
141 const uint32_t *HexagonRegisterInfo::getCallPreservedMask(
142 const MachineFunction
&MF
, CallingConv::ID
) const {
143 return HexagonCSR_RegMask
;
147 BitVector
HexagonRegisterInfo::getReservedRegs(const MachineFunction
&MF
)
149 BitVector
Reserved(getNumRegs());
150 Reserved
.set(Hexagon::R29
);
151 Reserved
.set(Hexagon::R30
);
152 Reserved
.set(Hexagon::R31
);
153 Reserved
.set(Hexagon::VTMP
);
156 Reserved
.set(Hexagon::GELR
); // G0
157 Reserved
.set(Hexagon::GSR
); // G1
158 Reserved
.set(Hexagon::GOSP
); // G2
159 Reserved
.set(Hexagon::G3
); // G3
161 // Control registers.
162 Reserved
.set(Hexagon::SA0
); // C0
163 Reserved
.set(Hexagon::LC0
); // C1
164 Reserved
.set(Hexagon::SA1
); // C2
165 Reserved
.set(Hexagon::LC1
); // C3
166 Reserved
.set(Hexagon::P3_0
); // C4
167 Reserved
.set(Hexagon::USR
); // C8
168 Reserved
.set(Hexagon::PC
); // C9
169 Reserved
.set(Hexagon::UGP
); // C10
170 Reserved
.set(Hexagon::GP
); // C11
171 Reserved
.set(Hexagon::CS0
); // C12
172 Reserved
.set(Hexagon::CS1
); // C13
173 Reserved
.set(Hexagon::UPCYCLELO
); // C14
174 Reserved
.set(Hexagon::UPCYCLEHI
); // C15
175 Reserved
.set(Hexagon::FRAMELIMIT
); // C16
176 Reserved
.set(Hexagon::FRAMEKEY
); // C17
177 Reserved
.set(Hexagon::PKTCOUNTLO
); // C18
178 Reserved
.set(Hexagon::PKTCOUNTHI
); // C19
179 Reserved
.set(Hexagon::UTIMERLO
); // C30
180 Reserved
.set(Hexagon::UTIMERHI
); // C31
181 // Out of the control registers, only C8 is explicitly defined in
182 // HexagonRegisterInfo.td. If others are defined, make sure to add
183 // them here as well.
184 Reserved
.set(Hexagon::C8
);
185 Reserved
.set(Hexagon::USR_OVF
);
187 // Leveraging these registers will require more work to recognize
188 // the new semantics posed, Hi/LoVec patterns, etc.
189 // Note well: if enabled, they should be restricted to only
190 // where `HST.useHVXOps() && HST.hasV67Ops()` is true.
191 for (auto Reg
: Hexagon_MC::GetVectRegRev())
194 if (MF
.getSubtarget
<HexagonSubtarget
>().hasReservedR19())
195 Reserved
.set(Hexagon::R19
);
197 for (int x
= Reserved
.find_first(); x
>= 0; x
= Reserved
.find_next(x
))
198 markSuperRegs(Reserved
, x
);
203 void HexagonRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II
,
204 int SPAdj
, unsigned FIOp
,
205 RegScavenger
*RS
) const {
206 static unsigned ReuseCount
= 0;
208 // Hexagon_TODO: Do we need to enforce this for Hexagon?
209 assert(SPAdj
== 0 && "Unexpected");
211 MachineInstr
&MI
= *II
;
212 MachineBasicBlock
&MB
= *MI
.getParent();
213 MachineFunction
&MF
= *MB
.getParent();
214 auto &HST
= MF
.getSubtarget
<HexagonSubtarget
>();
215 auto &HII
= *HST
.getInstrInfo();
216 auto &HFI
= *HST
.getFrameLowering();
219 int FI
= MI
.getOperand(FIOp
).getIndex();
220 // Select the base pointer (BP) and calculate the actual offset from BP
221 // to the beginning of the object at index FI.
222 int Offset
= HFI
.getFrameIndexReference(MF
, FI
, BP
).getFixed();
223 // Add the offset from the instruction.
224 int RealOffset
= Offset
+ MI
.getOperand(FIOp
+1).getImm();
226 unsigned Opc
= MI
.getOpcode();
228 case Hexagon::PS_fia
:
229 MI
.setDesc(HII
.get(Hexagon::A2_addi
));
230 MI
.getOperand(FIOp
).ChangeToImmediate(RealOffset
);
231 MI
.RemoveOperand(FIOp
+1);
234 // Set up the instruction for updating below.
235 MI
.setDesc(HII
.get(Hexagon::A2_addi
));
239 if (!HII
.isValidOffset(Opc
, RealOffset
, this)) {
240 // If the offset is not valid, calculate the address in a temporary
241 // register and use it with offset 0.
243 // The actual base register (BP) is typically shared between many
244 // instructions where frame indices are being replaced. In scalar
245 // instructions the offset range is large, and the need for an extra
246 // add instruction is infrequent. Vector loads/stores, however, have
247 // a much smaller offset range: [-8, 7), or #s4. In those cases it
248 // makes sense to "standardize" the immediate in the "addi" instruction
249 // so that multiple loads/stores could be based on it.
251 switch (MI
.getOpcode()) {
252 // All of these instructions have the same format: base+#s4.
253 case Hexagon::PS_vloadrw_ai
:
254 case Hexagon::PS_vloadrw_nt_ai
:
255 case Hexagon::PS_vstorerw_ai
:
256 case Hexagon::PS_vstorerw_nt_ai
:
259 case Hexagon::PS_vloadrv_ai
:
260 case Hexagon::PS_vloadrv_nt_ai
:
261 case Hexagon::PS_vstorerv_ai
:
262 case Hexagon::PS_vstorerv_nt_ai
:
263 case Hexagon::V6_vL32b_ai
:
264 case Hexagon::V6_vS32b_ai
: {
265 unsigned HwLen
= HST
.getVectorLength();
266 if (RealOffset
% HwLen
== 0) {
267 int VecOffset
= RealOffset
/ HwLen
;
268 // Rewrite the offset as "base + [-8, 7)".
270 // Pairs are expanded into two instructions: make sure that both
271 // can use the same base (i.e. VecOffset+1 is not a different
272 // multiple of 16 than VecOffset).
273 if (!IsPair
|| (VecOffset
+ 1) % 16 != 0) {
274 RealOffset
= (VecOffset
& -16) * HwLen
;
275 InstOffset
= (VecOffset
% 16 - 8) * HwLen
;
281 // Search backwards in the block for "Reg = A2_addi BP, RealOffset".
282 // This will give us a chance to avoid creating a new register.
285 if (ReuseCount
< FrameIndexReuseLimit
) {
286 unsigned SearchCount
= 0, SearchRange
= FrameIndexSearchRange
;
287 SmallSet
<Register
,2> SeenVRegs
;
288 bool PassedCall
= false;
289 LiveRegUnits
Defs(*this), Uses(*this);
291 for (auto I
= std::next(II
.getReverse()), E
= MB
.rend(); I
!= E
; ++I
) {
292 if (SearchCount
== SearchRange
)
295 const MachineInstr
&BI
= *I
;
296 LiveRegUnits::accumulateUsedDefed(BI
, Defs
, Uses
, this);
297 PassedCall
|= BI
.isCall();
298 for (const MachineOperand
&Op
: BI
.operands()) {
299 if (SeenVRegs
.size() > 1)
301 if (Op
.isReg() && Op
.getReg().isVirtual())
302 SeenVRegs
.insert(Op
.getReg());
304 if (BI
.getOpcode() != Hexagon::A2_addi
)
306 if (BI
.getOperand(1).getReg() != BP
)
308 const auto &Op2
= BI
.getOperand(2);
309 if (!Op2
.isImm() || Op2
.getImm() != RealOffset
)
312 Register R
= BI
.getOperand(0).getReg();
313 if (R
.isPhysical()) {
314 if (Defs
.available(R
))
316 } else if (R
.isVirtual()) {
317 // Extending a range of a virtual register can be dangerous,
318 // since the scavenger will need to find a physical register
319 // for it. Avoid extending the range past a function call,
320 // and avoid overlapping it with another virtual register.
321 if (!PassedCall
&& SeenVRegs
.size() <= 1)
330 auto &MRI
= MF
.getRegInfo();
332 ReuseBP
= MRI
.createVirtualRegister(&Hexagon::IntRegsRegClass
);
333 const DebugLoc
&DL
= MI
.getDebugLoc();
334 BuildMI(MB
, II
, DL
, HII
.get(Hexagon::A2_addi
), ReuseBP
)
339 RealOffset
= InstOffset
;
342 MI
.getOperand(FIOp
).ChangeToRegister(BP
, false, false, false);
343 MI
.getOperand(FIOp
+1).ChangeToImmediate(RealOffset
);
347 bool HexagonRegisterInfo::shouldCoalesce(MachineInstr
*MI
,
348 const TargetRegisterClass
*SrcRC
, unsigned SubReg
,
349 const TargetRegisterClass
*DstRC
, unsigned DstSubReg
,
350 const TargetRegisterClass
*NewRC
, LiveIntervals
&LIS
) const {
351 // Coalescing will extend the live interval of the destination register.
352 // If the destination register is a vector pair, avoid introducing function
353 // calls into the interval, since it could result in a spilling of a pair
354 // instead of a single vector.
355 MachineFunction
&MF
= *MI
->getParent()->getParent();
356 const HexagonSubtarget
&HST
= MF
.getSubtarget
<HexagonSubtarget
>();
357 if (!HST
.useHVXOps() || NewRC
->getID() != Hexagon::HvxWRRegClass
.getID())
359 bool SmallSrc
= SrcRC
->getID() == Hexagon::HvxVRRegClass
.getID();
360 bool SmallDst
= DstRC
->getID() == Hexagon::HvxVRRegClass
.getID();
361 if (!SmallSrc
&& !SmallDst
)
364 Register DstReg
= MI
->getOperand(0).getReg();
365 Register SrcReg
= MI
->getOperand(1).getReg();
366 const SlotIndexes
&Indexes
= *LIS
.getSlotIndexes();
367 auto HasCall
= [&Indexes
] (const LiveInterval::Segment
&S
) {
368 for (SlotIndex I
= S
.start
.getBaseIndex(), E
= S
.end
.getBaseIndex();
369 I
!= E
; I
= I
.getNextIndex()) {
370 if (const MachineInstr
*MI
= Indexes
.getInstructionFromIndex(I
))
377 if (SmallSrc
== SmallDst
) {
378 // Both must be true, because the case for both being false was
379 // checked earlier. Both registers will be coalesced into a register
380 // of a wider class (HvxWR), and we don't want its live range to
382 return !any_of(LIS
.getInterval(DstReg
), HasCall
) &&
383 !any_of(LIS
.getInterval(SrcReg
), HasCall
);
386 // If one register is large (HvxWR) and the other is small (HvxVR), then
387 // coalescing is ok if the large is already live across a function call,
388 // or if the small one is not.
389 unsigned SmallReg
= SmallSrc
? SrcReg
: DstReg
;
390 unsigned LargeReg
= SmallSrc
? DstReg
: SrcReg
;
391 return any_of(LIS
.getInterval(LargeReg
), HasCall
) ||
392 !any_of(LIS
.getInterval(SmallReg
), HasCall
);
396 unsigned HexagonRegisterInfo::getRARegister() const {
401 Register
HexagonRegisterInfo::getFrameRegister(const MachineFunction
403 const HexagonFrameLowering
*TFI
= getFrameLowering(MF
);
405 return getFrameRegister();
406 return getStackRegister();
410 unsigned HexagonRegisterInfo::getFrameRegister() const {
415 unsigned HexagonRegisterInfo::getStackRegister() const {
420 unsigned HexagonRegisterInfo::getHexagonSubRegIndex(
421 const TargetRegisterClass
&RC
, unsigned GenIdx
) const {
422 assert(GenIdx
== Hexagon::ps_sub_lo
|| GenIdx
== Hexagon::ps_sub_hi
);
424 static const unsigned ISub
[] = { Hexagon::isub_lo
, Hexagon::isub_hi
};
425 static const unsigned VSub
[] = { Hexagon::vsub_lo
, Hexagon::vsub_hi
};
426 static const unsigned WSub
[] = { Hexagon::wsub_lo
, Hexagon::wsub_hi
};
428 switch (RC
.getID()) {
429 case Hexagon::CtrRegs64RegClassID
:
430 case Hexagon::DoubleRegsRegClassID
:
432 case Hexagon::HvxWRRegClassID
:
434 case Hexagon::HvxVQRRegClassID
:
438 if (const TargetRegisterClass
*SuperRC
= *RC
.getSuperClasses())
439 return getHexagonSubRegIndex(*SuperRC
, GenIdx
);
441 llvm_unreachable("Invalid register class");
444 bool HexagonRegisterInfo::useFPForScavengingIndex(const MachineFunction
&MF
)
446 return MF
.getSubtarget
<HexagonSubtarget
>().getFrameLowering()->hasFP(MF
);
449 const TargetRegisterClass
*
450 HexagonRegisterInfo::getPointerRegClass(const MachineFunction
&MF
,
451 unsigned Kind
) const {
452 return &Hexagon::IntRegsRegClass
;
455 unsigned HexagonRegisterInfo::getFirstCallerSavedNonParamReg() const {