diff options
| author | Saleem Abdulrasool <compnerd@compnerd.org> | 2018-04-19 23:14:57 +0000 |
|---|---|---|
| committer | Saleem Abdulrasool <compnerd@compnerd.org> | 2018-04-19 23:14:57 +0000 |
| commit | 3fe5b7a497249a5886d437b67e8da3d70b098a4d (patch) | |
| tree | ea34faee7f50c5f41b1f1de379b65d3201ebbb39 /clang/lib | |
| parent | 72da02fc30cd7ce6344107c8b33e48e6322f4d7e (diff) | |
| download | bcm5719-llvm-3fe5b7a497249a5886d437b67e8da3d70b098a4d.tar.gz bcm5719-llvm-3fe5b7a497249a5886d437b67e8da3d70b098a4d.zip | |
Implement proper support for `-falign-functions`
This implements support for the previously ignored flag
`-falign-functions`. This allows the frontend to request alignment on
function definitions in the translation unit where they are not
explicitly requested in code. This is compatible with the GCC behaviour
and the ICC behaviour.
The scalar value passed to `-falign-functions` aligns functions to a
power-of-two boundary. If flag is used, the functions are aligned to
16-byte boundaries. If the scalar is specified, it must be an integer
less than or equal to 4096. If the value is not a power-of-two, the
driver will round it up to the nearest power of two.
llvm-svn: 330378
Diffstat (limited to 'clang/lib')
| -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 |
5 files changed, 51 insertions, 0 deletions
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. |

