brintos

brintos / llvm-project-archived public Read only

0
0
Text · 5.2 KiB · 920a795 Raw
148 lines · cpp
1//=- RISCVMachineFunctionInfo.cpp - RISC-V machine function info --*- 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 declares RISCV-specific per-machine-function information.10//11//===----------------------------------------------------------------------===//12 13#include "RISCVMachineFunctionInfo.h"14#include "llvm/IR/Module.h"15 16using namespace llvm;17 18yaml::RISCVMachineFunctionInfo::RISCVMachineFunctionInfo(19    const llvm::RISCVMachineFunctionInfo &MFI)20    : VarArgsFrameIndex(MFI.getVarArgsFrameIndex()),21      VarArgsSaveSize(MFI.getVarArgsSaveSize()) {}22 23MachineFunctionInfo *RISCVMachineFunctionInfo::clone(24    BumpPtrAllocator &Allocator, MachineFunction &DestMF,25    const DenseMap<MachineBasicBlock *, MachineBasicBlock *> &Src2DstMBB)26    const {27  return DestMF.cloneInfo<RISCVMachineFunctionInfo>(*this);28}29 30RISCVMachineFunctionInfo::RISCVMachineFunctionInfo(const Function &F,31                                                   const RISCVSubtarget *STI) {32 33  // The default stack probe size is 4096 if the function has no34  // stack-probe-size attribute. This is a safe default because it is the35  // smallest possible guard page size.36  uint64_t ProbeSize = 4096;37  if (F.hasFnAttribute("stack-probe-size"))38    ProbeSize = F.getFnAttributeAsParsedInteger("stack-probe-size");39  else if (const auto *PS = mdconst::extract_or_null<ConstantInt>(40               F.getParent()->getModuleFlag("stack-probe-size")))41    ProbeSize = PS->getZExtValue();42  assert(int64_t(ProbeSize) > 0 && "Invalid stack probe size");43 44  // Round down to the stack alignment.45  uint64_t StackAlign =46      STI->getFrameLowering()->getTransientStackAlign().value();47  ProbeSize = std::max(StackAlign, alignDown(ProbeSize, StackAlign));48  StringRef ProbeKind;49  if (F.hasFnAttribute("probe-stack"))50    ProbeKind = F.getFnAttribute("probe-stack").getValueAsString();51  else if (const auto *PS = dyn_cast_or_null<MDString>(52               F.getParent()->getModuleFlag("probe-stack")))53    ProbeKind = PS->getString();54  if (ProbeKind.size()) {55    StackProbeSize = ProbeSize;56  }57}58 59RISCVMachineFunctionInfo::InterruptStackKind60RISCVMachineFunctionInfo::getInterruptStackKind(61    const MachineFunction &MF) const {62  if (!MF.getFunction().hasFnAttribute("interrupt"))63    return InterruptStackKind::None;64 65  assert(VarArgsSaveSize == 0 &&66         "Interrupt functions should not having incoming varargs");67 68  StringRef InterruptVal =69      MF.getFunction().getFnAttribute("interrupt").getValueAsString();70 71  return StringSwitch<RISCVMachineFunctionInfo::InterruptStackKind>(72             InterruptVal)73      .Case("qci-nest", InterruptStackKind::QCINest)74      .Case("qci-nonest", InterruptStackKind::QCINoNest)75      .Case("SiFive-CLIC-preemptible",76            InterruptStackKind::SiFiveCLICPreemptible)77      .Case("SiFive-CLIC-stack-swap", InterruptStackKind::SiFiveCLICStackSwap)78      .Case("SiFive-CLIC-preemptible-stack-swap",79            InterruptStackKind::SiFiveCLICPreemptibleStackSwap)80      .Default(InterruptStackKind::None);81}82 83void yaml::RISCVMachineFunctionInfo::mappingImpl(yaml::IO &YamlIO) {84  MappingTraits<RISCVMachineFunctionInfo>::mapping(YamlIO, *this);85}86 87RISCVMachineFunctionInfo::PushPopKind88RISCVMachineFunctionInfo::getPushPopKind(const MachineFunction &MF) const {89  // We cannot use fixed locations for the callee saved spill slots if the90  // function uses a varargs save area.91  // TODO: Use a separate placement for vararg registers to enable Zcmp.92  if (VarArgsSaveSize != 0)93    return PushPopKind::None;94 95  // SiFive interrupts are not compatible with push/pop.96  if (useSiFiveInterrupt(MF))97    return PushPopKind::None;98 99  // Zcmp is not compatible with the frame pointer convention.100  if (MF.getSubtarget<RISCVSubtarget>().hasStdExtZcmp() &&101      !MF.getTarget().Options.DisableFramePointerElim(MF))102    return PushPopKind::StdExtZcmp;103 104  // Xqccmp is Zcmp but has a push order compatible with the frame-pointer105  // convention.106  if (MF.getSubtarget<RISCVSubtarget>().hasVendorXqccmp())107    return PushPopKind::VendorXqccmp;108 109  return PushPopKind::None;110}111 112bool RISCVMachineFunctionInfo::hasImplicitFPUpdates(113    const MachineFunction &MF) const {114  switch (getInterruptStackKind(MF)) {115  case InterruptStackKind::QCINest:116  case InterruptStackKind::QCINoNest:117    // QC.C.MIENTER and QC.C.MIENTER.NEST both update FP on function entry.118    return true;119  default:120    break;121  }122 123  switch (getPushPopKind(MF)) {124  case PushPopKind::VendorXqccmp:125    // When using Xqccmp, we will use `QC.CM.PUSHFP` when Frame Pointers are126    // enabled, which will update FP.127    return true;128  default:129    break;130  }131 132  return false;133}134 135void RISCVMachineFunctionInfo::initializeBaseYamlFields(136    const yaml::RISCVMachineFunctionInfo &YamlMFI) {137  VarArgsFrameIndex = YamlMFI.VarArgsFrameIndex;138  VarArgsSaveSize = YamlMFI.VarArgsSaveSize;139}140 141void RISCVMachineFunctionInfo::addSExt32Register(Register Reg) {142  SExt32Registers.push_back(Reg);143}144 145bool RISCVMachineFunctionInfo::isSExt32Register(Register Reg) const {146  return is_contained(SExt32Registers, Reg);147}148