BPFRegisterInfo.cpp 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. //===-- BPFRegisterInfo.cpp - BPF 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 BPF implementation of the TargetRegisterInfo class.
  10. //
  11. //===----------------------------------------------------------------------===//
  12. #include "BPFRegisterInfo.h"
  13. #include "BPF.h"
  14. #include "BPFSubtarget.h"
  15. #include "llvm/CodeGen/MachineFrameInfo.h"
  16. #include "llvm/CodeGen/MachineFunction.h"
  17. #include "llvm/CodeGen/MachineInstrBuilder.h"
  18. #include "llvm/CodeGen/RegisterScavenging.h"
  19. #include "llvm/CodeGen/TargetFrameLowering.h"
  20. #include "llvm/CodeGen/TargetInstrInfo.h"
  21. #include "llvm/IR/DiagnosticInfo.h"
  22. #include "llvm/Support/ErrorHandling.h"
  23. #define GET_REGINFO_TARGET_DESC
  24. #include "BPFGenRegisterInfo.inc"
  25. using namespace llvm;
  26. BPFRegisterInfo::BPFRegisterInfo()
  27. : BPFGenRegisterInfo(BPF::R0) {}
  28. const MCPhysReg *
  29. BPFRegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const {
  30. return CSR_SaveList;
  31. }
  32. BitVector BPFRegisterInfo::getReservedRegs(const MachineFunction &MF) const {
  33. BitVector Reserved(getNumRegs());
  34. markSuperRegs(Reserved, BPF::W10); // [W|R]10 is read only frame pointer
  35. markSuperRegs(Reserved, BPF::W11); // [W|R]11 is pseudo stack pointer
  36. return Reserved;
  37. }
  38. static void WarnSize(int Offset, MachineFunction &MF, DebugLoc& DL)
  39. {
  40. if (Offset <= -512) {
  41. const Function &F = MF.getFunction();
  42. DiagnosticInfoUnsupported DiagStackSize(F,
  43. "Looks like the BPF stack limit of 512 bytes is exceeded. "
  44. "Please move large on stack variables into BPF per-cpu array map.\n",
  45. DL);
  46. F.getContext().diagnose(DiagStackSize);
  47. }
  48. }
  49. bool BPFRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,
  50. int SPAdj, unsigned FIOperandNum,
  51. RegScavenger *RS) const {
  52. assert(SPAdj == 0 && "Unexpected");
  53. unsigned i = 0;
  54. MachineInstr &MI = *II;
  55. MachineBasicBlock &MBB = *MI.getParent();
  56. MachineFunction &MF = *MBB.getParent();
  57. DebugLoc DL = MI.getDebugLoc();
  58. if (!DL)
  59. /* try harder to get some debug loc */
  60. for (auto &I : MBB)
  61. if (I.getDebugLoc()) {
  62. DL = I.getDebugLoc();
  63. break;
  64. }
  65. while (!MI.getOperand(i).isFI()) {
  66. ++i;
  67. assert(i < MI.getNumOperands() && "Instr doesn't have FrameIndex operand!");
  68. }
  69. Register FrameReg = getFrameRegister(MF);
  70. int FrameIndex = MI.getOperand(i).getIndex();
  71. const TargetInstrInfo &TII = *MF.getSubtarget().getInstrInfo();
  72. if (MI.getOpcode() == BPF::MOV_rr) {
  73. int Offset = MF.getFrameInfo().getObjectOffset(FrameIndex);
  74. WarnSize(Offset, MF, DL);
  75. MI.getOperand(i).ChangeToRegister(FrameReg, false);
  76. Register reg = MI.getOperand(i - 1).getReg();
  77. BuildMI(MBB, ++II, DL, TII.get(BPF::ADD_ri), reg)
  78. .addReg(reg)
  79. .addImm(Offset);
  80. return false;
  81. }
  82. int Offset = MF.getFrameInfo().getObjectOffset(FrameIndex) +
  83. MI.getOperand(i + 1).getImm();
  84. if (!isInt<32>(Offset))
  85. llvm_unreachable("bug in frame offset");
  86. WarnSize(Offset, MF, DL);
  87. if (MI.getOpcode() == BPF::FI_ri) {
  88. // architecture does not really support FI_ri, replace it with
  89. // MOV_rr <target_reg>, frame_reg
  90. // ADD_ri <target_reg>, imm
  91. Register reg = MI.getOperand(i - 1).getReg();
  92. BuildMI(MBB, ++II, DL, TII.get(BPF::MOV_rr), reg)
  93. .addReg(FrameReg);
  94. BuildMI(MBB, II, DL, TII.get(BPF::ADD_ri), reg)
  95. .addReg(reg)
  96. .addImm(Offset);
  97. // Remove FI_ri instruction
  98. MI.eraseFromParent();
  99. } else {
  100. MI.getOperand(i).ChangeToRegister(FrameReg, false);
  101. MI.getOperand(i + 1).ChangeToImmediate(Offset);
  102. }
  103. return false;
  104. }
  105. Register BPFRegisterInfo::getFrameRegister(const MachineFunction &MF) const {
  106. return BPF::R10;
  107. }