Skip to content
Open
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
1 change: 1 addition & 0 deletions clang/include/clang/Basic/LangOptions.def
Original file line number Diff line number Diff line change
Expand Up @@ -419,6 +419,7 @@ ENUM_LANGOPT(ClangABICompat, ClangABI, 4, ClangABI::Latest, NotCompatible,
"with")

VALUE_LANGOPT(FunctionAlignment, 5, 0, Compatible, "Default alignment for functions")
VALUE_LANGOPT(PreferredFunctionAlignment, 5, 0, Compatible, "Preferred alignment for functions")
VALUE_LANGOPT(LoopAlignment, 32, 0, Compatible, "Default alignment for loops")

LANGOPT(FixedPoint, 1, 0, NotCompatible, "fixed point types")
Expand Down
5 changes: 5 additions & 0 deletions clang/include/clang/Driver/Options.td
Original file line number Diff line number Diff line change
Expand Up @@ -1551,6 +1551,8 @@ defm access_control : BoolFOption<"access-control",
PosFlag<SetTrue>>;
def falign_functions : Flag<["-"], "falign-functions">, Group<f_Group>;
def falign_functions_EQ : Joined<["-"], "falign-functions=">, Group<f_Group>;
def fpreferred_function_alignment_EQ :
Joined<["-"], "fpreferred-function-alignment=">, Group<f_Group>;
def falign_loops_EQ : Joined<["-"], "falign-loops=">, Group<f_Group>,
Visibility<[ClangOption, CC1Option]>, MetaVarName<"<N>">,
HelpText<"N must be a power of two. Align loops to the boundary">,
Expand Down Expand Up @@ -8505,6 +8507,9 @@ def fencode_extended_block_signature : Flag<["-"], "fencode-extended-block-signa
def function_alignment : Separate<["-"], "function-alignment">,
HelpText<"default alignment for functions">,
MarshallingInfoInt<LangOpts<"FunctionAlignment">>;
def preferred_function_alignment : Separate<["-"], "preferred-function-alignment">,
HelpText<"preferred alignment for functions">,
MarshallingInfoInt<LangOpts<"PreferredFunctionAlignment">>;
def fhalf_no_semantic_interposition : Flag<["-"], "fhalf-no-semantic-interposition">,
HelpText<"Like -fno-semantic-interposition but don't use local aliases">,
MarshallingInfoFlag<LangOpts<"HalfNoSemanticInterposition">>;
Expand Down
20 changes: 13 additions & 7 deletions clang/lib/CodeGen/CodeGenModule.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2822,13 +2822,19 @@ void CodeGenModule::SetLLVMFunctionAttributesForDefinition(const Decl *D,

F->addFnAttrs(B);

unsigned alignment = D->getMaxAlignment() / Context.getCharWidth();
if (alignment)
F->setAlignment(llvm::Align(alignment));

if (!D->hasAttr<AlignedAttr>())
if (LangOpts.FunctionAlignment)
F->setAlignment(llvm::Align(1ull << LangOpts.FunctionAlignment));
llvm::MaybeAlign ExplicitAlignment;
if (unsigned alignment = D->getMaxAlignment() / Context.getCharWidth())
ExplicitAlignment = llvm::Align(alignment);
else if (LangOpts.FunctionAlignment)
ExplicitAlignment = llvm::Align(1ull << LangOpts.FunctionAlignment);

if (ExplicitAlignment) {
F->setAlignment(ExplicitAlignment);
F->setPreferredAlignment(ExplicitAlignment);
} else if (LangOpts.PreferredFunctionAlignment) {
F->setPreferredAlignment(
llvm::Align(1ull << LangOpts.PreferredFunctionAlignment));
}

// Some C++ ABIs require 2-byte alignment for member functions, in order to
// reserve a bit for differentiating between virtual and non-virtual member
Expand Down
13 changes: 13 additions & 0 deletions clang/lib/Driver/ToolChains/Clang.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@
#include "llvm/Support/Compression.h"
#include "llvm/Support/Error.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/Process.h"
#include "llvm/Support/YAMLParser.h"
Expand Down Expand Up @@ -5468,6 +5469,18 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
CmdArgs.push_back(Args.MakeArgString(std::to_string(FunctionAlignment)));
}

if (const Arg *A = Args.getLastArg(options::OPT_fpreferred_function_alignment_EQ)) {
unsigned Value = 0;
if (StringRef(A->getValue()).getAsInteger(10, Value) || Value > 65536 ||
!llvm::isPowerOf2_32(Value))
TC.getDriver().Diag(diag::err_drv_invalid_int_value)
<< A->getAsString(Args) << A->getValue();

CmdArgs.push_back("-preferred-function-alignment");
CmdArgs.push_back(Args.MakeArgString(
std::to_string(llvm::Log2_32_Ceil(std::min(Value, 65536u)))));
}

// We support -falign-loops=N where N is a power of 2. GCC supports more
// forms.
if (const Arg *A = Args.getLastArg(options::OPT_falign_loops_EQ)) {
Expand Down
4 changes: 4 additions & 0 deletions clang/test/CodeGen/prefalign.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
// RUN: %clang_cc1 -emit-llvm -triple x86_64-unknown-linux -preferred-function-alignment 4 %s -o - | FileCheck %s

// CHECK: define {{.*}} void @f() {{.*}} prefalign 16
void f() {}
6 changes: 3 additions & 3 deletions clang/test/CodeGenCXX/member-alignment.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,9 @@ class t {
[[gnu::aligned(16)]]
void
t::baz(void) {
// CHECK-NOEXTRAALIGN: @_ZN1t3bazEv({{.*}}) #0 align 16 {
// CHECK-EXTRAALIGN: @_ZN1t3bazEv({{.*}}) #0 align 16 {
// CHECK-MSVC: @"?baz@t@@QEAAXXZ"({{.*}}) #0 align 16 {
// CHECK-NOEXTRAALIGN: @_ZN1t3bazEv({{.*}}) #0 align 16 prefalign 16 {
// CHECK-EXTRAALIGN: @_ZN1t3bazEv({{.*}}) #0 align 16 prefalign 16 {
// CHECK-MSVC: @"?baz@t@@QEAAXXZ"({{.*}}) #0 align 16 prefalign 16 {
}

void
Expand Down
5 changes: 5 additions & 0 deletions clang/test/Driver/prefalign.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
// RUN: %clang -### -fpreferred-function-alignment=16 %s 2>&1 | FileCheck %s -check-prefix CHECK-16
// RUN: not %clang -### -fpreferred-function-alignment=3 %s 2>&1 | FileCheck %s -check-prefix CHECK-INVALID

// CHECK-16: "-preferred-function-alignment" "4"
// CHECK-INVALID: invalid integral value '3' in '-fpreferred-function-alignment=3'
Loading