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(Register 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
);
198 MF
.getInfo
<HexagonMachineFunctionInfo
>()->getStackAlignBaseReg();
202 for (int x
= Reserved
.find_first(); x
>= 0; x
= Reserved
.find_next(x
))
203 markSuperRegs(Reserved
, x
);
208 bool HexagonRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II
,
209 int SPAdj
, unsigned FIOp
,
210 RegScavenger
*RS
) const {
211 static unsigned ReuseCount
= 0;
213 // Hexagon_TODO: Do we need to enforce this for Hexagon?
214 assert(SPAdj
== 0 && "Unexpected");
216 MachineInstr
&MI
= *II
;
217 MachineBasicBlock
&MB
= *MI
.getParent();
218 MachineFunction
&MF
= *MB
.getParent();
219 auto &HST
= MF
.getSubtarget
<HexagonSubtarget
>();
220 auto &HII
= *HST
.getInstrInfo();
221 auto &HFI
= *HST
.getFrameLowering();
224 int FI
= MI
.getOperand(FIOp
).getIndex();
225 // Select the base pointer (BP) and calculate the actual offset from BP
226 // to the beginning of the object at index FI.
227 int Offset
= HFI
.getFrameIndexReference(MF
, FI
, BP
).getFixed();
228 // Add the offset from the instruction.
229 int RealOffset
= Offset
+ MI
.getOperand(FIOp
+1).getImm();
231 unsigned Opc
= MI
.getOpcode();
233 case Hexagon::PS_fia
:
234 MI
.setDesc(HII
.get(Hexagon::A2_addi
));
235 MI
.getOperand(FIOp
).ChangeToImmediate(RealOffset
);
236 MI
.removeOperand(FIOp
+1);
239 // Set up the instruction for updating below.
240 MI
.setDesc(HII
.get(Hexagon::A2_addi
));
244 if (!HII
.isValidOffset(Opc
, RealOffset
, this)) {
245 // If the offset is not valid, calculate the address in a temporary
246 // register and use it with offset 0.
248 // The actual base register (BP) is typically shared between many
249 // instructions where frame indices are being replaced. In scalar
250 // instructions the offset range is large, and the need for an extra
251 // add instruction is infrequent. Vector loads/stores, however, have
252 // a much smaller offset range: [-8, 7), or #s4. In those cases it
253 // makes sense to "standardize" the immediate in the "addi" instruction
254 // so that multiple loads/stores could be based on it.
256 switch (MI
.getOpcode()) {
257 // All of these instructions have the same format: base+#s4.
258 case Hexagon::PS_vloadrw_ai
:
259 case Hexagon::PS_vloadrw_nt_ai
:
260 case Hexagon::PS_vstorerw_ai
:
261 case Hexagon::PS_vstorerw_nt_ai
:
264 case Hexagon::PS_vloadrv_ai
:
265 case Hexagon::PS_vloadrv_nt_ai
:
266 case Hexagon::PS_vstorerv_ai
:
267 case Hexagon::PS_vstorerv_nt_ai
:
268 case Hexagon::V6_vL32b_ai
:
269 case Hexagon::V6_vS32b_ai
: {
270 unsigned HwLen
= HST
.getVectorLength();
271 if (RealOffset
% HwLen
== 0) {
272 int VecOffset
= RealOffset
/ HwLen
;
273 // Rewrite the offset as "base + [-8, 7)".
275 // Pairs are expanded into two instructions: make sure that both
276 // can use the same base (i.e. VecOffset+1 is not a different
277 // multiple of 16 than VecOffset).
278 if (!IsPair
|| (VecOffset
+ 1) % 16 != 0) {
279 RealOffset
= (VecOffset
& -16) * HwLen
;
280 InstOffset
= (VecOffset
% 16 - 8) * HwLen
;
286 // Search backwards in the block for "Reg = A2_addi BP, RealOffset".
287 // This will give us a chance to avoid creating a new register.
290 if (ReuseCount
< FrameIndexReuseLimit
) {
291 unsigned SearchCount
= 0, SearchRange
= FrameIndexSearchRange
;
292 SmallSet
<Register
,2> SeenVRegs
;
293 bool PassedCall
= false;
294 LiveRegUnits
Defs(*this), Uses(*this);
296 for (auto I
= std::next(II
.getReverse()), E
= MB
.rend(); I
!= E
; ++I
) {
297 if (SearchCount
== SearchRange
)
300 const MachineInstr
&BI
= *I
;
301 LiveRegUnits::accumulateUsedDefed(BI
, Defs
, Uses
, this);
302 PassedCall
|= BI
.isCall();
303 for (const MachineOperand
&Op
: BI
.operands()) {
304 if (SeenVRegs
.size() > 1)
306 if (Op
.isReg() && Op
.getReg().isVirtual())
307 SeenVRegs
.insert(Op
.getReg());
309 if (BI
.getOpcode() != Hexagon::A2_addi
)
311 if (BI
.getOperand(1).getReg() != BP
)
313 const auto &Op2
= BI
.getOperand(2);
314 if (!Op2
.isImm() || Op2
.getImm() != RealOffset
)
317 Register R
= BI
.getOperand(0).getReg();
318 if (R
.isPhysical()) {
319 if (Defs
.available(R
))
321 } else if (R
.isVirtual()) {
322 // Extending a range of a virtual register can be dangerous,
323 // since the scavenger will need to find a physical register
324 // for it. Avoid extending the range past a function call,
325 // and avoid overlapping it with another virtual register.
326 if (!PassedCall
&& SeenVRegs
.size() <= 1)
335 auto &MRI
= MF
.getRegInfo();
337 ReuseBP
= MRI
.createVirtualRegister(&Hexagon::IntRegsRegClass
);
338 const DebugLoc
&DL
= MI
.getDebugLoc();
339 BuildMI(MB
, II
, DL
, HII
.get(Hexagon::A2_addi
), ReuseBP
)
344 RealOffset
= InstOffset
;
347 MI
.getOperand(FIOp
).ChangeToRegister(BP
, false, false, false);
348 MI
.getOperand(FIOp
+1).ChangeToImmediate(RealOffset
);
353 bool HexagonRegisterInfo::shouldCoalesce(MachineInstr
*MI
,
354 const TargetRegisterClass
*SrcRC
, unsigned SubReg
,
355 const TargetRegisterClass
*DstRC
, unsigned DstSubReg
,
356 const TargetRegisterClass
*NewRC
, LiveIntervals
&LIS
) const {
357 // Coalescing will extend the live interval of the destination register.
358 // If the destination register is a vector pair, avoid introducing function
359 // calls into the interval, since it could result in a spilling of a pair
360 // instead of a single vector.
361 MachineFunction
&MF
= *MI
->getParent()->getParent();
362 const HexagonSubtarget
&HST
= MF
.getSubtarget
<HexagonSubtarget
>();
363 if (!HST
.useHVXOps() || NewRC
->getID() != Hexagon::HvxWRRegClass
.getID())
365 bool SmallSrc
= SrcRC
->getID() == Hexagon::HvxVRRegClass
.getID();
366 bool SmallDst
= DstRC
->getID() == Hexagon::HvxVRRegClass
.getID();
367 if (!SmallSrc
&& !SmallDst
)
370 Register DstReg
= MI
->getOperand(0).getReg();
371 Register SrcReg
= MI
->getOperand(1).getReg();
372 const SlotIndexes
&Indexes
= *LIS
.getSlotIndexes();
373 auto HasCall
= [&Indexes
] (const LiveInterval::Segment
&S
) {
374 for (SlotIndex I
= S
.start
.getBaseIndex(), E
= S
.end
.getBaseIndex();
375 I
!= E
; I
= I
.getNextIndex()) {
376 if (const MachineInstr
*MI
= Indexes
.getInstructionFromIndex(I
))
383 if (SmallSrc
== SmallDst
) {
384 // Both must be true, because the case for both being false was
385 // checked earlier. Both registers will be coalesced into a register
386 // of a wider class (HvxWR), and we don't want its live range to
388 return !any_of(LIS
.getInterval(DstReg
), HasCall
) &&
389 !any_of(LIS
.getInterval(SrcReg
), HasCall
);
392 // If one register is large (HvxWR) and the other is small (HvxVR), then
393 // coalescing is ok if the large is already live across a function call,
394 // or if the small one is not.
395 Register SmallReg
= SmallSrc
? SrcReg
: DstReg
;
396 Register LargeReg
= SmallSrc
? DstReg
: SrcReg
;
397 return any_of(LIS
.getInterval(LargeReg
), HasCall
) ||
398 !any_of(LIS
.getInterval(SmallReg
), HasCall
);
402 Register
HexagonRegisterInfo::getFrameRegister(const MachineFunction
404 const HexagonFrameLowering
*TFI
= getFrameLowering(MF
);
406 return getFrameRegister();
407 return getStackRegister();
411 Register
HexagonRegisterInfo::getFrameRegister() const {
416 Register
HexagonRegisterInfo::getStackRegister() const {
421 unsigned HexagonRegisterInfo::getHexagonSubRegIndex(
422 const TargetRegisterClass
&RC
, unsigned GenIdx
) const {
423 assert(GenIdx
== Hexagon::ps_sub_lo
|| GenIdx
== Hexagon::ps_sub_hi
);
425 static const unsigned ISub
[] = { Hexagon::isub_lo
, Hexagon::isub_hi
};
426 static const unsigned VSub
[] = { Hexagon::vsub_lo
, Hexagon::vsub_hi
};
427 static const unsigned WSub
[] = { Hexagon::wsub_lo
, Hexagon::wsub_hi
};
429 switch (RC
.getID()) {
430 case Hexagon::CtrRegs64RegClassID
:
431 case Hexagon::DoubleRegsRegClassID
:
433 case Hexagon::HvxWRRegClassID
:
435 case Hexagon::HvxVQRRegClassID
:
439 if (const TargetRegisterClass
*SuperRC
= *RC
.getSuperClasses())
440 return getHexagonSubRegIndex(*SuperRC
, GenIdx
);
442 llvm_unreachable("Invalid register class");
445 bool HexagonRegisterInfo::useFPForScavengingIndex(const MachineFunction
&MF
)
447 return MF
.getSubtarget
<HexagonSubtarget
>().getFrameLowering()->hasFP(MF
);
450 const TargetRegisterClass
*
451 HexagonRegisterInfo::getPointerRegClass(const MachineFunction
&MF
,
452 unsigned Kind
) const {
453 return &Hexagon::IntRegsRegClass
;