Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
220 changes: 126 additions & 94 deletions llvm/lib/Target/AArch64/AArch64FrameLowering.cpp

Large diffs are not rendered by default.

20 changes: 15 additions & 5 deletions llvm/lib/Target/AArch64/AArch64FrameLowering.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,11 @@ class AArch64FunctionInfo;
class AArch64PrologueEmitter;
class AArch64EpilogueEmitter;

struct SVEStackSizes {
uint64_t ZPRStackSize{0};
uint64_t PPRStackSize{0};
};

class AArch64FrameLowering : public TargetFrameLowering {
public:
explicit AArch64FrameLowering()
Expand Down Expand Up @@ -147,7 +152,16 @@ class AArch64FrameLowering : public TargetFrameLowering {

bool requiresSaveVG(const MachineFunction &MF) const;

StackOffset getSVEStackSize(const MachineFunction &MF) const;
/// Returns the size of the entire ZPR stackframe (calleesaves + spills).
StackOffset getZPRStackSize(const MachineFunction &MF) const;

/// Returns the size of the entire PPR stackframe (calleesaves + spills).
StackOffset getPPRStackSize(const MachineFunction &MF) const;

/// Returns the size of the entire SVE stackframe (PPRs + ZPRs).
StackOffset getSVEStackSize(const MachineFunction &MF) const {
return getZPRStackSize(MF) + getPPRStackSize(MF);
}

friend class AArch64PrologueEpilogueCommon;
friend class AArch64PrologueEmitter;
Expand All @@ -167,10 +181,6 @@ class AArch64FrameLowering : public TargetFrameLowering {
/// Returns true if CSRs should be paired.
bool producePairRegisters(MachineFunction &MF) const;

int64_t estimateSVEStackObjectOffsets(MachineFrameInfo &MF) const;
int64_t assignSVEStackObjectOffsets(MachineFrameInfo &MF,
int &MinCSFrameIndex,
int &MaxCSFrameIndex) const;
/// Make a determination whether a Hazard slot is used and create it if
/// needed.
void determineStackHazardSlot(MachineFunction &MF,
Expand Down
20 changes: 15 additions & 5 deletions llvm/lib/Target/AArch64/AArch64MachineFunctionInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,21 @@

using namespace llvm;

static std::optional<uint64_t>
getSVEStackSize(const AArch64FunctionInfo &MFI,
uint64_t (AArch64FunctionInfo::*GetStackSize)() const) {
if (!MFI.hasCalculatedStackSizeSVE())
return std::nullopt;
return (MFI.*GetStackSize)();
}

yaml::AArch64FunctionInfo::AArch64FunctionInfo(
const llvm::AArch64FunctionInfo &MFI)
: HasRedZone(MFI.hasRedZone()),
StackSizeSVE(MFI.hasCalculatedStackSizeSVE()
? std::optional<uint64_t>(MFI.getStackSizeSVE())
: std::nullopt),
StackSizeZPR(
getSVEStackSize(MFI, &llvm::AArch64FunctionInfo::getStackSizeZPR)),
StackSizePPR(
getSVEStackSize(MFI, &llvm::AArch64FunctionInfo::getStackSizePPR)),
HasStackFrame(MFI.hasStackFrame()
? std::optional<bool>(MFI.hasStackFrame())
: std::nullopt) {}
Expand All @@ -41,8 +50,9 @@ void AArch64FunctionInfo::initializeBaseYamlFields(
const yaml::AArch64FunctionInfo &YamlMFI) {
if (YamlMFI.HasRedZone)
HasRedZone = YamlMFI.HasRedZone;
if (YamlMFI.StackSizeSVE)
setStackSizeSVE(*YamlMFI.StackSizeSVE);
if (YamlMFI.StackSizeZPR || YamlMFI.StackSizePPR)
setStackSizeSVE(YamlMFI.StackSizeZPR.value_or(0),
YamlMFI.StackSizePPR.value_or(0));
if (YamlMFI.HasStackFrame)
setHasStackFrame(*YamlMFI.HasStackFrame);
}
Expand Down
63 changes: 37 additions & 26 deletions llvm/lib/Target/AArch64/AArch64MachineFunctionInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -74,13 +74,10 @@ class AArch64FunctionInfo final : public MachineFunctionInfo {
/// Amount of stack frame size, not including callee-saved registers.
uint64_t LocalStackSize = 0;

/// The start and end frame indices for the SVE callee saves.
int MinSVECSFrameIndex = 0;
int MaxSVECSFrameIndex = 0;

/// Amount of stack frame size used for saving callee-saved registers.
unsigned CalleeSavedStackSize = 0;
unsigned SVECalleeSavedStackSize = 0;
unsigned ZPRCalleeSavedStackSize = 0;
unsigned PPRCalleeSavedStackSize = 0;
bool HasCalleeSavedStackSize = false;
bool HasSVECalleeSavedStackSize = false;

Expand Down Expand Up @@ -137,9 +134,10 @@ class AArch64FunctionInfo final : public MachineFunctionInfo {
/// SVE stack size (for predicates and data vectors) are maintained here
/// rather than in FrameInfo, as the placement and Stack IDs are target
/// specific.
uint64_t StackSizeSVE = 0;
uint64_t StackSizeZPR = 0;
uint64_t StackSizePPR = 0;

/// HasCalculatedStackSizeSVE indicates whether StackSizeSVE is valid.
/// HasCalculatedStackSizeSVE indicates whether StackSizeZPR/PPR is valid.
bool HasCalculatedStackSizeSVE = false;

/// Has a value when it is known whether or not the function uses a
Expand Down Expand Up @@ -312,16 +310,25 @@ class AArch64FunctionInfo final : public MachineFunctionInfo {
TailCallReservedStack = bytes;
}

bool hasCalculatedStackSizeSVE() const { return HasCalculatedStackSizeSVE; }

void setStackSizeSVE(uint64_t S) {
void setStackSizeSVE(uint64_t ZPR, uint64_t PPR) {
StackSizeZPR = ZPR;
StackSizePPR = PPR;
HasCalculatedStackSizeSVE = true;
StackSizeSVE = S;
}

uint64_t getStackSizeSVE() const {
uint64_t getStackSizeZPR() const {
assert(hasCalculatedStackSizeSVE());
return StackSizeSVE;
return StackSizeZPR;
}
uint64_t getStackSizePPR() const {
assert(hasCalculatedStackSizeSVE());
return StackSizePPR;
}

bool hasCalculatedStackSizeSVE() const { return HasCalculatedStackSizeSVE; }

bool hasSVEStackSize() const {
return getStackSizeZPR() > 0 || getStackSizePPR() > 0;
}

bool hasStackFrame() const { return HasStackFrame; }
Expand Down Expand Up @@ -414,23 +421,25 @@ class AArch64FunctionInfo final : public MachineFunctionInfo {
}

// Saves the CalleeSavedStackSize for SVE vectors in 'scalable bytes'
void setSVECalleeSavedStackSize(unsigned Size) {
SVECalleeSavedStackSize = Size;
void setSVECalleeSavedStackSize(unsigned ZPR, unsigned PPR) {
ZPRCalleeSavedStackSize = ZPR;
PPRCalleeSavedStackSize = PPR;
HasSVECalleeSavedStackSize = true;
}
unsigned getSVECalleeSavedStackSize() const {
unsigned getZPRCalleeSavedStackSize() const {
assert(HasSVECalleeSavedStackSize &&
"SVECalleeSavedStackSize has not been calculated");
return SVECalleeSavedStackSize;
"ZPRCalleeSavedStackSize has not been calculated");
return ZPRCalleeSavedStackSize;
}

void setMinMaxSVECSFrameIndex(int Min, int Max) {
MinSVECSFrameIndex = Min;
MaxSVECSFrameIndex = Max;
unsigned getPPRCalleeSavedStackSize() const {
assert(HasSVECalleeSavedStackSize &&
"PPRCalleeSavedStackSize has not been calculated");
return PPRCalleeSavedStackSize;
}

int getMinSVECSFrameIndex() const { return MinSVECSFrameIndex; }
int getMaxSVECSFrameIndex() const { return MaxSVECSFrameIndex; }
unsigned getSVECalleeSavedStackSize() const {
return getZPRCalleeSavedStackSize() + getPPRCalleeSavedStackSize();
}

void incNumLocalDynamicTLSAccesses() { ++NumLocalDynamicTLSAccesses; }
unsigned getNumLocalDynamicTLSAccesses() const {
Expand Down Expand Up @@ -611,7 +620,8 @@ class AArch64FunctionInfo final : public MachineFunctionInfo {
namespace yaml {
struct AArch64FunctionInfo final : public yaml::MachineFunctionInfo {
std::optional<bool> HasRedZone;
std::optional<uint64_t> StackSizeSVE;
std::optional<uint64_t> StackSizeZPR;
std::optional<uint64_t> StackSizePPR;
std::optional<bool> HasStackFrame;

AArch64FunctionInfo() = default;
Expand All @@ -624,7 +634,8 @@ struct AArch64FunctionInfo final : public yaml::MachineFunctionInfo {
template <> struct MappingTraits<AArch64FunctionInfo> {
static void mapping(IO &YamlIO, AArch64FunctionInfo &MFI) {
YamlIO.mapOptional("hasRedZone", MFI.HasRedZone);
YamlIO.mapOptional("stackSizeSVE", MFI.StackSizeSVE);
YamlIO.mapOptional("stackSizeZPR", MFI.StackSizeZPR);
YamlIO.mapOptional("stackSizePPR", MFI.StackSizePPR);
YamlIO.mapOptional("hasStackFrame", MFI.HasStackFrame);
}
};
Expand Down
Loading