diff options
-rw-r--r-- | clang/include/clang/Basic/LangOptions.def | 2 | ||||
-rw-r--r-- | clang/include/clang/Driver/CC1Options.td | 2 | ||||
-rw-r--r-- | clang/include/clang/Driver/Options.td | 5 | ||||
-rw-r--r-- | clang/lib/CodeGen/CodeGenModule.cpp | 4 | ||||
-rw-r--r-- | clang/lib/Driver/ToolChains/Clang.cpp | 7 | ||||
-rw-r--r-- | clang/lib/Driver/ToolChains/CommonArgs.cpp | 34 | ||||
-rw-r--r-- | clang/lib/Driver/ToolChains/CommonArgs.h | 3 | ||||
-rw-r--r-- | clang/lib/Frontend/CompilerInvocation.cpp | 3 | ||||
-rw-r--r-- | clang/test/CodeGen/function-alignment.c | 16 | ||||
-rw-r--r-- | clang/test/Driver/clang_f_opts.c | 4 | ||||
-rw-r--r-- | clang/test/Driver/function-alignment.c | 17 |
11 files changed, 91 insertions, 6 deletions
diff --git a/clang/include/clang/Basic/LangOptions.def b/clang/include/clang/Basic/LangOptions.def index 029e6516c0a..e7d8302e5c5 100644 --- a/clang/include/clang/Basic/LangOptions.def +++ b/clang/include/clang/Basic/LangOptions.def @@ -292,6 +292,8 @@ ENUM_LANGOPT(ClangABICompat, ClangABI, 4, ClangABI::Latest, "version of Clang that we should attempt to be ABI-compatible " "with") +COMPATIBLE_VALUE_LANGOPT(FunctionAlignment, 5, 0, "Default alignment for functions") + #undef LANGOPT #undef COMPATIBLE_LANGOPT #undef BENIGN_LANGOPT diff --git a/clang/include/clang/Driver/CC1Options.td b/clang/include/clang/Driver/CC1Options.td index d6202a25b38..03b43ddd48f 100644 --- a/clang/include/clang/Driver/CC1Options.td +++ b/clang/include/clang/Driver/CC1Options.td @@ -645,6 +645,8 @@ def disable_objc_default_synthesize_properties : Flag<["-"], "disable-objc-defau HelpText<"disable the default synthesis of Objective-C properties">; def fencode_extended_block_signature : Flag<["-"], "fencode-extended-block-signature">, HelpText<"enable extended encoding of block type signature">; +def function_alignment : Separate<["-"], "function-alignment">, + HelpText<"default alignment for functions">; def pic_level : Separate<["-"], "pic-level">, HelpText<"Value for __PIC__">; def pic_is_pie : Flag<["-"], "pic-is-pie">, diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td index d8e784a8abb..99a438092be 100644 --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -611,6 +611,9 @@ def fno_PIC : Flag<["-"], "fno-PIC">, Group<f_Group>; def fPIE : Flag<["-"], "fPIE">, Group<f_Group>; def fno_PIE : Flag<["-"], "fno-PIE">, Group<f_Group>; def faccess_control : Flag<["-"], "faccess-control">, Group<f_Group>; +def falign_functions : Flag<["-"], "falign-functions">, Group<f_Group>; +def falign_functions_EQ : Joined<["-"], "falign-functions=">, Group<f_Group>; +def fno_align_functions: Flag<["-"], "fno-align-functions">, Group<f_Group>; def fallow_unsupported : Flag<["-"], "fallow-unsupported">, Group<f_Group>; def fapple_kext : Flag<["-"], "fapple-kext">, Group<f_Group>, Flags<[CC1Option]>, HelpText<"Use Apple's kernel extensions ABI">; @@ -2728,8 +2731,6 @@ def fprofile_dir : Joined<["-"], "fprofile-dir=">, Group<f_Group>; def fuse_ld_EQ : Joined<["-"], "fuse-ld=">, Group<f_Group>, Flags<[CoreOption]>; -defm align_functions : BooleanFFlag<"align-functions">, Group<clang_ignored_gcc_optimization_f_Group>; -def falign_functions_EQ : Joined<["-"], "falign-functions=">, Group<clang_ignored_gcc_optimization_f_Group>; defm align_labels : BooleanFFlag<"align-labels">, Group<clang_ignored_gcc_optimization_f_Group>; def falign_labels_EQ : Joined<["-"], "falign-labels=">, Group<clang_ignored_gcc_optimization_f_Group>; defm align_loops : BooleanFFlag<"align-loops">, Group<clang_ignored_gcc_optimization_f_Group>; diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index a21527abba1..17d9db3399f 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -1238,6 +1238,10 @@ void CodeGenModule::SetLLVMFunctionAttributesForDefinition(const Decl *D, if (alignment) F->setAlignment(alignment); + if (!D->hasAttr<AlignedAttr>()) + if (LangOpts.FunctionAlignment) + F->setAlignment(1 << LangOpts.FunctionAlignment); + // Some C++ ABIs require 2-byte alignment for member functions, in order to // reserve a bit for differentiating between virtual and non-virtual member // functions. If the current target's C++ ABI requires this and this is a diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp index 15e7cf2847c..e96b5b7590f 100644 --- a/clang/lib/Driver/ToolChains/Clang.cpp +++ b/clang/lib/Driver/ToolChains/Clang.cpp @@ -3323,6 +3323,13 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, CheckCodeGenerationOptions(D, Args); + unsigned FunctionAlignment = ParseFunctionAlignment(getToolChain(), Args); + assert(FunctionAlignment <= 31 && "function alignment will be truncated!"); + if (FunctionAlignment) { + CmdArgs.push_back("-function-alignment"); + CmdArgs.push_back(Args.MakeArgString(std::to_string(FunctionAlignment))); + } + llvm::Reloc::Model RelocationModel; unsigned PICLevel; bool IsPIE; diff --git a/clang/lib/Driver/ToolChains/CommonArgs.cpp b/clang/lib/Driver/ToolChains/CommonArgs.cpp index 869cf4c8f2e..1527238c663 100644 --- a/clang/lib/Driver/ToolChains/CommonArgs.cpp +++ b/clang/lib/Driver/ToolChains/CommonArgs.cpp @@ -1033,6 +1033,40 @@ tools::ParsePICArgs(const ToolChain &ToolChain, const ArgList &Args) { return std::make_tuple(RelocM, 0U, false); } +// `-falign-functions` indicates that the functions should be aligned to a +// 16-byte boundary. +// +// `-falign-functions=1` is the same as `-fno-align-functions`. +// +// The scalar `n` in `-falign-functions=n` must be an integral value between +// [0, 65536]. If the value is not a power-of-two, it will be rounded up to +// the nearest power-of-two. +// +// If we return `0`, the frontend will default to the backend's preferred +// alignment. +// +// NOTE: icc only allows values between [0, 4096]. icc uses `-falign-functions` +// to mean `-falign-functions=16`. GCC defaults to the backend's preferred +// alignment. For unaligned functions, we default to the backend's preferred +// alignment. +unsigned tools::ParseFunctionAlignment(const ToolChain &TC, + const ArgList &Args) { + const Arg *A = Args.getLastArg(options::OPT_falign_functions, + options::OPT_falign_functions_EQ, + options::OPT_fno_align_functions); + if (!A || A->getOption().matches(options::OPT_fno_align_functions)) + return 0; + + if (A->getOption().matches(options::OPT_falign_functions)) + return 0; + + unsigned Value = 0; + if (StringRef(A->getValue()).getAsInteger(10, Value) || Value > 65536) + TC.getDriver().Diag(diag::err_drv_invalid_int_value) + << A->getAsString(Args) << A->getValue(); + return Value ? llvm::Log2_32_Ceil(std::min(Value, 65536u)) : Value; +} + void tools::AddAssemblerKPIC(const ToolChain &ToolChain, const ArgList &Args, ArgStringList &CmdArgs) { llvm::Reloc::Model RelocationModel; diff --git a/clang/lib/Driver/ToolChains/CommonArgs.h b/clang/lib/Driver/ToolChains/CommonArgs.h index 14db1ea7302..10a03d4a178 100644 --- a/clang/lib/Driver/ToolChains/CommonArgs.h +++ b/clang/lib/Driver/ToolChains/CommonArgs.h @@ -66,6 +66,9 @@ void AddGoldPlugin(const ToolChain &ToolChain, const llvm::opt::ArgList &Args, std::tuple<llvm::Reloc::Model, unsigned, bool> ParsePICArgs(const ToolChain &ToolChain, const llvm::opt::ArgList &Args); +unsigned ParseFunctionAlignment(const ToolChain &TC, + const llvm::opt::ArgList &Args); + void AddAssemblerKPIC(const ToolChain &ToolChain, const llvm::opt::ArgList &Args, llvm::opt::ArgStringList &CmdArgs); diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp index 9146d2a36df..67e15b41add 100644 --- a/clang/lib/Frontend/CompilerInvocation.cpp +++ b/clang/lib/Frontend/CompilerInvocation.cpp @@ -2968,6 +2968,9 @@ bool CompilerInvocation::CreateFromArgs(CompilerInvocation &Res, LangOpts.ObjCExceptions = 1; } + LangOpts.FunctionAlignment = + getLastArgIntValue(Args, OPT_function_alignment, 0, Diags); + if (LangOpts.CUDA) { // During CUDA device-side compilation, the aux triple is the // triple used for host compilation. diff --git a/clang/test/CodeGen/function-alignment.c b/clang/test/CodeGen/function-alignment.c new file mode 100644 index 00000000000..9101b2c043f --- /dev/null +++ b/clang/test/CodeGen/function-alignment.c @@ -0,0 +1,16 @@ +// RUN: %clang_cc1 -emit-llvm %s -o - | FileCheck %s -check-prefix CHECK-NONE +// RUN: %clang_cc1 -emit-llvm -function-alignment 4 %s -o - | FileCheck %s -check-prefix CHECK-16 +// RUN: %clang_cc1 -emit-llvm -function-alignment 5 %s -o - | FileCheck %s -check-prefix CHECK-32 + +void f(void) {} +void __attribute__((__aligned__(64))) g(void) {} + +// CHECK-NONE-NOT: define void @f() #0 align +// CHECK-NONE: define void @g() #0 align 64 + +// CHECK-16: define void @f() #0 align 16 +// CHECK-16: define void @g() #0 align 64 + +// CHECK-32: define void @f() #0 align 32 +// CHECK-32: define void @g() #0 align 64 + diff --git a/clang/test/Driver/clang_f_opts.c b/clang/test/Driver/clang_f_opts.c index 2b2a7e7b98f..be9ca2c93d6 100644 --- a/clang/test/Driver/clang_f_opts.c +++ b/clang/test/Driver/clang_f_opts.c @@ -302,8 +302,6 @@ // RUN: -fkeep-inline-functions \ // RUN: -fno-keep-inline-functions \ // RUN: -freorder-blocks \ -// RUN: -falign-functions \ -// RUN: -falign-functions=1 \ // RUN: -ffloat-store \ // RUN: -fgcse \ // RUN: -fivopts \ @@ -370,8 +368,6 @@ // CHECK-WARNING-DAG: optimization flag '-fkeep-inline-functions' is not supported // CHECK-WARNING-DAG: optimization flag '-fno-keep-inline-functions' is not supported // CHECK-WARNING-DAG: optimization flag '-freorder-blocks' is not supported -// CHECK-WARNING-DAG: optimization flag '-falign-functions' is not supported -// CHECK-WARNING-DAG: optimization flag '-falign-functions=1' is not supported // CHECK-WARNING-DAG: optimization flag '-ffloat-store' is not supported // CHECK-WARNING-DAG: optimization flag '-fgcse' is not supported // CHECK-WARNING-DAG: optimization flag '-fivopts' is not supported diff --git a/clang/test/Driver/function-alignment.c b/clang/test/Driver/function-alignment.c new file mode 100644 index 00000000000..3dd6ad1cbaa --- /dev/null +++ b/clang/test/Driver/function-alignment.c @@ -0,0 +1,17 @@ +// RUN: %clang -### %s 2>&1 | FileCheck %s -check-prefix CHECK-0 +// RUN: %clang -### -falign-functions %s 2>&1 | FileCheck %s -check-prefix CHECK-1 +// RUN: %clang -### -falign-functions=1 %s 2>&1 | FileCheck %s -check-prefix CHECK-1 +// RUN: %clang -### -falign-functions=2 %s 2>&1 | FileCheck %s -check-prefix CHECK-2 +// RUN: %clang -### -falign-functions=3 %s 2>&1 | FileCheck %s -check-prefix CHECK-3 +// RUN: %clang -### -falign-functions=4 %s 2>&1 | FileCheck %s -check-prefix CHECK-4 +// RUN: %clang -### -falign-functions=65537 %s 2>&1 | FileCheck %s -check-prefix CHECK-ERR-65537 +// RUN: %clang -### -falign-functions=a %s 2>&1 | FileCheck %s -check-prefix CHECK-ERR-A + +// CHECK-0-NOT: "-function-alignment" +// CHECK-1-NOT: "-function-alignment" +// CHECK-2: "-function-alignment" "1" +// CHECK-3: "-function-alignment" "2" +// CHECK-4: "-function-alignment" "2" +// CHECK-ERR-65537: error: invalid integral value '65537' in '-falign-functions=65537' +// CHECK-ERR-A: error: invalid integral value 'a' in '-falign-functions=a' + |