brintos

brintos / llvm-project-archived public Read only

0
0
Text · 4.6 KiB · f8e3fcd Raw
146 lines · cpp
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-exception6//7//===----------------------------------------------------------------------===//8//9// This file contains the BPF implementation of the TargetRegisterInfo class.10//11//===----------------------------------------------------------------------===//12 13#include "BPFRegisterInfo.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/CommandLine.h"23#include "llvm/Support/ErrorHandling.h"24 25#define GET_REGINFO_TARGET_DESC26#include "BPFGenRegisterInfo.inc"27using namespace llvm;28 29static cl::opt<int>30    BPFStackSizeOption("bpf-stack-size",31                       cl::desc("Specify the BPF stack size limit"),32                       cl::init(512));33 34BPFRegisterInfo::BPFRegisterInfo()35    : BPFGenRegisterInfo(BPF::R0) {}36 37const MCPhysReg *38BPFRegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const {39  return CSR_SaveList;40}41 42const uint32_t *43BPFRegisterInfo::getCallPreservedMask(const MachineFunction &MF,44                                      CallingConv::ID CC) const {45  switch (CC) {46  default:47    return CSR_RegMask;48  case CallingConv::PreserveAll:49    return CSR_PreserveAll_RegMask;50  }51}52 53BitVector BPFRegisterInfo::getReservedRegs(const MachineFunction &MF) const {54  BitVector Reserved(getNumRegs());55  markSuperRegs(Reserved, BPF::W10); // [W|R]10 is read only frame pointer56  markSuperRegs(Reserved, BPF::W11); // [W|R]11 is pseudo stack pointer57  return Reserved;58}59 60static void WarnSize(int Offset, MachineFunction &MF, DebugLoc& DL,61                     MachineBasicBlock& MBB) {62  if (Offset <= -BPFStackSizeOption) {63    if (!DL)64      /* try harder to get some debug loc */65      for (auto &I : MBB)66        if (I.getDebugLoc()) {67          DL = I.getDebugLoc();68          break;69        }70 71    const Function &F = MF.getFunction();72    F.getContext().diagnose(DiagnosticInfoUnsupported(73        F,74        "Looks like the BPF stack limit is exceeded. "75        "Please move large on stack variables into BPF per-cpu array map. For "76        "non-kernel uses, the stack can be increased using -mllvm "77        "-bpf-stack-size.\n",78        DL));79  }80}81 82bool BPFRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,83                                          int SPAdj, unsigned FIOperandNum,84                                          RegScavenger *RS) const {85  assert(SPAdj == 0 && "Unexpected");86 87  unsigned i = 0;88  MachineInstr &MI = *II;89  MachineBasicBlock &MBB = *MI.getParent();90  MachineFunction &MF = *MBB.getParent();91  DebugLoc DL = MI.getDebugLoc();92 93  while (!MI.getOperand(i).isFI()) {94    ++i;95    assert(i < MI.getNumOperands() && "Instr doesn't have FrameIndex operand!");96  }97 98  Register FrameReg = getFrameRegister(MF);99  int FrameIndex = MI.getOperand(i).getIndex();100  const TargetInstrInfo &TII = *MF.getSubtarget().getInstrInfo();101 102  if (MI.getOpcode() == BPF::MOV_rr) {103    int Offset = MF.getFrameInfo().getObjectOffset(FrameIndex);104 105    WarnSize(Offset, MF, DL, MBB);106    MI.getOperand(i).ChangeToRegister(FrameReg, false);107    Register reg = MI.getOperand(i - 1).getReg();108    BuildMI(MBB, ++II, DL, TII.get(BPF::ADD_ri), reg)109        .addReg(reg)110        .addImm(Offset);111    return false;112  }113 114  int Offset = MF.getFrameInfo().getObjectOffset(FrameIndex) +115               MI.getOperand(i + 1).getImm();116 117  if (!isInt<32>(Offset))118    llvm_unreachable("bug in frame offset");119 120  WarnSize(Offset, MF, DL, MBB);121 122  if (MI.getOpcode() == BPF::FI_ri) {123    // architecture does not really support FI_ri, replace it with124    //    MOV_rr <target_reg>, frame_reg125    //    ADD_ri <target_reg>, imm126    Register reg = MI.getOperand(i - 1).getReg();127 128    BuildMI(MBB, ++II, DL, TII.get(BPF::MOV_rr), reg)129        .addReg(FrameReg);130    BuildMI(MBB, II, DL, TII.get(BPF::ADD_ri), reg)131        .addReg(reg)132        .addImm(Offset);133 134    // Remove FI_ri instruction135    MI.eraseFromParent();136  } else {137    MI.getOperand(i).ChangeToRegister(FrameReg, false);138    MI.getOperand(i + 1).ChangeToImmediate(Offset);139  }140  return false;141}142 143Register BPFRegisterInfo::getFrameRegister(const MachineFunction &MF) const {144  return BPF::R10;145}146