diff options
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. |