diff options
author | Sander de Smalen <sander.desmalen@arm.com> | 2019-11-13 08:31:49 +0000 |
---|---|---|
committer | Sander de Smalen <sander.desmalen@arm.com> | 2019-11-13 09:45:24 +0000 |
commit | 9a1c243aa5ded10f7b39887b2be073d0bcfbf5c9 (patch) | |
tree | 11f26af5397630214e50df47c47cc49e50280543 /llvm/lib | |
parent | 5b9e4daef06dcfefc786737a32c8bbb5bd0fc5c4 (diff) | |
download | llvm-9a1c243aa5ded10f7b39887b2be073d0bcfbf5c9.zip llvm-9a1c243aa5ded10f7b39887b2be073d0bcfbf5c9.tar.gz llvm-9a1c243aa5ded10f7b39887b2be073d0bcfbf5c9.tar.bz2 |
[AArch64][SVE] Allocate locals that are scalable vectors.
This patch adds a target interface to set the StackID for a given type,
which allows scalable vectors (e.g. `<vscale x 16 x i8>`) to be assigned a
'sve-vec' StackID, so it is allocated in the SVE area of the stack frame.
Reviewers: ostannard, efriedma, rengolin, cameron.mcinally
Reviewed By: efriedma
Differential Revision: https://reviews.llvm.org/D70080
Diffstat (limited to 'llvm/lib')
-rw-r--r-- | llvm/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp | 9 | ||||
-rw-r--r-- | llvm/lib/Target/AArch64/AArch64FrameLowering.cpp | 54 | ||||
-rw-r--r-- | llvm/lib/Target/AArch64/AArch64FrameLowering.h | 1 |
3 files changed, 53 insertions, 11 deletions
diff --git a/llvm/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp b/llvm/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp index cf6711a..fa33400 100644 --- a/llvm/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp @@ -144,7 +144,8 @@ void FunctionLoweringInfo::set(const Function &fn, MachineFunction &mf, if (AI->isStaticAlloca() && (TFI->isStackRealignable() || (Align <= StackAlign))) { const ConstantInt *CUI = cast<ConstantInt>(AI->getArraySize()); - uint64_t TySize = MF->getDataLayout().getTypeAllocSize(Ty); + uint64_t TySize = + MF->getDataLayout().getTypeAllocSize(Ty).getKnownMinSize(); TySize *= CUI->getZExtValue(); // Get total allocated size. if (TySize == 0) TySize = 1; // Don't create zero-sized stack objects. @@ -159,6 +160,12 @@ void FunctionLoweringInfo::set(const Function &fn, MachineFunction &mf, MF->getFrameInfo().CreateStackObject(TySize, Align, false, AI); } + // Scalable vectors may need a special StackID to distinguish + // them from other (fixed size) stack objects. + if (Ty->isVectorTy() && Ty->getVectorIsScalable()) + MF->getFrameInfo().setStackID(FrameIndex, + TFI->getStackIDForScalableVectors()); + StaticAllocaMap[AI] = FrameIndex; // Update the catch handler information. if (Iter != CatchObjects.end()) { diff --git a/llvm/lib/Target/AArch64/AArch64FrameLowering.cpp b/llvm/lib/Target/AArch64/AArch64FrameLowering.cpp index 169c35c..970d780 100644 --- a/llvm/lib/Target/AArch64/AArch64FrameLowering.cpp +++ b/llvm/lib/Target/AArch64/AArch64FrameLowering.cpp @@ -206,6 +206,11 @@ static unsigned estimateRSStackSizeLimit(MachineFunction &MF) { return DefaultSafeSPDisplacement; } +TargetStackID::Value +AArch64FrameLowering::getStackIDForScalableVectors() const { + return TargetStackID::SVEVector; +} + /// Returns the size of the entire SVE stackframe (calleesaves + spills). static StackOffset getSVEStackSize(const MachineFunction &MF) { const AArch64FunctionInfo *AFI = MF.getInfo<AArch64FunctionInfo>(); @@ -2488,11 +2493,12 @@ bool AArch64FrameLowering::enableStackSlotScavenging( /// returns true if there are any SVE callee saves. static bool getSVECalleeSaveSlotRange(const MachineFrameInfo &MFI, int &Min, int &Max) { + Min = std::numeric_limits<int>::max(); + Max = std::numeric_limits<int>::min(); + if (!MFI.isCalleeSavedInfoValid()) return false; - Min = std::numeric_limits<int>::max(); - Max = std::numeric_limits<int>::min(); const std::vector<CalleeSavedInfo> &CSI = MFI.getCalleeSavedInfo(); for (auto &CS : CSI) { if (AArch64::ZPRRegClass.contains(CS.getReg()) || @@ -2526,6 +2532,11 @@ static int64_t determineSVEStackObjectOffsets(MachineFrameInfo &MFI, Offset = FixedOffset; } + auto Assign = [&MFI](int FI, int64_t Offset) { + LLVM_DEBUG(dbgs() << "alloc FI(" << FI << ") at SP[" << Offset << "]\n"); + MFI.setObjectOffset(FI, Offset); + }; + // Then process all callee saved slots. if (getSVECalleeSaveSlotRange(MFI, MinCSFrameIndex, MaxCSFrameIndex)) { // Make sure to align the last callee save slot. @@ -2535,17 +2546,40 @@ static int64_t determineSVEStackObjectOffsets(MachineFrameInfo &MFI, for (int I = MinCSFrameIndex; I <= MaxCSFrameIndex; ++I) { Offset += MFI.getObjectSize(I); Offset = alignTo(Offset, MFI.getObjectAlignment(I)); - if (AssignOffsets) { - LLVM_DEBUG(dbgs() << "alloc FI(" << I << ") at SP[" << Offset - << "]\n"); - MFI.setObjectOffset(I, -Offset); - } + if (AssignOffsets) + Assign(I, -Offset); } } - // Note: We don't take allocatable stack objects into - // account yet, because allocation for those is not yet - // implemented. + // Create a buffer of SVE objects to allocate and sort it. + SmallVector<int, 8> ObjectsToAllocate; + for (int I = 0, E = MFI.getObjectIndexEnd(); I != E; ++I) { + unsigned StackID = MFI.getStackID(I); + if (StackID != TargetStackID::SVEVector) + continue; + if (MaxCSFrameIndex >= I && I >= MinCSFrameIndex) + continue; + if (MFI.isDeadObjectIndex(I)) + continue; + + ObjectsToAllocate.push_back(I); + } + + // Allocate all SVE locals and spills + for (unsigned FI : ObjectsToAllocate) { + unsigned Align = MFI.getObjectAlignment(FI); + // FIXME: Given that the length of SVE vectors is not necessarily a power of + // two, we'd need to align every object dynamically at runtime if the + // alignment is larger than 16. This is not yet supported. + if (Align > 16) + report_fatal_error( + "Alignment of scalable vectors > 16 bytes is not yet supported"); + + Offset = alignTo(Offset + MFI.getObjectSize(FI), Align); + if (AssignOffsets) + Assign(FI, -Offset); + } + return Offset; } diff --git a/llvm/lib/Target/AArch64/AArch64FrameLowering.h b/llvm/lib/Target/AArch64/AArch64FrameLowering.h index f84847d..3ed8499 100644 --- a/llvm/lib/Target/AArch64/AArch64FrameLowering.h +++ b/llvm/lib/Target/AArch64/AArch64FrameLowering.h @@ -72,6 +72,7 @@ public: } bool enableStackSlotScavenging(const MachineFunction &MF) const override; + TargetStackID::Value getStackIDForScalableVectors() const override; void processFunctionBeforeFrameFinalized(MachineFunction &MF, RegScavenger *RS) const override; |