Skip to content

Commit 617f1c3

Browse files
committed
Only use omit the frame pointer on arm64, x86_64 darwin needs it for some its tools
1 parent e6f0cbc commit 617f1c3

File tree

4 files changed

+111
-23
lines changed

4 files changed

+111
-23
lines changed

lib/IRGen/IRGenModule.cpp

Lines changed: 31 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -91,32 +91,33 @@ static llvm::PointerType *createStructPointerType(IRGenModule &IGM,
9191
};
9292

9393
static clang::CodeGenOptions::FramePointerKind
94-
shouldUseFramePointer(const IRGenOptions &Opts) {
94+
shouldUseFramePointer(const IRGenOptions &Opts, const llvm::Triple &triple) {
9595
if (Opts.DisableFPElim) {
9696
// General frame pointer elimination is disabled.
9797
// Should we at least eliminate in leaf functions?
98+
// Currently we only do that on arm64 (this matches the behavior of clang).
9899
return Opts.DisableFPElimLeaf
99100
? clang::CodeGenOptions::FramePointerKind::All
100-
: clang::CodeGenOptions::FramePointerKind::NonLeaf;
101+
: triple.isAArch64()
102+
? clang::CodeGenOptions::FramePointerKind::NonLeaf
103+
: clang::CodeGenOptions::FramePointerKind::All;
101104
}
102105

103106
return clang::CodeGenOptions::FramePointerKind::None;
104-
105107
}
106108

107-
static clang::CodeGenerator *createClangCodeGenerator(ASTContext &Context,
108-
llvm::LLVMContext &LLVMContext,
109-
const IRGenOptions &Opts,
110-
StringRef ModuleName,
111-
StringRef PD) {
109+
static clang::CodeGenerator *
110+
createClangCodeGenerator(ASTContext &Context, llvm::LLVMContext &LLVMContext,
111+
const IRGenOptions &Opts, StringRef ModuleName,
112+
StringRef PD, const llvm::Triple &triple) {
112113
auto Loader = Context.getClangModuleLoader();
113114
auto *Importer = static_cast<ClangImporter*>(&*Loader);
114115
assert(Importer && "No clang module loader!");
115116
auto &ClangContext = Importer->getClangASTContext();
116117

117118
auto &CGO = Importer->getClangCodeGenOpts();
118119
CGO.OptimizationLevel = Opts.shouldOptimize() ? 3 : 0;
119-
CGO.setFramePointer(shouldUseFramePointer(Opts));
120+
CGO.setFramePointer(shouldUseFramePointer(Opts, triple));
120121
CGO.DiscardValueNames = !Opts.shouldProvideValueNames();
121122
switch (Opts.DebugInfoLevel) {
122123
case IRGenDebugInfoLevel::None:
@@ -206,17 +207,17 @@ static void sanityCheckStdlib(IRGenModule &IGM) {
206207

207208
IRGenModule::IRGenModule(IRGenerator &irgen,
208209
std::unique_ptr<llvm::TargetMachine> &&target,
209-
SourceFile *SF,
210-
StringRef ModuleName, StringRef OutputFilename,
210+
SourceFile *SF, StringRef ModuleName,
211+
StringRef OutputFilename,
211212
StringRef MainInputFilenameForDebugInfo,
212213
StringRef PrivateDiscriminator)
213-
: LLVMContext(new llvm::LLVMContext()),
214-
IRGen(irgen), Context(irgen.SIL.getASTContext()),
214+
: LLVMContext(new llvm::LLVMContext()), IRGen(irgen),
215+
Context(irgen.SIL.getASTContext()),
215216
// The LLVMContext (and the IGM itself) will get deleted by the IGMDeleter
216217
// as long as the IGM is registered with the IRGenerator.
217-
ClangCodeGen(createClangCodeGenerator(Context, *LLVMContext,
218-
irgen.Opts,
219-
ModuleName, PrivateDiscriminator)),
218+
ClangCodeGen(createClangCodeGenerator(Context, *LLVMContext, irgen.Opts,
219+
ModuleName, PrivateDiscriminator,
220+
irgen.getEffectiveClangTriple())),
220221
Module(*ClangCodeGen->GetModule()),
221222
DataLayout(irgen.getClangDataLayout()),
222223
Triple(irgen.getEffectiveClangTriple()), TargetMachine(std::move(target)),
@@ -1000,8 +1001,20 @@ bool swift::irgen::shouldRemoveTargetFeature(StringRef feature) {
10001001

10011002
void IRGenModule::setHasFramePointer(llvm::AttrBuilder &Attrs,
10021003
bool HasFramePointer) {
1003-
auto UseFramePointer = IRGen.Opts.DisableFPElimLeaf ? "all" : "non-leaf";
1004-
Attrs.addAttribute("frame-pointer", HasFramePointer ? UseFramePointer : "none");
1004+
if (!HasFramePointer) {
1005+
Attrs.addAttribute("frame-pointer", "none");
1006+
return;
1007+
}
1008+
if (IRGen.Opts.DisableFPElimLeaf) {
1009+
Attrs.addAttribute("frame-pointer", "all");
1010+
return;
1011+
}
1012+
1013+
// We omit frame pointers for leaf functions only for arm64 for now (matching
1014+
// clang's behavior).
1015+
auto framePointer =
1016+
IRGen.getEffectiveClangTriple().isAArch64() ? "non-leaf" : "all";
1017+
Attrs.addAttribute("frame-pointer", framePointer);
10051018
}
10061019

10071020
void IRGenModule::setHasFramePointer(llvm::Function *F,

test/IRGen/c_globals.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,5 +31,5 @@ public func testCaptureGlobal() {
3131
}) // CHECK: {{^}$}}
3232
}
3333

34-
// CHECK-DAG: attributes [[CLANG_FUNC_ATTR]] = { noinline nounwind {{.*}}"frame-pointer"="non-leaf"{{.*}}
35-
// CHECK-DAG: attributes [[SWIFT_FUNC_ATTR]] = { {{.*}}"frame-pointer"="non-leaf" {{.*}}"target-cpu"
34+
// CHECK-DAG: attributes [[CLANG_FUNC_ATTR]] = { noinline nounwind {{.*}}"frame-pointer"="all"{{.*}}
35+
// CHECK-DAG: attributes [[SWIFT_FUNC_ATTR]] = { {{.*}}"frame-pointer"="all" {{.*}}"target-cpu"

test/IRGen/framepointer.sil

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
// RUN: %target-swift-frontend -primary-file %s -emit-ir -no-omit-leaf-frame-pointer| %FileCheck %s --check-prefix=CHECK-ALL
33
// RUN: %target-swift-frontend -primary-file %s -S | %FileCheck %s --check-prefix=CHECKASM --check-prefix=CHECKASM-%target-os-%target-cpu
44

5+
// REQUIRES: CPU=x86_64
6+
57
sil_stage canonical
68

79
import Swift
@@ -29,7 +31,7 @@ entry(%i : $Int32):
2931
// CHECK: ret i32 %1
3032
// CHECK: }
3133

32-
// CHECK: attributes [[ATTR]] = {{{.*}}"frame-pointer"="non-leaf"
34+
// CHECK: attributes [[ATTR]] = {{{.*}}"frame-pointer"="all"
3335

3436
// CHECK-ALL: define{{.*}} swiftcc i32 @leaf_function_no_frame_pointer(i32 %0) [[ATTR:#.*]] {
3537
// CHECK-ALL: entry:
@@ -48,9 +50,9 @@ entry(%i : $Int32):
4850
// CHECKASM: {{.*}}
4951

5052
// CHECKASM-macosx-x86_64-LABEL: _leaf_function_no_frame_pointer:
51-
// CHECKASM-macosx-x86_64-NOT: push
53+
// CHECKASM-macosx-x86_64: push
5254
// CHECKASM-macosx-x86_64: movl %edi, %eax
53-
// CHECKASM-macosx-x86_64-NOT: pop
55+
// CHECKASM-macosx-x86_64: pop
5456
// CHECKASM-macosx-x86_64: ret
5557

5658

test/IRGen/framepointer_arm64.sil

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
// RUN: %target-swift-frontend -target arm64-apple-ios8.0 -primary-file %s -emit-ir | %FileCheck %s --check-prefix=CHECK
2+
// RUN: %target-swift-frontend -target arm64-apple-ios8.0 -primary-file %s -emit-ir -no-omit-leaf-frame-pointer| %FileCheck %s --check-prefix=CHECK-ALL
3+
// RUN: %target-swift-frontend -target arm64-apple-ios8.0 -primary-file %s -S | %FileCheck %s --check-prefix=CHECKASM
4+
// RUN: %target-swift-frontend -target arm64-apple-ios8.0 -primary-file %s -S -no-omit-leaf-frame-pointer | %FileCheck %s --check-prefix=CHECKASM-ALL
5+
6+
// REQUIRES: CODEGENERATOR=AArch64
7+
8+
// UNSUPPORTED: OS=linux
9+
// UNSUPPORTED: OS=windows
10+
11+
sil_stage canonical
12+
13+
import Swift
14+
15+
sil @leaf_function_no_frame_pointer : $@convention(thin) (Int32) -> Int32 {
16+
entry(%i : $Int32):
17+
return %i : $Int32
18+
}
19+
20+
sil @non_leaf_function_with_frame_pointer : $@convention(thin) (Int32) -> Int32 {
21+
entry(%i : $Int32):
22+
%f = function_ref @leaf_function_no_frame_pointer : $@convention(thin) (Int32) -> Int32
23+
%r = apply %f(%i) : $@convention(thin) (Int32) -> Int32
24+
return %r : $Int32
25+
}
26+
27+
// CHECK: define{{.*}} swiftcc i32 @leaf_function_no_frame_pointer(i32 %0) [[ATTR:#.*]] {
28+
// CHECK: entry:
29+
// CHECK: ret i32 %0
30+
// CHECK: }
31+
32+
// CHECK: define{{.*}} swiftcc i32 @non_leaf_function_with_frame_pointer(i32 %0) [[ATTR]] {
33+
// CHECK: entry:
34+
// CHECK: %1 = call swiftcc i32 @leaf_function_no_frame_pointer(i32 %0)
35+
// CHECK: ret i32 %1
36+
// CHECK: }
37+
38+
// CHECK: attributes [[ATTR]] = {{{.*}}"frame-pointer"="non-leaf"
39+
40+
// CHECK-ALL: define{{.*}} swiftcc i32 @leaf_function_no_frame_pointer(i32 %0) [[ATTR:#.*]] {
41+
// CHECK-ALL: entry:
42+
// CHECK-ALL: ret i32 %0
43+
// CHECK-ALL: }
44+
45+
// CHECK-ALL: define{{.*}} swiftcc i32 @non_leaf_function_with_frame_pointer(i32 %0) [[ATTR]] {
46+
// CHECK-ALL: entry:
47+
// CHECK-ALL: %1 = call swiftcc i32 @leaf_function_no_frame_pointer(i32 %0)
48+
// CHECK-ALL: ret i32 %1
49+
// CHECK-ALL: }
50+
51+
// CHECK-ALL: attributes [[ATTR]] = {{{.*}}"frame-pointer"="all"
52+
53+
// CHECKASM-LABEL: _leaf_function_no_frame_pointer:
54+
// CHECKASM-NOT: stp
55+
// CHECKASM-NOT: ldp
56+
// CHECKASM: ret
57+
58+
// CHECKASM-LABEL: _non_leaf_function_with_frame_pointer:
59+
// CHECKASM: stp
60+
// CHECKASM: _leaf_function_no_frame_pointer
61+
// CHECKASM: ldp
62+
// CHECKASM: ret
63+
64+
// CHECKASM-ALL-LABEL: _leaf_function_no_frame_pointer:
65+
// CHECKASM-ALL: stp
66+
// CHECKASM-ALL: ldp
67+
// CHECKASM-ALL: ret
68+
69+
// CHECKASM-ALL-LABEL: _non_leaf_function_with_frame_pointer:
70+
// CHECKASM-ALL: stp
71+
// CHECKASM-ALL: _leaf_function_no_frame_pointer
72+
// CHECKASM-ALL: ldp
73+
// CHECKASM-ALL: ret

0 commit comments

Comments
 (0)