Skip to content

Commit 1e141e8

Browse files
committed
[IR] Add target-independent option to preserve frame-pointer register
This adds a new value "reserved" to the "frame-pointer" function attribute. When this value is used, the frame pointer register must either be reserved, or updated to point to a new frame record, but must not be used for any other purpose. This is not yet supported by most targets, but will be used for the Arm -mframe-chain= option.
1 parent eea05c6 commit 1e141e8

File tree

13 files changed

+52
-8
lines changed

13 files changed

+52
-8
lines changed

clang/include/clang/Basic/CodeGenOptions.def

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ CODEGENOPT(SeparateNamedSections, 1, 0) ///< Set for -fseparate-named-sections.
6161
CODEGENOPT(EnableAIXExtendedAltivecABI, 1, 0) ///< Set for -mabi=vec-extabi. Enables the extended Altivec ABI on AIX.
6262
CODEGENOPT(XCOFFReadOnlyPointers, 1, 0) ///< Set for -mxcoff-roptr.
6363
CODEGENOPT(AllTocData, 1, 0) ///< AIX -mtocdata
64-
ENUM_CODEGENOPT(FramePointer, FramePointerKind, 2, FramePointerKind::None) /// frame-pointer: all,non-leaf,none
64+
ENUM_CODEGENOPT(FramePointer, FramePointerKind, 2, FramePointerKind::None) /// frame-pointer: all,non-leaf,reserved,none
6565

6666
CODEGENOPT(ClearASTBeforeBackend , 1, 0) ///< Free the AST before running backend code generation. Only works with -disable-free.
6767
CODEGENOPT(DisableFree , 1, 0) ///< Don't free memory.

