LLVM 19.0.0git
RISCVRegisterInfo.cpp
Go to the documentation of this file.
1//===-- RISCVRegisterInfo.cpp - RISC-V Register Information -----*- C++ -*-===//
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//===----------------------------------------------------------------------===//
8//
9// This file contains the RISC-V implementation of the TargetRegisterInfo class.
10//
11//===----------------------------------------------------------------------===//
12
13#include "RISCVRegisterInfo.h"
14#include "RISCV.h"
16#include "RISCVSubtarget.h"
17#include "llvm/ADT/SmallSet.h"
27
28#define GET_REGINFO_TARGET_DESC
29#include "RISCVGenRegisterInfo.inc"
30
31using namespace llvm;
32
33static cl::opt<bool> DisableCostPerUse("riscv-disable-cost-per-use",
34 cl::init(false), cl::Hidden);
35static cl::opt<bool>
36 DisableRegAllocHints("riscv-disable-regalloc-hints", cl::Hidden,
37 cl::init(false),
38 cl::desc("Disable two address hints for register "
39 "allocation"));
40
41static_assert(RISCV::X1 == RISCV::X0 + 1, "Register list not consecutive");
42static_assert(RISCV::X31 == RISCV::X0 + 31, "Register list not consecutive");
43static_assert(RISCV::F1_H == RISCV::F0_H + 1, "Register list not consecutive");
44static_assert(RISCV::F31_H == RISCV::F0_H + 31,
45 "Register list not consecutive");
46static_assert(RISCV::F1_F == RISCV::F0_F + 1, "Register list not consecutive");
47static_assert(RISCV::F31_F == RISCV::F0_F + 31,
48 "Register list not consecutive");
49static_assert(RISCV::F1_D == RISCV::F0_D + 1, "Register list not consecutive");
50static_assert(RISCV::F31_D == RISCV::F0_D + 31,
51 "Register list not consecutive");
52static_assert(RISCV::V1 == RISCV::V0 + 1, "Register list not consecutive");
53static_assert(RISCV::V31 == RISCV::V0 + 31, "Register list not consecutive");
54
56 : RISCVGenRegisterInfo(RISCV::X1, /*DwarfFlavour*/0, /*EHFlavor*/0,
57 /*PC*/0, HwMode) {}
58
59const MCPhysReg *
61 auto &Subtarget = MF->getSubtarget<RISCVSubtarget>();
63 return CSR_NoRegs_SaveList;
64 if (MF->getFunction().hasFnAttribute("interrupt")) {
65 if (Subtarget.hasStdExtD())
66 return CSR_XLEN_F64_Interrupt_SaveList;
67 if (Subtarget.hasStdExtF())
68 return Subtarget.isRVE() ? CSR_XLEN_F32_Interrupt_RVE_SaveList
69 : CSR_XLEN_F32_Interrupt_SaveList;
70 return Subtarget.isRVE() ? CSR_Interrupt_RVE_SaveList
71 : CSR_Interrupt_SaveList;
72 }
73
74 switch (Subtarget.getTargetABI()) {
75 default:
76 llvm_unreachable("Unrecognized ABI");
79 return CSR_ILP32E_LP64E_SaveList;
82 return CSR_ILP32_LP64_SaveList;
85 return CSR_ILP32F_LP64F_SaveList;
88 return CSR_ILP32D_LP64D_SaveList;
89 }
90}
91
93 const RISCVFrameLowering *TFI = getFrameLowering(MF);
94 BitVector Reserved(getNumRegs());
95 auto &Subtarget = MF.getSubtarget<RISCVSubtarget>();
96
97 // Mark any registers requested to be reserved as such
98 for (size_t Reg = 0; Reg < getNumRegs(); Reg++) {
99 if (Subtarget.isRegisterReservedByUser(Reg))
100 markSuperRegs(Reserved, Reg);
101 }
102
103 // Use markSuperRegs to ensure any register aliases are also reserved
104 markSuperRegs(Reserved, RISCV::X0); // zero
105 markSuperRegs(Reserved, RISCV::X2); // sp
106 markSuperRegs(Reserved, RISCV::X3); // gp
107 markSuperRegs(Reserved, RISCV::X4); // tp
108 if (TFI->hasFP(MF))
109 markSuperRegs(Reserved, RISCV::X8); // fp
110 // Reserve the base register if we need to realign the stack and allocate
111 // variable-sized objects at runtime.
112 if (TFI->hasBP(MF))
113 markSuperRegs(Reserved, RISCVABI::getBPReg()); // bp
114
115 // Additionally reserve dummy register used to form the register pair
116 // beginning with 'x0' for instructions that take register pairs.
117 markSuperRegs(Reserved, RISCV::DUMMY_REG_PAIR_WITH_X0);
118
119 // There are only 16 GPRs for RVE.
120 if (Subtarget.isRVE())
121 for (MCPhysReg Reg = RISCV::X16; Reg <= RISCV::X31; Reg++)
122 markSuperRegs(Reserved, Reg);
123
124 // V registers for code generation. We handle them manually.
125 markSuperRegs(Reserved, RISCV::VL);
126 markSuperRegs(Reserved, RISCV::VTYPE);
127 markSuperRegs(Reserved, RISCV::VXSAT);
128 markSuperRegs(Reserved, RISCV::VXRM);
129 markSuperRegs(Reserved, RISCV::VLENB); // vlenb (constant)
130
131 // Floating point environment registers.
132 markSuperRegs(Reserved, RISCV::FRM);
133 markSuperRegs(Reserved, RISCV::FFLAGS);
134
135 // SiFive VCIX state registers.
136 markSuperRegs(Reserved, RISCV::VCIX_STATE);
137
139 if (Subtarget.isRVE())
140 report_fatal_error("Graal reserved registers do not exist in RVE");
141 markSuperRegs(Reserved, RISCV::X23);
142 markSuperRegs(Reserved, RISCV::X27);
143 }
144
145 // Shadow stack pointer.
146 markSuperRegs(Reserved, RISCV::SSP);
147
148 assert(checkAllSuperRegsMarked(Reserved));
149 return Reserved;
150}
151
153 MCRegister PhysReg) const {
154 return !MF.getSubtarget<RISCVSubtarget>().isRegisterReservedByUser(PhysReg);
155}
156
158 return CSR_NoRegs_RegMask;
159}
160
163 const DebugLoc &DL, Register DestReg,
166 MaybeAlign RequiredAlign) const {
167
168 if (DestReg == SrcReg && !Offset.getFixed() && !Offset.getScalable())
169 return;
170
174 const RISCVInstrInfo *TII = ST.getInstrInfo();
175
176 bool KillSrcReg = false;
177
178 if (Offset.getScalable()) {
179 unsigned ScalableAdjOpc = RISCV::ADD;
180 int64_t ScalableValue = Offset.getScalable();
181 if (ScalableValue < 0) {
182 ScalableValue = -ScalableValue;
183 ScalableAdjOpc = RISCV::SUB;
184 }
185 // Get vlenb and multiply vlen with the number of vector registers.
186 Register ScratchReg = DestReg;
187 if (DestReg == SrcReg)
188 ScratchReg = MRI.createVirtualRegister(&RISCV::GPRRegClass);
189 TII->getVLENFactoredAmount(MF, MBB, II, DL, ScratchReg, ScalableValue, Flag);
190 BuildMI(MBB, II, DL, TII->get(ScalableAdjOpc), DestReg)
191 .addReg(SrcReg).addReg(ScratchReg, RegState::Kill)
192 .setMIFlag(Flag);
193 SrcReg = DestReg;
194 KillSrcReg = true;
195 }
196
197 int64_t Val = Offset.getFixed();
198 if (DestReg == SrcReg && Val == 0)
199 return;
200
201 const uint64_t Align = RequiredAlign.valueOrOne().value();
202
203 if (isInt<12>(Val)) {
204 BuildMI(MBB, II, DL, TII->get(RISCV::ADDI), DestReg)
205 .addReg(SrcReg, getKillRegState(KillSrcReg))
206 .addImm(Val)
207 .setMIFlag(Flag);
208 return;
209 }
210
211 // Try to split the offset across two ADDIs. We need to keep the intermediate
212 // result aligned after each ADDI. We need to determine the maximum value we
213 // can put in each ADDI. In the negative direction, we can use -2048 which is
214 // always sufficiently aligned. In the positive direction, we need to find the
215 // largest 12-bit immediate that is aligned. Exclude -4096 since it can be
216 // created with LUI.
217 assert(Align < 2048 && "Required alignment too large");
218 int64_t MaxPosAdjStep = 2048 - Align;
219 if (Val > -4096 && Val <= (2 * MaxPosAdjStep)) {
220 int64_t FirstAdj = Val < 0 ? -2048 : MaxPosAdjStep;
221 Val -= FirstAdj;
222 BuildMI(MBB, II, DL, TII->get(RISCV::ADDI), DestReg)
223 .addReg(SrcReg, getKillRegState(KillSrcReg))
224 .addImm(FirstAdj)
225 .setMIFlag(Flag);
226 BuildMI(MBB, II, DL, TII->get(RISCV::ADDI), DestReg)
227 .addReg(DestReg, RegState::Kill)
228 .addImm(Val)
229 .setMIFlag(Flag);
230 return;
231 }
232
233 unsigned Opc = RISCV::ADD;
234 if (Val < 0) {
235 Val = -Val;
236 Opc = RISCV::SUB;
237 }
238
239 Register ScratchReg = MRI.createVirtualRegister(&RISCV::GPRRegClass);
240 TII->movImm(MBB, II, DL, ScratchReg, Val, Flag);
241 BuildMI(MBB, II, DL, TII->get(Opc), DestReg)
242 .addReg(SrcReg, getKillRegState(KillSrcReg))
243 .addReg(ScratchReg, RegState::Kill)
244 .setMIFlag(Flag);
245}
246
247// Split a VSPILLx_Mx pseudo into multiple whole register stores separated by
248// LMUL*VLENB bytes.
250 DebugLoc DL = II->getDebugLoc();
251 MachineBasicBlock &MBB = *II->getParent();
254 const RISCVSubtarget &STI = MF.getSubtarget<RISCVSubtarget>();
255 const TargetInstrInfo *TII = STI.getInstrInfo();
257
258 auto ZvlssegInfo = RISCV::isRVVSpillForZvlsseg(II->getOpcode());
259 unsigned NF = ZvlssegInfo->first;
260 unsigned LMUL = ZvlssegInfo->second;
261 assert(NF * LMUL <= 8 && "Invalid NF/LMUL combinations.");
262 unsigned Opcode, SubRegIdx;
263 switch (LMUL) {
264 default:
265 llvm_unreachable("LMUL must be 1, 2, or 4.");
266 case 1:
267 Opcode = RISCV::VS1R_V;
268 SubRegIdx = RISCV::sub_vrm1_0;
269 break;
270 case 2:
271 Opcode = RISCV::VS2R_V;
272 SubRegIdx = RISCV::sub_vrm2_0;
273 break;
274 case 4:
275 Opcode = RISCV::VS4R_V;
276 SubRegIdx = RISCV::sub_vrm4_0;
277 break;
278 }
279 static_assert(RISCV::sub_vrm1_7 == RISCV::sub_vrm1_0 + 7,
280 "Unexpected subreg numbering");
281 static_assert(RISCV::sub_vrm2_3 == RISCV::sub_vrm2_0 + 3,
282 "Unexpected subreg numbering");
283 static_assert(RISCV::sub_vrm4_1 == RISCV::sub_vrm4_0 + 1,
284 "Unexpected subreg numbering");
285
286 Register VL = MRI.createVirtualRegister(&RISCV::GPRRegClass);
287 // Optimize for constant VLEN.
288 if (auto VLEN = STI.getRealVLen()) {
289 const int64_t VLENB = *VLEN / 8;
290 int64_t Offset = VLENB * LMUL;
291 STI.getInstrInfo()->movImm(MBB, II, DL, VL, Offset);
292 } else {
293 BuildMI(MBB, II, DL, TII->get(RISCV::PseudoReadVLENB), VL);
294 uint32_t ShiftAmount = Log2_32(LMUL);
295 if (ShiftAmount != 0)
296 BuildMI(MBB, II, DL, TII->get(RISCV::SLLI), VL)
297 .addReg(VL)
298 .addImm(ShiftAmount);
299 }
300
301 Register SrcReg = II->getOperand(0).getReg();
302 Register Base = II->getOperand(1).getReg();
303 bool IsBaseKill = II->getOperand(1).isKill();
304 Register NewBase = MRI.createVirtualRegister(&RISCV::GPRRegClass);
305 for (unsigned I = 0; I < NF; ++I) {
306 // Adding implicit-use of super register to describe we are using part of
307 // super register, that prevents machine verifier complaining when part of
308 // subreg is undef, see comment in MachineVerifier::checkLiveness for more
309 // detail.
310 BuildMI(MBB, II, DL, TII->get(Opcode))
311 .addReg(TRI->getSubReg(SrcReg, SubRegIdx + I))
312 .addReg(Base, getKillRegState(I == NF - 1))
313 .addMemOperand(*(II->memoperands_begin()))
314 .addReg(SrcReg, RegState::Implicit);
315 if (I != NF - 1)
316 BuildMI(MBB, II, DL, TII->get(RISCV::ADD), NewBase)
317 .addReg(Base, getKillRegState(I != 0 || IsBaseKill))
318 .addReg(VL, getKillRegState(I == NF - 2));
319 Base = NewBase;
320 }
321 II->eraseFromParent();
322}
323
324// Split a VSPILLx_Mx pseudo into multiple whole register loads separated by
325// LMUL*VLENB bytes.
327 DebugLoc DL = II->getDebugLoc();
328 MachineBasicBlock &MBB = *II->getParent();
331 const RISCVSubtarget &STI = MF.getSubtarget<RISCVSubtarget>();
332 const TargetInstrInfo *TII = STI.getInstrInfo();
334
335 auto ZvlssegInfo = RISCV::isRVVSpillForZvlsseg(II->getOpcode());
336 unsigned NF = ZvlssegInfo->first;
337 unsigned LMUL = ZvlssegInfo->second;
338 assert(NF * LMUL <= 8 && "Invalid NF/LMUL combinations.");
339 unsigned Opcode, SubRegIdx;
340 switch (LMUL) {
341 default:
342 llvm_unreachable("LMUL must be 1, 2, or 4.");
343 case 1:
344 Opcode = RISCV::VL1RE8_V;
345 SubRegIdx = RISCV::sub_vrm1_0;
346 break;
347 case 2:
348 Opcode = RISCV::VL2RE8_V;
349 SubRegIdx = RISCV::sub_vrm2_0;
350 break;
351 case 4:
352 Opcode = RISCV::VL4RE8_V;
353 SubRegIdx = RISCV::sub_vrm4_0;
354 break;
355 }
356 static_assert(RISCV::sub_vrm1_7 == RISCV::sub_vrm1_0 + 7,
357 "Unexpected subreg numbering");
358 static_assert(RISCV::sub_vrm2_3 == RISCV::sub_vrm2_0 + 3,
359 "Unexpected subreg numbering");
360 static_assert(RISCV::sub_vrm4_1 == RISCV::sub_vrm4_0 + 1,
361 "Unexpected subreg numbering");
362
363 Register VL = MRI.createVirtualRegister(&RISCV::GPRRegClass);
364 // Optimize for constant VLEN.
365 if (auto VLEN = STI.getRealVLen()) {
366 const int64_t VLENB = *VLEN / 8;
367 int64_t Offset = VLENB * LMUL;
368 STI.getInstrInfo()->movImm(MBB, II, DL, VL, Offset);
369 } else {
370 BuildMI(MBB, II, DL, TII->get(RISCV::PseudoReadVLENB), VL);
371 uint32_t ShiftAmount = Log2_32(LMUL);
372 if (ShiftAmount != 0)
373 BuildMI(MBB, II, DL, TII->get(RISCV::SLLI), VL)
374 .addReg(VL)
375 .addImm(ShiftAmount);
376 }
377
378 Register DestReg = II->getOperand(0).getReg();
379 Register Base = II->getOperand(1).getReg();
380 bool IsBaseKill = II->getOperand(1).isKill();
381 Register NewBase = MRI.createVirtualRegister(&RISCV::GPRRegClass);
382 for (unsigned I = 0; I < NF; ++I) {
383 BuildMI(MBB, II, DL, TII->get(Opcode),
384 TRI->getSubReg(DestReg, SubRegIdx + I))
385 .addReg(Base, getKillRegState(I == NF - 1))
386 .addMemOperand(*(II->memoperands_begin()));
387 if (I != NF - 1)
388 BuildMI(MBB, II, DL, TII->get(RISCV::ADD), NewBase)
389 .addReg(Base, getKillRegState(I != 0 || IsBaseKill))
390 .addReg(VL, getKillRegState(I == NF - 2));
391 Base = NewBase;
392 }
393 II->eraseFromParent();
394}
395
397 int SPAdj, unsigned FIOperandNum,
398 RegScavenger *RS) const {
399 assert(SPAdj == 0 && "Unexpected non-zero SPAdj value");
400
401 MachineInstr &MI = *II;
402 MachineFunction &MF = *MI.getParent()->getParent();
405 DebugLoc DL = MI.getDebugLoc();
406
407 int FrameIndex = MI.getOperand(FIOperandNum).getIndex();
408 Register FrameReg;
410 getFrameLowering(MF)->getFrameIndexReference(MF, FrameIndex, FrameReg);
411 bool IsRVVSpill = RISCV::isRVVSpill(MI);
412 if (!IsRVVSpill)
413 Offset += StackOffset::getFixed(MI.getOperand(FIOperandNum + 1).getImm());
414
415 if (Offset.getScalable() &&
416 ST.getRealMinVLen() == ST.getRealMaxVLen()) {
417 // For an exact VLEN value, scalable offsets become constant and thus
418 // can be converted entirely into fixed offsets.
419 int64_t FixedValue = Offset.getFixed();
420 int64_t ScalableValue = Offset.getScalable();
421 assert(ScalableValue % 8 == 0 &&
422 "Scalable offset is not a multiple of a single vector size.");
423 int64_t NumOfVReg = ScalableValue / 8;
424 int64_t VLENB = ST.getRealMinVLen() / 8;
425 Offset = StackOffset::getFixed(FixedValue + NumOfVReg * VLENB);
426 }
427
428 if (!isInt<32>(Offset.getFixed())) {
430 "Frame offsets outside of the signed 32-bit range not supported");
431 }
432
433 if (!IsRVVSpill) {
434 if (MI.getOpcode() == RISCV::ADDI && !isInt<12>(Offset.getFixed())) {
435 // We chose to emit the canonical immediate sequence rather than folding
436 // the offset into the using add under the theory that doing so doesn't
437 // save dynamic instruction count and some target may fuse the canonical
438 // 32 bit immediate sequence. We still need to clear the portion of the
439 // offset encoded in the immediate.
440 MI.getOperand(FIOperandNum + 1).ChangeToImmediate(0);
441 } else {
442 // We can encode an add with 12 bit signed immediate in the immediate
443 // operand of our user instruction. As a result, the remaining
444 // offset can by construction, at worst, a LUI and a ADD.
445 int64_t Val = Offset.getFixed();
446 int64_t Lo12 = SignExtend64<12>(Val);
447 if ((MI.getOpcode() == RISCV::PREFETCH_I ||
448 MI.getOpcode() == RISCV::PREFETCH_R ||
449 MI.getOpcode() == RISCV::PREFETCH_W) &&
450 (Lo12 & 0b11111) != 0)
451 MI.getOperand(FIOperandNum + 1).ChangeToImmediate(0);
452 else {
453 MI.getOperand(FIOperandNum + 1).ChangeToImmediate(Lo12);
455 Offset.getScalable());
456 }
457 }
458 }
459
460 if (Offset.getScalable() || Offset.getFixed()) {
461 Register DestReg;
462 if (MI.getOpcode() == RISCV::ADDI)
463 DestReg = MI.getOperand(0).getReg();
464 else
465 DestReg = MRI.createVirtualRegister(&RISCV::GPRRegClass);
466 adjustReg(*II->getParent(), II, DL, DestReg, FrameReg, Offset,
467 MachineInstr::NoFlags, std::nullopt);
468 MI.getOperand(FIOperandNum).ChangeToRegister(DestReg, /*IsDef*/false,
469 /*IsImp*/false,
470 /*IsKill*/true);
471 } else {
472 MI.getOperand(FIOperandNum).ChangeToRegister(FrameReg, /*IsDef*/false,
473 /*IsImp*/false,
474 /*IsKill*/false);
475 }
476
477 // If after materializing the adjustment, we have a pointless ADDI, remove it
478 if (MI.getOpcode() == RISCV::ADDI &&
479 MI.getOperand(0).getReg() == MI.getOperand(1).getReg() &&
480 MI.getOperand(2).getImm() == 0) {
481 MI.eraseFromParent();
482 return true;
483 }
484
485 // Handle spill/fill of synthetic register classes for segment operations to
486 // ensure correctness in the edge case one gets spilled. There are many
487 // possible optimizations here, but given the extreme rarity of such spills,
488 // we prefer simplicity of implementation for now.
489 switch (MI.getOpcode()) {
490 case RISCV::PseudoVSPILL2_M1:
491 case RISCV::PseudoVSPILL2_M2:
492 case RISCV::PseudoVSPILL2_M4:
493 case RISCV::PseudoVSPILL3_M1:
494 case RISCV::PseudoVSPILL3_M2:
495 case RISCV::PseudoVSPILL4_M1:
496 case RISCV::PseudoVSPILL4_M2:
497 case RISCV::PseudoVSPILL5_M1:
498 case RISCV::PseudoVSPILL6_M1:
499 case RISCV::PseudoVSPILL7_M1:
500 case RISCV::PseudoVSPILL8_M1:
501 lowerVSPILL(II);
502 return true;
503 case RISCV::PseudoVRELOAD2_M1:
504 case RISCV::PseudoVRELOAD2_M2:
505 case RISCV::PseudoVRELOAD2_M4:
506 case RISCV::PseudoVRELOAD3_M1:
507 case RISCV::PseudoVRELOAD3_M2:
508 case RISCV::PseudoVRELOAD4_M1:
509 case RISCV::PseudoVRELOAD4_M2:
510 case RISCV::PseudoVRELOAD5_M1:
511 case RISCV::PseudoVRELOAD6_M1:
512 case RISCV::PseudoVRELOAD7_M1:
513 case RISCV::PseudoVRELOAD8_M1:
514 lowerVRELOAD(II);
515 return true;
516 }
517
518 return false;
519}
520
522 const MachineFunction &MF) const {
523 return true;
524}
525
526// Returns true if the instruction's frame index reference would be better
527// served by a base register other than FP or SP.
528// Used by LocalStackSlotAllocation pass to determine which frame index
529// references it should create new base registers for.
531 int64_t Offset) const {
532 unsigned FIOperandNum = 0;
533 for (; !MI->getOperand(FIOperandNum).isFI(); FIOperandNum++)
534 assert(FIOperandNum < MI->getNumOperands() &&
535 "Instr doesn't have FrameIndex operand");
536
537 // For RISC-V, The machine instructions that include a FrameIndex operand
538 // are load/store, ADDI instructions.
539 unsigned MIFrm = RISCVII::getFormat(MI->getDesc().TSFlags);
540 if (MIFrm != RISCVII::InstFormatI && MIFrm != RISCVII::InstFormatS)
541 return false;
542 // We only generate virtual base registers for loads and stores, so
543 // return false for everything else.
544 if (!MI->mayLoad() && !MI->mayStore())
545 return false;
546
547 const MachineFunction &MF = *MI->getMF();
548 const MachineFrameInfo &MFI = MF.getFrameInfo();
549 const RISCVFrameLowering *TFI = getFrameLowering(MF);
550 const MachineRegisterInfo &MRI = MF.getRegInfo();
551 unsigned CalleeSavedSize = 0;
552 Offset += getFrameIndexInstrOffset(MI, FIOperandNum);
553
554 // Estimate the stack size used to store callee saved registers(
555 // excludes reserved registers).
556 BitVector ReservedRegs = getReservedRegs(MF);
557 for (const MCPhysReg *R = MRI.getCalleeSavedRegs(); MCPhysReg Reg = *R; ++R) {
558 if (!ReservedRegs.test(Reg))
559 CalleeSavedSize += getSpillSize(*getMinimalPhysRegClass(Reg));
560 }
561
562 int64_t MaxFPOffset = Offset - CalleeSavedSize;
563 if (TFI->hasFP(MF) && !shouldRealignStack(MF))
564 return !isFrameOffsetLegal(MI, RISCV::X8, MaxFPOffset);
565
566 // Assume 128 bytes spill slots size to estimate the maximum possible
567 // offset relative to the stack pointer.
568 // FIXME: The 128 is copied from ARM. We should run some statistics and pick a
569 // real one for RISC-V.
570 int64_t MaxSPOffset = Offset + 128;
571 MaxSPOffset += MFI.getLocalFrameSize();
572 return !isFrameOffsetLegal(MI, RISCV::X2, MaxSPOffset);
573}
574
575// Determine whether a given base register plus offset immediate is
576// encodable to resolve a frame index.
578 Register BaseReg,
579 int64_t Offset) const {
580 unsigned FIOperandNum = 0;
581 while (!MI->getOperand(FIOperandNum).isFI()) {
582 FIOperandNum++;
583 assert(FIOperandNum < MI->getNumOperands() &&
584 "Instr does not have a FrameIndex operand!");
585 }
586
587 Offset += getFrameIndexInstrOffset(MI, FIOperandNum);
588 return isInt<12>(Offset);
589}
590
591// Insert defining instruction(s) for a pointer to FrameIdx before
592// insertion point I.
593// Return materialized frame pointer.
595 int FrameIdx,
596 int64_t Offset) const {
598 DebugLoc DL;
599 if (MBBI != MBB->end())
600 DL = MBBI->getDebugLoc();
602 MachineRegisterInfo &MFI = MF->getRegInfo();
604
605 Register BaseReg = MFI.createVirtualRegister(&RISCV::GPRRegClass);
606 BuildMI(*MBB, MBBI, DL, TII->get(RISCV::ADDI), BaseReg)
607 .addFrameIndex(FrameIdx)
608 .addImm(Offset);
609 return BaseReg;
610}
611
612// Resolve a frame index operand of an instruction to reference the
613// indicated base register plus offset instead.
615 int64_t Offset) const {
616 unsigned FIOperandNum = 0;
617 while (!MI.getOperand(FIOperandNum).isFI()) {
618 FIOperandNum++;
619 assert(FIOperandNum < MI.getNumOperands() &&
620 "Instr does not have a FrameIndex operand!");
621 }
622
623 Offset += getFrameIndexInstrOffset(&MI, FIOperandNum);
624 // FrameIndex Operands are always represented as a
625 // register followed by an immediate.
626 MI.getOperand(FIOperandNum).ChangeToRegister(BaseReg, false);
627 MI.getOperand(FIOperandNum + 1).ChangeToImmediate(Offset);
628}
629
630// Get the offset from the referenced frame index in the instruction,
631// if there is one.
633 int Idx) const {
634 assert((RISCVII::getFormat(MI->getDesc().TSFlags) == RISCVII::InstFormatI ||
635 RISCVII::getFormat(MI->getDesc().TSFlags) == RISCVII::InstFormatS) &&
636 "The MI must be I or S format.");
637 assert(MI->getOperand(Idx).isFI() && "The Idx'th operand of MI is not a "
638 "FrameIndex operand");
639 return MI->getOperand(Idx + 1).getImm();
640}
641
643 const TargetFrameLowering *TFI = getFrameLowering(MF);
644 return TFI->hasFP(MF) ? RISCV::X8 : RISCV::X2;
645}
646
647const uint32_t *
649 CallingConv::ID CC) const {
650 auto &Subtarget = MF.getSubtarget<RISCVSubtarget>();
651
652 if (CC == CallingConv::GHC)
653 return CSR_NoRegs_RegMask;
654 switch (Subtarget.getTargetABI()) {
655 default:
656 llvm_unreachable("Unrecognized ABI");
659 return CSR_ILP32E_LP64E_RegMask;
662 return CSR_ILP32_LP64_RegMask;
665 return CSR_ILP32F_LP64F_RegMask;
668 return CSR_ILP32D_LP64D_RegMask;
669 }
670}
671
674 const MachineFunction &) const {
675 if (RC == &RISCV::VMV0RegClass)
676 return &RISCV::VRRegClass;
677 if (RC == &RISCV::VRNoV0RegClass)
678 return &RISCV::VRRegClass;
679 if (RC == &RISCV::VRM2NoV0RegClass)
680 return &RISCV::VRM2RegClass;
681 if (RC == &RISCV::VRM4NoV0RegClass)
682 return &RISCV::VRM4RegClass;
683 if (RC == &RISCV::VRM8NoV0RegClass)
684 return &RISCV::VRM8RegClass;
685 return RC;
686}
687
689 SmallVectorImpl<uint64_t> &Ops) const {
690 // VLENB is the length of a vector register in bytes. We use <vscale x 8 x i8>
691 // to represent one vector register. The dwarf offset is
692 // VLENB * scalable_offset / 8.
693 assert(Offset.getScalable() % 8 == 0 && "Invalid frame offset");
694
695 // Add fixed-sized offset using existing DIExpression interface.
696 DIExpression::appendOffset(Ops, Offset.getFixed());
697
698 unsigned VLENB = getDwarfRegNum(RISCV::VLENB, true);
699 int64_t VLENBSized = Offset.getScalable() / 8;
700 if (VLENBSized > 0) {
701 Ops.push_back(dwarf::DW_OP_constu);
702 Ops.push_back(VLENBSized);
703 Ops.append({dwarf::DW_OP_bregx, VLENB, 0ULL});
704 Ops.push_back(dwarf::DW_OP_mul);
705 Ops.push_back(dwarf::DW_OP_plus);
706 } else if (VLENBSized < 0) {
707 Ops.push_back(dwarf::DW_OP_constu);
708 Ops.push_back(-VLENBSized);
709 Ops.append({dwarf::DW_OP_bregx, VLENB, 0ULL});
710 Ops.push_back(dwarf::DW_OP_mul);
711 Ops.push_back(dwarf::DW_OP_minus);
712 }
713}
714
715unsigned
717 return MF.getSubtarget<RISCVSubtarget>().hasStdExtCOrZca() &&
719 ? 1
720 : 0;
721}
722
723// Add two address hints to improve chances of being able to use a compressed
724// instruction.
726 Register VirtReg, ArrayRef<MCPhysReg> Order,
728 const VirtRegMap *VRM, const LiveRegMatrix *Matrix) const {
729 const MachineRegisterInfo *MRI = &MF.getRegInfo();
730 auto &Subtarget = MF.getSubtarget<RISCVSubtarget>();
731
732 bool BaseImplRetVal = TargetRegisterInfo::getRegAllocationHints(
733 VirtReg, Order, Hints, MF, VRM, Matrix);
734
735 if (!VRM || DisableRegAllocHints)
736 return BaseImplRetVal;
737
738 // Add any two address hints after any copy hints.
739 SmallSet<Register, 4> TwoAddrHints;
740
741 auto tryAddHint = [&](const MachineOperand &VRRegMO, const MachineOperand &MO,
742 bool NeedGPRC) -> void {
743 Register Reg = MO.getReg();
744 Register PhysReg = Reg.isPhysical() ? Reg : Register(VRM->getPhys(Reg));
745 if (PhysReg && (!NeedGPRC || RISCV::GPRCRegClass.contains(PhysReg))) {
746 assert(!MO.getSubReg() && !VRRegMO.getSubReg() && "Unexpected subreg!");
747 if (!MRI->isReserved(PhysReg) && !is_contained(Hints, PhysReg))
748 TwoAddrHints.insert(PhysReg);
749 }
750 };
751
752 // This is all of the compressible binary instructions. If an instruction
753 // needs GPRC register class operands \p NeedGPRC will be set to true.
754 auto isCompressible = [&Subtarget](const MachineInstr &MI, bool &NeedGPRC) {
755 NeedGPRC = false;
756 switch (MI.getOpcode()) {
757 default:
758 return false;
759 case RISCV::AND:
760 case RISCV::OR:
761 case RISCV::XOR:
762 case RISCV::SUB:
763 case RISCV::ADDW:
764 case RISCV::SUBW:
765 NeedGPRC = true;
766 return true;
767 case RISCV::ANDI: {
768 NeedGPRC = true;
769 if (!MI.getOperand(2).isImm())
770 return false;
771 int64_t Imm = MI.getOperand(2).getImm();
772 if (isInt<6>(Imm))
773 return true;
774 // c.zext.b
775 return Subtarget.hasStdExtZcb() && Imm == 255;
776 }
777 case RISCV::SRAI:
778 case RISCV::SRLI:
779 NeedGPRC = true;
780 return true;
781 case RISCV::ADD:
782 case RISCV::SLLI:
783 return true;
784 case RISCV::ADDI:
785 case RISCV::ADDIW:
786 return MI.getOperand(2).isImm() && isInt<6>(MI.getOperand(2).getImm());
787 case RISCV::MUL:
788 case RISCV::SEXT_B:
789 case RISCV::SEXT_H:
790 case RISCV::ZEXT_H_RV32:
791 case RISCV::ZEXT_H_RV64:
792 // c.mul, c.sext.b, c.sext.h, c.zext.h
793 NeedGPRC = true;
794 return Subtarget.hasStdExtZcb();
795 case RISCV::ADD_UW:
796 // c.zext.w
797 NeedGPRC = true;
798 return Subtarget.hasStdExtZcb() && MI.getOperand(2).isReg() &&
799 MI.getOperand(2).getReg() == RISCV::X0;
800 case RISCV::XORI:
801 // c.not
802 NeedGPRC = true;
803 return Subtarget.hasStdExtZcb() && MI.getOperand(2).isImm() &&
804 MI.getOperand(2).getImm() == -1;
805 }
806 };
807
808 // Returns true if this operand is compressible. For non-registers it always
809 // returns true. Immediate range was already checked in isCompressible.
810 // For registers, it checks if the register is a GPRC register. reg-reg
811 // instructions that require GPRC need all register operands to be GPRC.
812 auto isCompressibleOpnd = [&](const MachineOperand &MO) {
813 if (!MO.isReg())
814 return true;
815 Register Reg = MO.getReg();
816 Register PhysReg = Reg.isPhysical() ? Reg : Register(VRM->getPhys(Reg));
817 return PhysReg && RISCV::GPRCRegClass.contains(PhysReg);
818 };
819
820 for (auto &MO : MRI->reg_nodbg_operands(VirtReg)) {
821 const MachineInstr &MI = *MO.getParent();
822 unsigned OpIdx = MO.getOperandNo();
823 bool NeedGPRC;
824 if (isCompressible(MI, NeedGPRC)) {
825 if (OpIdx == 0 && MI.getOperand(1).isReg()) {
826 if (!NeedGPRC || MI.getNumExplicitOperands() < 3 ||
827 MI.getOpcode() == RISCV::ADD_UW ||
828 isCompressibleOpnd(MI.getOperand(2)))
829 tryAddHint(MO, MI.getOperand(1), NeedGPRC);
830 if (MI.isCommutable() && MI.getOperand(2).isReg() &&
831 (!NeedGPRC || isCompressibleOpnd(MI.getOperand(1))))
832 tryAddHint(MO, MI.getOperand(2), NeedGPRC);
833 } else if (OpIdx == 1 && (!NeedGPRC || MI.getNumExplicitOperands() < 3 ||
834 isCompressibleOpnd(MI.getOperand(2)))) {
835 tryAddHint(MO, MI.getOperand(0), NeedGPRC);
836 } else if (MI.isCommutable() && OpIdx == 2 &&
837 (!NeedGPRC || isCompressibleOpnd(MI.getOperand(1)))) {
838 tryAddHint(MO, MI.getOperand(0), NeedGPRC);
839 }
840 }
841 }
842
843 for (MCPhysReg OrderReg : Order)
844 if (TwoAddrHints.count(OrderReg))
845 Hints.push_back(OrderReg);
846
847 return BaseImplRetVal;
848}
unsigned const MachineRegisterInfo * MRI
MachineBasicBlock & MBB
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
MachineBasicBlock MachineBasicBlock::iterator MBBI
Returns the sub type a function will return at a given Idx Should correspond to the result type of an ExtractValue instruction executed with just that one unsigned Idx
This file contains constants used for implementing Dwarf debug support.
const HexagonInstrInfo * TII
IRTranslator LLVM IR MI
Live Register Matrix
#define I(x, y, z)
Definition: MD5.cpp:58
unsigned const TargetRegisterInfo * TRI
static cl::opt< bool > DisableRegAllocHints("riscv-disable-regalloc-hints", cl::Hidden, cl::init(false), cl::desc("Disable two address hints for register " "allocation"))
static cl::opt< bool > DisableCostPerUse("riscv-disable-cost-per-use", cl::init(false), cl::Hidden)
This file declares the machine register scavenger class.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file defines the SmallSet class.
static unsigned getDwarfRegNum(unsigned Reg, const TargetRegisterInfo *TRI)
Go up the super-register chain until we hit a valid dwarf register number.
Definition: StackMaps.cpp:195
static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)
Definition: Value.cpp:469
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition: ArrayRef.h:41
bool test(unsigned Idx) const
Definition: BitVector.h:461
static void appendOffset(SmallVectorImpl< uint64_t > &Ops, int64_t Offset)
Append Ops with operations to apply the Offset.
A debug info location.
Definition: DebugLoc.h:33
CallingConv::ID getCallingConv() const
getCallingConv()/setCallingConv(CC) - These method get and set the calling convention of this functio...
Definition: Function.h:262
bool hasFnAttribute(Attribute::AttrKind Kind) const
Return true if the function has the attribute.
Definition: Function.cpp:669
Wrapper class representing physical registers. Should be passed by value.
Definition: MCRegister.h:33
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted.
int64_t getLocalFrameSize() const
Get the size of the local object blob.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
Function & getFunction()
Return the LLVM function that this machine code represents.
const MachineInstrBuilder & setMIFlag(MachineInstr::MIFlag Flag) const
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
const MachineInstrBuilder & addFrameIndex(int Idx) const
const MachineInstrBuilder & addReg(Register RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
const MachineInstrBuilder & addMemOperand(MachineMemOperand *MMO) const
Representation of each machine instruction.
Definition: MachineInstr.h:69
MachineOperand class - Representation of each machine instruction operand.
unsigned getSubReg() const
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
Register createVirtualRegister(const TargetRegisterClass *RegClass, StringRef Name="")
createVirtualRegister - Create and return a new virtual register in the function with the specified r...
bool hasBP(const MachineFunction &MF) const
bool hasFP(const MachineFunction &MF) const override
hasFP - Return true if the specified function should have a dedicated frame pointer register.
void movImm(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, const DebugLoc &DL, Register DstReg, uint64_t Val, MachineInstr::MIFlag Flag=MachineInstr::NoFlags, bool DstRenamable=false, bool DstIsDead=false) const
std::optional< unsigned > getRealVLen() const
const RISCVRegisterInfo * getRegisterInfo() const override
const RISCVInstrInfo * getInstrInfo() const override
Wrapper class representing virtual and physical registers.
Definition: Register.h:19
SmallSet - This maintains a set of unique values, optimizing for the case when the set is small (less...
Definition: SmallSet.h:135
size_type count(const T &V) const
count - Return 1 if the element is in the set, 0 otherwise.
Definition: SmallSet.h:166
std::pair< const_iterator, bool > insert(const T &V)
insert - Insert an element into the set if it isn't already there.
Definition: SmallSet.h:179
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Definition: SmallVector.h:586
void append(ItTy in_start, ItTy in_end)
Add the specified range to the end of the SmallVector.
Definition: SmallVector.h:696
void push_back(const T &Elt)
Definition: SmallVector.h:426
StackOffset holds a fixed and a scalable offset in bytes.
Definition: TypeSize.h:33
int64_t getFixed() const
Returns the fixed component of the stack.
Definition: TypeSize.h:49
static StackOffset get(int64_t Fixed, int64_t Scalable)
Definition: TypeSize.h:44
Information about stack frame layout on the target.
virtual bool hasFP(const MachineFunction &MF) const =0
hasFP - Return true if the specified function should have a dedicated frame pointer register.
TargetInstrInfo - Interface to description of machine instruction set.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
virtual bool getRegAllocationHints(Register VirtReg, ArrayRef< MCPhysReg > Order, SmallVectorImpl< MCPhysReg > &Hints, const MachineFunction &MF, const VirtRegMap *VRM=nullptr, const LiveRegMatrix *Matrix=nullptr) const
Get a list of 'hint' registers that the register allocator should try first when allocating a physica...
virtual const TargetInstrInfo * getInstrInfo() const
MCRegister getPhys(Register virtReg) const
returns the physical register mapped to the specified virtual register
Definition: VirtRegMap.h:105
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ GHC
Used by the Glasgow Haskell Compiler (GHC).
Definition: CallingConv.h:50
@ GRAAL
Used by GraalVM. Two additional registers are reserved.
Definition: CallingConv.h:255
MCRegister getBPReg()
static unsigned getFormat(uint64_t TSFlags)
std::optional< std::pair< unsigned, unsigned > > isRVVSpillForZvlsseg(unsigned Opcode)
bool isRVVSpill(const MachineInstr &MI)
@ Implicit
Not emitted register (e.g. carry, or temporary result).
@ Kill
The last use of a register.
initializer< Ty > init(const Ty &Val)
Definition: CommandLine.h:450
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
@ Offset
Definition: DWP.cpp:456
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
unsigned Log2_32(uint32_t Value)
Return the floor log base 2 of the specified value, -1 if the value is zero.
Definition: MathExtras.h:313
void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
Definition: Error.cpp:156
unsigned getKillRegState(bool B)
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.
Definition: STLExtras.h:1888
This struct is a compact representation of a valid (non-zero power of two) alignment.
Definition: Alignment.h:39
uint64_t value() const
This is a hole in the type system and should not be abused.
Definition: Alignment.h:85
This struct is a compact representation of a valid (power of two) or undefined (0) alignment.
Definition: Alignment.h:117
Align valueOrOne() const
For convenience, returns a valid alignment or 1 if undefined.
Definition: Alignment.h:141
bool needsFrameBaseReg(MachineInstr *MI, int64_t Offset) const override
bool requiresVirtualBaseRegisters(const MachineFunction &MF) const override
const TargetRegisterClass * getLargestLegalSuperClass(const TargetRegisterClass *RC, const MachineFunction &) const override
const MCPhysReg * getCalleeSavedRegs(const MachineFunction *MF) const override
BitVector getReservedRegs(const MachineFunction &MF) const override
void lowerVRELOAD(MachineBasicBlock::iterator II) const
const uint32_t * getCallPreservedMask(const MachineFunction &MF, CallingConv::ID) const override
Register materializeFrameBaseRegister(MachineBasicBlock *MBB, int FrameIdx, int64_t Offset) const override
RISCVRegisterInfo(unsigned HwMode)
void getOffsetOpcodes(const StackOffset &Offset, SmallVectorImpl< uint64_t > &Ops) const override
bool isFrameOffsetLegal(const MachineInstr *MI, Register BaseReg, int64_t Offset) const override
void lowerVSPILL(MachineBasicBlock::iterator II) const
Register getFrameRegister(const MachineFunction &MF) const override
void adjustReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator II, const DebugLoc &DL, Register DestReg, Register SrcReg, StackOffset Offset, MachineInstr::MIFlag Flag, MaybeAlign RequiredAlign) const
bool isAsmClobberable(const MachineFunction &MF, MCRegister PhysReg) const override
const uint32_t * getNoPreservedMask() const override
void resolveFrameIndex(MachineInstr &MI, Register BaseReg, int64_t Offset) const override
bool getRegAllocationHints(Register VirtReg, ArrayRef< MCPhysReg > Order, SmallVectorImpl< MCPhysReg > &Hints, const MachineFunction &MF, const VirtRegMap *VRM, const LiveRegMatrix *Matrix) const override
int64_t getFrameIndexInstrOffset(const MachineInstr *MI, int Idx) const override
unsigned getRegisterCostTableIndex(const MachineFunction &MF) const override
bool eliminateFrameIndex(MachineBasicBlock::iterator MI, int SPAdj, unsigned FIOperandNum, RegScavenger *RS=nullptr) const override