Skip to content

Commit bbf59ae

Browse files
committed
[𝘀𝗽𝗿] initial version
Created using spr 1.3.6-beta.1
2 parents a1eeb59 + 6e00a16 commit bbf59ae

39 files changed

+369
-48
lines changed

clang/include/clang/Basic/LangOptions.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -418,6 +418,7 @@ ENUM_LANGOPT(ClangABICompat, ClangABI, 4, ClangABI::Latest, NotCompatible,
418418
"with")
419419

420420
VALUE_LANGOPT(FunctionAlignment, 5, 0, Compatible, "Default alignment for functions")
421+
VALUE_LANGOPT(PreferredFunctionAlignment, 5, 0, Compatible, "Preferred alignment for functions")
421422
VALUE_LANGOPT(LoopAlignment, 32, 0, Compatible, "Default alignment for loops")
422423

423424
LANGOPT(FixedPoint, 1, 0, NotCompatible, "fixed point types")

clang/include/clang/Driver/Options.td

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1550,6 +1550,8 @@ defm access_control : BoolFOption<"access-control",
15501550
PosFlag<SetTrue>>;
15511551
def falign_functions : Flag<["-"], "falign-functions">, Group<f_Group>;
15521552
def falign_functions_EQ : Joined<["-"], "falign-functions=">, Group<f_Group>;
1553+
def fpreferred_function_alignment_EQ :
1554+
Joined<["-"], "fpreferred-function-alignment=">, Group<f_Group>;
15531555
def falign_loops_EQ : Joined<["-"], "falign-loops=">, Group<f_Group>,
15541556
Visibility<[ClangOption, CC1Option]>, MetaVarName<"<N>">,
15551557
HelpText<"N must be a power of two. Align loops to the boundary">,
@@ -8446,6 +8448,9 @@ def fencode_extended_block_signature : Flag<["-"], "fencode-extended-block-signa
84468448
def function_alignment : Separate<["-"], "function-alignment">,
84478449
HelpText<"default alignment for functions">,
84488450
MarshallingInfoInt<LangOpts<"FunctionAlignment">>;
8451+
def preferred_function_alignment : Separate<["-"], "preferred-function-alignment">,
8452+
HelpText<"preferred alignment for functions">,
8453+
MarshallingInfoInt<LangOpts<"PreferredFunctionAlignment">>;
84498454
def fhalf_no_semantic_interposition : Flag<["-"], "fhalf-no-semantic-interposition">,
84508455
HelpText<"Like -fno-semantic-interposition but don't use local aliases">,
84518456
MarshallingInfoFlag<LangOpts<"HalfNoSemanticInterposition">>;

clang/lib/CodeGen/CodeGenModule.cpp

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2794,13 +2794,19 @@ void CodeGenModule::SetLLVMFunctionAttributesForDefinition(const Decl *D,
27942794

27952795
F->addFnAttrs(B);
27962796

2797-
unsigned alignment = D->getMaxAlignment() / Context.getCharWidth();
2798-
if (alignment)
2799-
F->setAlignment(llvm::Align(alignment));
2800-
2801-
if (!D->hasAttr<AlignedAttr>())
2802-
if (LangOpts.FunctionAlignment)
2803-
F->setAlignment(llvm::Align(1ull << LangOpts.FunctionAlignment));
2797+
llvm::MaybeAlign ExplicitAlignment;
2798+
if (unsigned alignment = D->getMaxAlignment() / Context.getCharWidth())
2799+
ExplicitAlignment = llvm::Align(alignment);
2800+
else if (LangOpts.FunctionAlignment)
2801+
ExplicitAlignment = llvm::Align(1ull << LangOpts.FunctionAlignment);
2802+
2803+
if (ExplicitAlignment) {
2804+
F->setAlignment(ExplicitAlignment);
2805+
F->setPreferredAlignment(ExplicitAlignment);
2806+
} else if (LangOpts.PreferredFunctionAlignment) {
2807+
F->setPreferredAlignment(
2808+
llvm::Align(1ull << LangOpts.PreferredFunctionAlignment));
2809+
}
28042810

28052811
// Some C++ ABIs require 2-byte alignment for member functions, in order to
28062812
// reserve a bit for differentiating between virtual and non-virtual member

clang/lib/Driver/ToolChains/Clang.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@
4646
#include "llvm/Support/Compression.h"
4747
#include "llvm/Support/Error.h"
4848
#include "llvm/Support/FileSystem.h"
49+
#include "llvm/Support/MathExtras.h"
4950
#include "llvm/Support/Path.h"
5051
#include "llvm/Support/Process.h"
5152
#include "llvm/Support/YAMLParser.h"
@@ -5503,6 +5504,18 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
55035504
CmdArgs.push_back(Args.MakeArgString(std::to_string(FunctionAlignment)));
55045505
}
55055506