clang/include/clang/Basic/CodeGenOptions.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,7 @@ class CodeGenOptions : public CodeGenOptionsBase {
128128

129129
enum class FramePointerKind {
130130
None, // Omit all frame pointers.
131+
Reserved, // Maintain valid frame pointer chain.
131132
NonLeaf, // Keep non-leaf frame pointers.
132133
All, // Keep all frame pointers.
133134
};
@@ -136,6 +137,8 @@ class CodeGenOptions : public CodeGenOptionsBase {
136137
switch (Kind) {
137138
case FramePointerKind::None:
138139
return "none";
140+
case FramePointerKind::Reserved:
141+
return "reserved";
139142
case FramePointerKind::NonLeaf:
140143
return "non-leaf";
141144
case FramePointerKind::All:

clang/include/clang/Driver/Options.td

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7706,8 +7706,8 @@ def pic_is_pie : Flag<["-"], "pic-is-pie">,
77067706
MarshallingInfoFlag<LangOpts<"PIE">>;
77077707

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

77137713

clang/lib/CodeGen/CGCall.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1917,6 +1917,7 @@ static void getTrivialDefaultFunctionAttributes(
19171917
case CodeGenOptions::FramePointerKind::None:
19181918
// This is the default behavior.
19191919
break;
1920+
case CodeGenOptions::FramePointerKind::Reserved:
19201921
case CodeGenOptions::FramePointerKind::NonLeaf:
19211922
case CodeGenOptions::FramePointerKind::All:
19221923
FuncAttrs.addAttribute("frame-pointer",

clang/lib/CodeGen/CodeGenModule.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1328,6 +1328,9 @@ void CodeGenModule::Release() {
13281328
case CodeGenOptions::FramePointerKind::None:
13291329
// 0 ("none") is the default.
13301330
break;
1331+
case CodeGenOptions::FramePointerKind::Reserved:
1332+
getModule().setFramePointer(llvm::FramePointerKind::Reserved);
1333+
break;
13311334
case CodeGenOptions::FramePointerKind::NonLeaf:
13321335
getModule().setFramePointer(llvm::FramePointerKind::NonLeaf);
13331336
break;

clang/lib/Driver/ToolChains/Clang.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5678,6 +5678,9 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
56785678
case CodeGenOptions::FramePointerKind::None:
56795679
FPKeepKindStr = "-mframe-pointer=none";
56805680
break;
5681+
case CodeGenOptions::FramePointerKind::Reserved:
5682+
FPKeepKindStr = "-mframe-pointer=reserved";
5683+
break;
56815684
case CodeGenOptions::FramePointerKind::NonLeaf:
56825685
FPKeepKindStr = "-mframe-pointer=non-leaf";
56835686
break;

llvm/docs/LangRef.rst

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1924,7 +1924,11 @@ example:
19241924
even if this attribute says the frame pointer can be eliminated.
19251925
The allowed string values are:
19261926

1927-
* ``"none"`` (default) - the frame pointer can be eliminated.
1927+
* ``"none"`` (default) - the frame pointer can be eliminated, and it's
1928+
register can be used for other purposes.
1929+
* ``"reserved"`` - the frame pointer register must either be updated to
1930+
point to a valid frame record for the current function, or not be
1931+
modified.
19281932
* ``"non-leaf"`` - the frame pointer should be kept if the function calls
19291933
other functions.
19301934
* ``"all"`` - the frame pointer should be kept.

llvm/include/llvm/Support/CodeGen.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ namespace llvm {
8787
};
8888

8989
// Specify what functions should keep the frame pointer.
90-
enum class FramePointerKind { None, NonLeaf, All };
90+
enum class FramePointerKind { None, NonLeaf, All, Reserved };
9191

9292
// Specify what type of zeroing callee-used registers.
9393
namespace ZeroCallUsedRegs {

llvm/include/llvm/Target/TargetOptions.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,11 @@ namespace llvm {
161161
/// optimization should be disabled for the given machine function.
162162
bool DisableFramePointerElim(const MachineFunction &MF) const;
163163

164+
/// FramePointerIsReserved - This returns true if the frame pointer must
165+
/// always either point to a new frame record or be un-modified in the given
166+
/// function.
167+
bool FramePointerIsReserved(const MachineFunction &MF) const;
168+
164169
/// If greater than 0, override the default value of
165170
/// MCAsmInfo::BinutilsVersion.
166171
std::pair<int, int> BinutilsVersion{0, 0};

llvm/lib/CodeGen/CommandFlags.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,9 @@ codegen::RegisterCodeGenFlags::RegisterCodeGenFlags() {
211211
"Disable frame pointer elimination"),
212212
clEnumValN(FramePointerKind::NonLeaf, "non-leaf",
213213
"Disable frame pointer elimination for non-leaf frame"),
214+
clEnumValN(FramePointerKind::Reserved, "reserved",
215+
"Enable frame pointer elimination, but reserve the frame "
216+
"pointer register"),
214217
clEnumValN(FramePointerKind::None, "none",
215218
"Enable frame pointer elimination")));
216219
CGBINDOPT(FramePointerUsage);
@@ -693,6 +696,8 @@ void codegen::setFunctionAttributes(StringRef CPU, StringRef Features,
693696
NewAttrs.addAttribute("frame-pointer", "all");
694697
else if (getFramePointerUsage() == FramePointerKind::NonLeaf)
695698
NewAttrs.addAttribute("frame-pointer", "non-leaf");
699+
else if (getFramePointerUsage() == FramePointerKind::Reserved)
700+
NewAttrs.addAttribute("frame-pointer", "reserved");
696701
else if (getFramePointerUsage() == FramePointerKind::None)
697702
NewAttrs.addAttribute("frame-pointer", "none");
698703
}

llvm/lib/CodeGen/TargetOptionsImpl.cpp

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
//
1111
//===----------------------------------------------------------------------===//
1212

13+
#include "llvm/ADT/StringSwitch.h"
1314
#include "llvm/CodeGen/MachineFrameInfo.h"
1415
#include "llvm/CodeGen/MachineFunction.h"
1516
#include "llvm/CodeGen/TargetFrameLowering.h"
@@ -21,7 +22,7 @@ using namespace llvm;
2122
/// DisableFramePointerElim - This returns true if frame pointer elimination
2223
/// optimization should be disabled for the given machine function.
2324
bool TargetOptions::DisableFramePointerElim(const MachineFunction &MF) const {
24-
// Check to see if the target want to forcably keep frame pointer.
25+
// Check to see if the target want to forcibly keep frame pointer.
2526
if (MF.getSubtarget().getFrameLowering()->keepFramePointer(MF))
2627
return true;
2728

@@ -34,11 +35,27 @@ bool TargetOptions::DisableFramePointerElim(const MachineFunction &MF) const {
3435
return true;
3536
if (FP == "non-leaf")
3637
return MF.getFrameInfo().hasCalls();
37-
if (FP == "none")
38+
if (FP == "none" || FP == "reserved")
3839
return false;
3940
llvm_unreachable("unknown frame pointer flag");
4041
}
4142

43+
bool TargetOptions::FramePointerIsReserved(const MachineFunction &MF) const {
44+
// Check to see if the target want to forcibly keep frame pointer.
45+
if (MF.getSubtarget().getFrameLowering()->keepFramePointer(MF))
46+
return true;
47+
48+
const Function &F = MF.getFunction();
49+
50+
if (!F.hasFnAttribute("frame-pointer"))
51+
return false;
52+
53+
StringRef FP = F.getFnAttribute("frame-pointer").getValueAsString();
54+
return StringSwitch<bool>(FP)
55+
.Cases("all", "non-leaf", "reserved", true)
56+
.Case("none", false);
57+
}
58+
4259
/// HonorSignDependentRoundingFPMath - Return true if the codegen must assume
4360
/// that the rounding mode of the FPU can change from its default.
4461
bool TargetOptions::HonorSignDependentRoundingFPMath() const {

llvm/lib/IR/Function.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -383,6 +383,9 @@ Function *Function::createWithDefaultAttr(FunctionType *Ty,
383383
case FramePointerKind::None:
384384
// 0 ("none") is the default.
385385
break;
386+
case FramePointerKind::Reserved:
387+
B.addAttribute("frame-pointer", "reserved");
388+
break;
386389
case FramePointerKind::NonLeaf:
387390
B.addAttribute("frame-pointer", "non-leaf");
388391
break;

llvm/lib/IR/Verifier.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2322,7 +2322,7 @@ void Verifier::verifyFunctionAttrs(FunctionType *FT, AttributeList Attrs,
23222322

23232323
if (Attrs.hasFnAttr("frame-pointer")) {
23242324
StringRef FP = Attrs.getFnAttr("frame-pointer").getValueAsString();
2325-
if (FP != "all" && FP != "non-leaf" && FP != "none")
2325+
if (FP != "all" && FP != "non-leaf" && FP != "none" && FP != "reserved")
23262326
CheckFailed("invalid value for 'frame-pointer' attribute: " + FP, V);
23272327
}
23282328

0 commit comments

Comments
 (0)