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