summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/Target/AArch64/AArch64FrameLowering.cpp6
-rw-r--r--llvm/lib/Target/AArch64/AArch64InstrInfo.cpp13
-rw-r--r--llvm/lib/Target/AArch64/AArch64MachineFunctionInfo.h15
3 files changed, 27 insertions, 7 deletions
diff --git a/llvm/lib/Target/AArch64/AArch64FrameLowering.cpp b/llvm/lib/Target/AArch64/AArch64FrameLowering.cpp
index e81eb5ea852..22a10511d37 100644
--- a/llvm/lib/Target/AArch64/AArch64FrameLowering.cpp
+++ b/llvm/lib/Target/AArch64/AArch64FrameLowering.cpp
@@ -531,9 +531,11 @@ void AArch64FrameLowering::emitPrologue(MachineFunction &MF,
return;
// REDZONE: If the stack size is less than 128 bytes, we don't need
// to actually allocate.
- if (canUseRedZone(MF))
+ if (canUseRedZone(MF)) {
+ AFI->setHasRedZone(true);
++NumRedZoneFunctions;
- else {
+ } else {
+ AFI->setHasRedZone(false);
emitFrameOffset(MBB, MBBI, DL, AArch64::SP, AArch64::SP, -NumBytes, TII,
MachineInstr::FrameSetup);
diff --git a/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp b/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp
index 2f147bcb2d5..04da72a360a 100644
--- a/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp
+++ b/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp
@@ -4985,15 +4985,18 @@ bool AArch64InstrInfo::isFunctionSafeToOutlineFrom(
MachineFunction &MF, bool OutlineFromLinkOnceODRs) const {
const Function &F = MF.getFunction();
- // If F uses a redzone, then don't outline from it because it might mess up
- // the stack.
- if (!F.hasFnAttribute(Attribute::NoRedZone))
- return false;
-
// Can F be deduplicated by the linker? If it can, don't outline from it.
if (!OutlineFromLinkOnceODRs && F.hasLinkOnceODRLinkage())
return false;
+ // Outlining from functions with redzones is unsafe since the outliner may
+ // modify the stack. Check if hasRedZone is true or unknown; if yes, don't
+ // outline from it.
+ AArch64FunctionInfo *AFI = MF.getInfo<AArch64FunctionInfo>();
+ if (!AFI || AFI->hasRedZone().getValueOr(true))
+ return false;
+
+ // It's safe to outline from MF.
return true;
}
diff --git a/llvm/lib/Target/AArch64/AArch64MachineFunctionInfo.h b/llvm/lib/Target/AArch64/AArch64MachineFunctionInfo.h
index 9f354c00946..e7feb021f52 100644
--- a/llvm/lib/Target/AArch64/AArch64MachineFunctionInfo.h
+++ b/llvm/lib/Target/AArch64/AArch64MachineFunctionInfo.h
@@ -15,6 +15,7 @@
#define LLVM_LIB_TARGET_AARCH64_AARCH64MACHINEFUNCTIONINFO_H
#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/Optional.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/CodeGen/MachineFunction.h"
@@ -90,11 +91,22 @@ class AArch64FunctionInfo final : public MachineFunctionInfo {
/// other stack allocations.
bool CalleeSaveStackHasFreeSpace = false;
+ /// \brief Has a value when it is known whether or not the function uses a
+ /// redzone, and no value otherwise.
+ /// Initialized during frame lowering, unless the function has the noredzone
+ /// attribute, in which case it is set to false at construction.
+ Optional<bool> HasRedZone;
+
public:
AArch64FunctionInfo() = default;
explicit AArch64FunctionInfo(MachineFunction &MF) {
(void)MF;
+
+ // If we already know that the function doesn't have a redzone, set
+ // HasRedZone here.
+ if (MF.getFunction().hasFnAttribute(Attribute::NoRedZone))
+ HasRedZone = false;
}
unsigned getBytesInStackArgArea() const { return BytesInStackArgArea; }
@@ -132,6 +144,9 @@ public:
return NumLocalDynamicTLSAccesses;
}
+ Optional<bool> hasRedZone() const { return HasRedZone; }
+ void setHasRedZone(bool s) { HasRedZone = s; }
+
int getVarArgsStackIndex() const { return VarArgsStackIndex; }
void setVarArgsStackIndex(int Index) { VarArgsStackIndex = Index; }
OpenPOWER on IntegriCloud