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/STLExtras.h"
21 #include "llvm/CodeGen/LiveIntervals.h"
22 #include "llvm/CodeGen/MachineFrameInfo.h"
23 #include "llvm/CodeGen/MachineFunction.h"
24 #include "llvm/CodeGen/MachineFunctionPass.h"
25 #include "llvm/CodeGen/MachineInstrBuilder.h"
26 #include "llvm/CodeGen/MachineRegisterInfo.h"
27 #include "llvm/CodeGen/PseudoSourceValue.h"
28 #include "llvm/CodeGen/RegisterScavenging.h"
29 #include "llvm/CodeGen/TargetInstrInfo.h"
30 #include "llvm/IR/Function.h"
31 #include "llvm/IR/Type.h"
32 #include "llvm/MC/MachineLocation.h"
33 #include "llvm/Support/Debug.h"
34 #include "llvm/Support/ErrorHandling.h"
35 #include "llvm/Support/raw_ostream.h"
36 #include "llvm/Target/TargetMachine.h"
37 #include "llvm/Target/TargetOptions.h"
39 #define GET_REGINFO_TARGET_DESC
40 #include "HexagonGenRegisterInfo.inc"
44 HexagonRegisterInfo::HexagonRegisterInfo(unsigned HwMode
)
45 : HexagonGenRegisterInfo(Hexagon::R31
, 0/*DwarfFlavor*/, 0/*EHFlavor*/,
49 bool HexagonRegisterInfo::isEHReturnCalleeSaveReg(unsigned R
) const {
50 return R
== Hexagon::R0
|| R
== Hexagon::R1
|| R
== Hexagon::R2
||
51 R
== Hexagon::R3
|| R
== Hexagon::D0
|| R
== Hexagon::D1
;
55 HexagonRegisterInfo::getCallerSavedRegs(const MachineFunction
*MF
,
56 const TargetRegisterClass
*RC
) const {
57 using namespace Hexagon
;
59 static const MCPhysReg Int32
[] = {
60 R0
, R1
, R2
, R3
, R4
, R5
, R6
, R7
, R8
, R9
, R10
, R11
, R12
, R13
, R14
, R15
, 0
62 static const MCPhysReg Int64
[] = {
63 D0
, D1
, D2
, D3
, D4
, D5
, D6
, D7
, 0
65 static const MCPhysReg Pred
[] = {
68 static const MCPhysReg VecSgl
[] = {
69 V0
, V1
, V2
, V3
, V4
, V5
, V6
, V7
, V8
, V9
, V10
, V11
, V12
, V13
,
70 V14
, V15
, V16
, V17
, V18
, V19
, V20
, V21
, V22
, V23
, V24
, V25
, V26
, V27
,
73 static const MCPhysReg VecDbl
[] = {
74 W0
, W1
, W2
, W3
, W4
, W5
, W6
, W7
, W8
, W9
, W10
, W11
, W12
, W13
, W14
, W15
, 0
77 switch (RC
->getID()) {
78 case IntRegsRegClassID
:
80 case DoubleRegsRegClassID
:
82 case PredRegsRegClassID
:
92 static const MCPhysReg Empty
[] = { 0 };
94 dbgs() << "Register class: " << getRegClassName(RC
) << "\n";
96 llvm_unreachable("Unexpected register class");
102 HexagonRegisterInfo::getCalleeSavedRegs(const MachineFunction
*MF
) const {
103 static const MCPhysReg CalleeSavedRegsV3
[] = {
104 Hexagon::R16
, Hexagon::R17
, Hexagon::R18
, Hexagon::R19
,
105 Hexagon::R20
, Hexagon::R21
, Hexagon::R22
, Hexagon::R23
,
106 Hexagon::R24
, Hexagon::R25
, Hexagon::R26
, Hexagon::R27
, 0
109 // Functions that contain a call to __builtin_eh_return also save the first 4
110 // parameter registers.
111 static const MCPhysReg CalleeSavedRegsV3EHReturn
[] = {
112 Hexagon::R0
, Hexagon::R1
, Hexagon::R2
, Hexagon::R3
,
113 Hexagon::R16
, Hexagon::R17
, Hexagon::R18
, Hexagon::R19
,
114 Hexagon::R20
, Hexagon::R21
, Hexagon::R22
, Hexagon::R23
,
115 Hexagon::R24
, Hexagon::R25
, Hexagon::R26
, Hexagon::R27
, 0
118 bool HasEHReturn
= MF
->getInfo
<HexagonMachineFunctionInfo
>()->hasEHReturn();
120 return HasEHReturn
? CalleeSavedRegsV3EHReturn
: CalleeSavedRegsV3
;
124 const uint32_t *HexagonRegisterInfo::getCallPreservedMask(
125 const MachineFunction
&MF
, CallingConv::ID
) const {
126 return HexagonCSR_RegMask
;
130 BitVector
HexagonRegisterInfo::getReservedRegs(const MachineFunction
&MF
)
132 BitVector
Reserved(getNumRegs());
133 Reserved
.set(Hexagon::R29
);
134 Reserved
.set(Hexagon::R30
);
135 Reserved
.set(Hexagon::R31
);
136 Reserved
.set(Hexagon::VTMP
);
139 Reserved
.set(Hexagon::GELR
); // G0
140 Reserved
.set(Hexagon::GSR
); // G1
141 Reserved
.set(Hexagon::GOSP
); // G2
142 Reserved
.set(Hexagon::G3
); // G3
144 // Control registers.
145 Reserved
.set(Hexagon::SA0
); // C0
146 Reserved
.set(Hexagon::LC0
); // C1
147 Reserved
.set(Hexagon::SA1
); // C2
148 Reserved
.set(Hexagon::LC1
); // C3
149 Reserved
.set(Hexagon::P3_0
); // C4
150 Reserved
.set(Hexagon::USR
); // C8
151 Reserved
.set(Hexagon::PC
); // C9
152 Reserved
.set(Hexagon::UGP
); // C10
153 Reserved
.set(Hexagon::GP
); // C11
154 Reserved
.set(Hexagon::CS0
); // C12
155 Reserved
.set(Hexagon::CS1
); // C13
156 Reserved
.set(Hexagon::UPCYCLELO
); // C14
157 Reserved
.set(Hexagon::UPCYCLEHI
); // C15
158 Reserved
.set(Hexagon::FRAMELIMIT
); // C16
159 Reserved
.set(Hexagon::FRAMEKEY
); // C17
160 Reserved
.set(Hexagon::PKTCOUNTLO
); // C18
161 Reserved
.set(Hexagon::PKTCOUNTHI
); // C19
162 Reserved
.set(Hexagon::UTIMERLO
); // C30
163 Reserved
.set(Hexagon::UTIMERHI
); // C31
164 // Out of the control registers, only C8 is explicitly defined in
165 // HexagonRegisterInfo.td. If others are defined, make sure to add
166 // them here as well.
167 Reserved
.set(Hexagon::C8
);
168 Reserved
.set(Hexagon::USR_OVF
);
170 if (MF
.getSubtarget
<HexagonSubtarget
>().hasReservedR19())
171 Reserved
.set(Hexagon::R19
);
173 for (int x
= Reserved
.find_first(); x
>= 0; x
= Reserved
.find_next(x
))
174 markSuperRegs(Reserved
, x
);
180 void HexagonRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II
,
181 int SPAdj
, unsigned FIOp
,
182 RegScavenger
*RS
) const {
184 // Hexagon_TODO: Do we need to enforce this for Hexagon?
185 assert(SPAdj
== 0 && "Unexpected");
187 MachineInstr
&MI
= *II
;
188 MachineBasicBlock
&MB
= *MI
.getParent();
189 MachineFunction
&MF
= *MB
.getParent();
190 auto &HST
= MF
.getSubtarget
<HexagonSubtarget
>();
191 auto &HII
= *HST
.getInstrInfo();
192 auto &HFI
= *HST
.getFrameLowering();
195 int FI
= MI
.getOperand(FIOp
).getIndex();
196 // Select the base pointer (BP) and calculate the actual offset from BP
197 // to the beginning of the object at index FI.
198 int Offset
= HFI
.getFrameIndexReference(MF
, FI
, BP
);
199 // Add the offset from the instruction.
200 int RealOffset
= Offset
+ MI
.getOperand(FIOp
+1).getImm();
203 unsigned Opc
= MI
.getOpcode();
205 case Hexagon::PS_fia
:
206 MI
.setDesc(HII
.get(Hexagon::A2_addi
));
207 MI
.getOperand(FIOp
).ChangeToImmediate(RealOffset
);
208 MI
.RemoveOperand(FIOp
+1);
211 // Set up the instruction for updating below.
212 MI
.setDesc(HII
.get(Hexagon::A2_addi
));
216 if (!HII
.isValidOffset(Opc
, RealOffset
, this)) {
217 // If the offset is not valid, calculate the address in a temporary
218 // register and use it with offset 0.
219 auto &MRI
= MF
.getRegInfo();
220 Register TmpR
= MRI
.createVirtualRegister(&Hexagon::IntRegsRegClass
);
221 const DebugLoc
&DL
= MI
.getDebugLoc();
222 BuildMI(MB
, II
, DL
, HII
.get(Hexagon::A2_addi
), TmpR
)
230 MI
.getOperand(FIOp
).ChangeToRegister(BP
, false, false, IsKill
);
231 MI
.getOperand(FIOp
+1).ChangeToImmediate(RealOffset
);
235 bool HexagonRegisterInfo::shouldCoalesce(MachineInstr
*MI
,
236 const TargetRegisterClass
*SrcRC
, unsigned SubReg
,
237 const TargetRegisterClass
*DstRC
, unsigned DstSubReg
,
238 const TargetRegisterClass
*NewRC
, LiveIntervals
&LIS
) const {
239 // Coalescing will extend the live interval of the destination register.
240 // If the destination register is a vector pair, avoid introducing function
241 // calls into the interval, since it could result in a spilling of a pair
242 // instead of a single vector.
243 MachineFunction
&MF
= *MI
->getParent()->getParent();
244 const HexagonSubtarget
&HST
= MF
.getSubtarget
<HexagonSubtarget
>();
245 if (!HST
.useHVXOps() || NewRC
->getID() != Hexagon::HvxWRRegClass
.getID())
247 bool SmallSrc
= SrcRC
->getID() == Hexagon::HvxVRRegClass
.getID();
248 bool SmallDst
= DstRC
->getID() == Hexagon::HvxVRRegClass
.getID();
249 if (!SmallSrc
&& !SmallDst
)
252 Register DstReg
= MI
->getOperand(0).getReg();
253 Register SrcReg
= MI
->getOperand(1).getReg();
254 const SlotIndexes
&Indexes
= *LIS
.getSlotIndexes();
255 auto HasCall
= [&Indexes
] (const LiveInterval::Segment
&S
) {
256 for (SlotIndex I
= S
.start
.getBaseIndex(), E
= S
.end
.getBaseIndex();
257 I
!= E
; I
= I
.getNextIndex()) {
258 if (const MachineInstr
*MI
= Indexes
.getInstructionFromIndex(I
))
265 if (SmallSrc
== SmallDst
) {
266 // Both must be true, because the case for both being false was
267 // checked earlier. Both registers will be coalesced into a register
268 // of a wider class (HvxWR), and we don't want its live range to
270 return !any_of(LIS
.getInterval(DstReg
), HasCall
) &&
271 !any_of(LIS
.getInterval(SrcReg
), HasCall
);
274 // If one register is large (HvxWR) and the other is small (HvxVR), then
275 // coalescing is ok if the large is already live across a function call,
276 // or if the small one is not.
277 unsigned SmallReg
= SmallSrc
? SrcReg
: DstReg
;
278 unsigned LargeReg
= SmallSrc
? DstReg
: SrcReg
;
279 return any_of(LIS
.getInterval(LargeReg
), HasCall
) ||
280 !any_of(LIS
.getInterval(SmallReg
), HasCall
);
284 unsigned HexagonRegisterInfo::getRARegister() const {
289 Register
HexagonRegisterInfo::getFrameRegister(const MachineFunction
291 const HexagonFrameLowering
*TFI
= getFrameLowering(MF
);
293 return getFrameRegister();
294 return getStackRegister();
298 unsigned HexagonRegisterInfo::getFrameRegister() const {
303 unsigned HexagonRegisterInfo::getStackRegister() const {
308 unsigned HexagonRegisterInfo::getHexagonSubRegIndex(
309 const TargetRegisterClass
&RC
, unsigned GenIdx
) const {
310 assert(GenIdx
== Hexagon::ps_sub_lo
|| GenIdx
== Hexagon::ps_sub_hi
);
312 static const unsigned ISub
[] = { Hexagon::isub_lo
, Hexagon::isub_hi
};
313 static const unsigned VSub
[] = { Hexagon::vsub_lo
, Hexagon::vsub_hi
};
314 static const unsigned WSub
[] = { Hexagon::wsub_lo
, Hexagon::wsub_hi
};
316 switch (RC
.getID()) {
317 case Hexagon::CtrRegs64RegClassID
:
318 case Hexagon::DoubleRegsRegClassID
:
320 case Hexagon::HvxWRRegClassID
:
322 case Hexagon::HvxVQRRegClassID
:
326 if (const TargetRegisterClass
*SuperRC
= *RC
.getSuperClasses())
327 return getHexagonSubRegIndex(*SuperRC
, GenIdx
);
329 llvm_unreachable("Invalid register class");
332 bool HexagonRegisterInfo::useFPForScavengingIndex(const MachineFunction
&MF
)
334 return MF
.getSubtarget
<HexagonSubtarget
>().getFrameLowering()->hasFP(MF
);
337 const TargetRegisterClass
*
338 HexagonRegisterInfo::getPointerRegClass(const MachineFunction
&MF
,
339 unsigned Kind
) const {
340 return &Hexagon::IntRegsRegClass
;
343 unsigned HexagonRegisterInfo::getFirstCallerSavedNonParamReg() const {