CodeQL / Analyze (actions) (push) Canceled after 0s
CodeQL / Analyze (python) (push) Canceled after 0s
pre-commit / pre-commit (push) Canceled after 0s
Multi-Arch CI / setup (push) Canceled after 0s
Publish build_manylinux_x86_64 images / publish_build_manylinux_x86_64 (push) Canceled after 0s
Setup (Multi-Arch) / setup (push) Canceled after 0s
Multi-Arch CI / Linux::${{ fromJSON(needs.setup.outputs.linux_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubi10 image / publish_no_rocm_image_ubi10 (push) Canceled after 0s
Multi-Arch CI / Windows::${{ fromJSON(needs.setup.outputs.windows_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Multi-Arch CI / Manifest Diff (push) Canceled after 0s
TheRock Manifest Diff Report / Generate Manifest Diff Report (push) Canceled after 0s
Multi-Arch CI / CI Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_ocl_rt images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_rocgdb images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Unit Tests / Unit Tests :: ubuntu-24.04 (push) Canceled after 0s
Unit Tests / Unit Tests :: windows-2022 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_media (push) Canceled after 0s
Unit Tests / Unit Tests Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_openmpi (push) Canceled after 0s
151 lines
5.4 KiB
C++
151 lines
5.4 KiB
C++
//=- RISCVMachineFunctionInfo.cpp - RISC-V machine function info --*- C++ -*-=//
|
|
//
|
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
// See https://llvm.org/LICENSE.txt for license information.
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
//
|
|
// This file declares RISCV-specific per-machine-function information.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#include "RISCVMachineFunctionInfo.h"
|
|
#include "llvm/IR/Module.h"
|
|
|
|
using namespace llvm;
|
|
|
|
yaml::RISCVMachineFunctionInfo::RISCVMachineFunctionInfo(
|
|
const llvm::RISCVMachineFunctionInfo &MFI)
|
|
: VarArgsFrameIndex(MFI.getVarArgsFrameIndex()),
|
|
VarArgsSaveSize(MFI.getVarArgsSaveSize()) {}
|
|
|
|
MachineFunctionInfo *RISCVMachineFunctionInfo::clone(
|
|
BumpPtrAllocator &Allocator, MachineFunction &DestMF,
|
|
const DenseMap<MachineBasicBlock *, MachineBasicBlock *> &Src2DstMBB)
|
|
const {
|
|
return DestMF.cloneInfo<RISCVMachineFunctionInfo>(*this);
|
|
}
|
|
|
|
RISCVMachineFunctionInfo::RISCVMachineFunctionInfo(const Function &F,
|
|
const RISCVSubtarget *STI) {
|
|
if (const auto *CFB = mdconst::extract_or_null<ConstantInt>(
|
|
F.getParent()->getModuleFlag("cf-protection-branch")))
|
|
CFProtectionBranch = CFB->getZExtValue() != 0;
|
|
|
|
// The default stack probe size is 4096 if the function has no
|
|
// stack-probe-size attribute. This is a safe default because it is the
|
|
// smallest possible guard page size.
|
|
uint64_t ProbeSize = 4096;
|
|
if (F.hasFnAttribute("stack-probe-size"))
|
|
ProbeSize = F.getFnAttributeAsParsedInteger("stack-probe-size");
|
|
else if (const auto *PS = mdconst::extract_or_null<ConstantInt>(
|
|
F.getParent()->getModuleFlag("stack-probe-size")))
|
|
ProbeSize = PS->getZExtValue();
|
|
assert(int64_t(ProbeSize) > 0 && "Invalid stack probe size");
|
|
|
|
// Round down to the stack alignment.
|
|
uint64_t StackAlign =
|
|
STI->getFrameLowering()->getTransientStackAlign().value();
|
|
ProbeSize = std::max(StackAlign, alignDown(ProbeSize, StackAlign));
|
|
StringRef ProbeKind;
|
|
if (F.hasFnAttribute("probe-stack"))
|
|
ProbeKind = F.getFnAttribute("probe-stack").getValueAsString();
|
|
else if (const auto *PS = dyn_cast_or_null<MDString>(
|
|
F.getParent()->getModuleFlag("probe-stack")))
|
|
ProbeKind = PS->getString();
|
|
if (ProbeKind.size()) {
|
|
StackProbeSize = ProbeSize;
|
|
}
|
|
}
|
|
|
|
RISCVMachineFunctionInfo::InterruptStackKind
|
|
RISCVMachineFunctionInfo::getInterruptStackKind(
|
|
const MachineFunction &MF) const {
|
|
if (!MF.getFunction().hasFnAttribute("interrupt"))
|
|
return InterruptStackKind::None;
|
|
|
|
assert(VarArgsSaveSize == 0 &&
|
|
"Interrupt functions should not having incoming varargs");
|
|
|
|
StringRef InterruptVal =
|
|
MF.getFunction().getFnAttribute("interrupt").getValueAsString();
|
|
|
|
return StringSwitch<RISCVMachineFunctionInfo::InterruptStackKind>(
|
|
InterruptVal)
|
|
.Case("qci-nest", InterruptStackKind::QCINest)
|
|
.Case("qci-nonest", InterruptStackKind::QCINoNest)
|
|
.Case("SiFive-CLIC-preemptible",
|
|
InterruptStackKind::SiFiveCLICPreemptible)
|
|
.Case("SiFive-CLIC-stack-swap", InterruptStackKind::SiFiveCLICStackSwap)
|
|
.Case("SiFive-CLIC-preemptible-stack-swap",
|
|
InterruptStackKind::SiFiveCLICPreemptibleStackSwap)
|
|
.Default(InterruptStackKind::None);
|
|
}
|
|
|
|
void yaml::RISCVMachineFunctionInfo::mappingImpl(yaml::IO &YamlIO) {
|
|
MappingTraits<RISCVMachineFunctionInfo>::mapping(YamlIO, *this);
|
|
}
|
|
|
|
RISCVMachineFunctionInfo::PushPopKind
|
|
RISCVMachineFunctionInfo::getPushPopKind(const MachineFunction &MF) const {
|
|
// We cannot use fixed locations for the callee saved spill slots if the
|
|
// function uses a varargs save area.
|
|
// TODO: Use a separate placement for vararg registers to enable Zcmp.
|
|
if (VarArgsSaveSize != 0)
|
|
return PushPopKind::None;
|
|
|
|
// SiFive interrupts are not compatible with push/pop.
|
|
if (useSiFiveInterrupt(MF))
|
|
return PushPopKind::None;
|
|
|
|
// Zcmp is not compatible with the frame pointer convention.
|
|
if (MF.getSubtarget<RISCVSubtarget>().hasStdExtZcmp() &&
|
|
!MF.getTarget().Options.DisableFramePointerElim(MF))
|
|
return PushPopKind::StdExtZcmp;
|
|
|
|
// Xqccmp is Zcmp but has a push order compatible with the frame-pointer
|
|
// convention.
|
|
if (MF.getSubtarget<RISCVSubtarget>().hasVendorXqccmp())
|
|
return PushPopKind::VendorXqccmp;
|
|
|
|
return PushPopKind::None;
|
|
}
|
|
|
|
bool RISCVMachineFunctionInfo::hasImplicitFPUpdates(
|
|
const MachineFunction &MF) const {
|
|
switch (getInterruptStackKind(MF)) {
|
|
case InterruptStackKind::QCINest:
|
|
case InterruptStackKind::QCINoNest:
|
|
// QC.C.MIENTER and QC.C.MIENTER.NEST both update FP on function entry.
|
|
return true;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
switch (getPushPopKind(MF)) {
|
|
case PushPopKind::VendorXqccmp:
|
|
// When using Xqccmp, we will use `QC.CM.PUSHFP` when Frame Pointers are
|
|
// enabled, which will update FP.
|
|
return true;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
void RISCVMachineFunctionInfo::initializeBaseYamlFields(
|
|
const yaml::RISCVMachineFunctionInfo &YamlMFI) {
|
|
VarArgsFrameIndex = YamlMFI.VarArgsFrameIndex;
|
|
VarArgsSaveSize = YamlMFI.VarArgsSaveSize;
|
|
}
|
|
|
|
void RISCVMachineFunctionInfo::addSExt32Register(Register Reg) {
|
|
SExt32Registers.push_back(Reg);
|
|
}
|
|
|
|
bool RISCVMachineFunctionInfo::isSExt32Register(Register Reg) const {
|
|
return is_contained(SExt32Registers, Reg);
|
|
}
|