// RUN: %target-swift-frontend -primary-file %s -emit-ir | %FileCheck %s -check-prefix CHECK --check-prefix=CHECK-%target-abi --check-prefix=CHECK-%target-abi-%target-os // RUN: %target-swift-frontend -primary-file %s -emit-ir -Xcc -mno-omit-leaf-frame-pointer | %FileCheck %s -check-prefix CHECK-ALL --check-prefix=CHECK-%target-abi-ALL // RUN: %target-swift-frontend -primary-file %s -S | %FileCheck %s --check-prefix=CHECKASM --check-prefix=CHECKASM-%target-os-%target-cpu // RUN: %target-swift-frontend -primary-file %s -emit-ir -Xcc -momit-leaf-frame-pointer | %FileCheck %s -check-prefix LEAF --check-prefix=LEAF-%target-abi // RUN: %target-swift-frontend -primary-file %s -emit-ir -Xcc -fomit-frame-pointer | %FileCheck %s --check-prefix=NOFP // REQUIRES: CPU=x86_64 sil_stage canonical import Swift sil @leaf_function_no_frame_pointer : $@convention(thin) (Int32) -> Int32 { entry(%i : $Int32): return %i : $Int32 } sil @non_leaf_function_with_frame_pointer : $@convention(thin) (Int32) -> Int32 { entry(%i : $Int32): %f = function_ref @leaf_function_no_frame_pointer : $@convention(thin) (Int32) -> Int32 %r = apply %f(%i) : $@convention(thin) (Int32) -> Int32 return %r : $Int32 } // CHECK: define{{.*}} swiftcc i32 @leaf_function_no_frame_pointer(i32 %0) [[ATTR:#.*]] { // CHECK: entry: // CHECK: ret i32 %0 // CHECK: } // CHECK: define{{.*}} swiftcc i32 @non_leaf_function_with_frame_pointer(i32 %0) [[ATTR]] { // CHECK: entry: // CHECK: %1 = call swiftcc i32 @leaf_function_no_frame_pointer(i32 %0) // CHECK: ret i32 %1 // CHECK-SYSV: } // CHECK-SYSV-macosx: attributes [[ATTR]] = { {{.*}}"frame-pointer"="all" // CHECK-SYSV-linux-gnu: attributes [[ATTR]] = { {{.*}}"frame-pointer"="all" // CHECK-SYSV-linux-android: attributes [[ATTR]] = { {{.*}}"frame-pointer"="non-leaf" // CHECK-WIN: } // CHECK-WIN: attributes [[ATTR]] = { {{.*}} // CHECK-ALL: define{{.*}} swiftcc i32 @leaf_function_no_frame_pointer(i32 %0) [[ATTR:#.*]] { // CHECK-ALL: entry: // CHECK-ALL: ret i32 %0 // CHECK-ALL: } // CHECK-ALL: define{{.*}} swiftcc i32 @non_leaf_function_with_frame_pointer(i32 %0) [[ATTR]] { // CHECK-ALL: entry: // CHECK-ALL: %1 = call swiftcc i32 @leaf_function_no_frame_pointer(i32 %0) // CHECK-ALL: ret i32 %1 // CHECK-ALL: } // CHECK-SYSV-ALL: attributes [[ATTR]] = {{{.*}}"frame-pointer"="all" // CHECK-WIN-ALL: attributes [[ATTR]] = {{{.*}} // LEAF: define{{.*}} swiftcc i32 @leaf_function_no_frame_pointer(i32 %0) [[ATTR:#.*]] { // LEAF: entry: // LEAF: ret i32 %0 // LEAF: } // LEAF: define{{.*}} swiftcc i32 @non_leaf_function_with_frame_pointer(i32 %0) [[ATTR]] { // LEAF: entry: // LEAF: %1 = call swiftcc i32 @leaf_function_no_frame_pointer(i32 %0) // LEAF: ret i32 %1 // LEAF: } // LEAF-SYSV: attributes [[ATTR]] = {{{.*}}"frame-pointer"="non-leaf" // LEAF-WIN: attributes [[ATTR]] = {{{.*}} // NOFP: define{{.*}} swiftcc i32 @leaf_function_no_frame_pointer(i32 %0) [[ATTR:#.*]] { // NOFP: entry: // NOFP: ret i32 %0 // NOFP: } // NOFP: define{{.*}} swiftcc i32 @non_leaf_function_with_frame_pointer(i32 %0) [[ATTR]] { // NOFP: entry: // NOFP: %1 = call swiftcc i32 @leaf_function_no_frame_pointer(i32 %0) // NOFP: ret i32 %1 // NOFP: } // The clang frontend's -fomit-frame-pointer no longer leads to frame-pointer=none // attributes [[ATTR]] = {{{.*}} // Silence other os-archs. // CHECKASM: {{.*}} // CHECKASM-macosx-x86_64-LABEL: _leaf_function_no_frame_pointer: // CHECKASM-macosx-x86_64: push // CHECKASM-macosx-x86_64: movl %edi, %eax // CHECKASM-macosx-x86_64: pop // CHECKASM-macosx-x86_64: ret // CHECKASM-macosx-x86_64-LABEL: _non_leaf_function_with_frame_pointer: // CHECKASM-macosx-x86_64: pushq %rbp // CHECKASM-macosx-x86_64: movq %rsp, %rbp // CHECKASM-macosx-x86_64: callq _leaf_function_no_frame_pointer // CHECKASM-macosx-x86_64: popq %rbp // CHECKASM-macosx-x86_64: ret