Skip to content
Open
Show file tree
Hide file tree
Changes from 2 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
2 changes: 1 addition & 1 deletion clang/include/clang/Basic/CodeGenOptions.def
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ CODEGENOPT(SeparateNamedSections, 1, 0, Benign) ///< Set for -fseparate-named-se
CODEGENOPT(EnableAIXExtendedAltivecABI, 1, 0, Benign) ///< Set for -mabi=vec-extabi. Enables the extended Altivec ABI on AIX.
CODEGENOPT(XCOFFReadOnlyPointers, 1, 0, Benign) ///< Set for -mxcoff-roptr.
CODEGENOPT(AllTocData, 1, 0, Benign) ///< AIX -mtocdata
ENUM_CODEGENOPT(FramePointer, FramePointerKind, 2, FramePointerKind::None, Benign) /// frame-pointer: all,non-leaf,reserved,none
ENUM_CODEGENOPT(FramePointer, FramePointerKind, 3, FramePointerKind::None, Benign) /// frame-pointer: all,non-leaf,non-leaf-no-reserve,reserved,none

ENUM_CODEGENOPT(ExceptionHandling, ExceptionHandlingKind, 3, ExceptionHandlingKind::None, NotCompatible)

Expand Down
13 changes: 9 additions & 4 deletions clang/include/clang/Basic/CodeGenOptions.h
Original file line number Diff line number Diff line change
Expand Up @@ -155,10 +155,13 @@ class CodeGenOptions : public CodeGenOptionsBase {
std::string BinutilsVersion;

enum class FramePointerKind {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Silly question - why is this enum ordered so differently to llvm/include/llvm/Support/CodeGen.h?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've checked and the order doesn't appear to matter apart from some sanitizer tests which have the frame pointer metadata written like: !1 = !{i32 7, !"frame-pointer", i32 2}. I can make it consistent if you'd like.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've no strong objection to keeping it as it is but it would make sense to match the llvm implementation (assuming that's the one hardwired by metadata) - but I assume that can be done as a followup PR. Thanks for checking

None, // Omit all frame pointers.
Reserved, // Maintain valid frame pointer chain.
NonLeaf, // Keep non-leaf frame pointers.
All, // Keep all frame pointers.
NonLeafNoReserve, // Keep non-leaf frame pointers, allow the FP to be used
// as a GPR in leaf functions.
None, // Omit all frame pointers.
Reserved, // Maintain valid frame pointer chain.
NonLeaf, // Keep non-leaf frame pointers, don't allow the FP to be used as a
// GPR in leaf functions.
All, // Keep all frame pointers.
};

static StringRef getFramePointerKindName(FramePointerKind Kind) {
Expand All @@ -167,6 +170,8 @@ class CodeGenOptions : public CodeGenOptionsBase {
return "none";
case FramePointerKind::Reserved:
return "reserved";
case FramePointerKind::NonLeafNoReserve:
return "non-leaf-no-reserve";
case FramePointerKind::NonLeaf:
return "non-leaf";
case FramePointerKind::All:
Expand Down
4 changes: 2 additions & 2 deletions clang/include/clang/Driver/Options.td
Original file line number Diff line number Diff line change
Expand Up @@ -8481,8 +8481,8 @@ def pic_is_pie : Flag<["-"], "pic-is-pie">,
MarshallingInfoFlag<LangOpts<"PIE">>;

def mframe_pointer_EQ : Joined<["-"], "mframe-pointer=">,
HelpText<"Specify which frame pointers to retain.">, Values<"all,non-leaf,reserved,none">,
NormalizedValuesScope<"CodeGenOptions::FramePointerKind">, NormalizedValues<["All", "NonLeaf", "Reserved", "None"]>,
HelpText<"Specify which frame pointers to retain.">, Values<"all,non-leaf,non-leaf-no-reserve,reserved,none">,
NormalizedValuesScope<"CodeGenOptions::FramePointerKind">, NormalizedValues<["All", "NonLeaf", "NonLeafNoReserve", "Reserved", "None"]>,
MarshallingInfoEnum<CodeGenOpts<"FramePointer">, "None">;


Expand Down
1 change: 1 addition & 0 deletions clang/lib/CodeGen/CGCall.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1990,6 +1990,7 @@ static void getTrivialDefaultFunctionAttributes(
// This is the default behavior.
break;
case CodeGenOptions::FramePointerKind::Reserved:
case CodeGenOptions::FramePointerKind::NonLeafNoReserve:
case CodeGenOptions::FramePointerKind::NonLeaf:
case CodeGenOptions::FramePointerKind::All:
FuncAttrs.addAttribute("frame-pointer",
Expand Down
3 changes: 3 additions & 0 deletions clang/lib/CodeGen/CodeGenModule.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1506,6 +1506,9 @@ void CodeGenModule::Release() {
case CodeGenOptions::FramePointerKind::Reserved:
getModule().setFramePointer(llvm::FramePointerKind::Reserved);
break;
case CodeGenOptions::FramePointerKind::NonLeafNoReserve:
getModule().setFramePointer(llvm::FramePointerKind::NonLeafNoReserve);
break;
case CodeGenOptions::FramePointerKind::NonLeaf:
getModule().setFramePointer(llvm::FramePointerKind::NonLeaf);
break;
Expand Down
3 changes: 3 additions & 0 deletions clang/lib/Driver/ToolChains/Clang.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5748,6 +5748,9 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
case CodeGenOptions::FramePointerKind::Reserved:
FPKeepKindStr = "-mframe-pointer=reserved";
break;
case CodeGenOptions::FramePointerKind::NonLeafNoReserve:
FPKeepKindStr = "-mframe-pointer=non-leaf-no-reserve";
break;
case CodeGenOptions::FramePointerKind::NonLeaf:
FPKeepKindStr = "-mframe-pointer=non-leaf";
break;
Expand Down
44 changes: 30 additions & 14 deletions clang/lib/Driver/ToolChains/CommonArgs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -222,26 +222,38 @@ static bool framePointerImpliesLeafFramePointer(const llvm::opt::ArgList &Args,
clang::CodeGenOptions::FramePointerKind
getFramePointerKind(const llvm::opt::ArgList &Args,
const llvm::Triple &Triple) {
// There are three things to consider here:
// There are four things to consider here:
// * Should a frame record be created for non-leaf functions?
// * Should a frame record be created for leaf functions?
// * Is the frame pointer register reserved, i.e. must it always point to
// either a new, valid frame record or be un-modified?
// * Is the frame pointer register reserved in non-leaf functions?
// i.e. must it always point to either a new, valid frame record or be
// un-modified?
// * Is the frame pointer register reserved in leaf functions?
//
// Not all combinations of these are valid:
// * It's not useful to have leaf frame records without non-leaf ones.
// * It's not useful to have frame records without reserving the frame
// pointer.
//
// | Non-leaf | Leaf | Reserved |
// | N | N | N | FramePointerKind::None
// | N | N | Y | FramePointerKind::Reserved
// | N | Y | N | Invalid
// | N | Y | Y | Invalid
// | Y | N | N | Invalid
// | Y | N | Y | FramePointerKind::NonLeaf
// | Y | Y | N | Invalid
// | Y | Y | Y | FramePointerKind::All
// | Non-leaf | Leaf | Reserved In Non-Leaf | Reserved In Leaf |
// |----------|------|-----------------------|------------------|
// | N | N | N | N |
// FramePointerKind::None | N | N | N | Y |
// Invalid | N | N | Y | N |
// Invalid | N | N | Y | Y |
// FramePointerKind::Reserved | N | Y | N | N |
// Invalid | N | Y | N | Y |
// Invalid | N | Y | Y | N |
// Invalid | N | Y | Y | Y |
// Invalid | Y | N | N | N |
// Invalid | Y | N | N | Y |
// Invalid | Y | N | Y | N |
// FramePointerKind::NonLeafNoReserve | Y | N | Y | Y |
// FramePointerKind::NonLeaf | Y | Y | N | N |
// Invalid | Y | Y | N | Y |
// Invalid | Y | Y | Y | N |
// Invalid | Y | Y | Y | Y |
// FramePointerKind::All
//
// The FramePointerKind::Reserved case is currently only reachable for Arm,
// which has the -mframe-chain= option which can (in combination with
Expand All @@ -261,12 +273,16 @@ getFramePointerKind(const llvm::opt::ArgList &Args,
clang::driver::options::OPT_mno_omit_leaf_frame_pointer,
clang::driver::options::OPT_momit_leaf_frame_pointer, DefaultLeafFP);

bool FPRegReserved = EnableFP || mustMaintainValidFrameChain(Args, Triple);
bool FPRegReserved = mustMaintainValidFrameChain(Args, Triple);

if (EnableFP) {
if (EnableLeafFP)
return clang::CodeGenOptions::FramePointerKind::All;
return clang::CodeGenOptions::FramePointerKind::NonLeaf;

if (FPRegReserved)
return clang::CodeGenOptions::FramePointerKind::NonLeaf;

return clang::CodeGenOptions::FramePointerKind::NonLeafNoReserve;
}
if (FPRegReserved)
return clang::CodeGenOptions::FramePointerKind::Reserved;
Expand Down
3 changes: 3 additions & 0 deletions clang/lib/Driver/ToolChains/Flang.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1064,6 +1064,9 @@ void Flang::ConstructJob(Compilation &C, const JobAction &JA,
case CodeGenOptions::FramePointerKind::Reserved:
FPKeepKindStr = "-mframe-pointer=reserved";
break;
case CodeGenOptions::FramePointerKind::NonLeafNoReserve:
FPKeepKindStr = "-mframe-pointer=non-leaf-no-reserve";
break;
case CodeGenOptions::FramePointerKind::NonLeaf:
FPKeepKindStr = "-mframe-pointer=non-leaf";
break;
Expand Down
8 changes: 4 additions & 4 deletions clang/test/Driver/frame-pointer-elim.c
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// KEEP-ALL-NOT: warning: argument unused
// KEEP-ALL: "-mframe-pointer=all"
// KEEP-NON-LEAF-NOT: warning: argument unused
// KEEP-NON-LEAF: "-mframe-pointer=non-leaf"
// KEEP-NON-LEAF: "-mframe-pointer=non-leaf-no-reserve"
// KEEP-NONE-NOT: warning: argument unused
// KEEP-NONE: "-mframe-pointer=none"
// KEEP-RESERVED-NOT: warning: argument unused
Expand Down Expand Up @@ -73,17 +73,17 @@
// RUN: %clang -### -target armv7s-apple-ios -fomit-frame-pointer %s 2>&1 | \
// RUN: FileCheck --check-prefix=WARN-OMIT-7S %s
// WARN-OMIT-7S: warning: optimization flag '-fomit-frame-pointer' is not supported for target 'armv7s'
// WARN-OMIT-7S: "-mframe-pointer=non-leaf"
// WARN-OMIT-7S: "-mframe-pointer=non-leaf-no-reserve"

// RUN: %clang -### -target armv7k-apple-watchos -fomit-frame-pointer %s 2>&1 | \
// RUN: FileCheck --check-prefix=WARN-OMIT-7K %s
// WARN-OMIT-7K: warning: optimization flag '-fomit-frame-pointer' is not supported for target 'armv7k'
// WARN-OMIT-7K: "-mframe-pointer=non-leaf"
// WARN-OMIT-7K: "-mframe-pointer=non-leaf-no-reserve"

// RUN: %clang -### -target armv7s-apple-ios8.0 -momit-leaf-frame-pointer %s 2>&1 | \
// RUN: FileCheck --check-prefix=WARN-OMIT-LEAF-7S %s
// WARN-OMIT-LEAF-7S-NOT: warning: optimization flag '-momit-leaf-frame-pointer' is not supported for target 'armv7s'
// WARN-OMIT-LEAF-7S: "-mframe-pointer=non-leaf"
// WARN-OMIT-LEAF-7S: "-mframe-pointer=non-leaf-no-reserve"

// On AArch64, PS4, PS5, and VE, default to omitting the frame pointer on leaf
// functions
Expand Down
2 changes: 1 addition & 1 deletion clang/test/Driver/fuchsia.c
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@
// RUN: %clang -### %s --target=aarch64-unknown-fuchsia -O3 2>&1 \
// RUN: | FileCheck %s -check-prefix=CHECK-FP-NONE
// CHECK-FP-ALL: "-mframe-pointer=all"
// CHECK-FP-NONLEAF: "-mframe-pointer=non-leaf"
// CHECK-FP-NONLEAF: "-mframe-pointer=non-leaf-no-reserve"
// CHECK-FP-NONE: "-mframe-pointer=none"

// RUN: not %clang -### %s --target=x86_64-unknown-fuchsia -rtlib=libgcc 2>&1 \
Expand Down
8 changes: 7 additions & 1 deletion llvm/include/llvm/Support/CodeGen.h
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,13 @@ namespace llvm {
};

// Specify what functions should keep the frame pointer.
enum class FramePointerKind { None, NonLeaf, All, Reserved };
enum class FramePointerKind {
None,
NonLeaf,
All,
Reserved,
NonLeafNoReserve
};

// Specify what type of zeroing callee-used registers.
namespace ZeroCallUsedRegs {
Expand Down
5 changes: 5 additions & 0 deletions llvm/lib/CodeGen/CommandFlags.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,9 @@ codegen::RegisterCodeGenFlags::RegisterCodeGenFlags() {
clEnumValN(FramePointerKind::All, "all",
"Disable frame pointer elimination"),
clEnumValN(FramePointerKind::NonLeaf, "non-leaf",
"Disable frame pointer elimination for non-leaf frame but "
"reserve the register in leaf functions"),
clEnumValN(FramePointerKind::NonLeafNoReserve, "non-leaf-no-reserve",
"Disable frame pointer elimination for non-leaf frame"),
clEnumValN(FramePointerKind::Reserved, "reserved",
"Enable frame pointer elimination, but reserve the frame "
Expand Down Expand Up @@ -695,6 +698,8 @@ void codegen::setFunctionAttributes(StringRef CPU, StringRef Features,
NewAttrs.addAttribute("frame-pointer", "all");
else if (getFramePointerUsage() == FramePointerKind::NonLeaf)
NewAttrs.addAttribute("frame-pointer", "non-leaf");
else if (getFramePointerUsage() == FramePointerKind::NonLeafNoReserve)
NewAttrs.addAttribute("frame-pointer", "non-leaf-no-reserve");
else if (getFramePointerUsage() == FramePointerKind::Reserved)
NewAttrs.addAttribute("frame-pointer", "reserved");
else if (getFramePointerUsage() == FramePointerKind::None)
Expand Down
3 changes: 2 additions & 1 deletion llvm/lib/CodeGen/TargetOptionsImpl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ bool TargetOptions::DisableFramePointerElim(const MachineFunction &MF) const {
StringRef FP = FPAttr.getValueAsString();
if (FP == "all")
return true;
if (FP == "non-leaf")
if (FP == "non-leaf" || FP == "non-leaf-no-reserve")
return MF.getFrameInfo().hasCalls();
if (FP == "none" || FP == "reserved")
return false;
Expand All @@ -45,6 +45,7 @@ bool TargetOptions::FramePointerIsReserved(const MachineFunction &MF) const {

return StringSwitch<bool>(FPAttr.getValueAsString())
.Cases("all", "non-leaf", "reserved", true)
.Case(("non-leaf-no-reserve"), MF.getFrameInfo().hasCalls())
.Case("none", false);
}

Expand Down
3 changes: 3 additions & 0 deletions llvm/lib/IR/Function.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -396,6 +396,9 @@ Function *Function::createWithDefaultAttr(FunctionType *Ty,
case FramePointerKind::NonLeaf:
B.addAttribute("frame-pointer", "non-leaf");
break;
case FramePointerKind::NonLeafNoReserve:
B.addAttribute("frame-pointer", "non-leaf-no-reserve");
break;
case FramePointerKind::All:
B.addAttribute("frame-pointer", "all");
break;
Expand Down
3 changes: 2 additions & 1 deletion llvm/lib/IR/Verifier.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2484,7 +2484,8 @@ void Verifier::verifyFunctionAttrs(FunctionType *FT, AttributeList Attrs,

if (Attribute FPAttr = Attrs.getFnAttr("frame-pointer"); FPAttr.isValid()) {
StringRef FP = FPAttr.getValueAsString();
if (FP != "all" && FP != "non-leaf" && FP != "none" && FP != "reserved")
if (FP != "all" && FP != "non-leaf" && FP != "none" && FP != "reserved" &&
FP != "non-leaf-no-reserve")
CheckFailed("invalid value for 'frame-pointer' attribute: " + FP, V);
}

Expand Down
Loading
Loading