5507+
if (const Arg *A = Args.getLastArg(options::OPT_fpreferred_function_alignment_EQ)) {
5508+
unsigned Value = 0;
5509+
if (StringRef(A->getValue()).getAsInteger(10, Value) || Value > 65536 ||
5510+
!llvm::isPowerOf2_32(Value))
5511+
TC.getDriver().Diag(diag::err_drv_invalid_int_value)
5512+
<< A->getAsString(Args) << A->getValue();
5513+
5514+
CmdArgs.push_back("-preferred-function-alignment");
5515+
CmdArgs.push_back(Args.MakeArgString(
5516+
std::to_string(llvm::Log2_32_Ceil(std::min(Value, 65536u)))));
5517+
}
5518+
55065519
// We support -falign-loops=N where N is a power of 2. GCC supports more
55075520
// forms.
55085521
if (const Arg *A = Args.getLastArg(options::OPT_falign_loops_EQ)) {

clang/test/CodeGen/prefalign.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
// RUN: %clang_cc1 -emit-llvm -triple x86_64-unknown-linux -preferred-function-alignment 4 %s -o - | FileCheck %s
2+
3+
// CHECK: define {{.*}} void @f() {{.*}} prefalign 16
4+
void f() {}

clang/test/CodeGenCXX/member-alignment.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,9 @@ class t {
3131
[[gnu::aligned(16)]]
3232
void
3333
t::baz(void) {
34-
// CHECK-NOEXTRAALIGN: @_ZN1t3bazEv({{.*}}) #0 align 16 {
35-
// CHECK-EXTRAALIGN: @_ZN1t3bazEv({{.*}}) #0 align 16 {
36-
// CHECK-MSVC: @"?baz@t@@QEAAXXZ"({{.*}}) #0 align 16 {
34+
// CHECK-NOEXTRAALIGN: @_ZN1t3bazEv({{.*}}) #0 align 16 prefalign 16 {
35+
// CHECK-EXTRAALIGN: @_ZN1t3bazEv({{.*}}) #0 align 16 prefalign 16 {
36+
// CHECK-MSVC: @"?baz@t@@QEAAXXZ"({{.*}}) #0 align 16 prefalign 16 {
3737
}
3838

3939
void

clang/test/Driver/prefalign.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
// RUN: %clang -### -fpreferred-function-alignment=16 %s 2>&1 | FileCheck %s -check-prefix CHECK-16
2+
// RUN: not %clang -### -fpreferred-function-alignment=3 %s 2>&1 | FileCheck %s -check-prefix CHECK-INVALID
3+
4+
// CHECK-16: "-preferred-function-alignment" "4"
5+
// CHECK-INVALID: invalid integral value '3' in '-fpreferred-function-alignment=3'

llvm/docs/Extensions.rst

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,21 @@ hexadecimal format instead of decimal if desired.
2828
.section .data
2929
.float 0x1c2.2ap3
3030
31+
``.prefalign`` directive
32+
------------------------
33+
34+
The ``.prefalign`` directive sets the preferred alignment for a section,
35+
and enables the section's final alignment to be set in a way that is
36+
dependent on the section size (currently only supported with ELF).
37+
38+
If the section size is less than the section's minimum alignment as
39+
determined using ``.align`` family directives, the section's alignment
40+
will be equal to its minimum alignment. Otherwise, if the section size is
41+
between the minimum alignment and the preferred alignment, the section's
42+
alignment will be equal to the power of 2 greater than or equal to the
43+
section size. Otherwise, the section's alignment will be equal to the
44+
preferred alignment.
45+
3146
Machine-specific Assembly Syntax
3247
================================
3348

llvm/docs/LangRef.rst

Lines changed: 23 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -877,7 +877,9 @@ an optional ``unnamed_addr`` attribute, a return type, an optional
877877
name, a (possibly empty) argument list (each with optional :ref:`parameter
878878
attributes <paramattrs>`), optional :ref:`function attributes <fnattrs>`,
879879
an optional address space, an optional section, an optional partition,
880-
an optional alignment, an optional :ref:`comdat <langref_comdats>`,
880+
an optional minimum alignment,
881+
an optional preferred alignment,
882+
an optional :ref:`comdat <langref_comdats>`,
881883
an optional :ref:`garbage collector name <gc>`, an optional :ref:`prefix <prefixdata>`,
882884
an optional :ref:`prologue <prologuedata>`,
883885
an optional :ref:`personality <personalityfn>`,
@@ -891,8 +893,8 @@ Syntax::
891893
<ResultType> @<FunctionName> ([argument list])
892894
[(unnamed_addr|local_unnamed_addr)] [AddrSpace] [fn Attrs]
893895
[section "name"] [partition "name"] [comdat [($name)]] [align N]
894-
[gc] [prefix Constant] [prologue Constant] [personality Constant]
895-
(!name !N)* { ... }
896+
[prefalign N] [gc] [prefix Constant] [prologue Constant]
897+
[personality Constant] (!name !N)* { ... }
896898

897899
The argument list is a comma-separated sequence of arguments where each
898900
argument is of the following form:
@@ -942,11 +944,24 @@ LLVM allows an explicit section to be specified for functions. If the
942944
target supports it, it will emit functions to the section specified.
943945
Additionally, the function can be placed in a COMDAT.
944946

945-
An explicit alignment may be specified for a function. If not present,
946-
or if the alignment is set to zero, the alignment of the function is set
947-
by the target to whatever it feels convenient. If an explicit alignment
948-
is specified, the function is forced to have at least that much
949-
alignment. All alignments must be a power of 2.
947+
An explicit minimum alignment (``align``) may be specified for a
948+
function. If not present, or if the alignment is set to zero, the
949+
alignment of the function is set according to the preferred alignment
950+
rules described below. If an explicit minimum alignment is specified, the
951+
function is forced to have at least that much alignment. All alignments
952+
must be a power of 2.
953+
954+
An explicit preferred alignment (``prefalign``) may also be specified
955+
for a function (definitions only, and must be a power of 2). If a
956+
function does not have a preferred alignment attribute, the preferred
957+
alignment is determined in a target-specific way. The final alignment
958+
of the function is determined in the following way: if the function
959+
size is less than the minimum alignment, the function's alignment will
960+
be at least the minimum alignment. Otherwise, if the function size is
961+
between the minimum alignment and the preferred alignment, the function's
962+
alignment will be at least the power of 2 greater than or equal to the
963+
function size. Otherwise, the function's alignment will be at least the
964+
preferred alignment.
950965

951966
If the ``unnamed_addr`` attribute is given, the address is known to not
952967
be significant and two identical functions can be merged.

llvm/include/llvm/AsmParser/LLParser.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -311,7 +311,7 @@ namespace llvm {
311311
GlobalValueSummary::ImportKind &Res);
312312
void parseOptionalDLLStorageClass(unsigned &Res);
313313
bool parseOptionalCallingConv(unsigned &CC);
314-
bool parseOptionalAlignment(MaybeAlign &Alignment,
314+
bool parseOptionalAlignment(lltok::Kind KW, MaybeAlign &Alignment,
315315
bool AllowParens = false);
316316
bool parseOptionalCodeModel(CodeModel::Model &model);
317317
bool parseOptionalDerefAttrBytes(lltok::Kind AttrKind, uint64_t &Bytes);

0 commit comments

Comments
 (0)