Skip to content

Expose function sections option #28088

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Jan 13, 2020
Merged
Show file tree
Hide file tree
Changes from all 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
5 changes: 4 additions & 1 deletion include/swift/AST/IRGenOptions.h
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,9 @@ class IRGenOptions {
/// objects.
unsigned EmitStackPromotionChecks : 1;

/// Emit functions to separate sections.
unsigned FunctionSections : 1;

/// The maximum number of bytes used on a stack frame for stack promotion
/// (includes alloc_stack allocations).
unsigned StackPromotionSizeLimit = 1024;
Expand Down Expand Up @@ -249,7 +252,7 @@ class IRGenOptions {
IntegratedREPL(false), DisableLLVMOptzns(false),
DisableSwiftSpecificLLVMOptzns(false), DisableLLVMSLPVectorizer(false),
DisableFPElim(true), Playground(false), EmitStackPromotionChecks(false),
PrintInlineTree(false), EmbedMode(IRGenEmbedMode::None),
FunctionSections(false), PrintInlineTree(false), EmbedMode(IRGenEmbedMode::None),
HasValueNamesSetting(false), ValueNames(false),
EnableReflectionMetadata(true), EnableReflectionNames(true),
EnableAnonymousContextMangledNames(false), ForcePublicLinkage(false),
Expand Down
4 changes: 4 additions & 0 deletions include/swift/Option/FrontendOptions.td
Original file line number Diff line number Diff line change
Expand Up @@ -334,6 +334,10 @@ def disable_reflection_names : Flag<["-"], "disable-reflection-names">,
HelpText<"Disable emission of names of stored properties and enum cases in"
"reflection metadata">;

def function_sections: Flag<["-"], "function-sections">,
Flags<[FrontendOption, NoInteractiveOption]>,
HelpText<"Emit functions to separate sections.">;

def stack_promotion_checks : Flag<["-"], "emit-stack-promotion-checks">,
HelpText<"Emit runtime checks for correct stack promotion of objects.">;

Expand Down
2 changes: 2 additions & 0 deletions lib/Frontend/CompilerInvocation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1136,6 +1136,8 @@ static bool ParseIRGenArgs(IRGenOptions &Opts, ArgList &Args,
Opts.StackPromotionSizeLimit = limit;
}

Opts.FunctionSections = Args.hasArg(OPT_function_sections);

if (Args.hasArg(OPT_autolink_force_load))
Opts.ForceLoadSymbolName = Args.getLastArgValue(OPT_module_link_name);

Expand Down
1 change: 1 addition & 0 deletions lib/IRGen/IRGen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,7 @@ swift::getIRTargetOptions(IRGenOptions &Opts, ASTContext &Ctx) {
// Explicitly request debugger tuning for LLDB which is the default
// on Darwin platforms but not on others.
TargetOpts.DebuggerTuning = llvm::DebuggerKind::LLDB;
TargetOpts.FunctionSections = Opts.FunctionSections;

auto *Clang = static_cast<ClangImporter *>(Ctx.getClangModuleLoader());
clang::TargetOptions &ClangOpts = Clang->getTargetInfo().getTargetOpts();
Expand Down
5 changes: 5 additions & 0 deletions test/LinkerSections/Inputs/FunctionSections.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
public typealias Void = ()

public func func1() -> Void {}

public func func2() -> Void {}
3 changes: 3 additions & 0 deletions test/LinkerSections/Inputs/FunctionSectionsUse.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import FunctionSections

func1()
10 changes: 10 additions & 0 deletions test/LinkerSections/function_sections.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
// REQUIRES: OS=linux-gnu || OS=linux-androideabi || OS=linux-android || OS=freebsd
Copy link
Member

Choose a reason for hiding this comment

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

Can we use %target-object-format and compare it to ELF instead?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Not in the REQUIRES directive:

ValueError: couldn't parse text: '%target-object-format=elf'
in expression: '%target-object-format=elf'
in REQUIRES: directive on test line 1

If there is another way to limit it to ELF, that'd be cool.

Copy link
Member

Choose a reason for hiding this comment

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

That is rather unfortunate. Out of curiosity, what happens if you use -function-sections on MachO or PE/COFF? I'm wondering if we should actually prevent that in the driver. Apple's usage of MachO actually uses .subsections_via_symbols which means that everything is atomized and you effectively are doing -function-sections, and PE/COFF's symbol resolution is pretty close to this already.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I don't have easy access to the other platforms. Also, is the linker / the map file format the same, at this point?

Copy link
Member

Choose a reason for hiding this comment

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

The linker map is linker dependent unfortunately.

// RUN: %empty-directory(%t)
// RUN: %target-build-swift -Xfrontend -function-sections -emit-module -emit-library -static -parse-stdlib %S/Inputs/FunctionSections.swift
// RUN: %target-build-swift -Xlinker --gc-sections -Xlinker -Map=%t/../../FunctionSections.map -I%t/../.. -L%t/../.. -lFunctionSections %S/Inputs/FunctionSectionsUse.swift
// RUN: %FileCheck %s < %t/../../FunctionSections.map

// CHECK: Discarded input sections
// CHECK: .text.$s16FunctionSections5func2yyF
// CHECK: Memory map
// CHECK: .text.$s16FunctionSections5func1yyF
12 changes: 12 additions & 0 deletions test/LinkerSections/function_sections_ir_check.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
// RUN: %empty-directory(%t)
// RUN: %target-build-swift -Xfrontend -function-sections -emit-library -emit-ir -static -parse-stdlib %S/Inputs/FunctionSections.swift | %FileCheck %s

// CHECK: define {{(dllexport |protected )?}}swiftcc void @"$s16FunctionSections5func1yyF"() #0 {
// CHECK: entry:
// CHECK: ret void
// CHECK: }

// CHECK: define {{(dllexport |protected )?}}swiftcc void @"$s16FunctionSections5func2yyF"() #0 {
// CHECK: entry:
// CHECK: ret void
// CHECK: }