gcc: upstream alignment cleanups.

This solves GCC/32617 and contributes to reduce differences with
Apple's gcc42.

Complete some references in the ChangeLog while here.

Obtained from:	gcc 4.3 (rev. 126529, 126588; GPLv2)
MFC after:	3 weeks
This commit is contained in:
pfg 2013-11-29 18:46:02 +00:00
parent 430acb4217
commit 412075b231
14 changed files with 152 additions and 81 deletions

View File

@ -4,6 +4,47 @@
* config/arm/unwind-arm.h (__gnu_Unwind_Backtrace): New.
* config/arm/unwind-arm.c (__gnu_Unwind_Backtrace): New.
2007-07-12 Geoffrey Keating <geoffk@apple.com> (r126588)
* builtins.c (get_pointer_alignment): Honor DECL_ALIGN on a
FUNCTION_DECL.
* tree.c (build_decl_stat): Move code from here...
(make_node_stat): ... to here. Don't uselessly clear DECL_USER_ALIGN.
(expr_align): Honor DECL_ALIGN on a FUNCTION_DECL. Add comment
about using DECL_ALIGN of LABEL_DECL and CONST_DECL.
* tree.h (DECL_USER_ALIGN): Fix misplaced comment.
* varasm.c (assemble_start_function): Use DECL_ALIGN instead of
FUNCTION_BOUNDARY.
2007-07-09 Geoffrey Keating <geoffk@apple.com> (r126529)
PR 32617
* c-common.c (c_alignof_expr): Look at DECL_ALIGN of
FUNCTION_DECLs.
(handle_aligned_attribute): Allow use on FUNCTION_DECLs.
* varasm.c (assemble_start_function): Honor DECL_ALIGN
for FUNCTION_DECLs. Don't use align_functions_log if
DECL_USER_ALIGN.
* print-tree.c (print_node): Print DECL_ALIGN and DECL_USER_ALIGN
even for FUNCTION_DECLs.
* c-decl.c (merge_decls): Propagate DECL_ALIGN even for
FUNCTION_DECLs.
* tree.h (DECL_ALIGN): Update for new location of 'align'.
(DECL_FUNCTION_CODE): Update for new location and name of
'function_code'.
(DECL_OFFSET_ALIGN): Update for new location of 'off_align'.
(struct tree_decl_common): Move 'align' and 'off_align' out
of union, ensure they're still on a 32-bit boundary. Remove
other fields in union 'u1'.
(struct tree_function_decl): Add field 'function_code' replacing
'u1.f' in tree_decl_common.
* tree.c (build_decl_stat): Set initial value of DECL_ALIGN.
* doc/extend.texi (Function Attributes): Add 'aligned' attribute.
(Variable Attributes): Cross-reference 'aligned' attribute
to Function Attributes.
* flags.h (force_align_functions_log): Delete.
* toplev.c (force_align_functions_log): Delete.
2007-06-05 Joerg Wunsch <j.gnu@uriah.heep.sax.de> (r125346)
PR preprocessor/23479
@ -60,7 +101,7 @@
alignment for amdfam10 architecture. Increasing the max loop
alignment to 24 bytes.
2007-04-16 Lawrence Crowl <crowl@google.com>
2007-04-16 Lawrence Crowl <crowl@google.com> (r123909)
* doc/invoke.texi (Debugging Options): Add documentation for the
-femit-struct-debug options -femit-struct-debug-baseonly,
@ -139,7 +180,7 @@
* config/i386/i386.c (override_options): Likewise.
* doc/invoke.texi: Likewise.
2007-03-12 Seongbae Park <seongbae.park@gmail.com>
2007-03-12 Seongbae Park <seongbae.park@gmail.com> (r122851)
* c-decl.c (warn_variable_length_array): New function.
Refactored from grokdeclarator to handle warn_vla
@ -340,7 +381,7 @@
* config.gcc: Support core2 processor.
2007-01-05 Manuel Lopez-Ibanez <manu@gcc.gnu.org>
2007-01-05 Manuel Lopez-Ibanez <manu@gcc.gnu.org> (r120505)
PR c/19978
* tree.h (TREE_OVERFLOW_P): New.

View File

@ -315,9 +315,7 @@ get_pointer_alignment (tree exp, unsigned int max_align)
else if (offset)
inner = MIN (inner, BITS_PER_UNIT);
}
if (TREE_CODE (exp) == FUNCTION_DECL)
align = FUNCTION_BOUNDARY;
else if (DECL_P (exp))
if (DECL_P (exp))
align = MIN (inner, DECL_ALIGN (exp));
#ifdef CONSTANT_ALIGNMENT
else if (CONSTANT_CLASS_P (exp))

View File

@ -2995,16 +2995,16 @@ c_sizeof_or_alignof_type (tree type, bool is_sizeof, int complain)
}
/* Implement the __alignof keyword: Return the minimum required
alignment of EXPR, measured in bytes. For VAR_DECL's and
FIELD_DECL's return DECL_ALIGN (which can be set from an
"aligned" __attribute__ specification). */
alignment of EXPR, measured in bytes. For VAR_DECLs,
FUNCTION_DECLs and FIELD_DECLs return DECL_ALIGN (which can be set
from an "aligned" __attribute__ specification). */
tree
c_alignof_expr (tree expr)
{
tree t;
if (TREE_CODE (expr) == VAR_DECL)
if (VAR_OR_FUNCTION_DECL_P (expr))
t = size_int (DECL_ALIGN_UNIT (expr));
else if (TREE_CODE (expr) == COMPONENT_REF
@ -4809,12 +4809,24 @@ handle_aligned_attribute (tree *node, tree ARG_UNUSED (name), tree args,
TYPE_ALIGN (*type) = (1 << i) * BITS_PER_UNIT;
TYPE_USER_ALIGN (*type) = 1;
}
else if (TREE_CODE (decl) != VAR_DECL
else if (! VAR_OR_FUNCTION_DECL_P (decl)
&& TREE_CODE (decl) != FIELD_DECL)
{
error ("alignment may not be specified for %q+D", decl);
*no_add_attrs = true;
}
else if (TREE_CODE (decl) == FUNCTION_DECL
&& DECL_ALIGN (decl) > (1 << i) * BITS_PER_UNIT)
{
if (DECL_USER_ALIGN (decl))
error ("alignment for %q+D was previously specified as %d "
"and may not be decreased", decl,
DECL_ALIGN (decl) / BITS_PER_UNIT);
else
error ("alignment for %q+D must be at least %d", decl,
DECL_ALIGN (decl) / BITS_PER_UNIT);
*no_add_attrs = true;
}
else
{
DECL_ALIGN (decl) = (1 << i) * BITS_PER_UNIT;

View File

@ -1690,12 +1690,11 @@ merge_decls (tree newdecl, tree olddecl, tree newtype, tree oldtype)
DECL_SIZE (newdecl) = DECL_SIZE (olddecl);
DECL_SIZE_UNIT (newdecl) = DECL_SIZE_UNIT (olddecl);
DECL_MODE (newdecl) = DECL_MODE (olddecl);
if (TREE_CODE (olddecl) != FUNCTION_DECL)
if (DECL_ALIGN (olddecl) > DECL_ALIGN (newdecl))
{
DECL_ALIGN (newdecl) = DECL_ALIGN (olddecl);
DECL_USER_ALIGN (newdecl) |= DECL_ALIGN (olddecl);
}
if (DECL_ALIGN (olddecl) > DECL_ALIGN (newdecl))
{
DECL_ALIGN (newdecl) = DECL_ALIGN (olddecl);
DECL_USER_ALIGN (newdecl) |= DECL_ALIGN (olddecl);
}
}

View File

@ -1,3 +1,12 @@
2007-07-09 Geoffrey Keating <geoffk@apple.com>
PR 32617
* decl.c (cxx_init_decl_processing): Don't set
force_align_functions_log.
(grokfndecl): Honour ptrmemfunc_vbit_in_pfn.
* typeck.c (cxx_alignof_expr): When alignof is used on a plain
FUNCTION_DECL, return its alignment.
2007-06-28 Geoffrey Keating <geoffk@apple.com> (r126080)
* decl2.c (start_objects): Mark constructor-runnning function

View File

@ -3158,12 +3158,6 @@ cxx_init_decl_processing (void)
if (flag_inline_functions)
flag_inline_trees = 2;
/* Force minimum function alignment if using the least significant
bit of function pointers to store the virtual bit. */
if (TARGET_PTRMEMFUNC_VBIT_LOCATION == ptrmemfunc_vbit_in_pfn
&& force_align_functions_log < 1)
force_align_functions_log = 1;
/* Initially, C. */
current_lang_name = lang_name_c;
@ -6065,6 +6059,14 @@ grokfndecl (tree ctype,
if (TYPE_VOLATILE (type))
TREE_THIS_VOLATILE (decl) = 1;
/* If pointers to member functions use the least significant bit to
indicate whether a function is virtual, ensure a pointer
to this function will have that bit clear. */
if (TARGET_PTRMEMFUNC_VBIT_LOCATION == ptrmemfunc_vbit_in_pfn
&& TREE_CODE (type) == METHOD_TYPE
&& DECL_ALIGN (decl) < 2 * BITS_PER_UNIT)
DECL_ALIGN (decl) = 2 * BITS_PER_UNIT;
if (friendp
&& TREE_CODE (orig_declarator) == TEMPLATE_ID_EXPR)
{

View File

@ -1358,7 +1358,10 @@ cxx_alignof_expr (tree e)
{
pedwarn ("ISO C++ forbids applying %<__alignof%> to an expression of "
"function type");
t = size_one_node;
if (TREE_CODE (e) == FUNCTION_DECL)
t = size_int (DECL_ALIGN_UNIT (e));
else
t = size_one_node;
}
else if (type_unknown_p (e))
{

View File

@ -1577,6 +1577,7 @@ The keyword @code{__attribute__} allows you to specify special
attributes when making a declaration. This keyword is followed by an
attribute specification inside double parentheses. The following
attributes are currently defined for functions on all targets:
@code{aligned},
@code{noreturn}, @code{returns_twice}, @code{noinline}, @code{always_inline},
@code{flatten}, @code{pure}, @code{const}, @code{nothrow}, @code{sentinel},
@code{format}, @code{format_arg}, @code{no_instrument_function},
@ -1615,6 +1616,27 @@ is not defined in the same translation unit.
Not all target machines support this attribute.
@item aligned (@var{alignment})
@cindex @code{aligned} attribute
This attribute specifies a minimum alignment for the function,
measured in bytes.
You cannot use this attribute to decrease the alignment of a function,
only to increase it. However, when you explicitly specify a function
alignment this will override the effect of the
@option{-falign-functions} (@pxref{Optimize Options}) option for this
function.
Note that the effectiveness of @code{aligned} attributes may be
limited by inherent limitations in your linker. On many systems, the
linker is only able to arrange for functions to be aligned up to a
certain maximum alignment. (For some linkers, the maximum supported
alignment may be very very small.) See your linker documentation for
further information.
The @code{aligned} attribute can also be used for variables and fields
(@pxref{Variable Attributes}.)
@item always_inline
@cindex @code{always_inline} function attribute
Generally, functions are not inlined unless optimization is specified.
@ -3044,6 +3066,9 @@ up to a maximum of 8 byte alignment, then specifying @code{aligned(16)}
in an @code{__attribute__} will still only provide you with 8 byte
alignment. See your linker documentation for further information.
The @code{aligned} attribute can also be used for functions
(@pxref{Function Attributes}.)
@item cleanup (@var{cleanup_function})
@cindex @code{cleanup} attribute
The @code{cleanup} attribute runs a function when the variable goes

View File

@ -261,10 +261,6 @@ extern int align_labels_log;
extern int align_labels_max_skip;
extern int align_functions_log;
/* Like align_functions_log above, but used by front-ends to force the
minimum function alignment. Zero means no alignment is forced. */
extern int force_align_functions_log;
/* Nonzero if we dump in VCG format, not plain text. */
extern int dump_for_graph;

View File

@ -439,17 +439,15 @@ print_node (FILE *file, const char *prefix, tree node, int indent)
|| DECL_INLINE (node) || DECL_BUILT_IN (node))
indent_to (file, indent + 3);
if (TREE_CODE (node) != FUNCTION_DECL)
{
if (DECL_USER_ALIGN (node))
fprintf (file, " user");
fprintf (file, " align %d", DECL_ALIGN (node));
if (TREE_CODE (node) == FIELD_DECL)
fprintf (file, " offset_align " HOST_WIDE_INT_PRINT_UNSIGNED,
DECL_OFFSET_ALIGN (node));
}
else if (DECL_BUILT_IN (node))
if (DECL_USER_ALIGN (node))
fprintf (file, " user");
fprintf (file, " align %d", DECL_ALIGN (node));
if (TREE_CODE (node) == FIELD_DECL)
fprintf (file, " offset_align " HOST_WIDE_INT_PRINT_UNSIGNED,
DECL_OFFSET_ALIGN (node));
if (TREE_CODE (node) == FUNCTION_DECL && DECL_BUILT_IN (node))
{
if (DECL_BUILT_IN_CLASS (node) == BUILT_IN_MD)
fprintf (file, " built-in BUILT_IN_MD %d", DECL_FUNCTION_CODE (node));

View File

@ -369,10 +369,6 @@ int align_labels_log;
int align_labels_max_skip;
int align_functions_log;
/* Like align_functions_log above, but used by front-ends to force the
minimum function alignment. Zero means no alignment is forced. */
int force_align_functions_log;
typedef struct
{
const char *const string;

View File

@ -541,9 +541,13 @@ make_node_stat (enum tree_code code MEM_STAT_DECL)
DECL_IN_SYSTEM_HEADER (t) = in_system_header;
if (CODE_CONTAINS_STRUCT (code, TS_DECL_COMMON))
{
if (code != FUNCTION_DECL)
if (code == FUNCTION_DECL)
{
DECL_ALIGN (t) = FUNCTION_BOUNDARY;
DECL_MODE (t) = FUNCTION_MODE;
}
else
DECL_ALIGN (t) = 1;
DECL_USER_ALIGN (t) = 0;
/* We have not yet computed the alias set for this declaration. */
DECL_POINTER_ALIAS_SET (t) = -1;
}
@ -1881,14 +1885,13 @@ expr_align (tree t)
align1 = expr_align (TREE_OPERAND (t, 2));
return MIN (align0, align1);
/* FIXME: LABEL_DECL and CONST_DECL never have DECL_ALIGN set
meaningfully, it's always 1. */
case LABEL_DECL: case CONST_DECL:
case VAR_DECL: case PARM_DECL: case RESULT_DECL:
if (DECL_ALIGN (t) != 0)
return DECL_ALIGN (t);
break;
case FUNCTION_DECL:
return FUNCTION_BOUNDARY;
gcc_assert (DECL_ALIGN (t) != 0);
return DECL_ALIGN (t);
default:
break;
@ -3174,8 +3177,6 @@ build_decl_stat (enum tree_code code, tree name, tree type MEM_STAT_DECL)
if (code == VAR_DECL || code == PARM_DECL || code == RESULT_DECL)
layout_decl (t, 0);
else if (code == FUNCTION_DECL)
DECL_MODE (t) = FUNCTION_MODE;
return t;
}

View File

@ -2426,13 +2426,11 @@ struct tree_struct_field_tag GTY(())
/* Likewise for the size in bytes. */
#define DECL_SIZE_UNIT(NODE) (DECL_COMMON_CHECK (NODE)->decl_common.size_unit)
/* Holds the alignment required for the datum, in bits. */
#define DECL_ALIGN(NODE) (DECL_COMMON_CHECK (NODE)->decl_common.u1.a.align)
#define DECL_ALIGN(NODE) (DECL_COMMON_CHECK (NODE)->decl_common.align)
/* The alignment of NODE, in bytes. */
#define DECL_ALIGN_UNIT(NODE) (DECL_ALIGN (NODE) / BITS_PER_UNIT)
/* For FIELD_DECLs, off_align holds the number of low-order bits of
DECL_FIELD_OFFSET which are known to be always zero.
DECL_OFFSET_ALIGN thus returns the alignment that DECL_FIELD_OFFSET
has. */
/* Set if the alignment of this DECL has been set by the user, for
example with an 'aligned' attribute. */
#define DECL_USER_ALIGN(NODE) (DECL_COMMON_CHECK (NODE)->decl_common.user_align)
/* Holds the machine mode corresponding to the declaration of a variable or
field. Always equal to TYPE_MODE (TREE_TYPE (decl)) except for a
@ -2443,7 +2441,8 @@ struct tree_struct_field_tag GTY(())
operation it is. Note, however, that this field is overloaded, with
DECL_BUILT_IN_CLASS as the discriminant, so the latter must always be
checked before any access to the former. */
#define DECL_FUNCTION_CODE(NODE) (FUNCTION_DECL_CHECK (NODE)->decl_common.u1.f)
#define DECL_FUNCTION_CODE(NODE) \
(FUNCTION_DECL_CHECK (NODE)->function_decl.function_code)
#define DECL_DEBUG_EXPR_IS_FROM(NODE) \
(DECL_COMMON_CHECK (NODE)->decl_common.debug_expr_is_from)
@ -2581,20 +2580,9 @@ struct tree_decl_common GTY(())
unsigned gimple_reg_flag : 1;
unsigned call_clobbered_flag : 1;
union tree_decl_u1 {
/* In a FUNCTION_DECL for which DECL_BUILT_IN holds, this is
DECL_FUNCTION_CODE. */
enum built_in_function f;
/* In a FUNCTION_DECL for which DECL_BUILT_IN does not hold, this
is used by language-dependent code. */
HOST_WIDE_INT i;
/* DECL_ALIGN and DECL_OFFSET_ALIGN. (These are not used for
FUNCTION_DECLs). */
struct tree_decl_u1_a {
unsigned int align : 24;
unsigned int off_align : 8;
} a;
} GTY ((skip)) u1;
unsigned int align : 24;
/* DECL_OFFSET_ALIGN, used only for FIELD_DECLs. */
unsigned int off_align : 8;
tree size_unit;
tree initial;
@ -2679,11 +2667,11 @@ struct tree_decl_with_rtl GTY(())
DECL_OFFSET_ALIGN thus returns the alignment that DECL_FIELD_OFFSET
has. */
#define DECL_OFFSET_ALIGN(NODE) \
(((unsigned HOST_WIDE_INT)1) << FIELD_DECL_CHECK (NODE)->decl_common.u1.a.off_align)
(((unsigned HOST_WIDE_INT)1) << FIELD_DECL_CHECK (NODE)->decl_common.off_align)
/* Specify that DECL_ALIGN(NODE) is a multiple of X. */
#define SET_DECL_OFFSET_ALIGN(NODE, X) \
(FIELD_DECL_CHECK (NODE)->decl_common.u1.a.off_align = exact_log2 ((X) & -(X)))
(FIELD_DECL_CHECK (NODE)->decl_common.off_align = exact_log2 ((X) & -(X)))
/* 1 if the alignment for this type was requested by "aligned" attribute,
0 if it is the default for this type. */
@ -3096,6 +3084,10 @@ struct tree_function_decl GTY(())
{
struct tree_decl_non_common common;
/* In a FUNCTION_DECL for which DECL_BUILT_IN holds, this is
DECL_FUNCTION_CODE. Otherwise unused. */
enum built_in_function function_code;
unsigned static_ctor_flag : 1;
unsigned static_dtor_flag : 1;
unsigned uninlinable : 1;

View File

@ -1383,7 +1383,7 @@ assemble_start_function (tree decl, const char *fnname)
if (flag_reorder_blocks_and_partition)
{
switch_to_section (unlikely_text_section ());
assemble_align (FUNCTION_BOUNDARY);
assemble_align (DECL_ALIGN (decl));
ASM_OUTPUT_LABEL (asm_out_file, cfun->cold_section_label);
/* When the function starts with a cold section, we need to explicitly
@ -1393,7 +1393,7 @@ assemble_start_function (tree decl, const char *fnname)
&& BB_PARTITION (ENTRY_BLOCK_PTR->next_bb) == BB_COLD_PARTITION)
{
switch_to_section (text_section);
assemble_align (FUNCTION_BOUNDARY);
assemble_align (DECL_ALIGN (decl));
ASM_OUTPUT_LABEL (asm_out_file, cfun->hot_section_label);
hot_label_written = true;
first_function_block_is_cold = true;
@ -1424,18 +1424,17 @@ assemble_start_function (tree decl, const char *fnname)
ASM_OUTPUT_LABEL (asm_out_file, cfun->hot_section_label);
/* Tell assembler to move to target machine's alignment for functions. */
align = floor_log2 (FUNCTION_BOUNDARY / BITS_PER_UNIT);
if (align < force_align_functions_log)
align = force_align_functions_log;
align = floor_log2 (DECL_ALIGN (decl) / BITS_PER_UNIT);
if (align > 0)
{
ASM_OUTPUT_ALIGN (asm_out_file, align);
}
/* Handle a user-specified function alignment.
Note that we still need to align to FUNCTION_BOUNDARY, as above,
Note that we still need to align to DECL_ALIGN, as above,
because ASM_OUTPUT_MAX_SKIP_ALIGN might not do any alignment at all. */
if (align_functions_log > align
if (! DECL_USER_ALIGN (decl)
&& align_functions_log > align
&& cfun->function_frequency != FUNCTION_FREQUENCY_UNLIKELY_EXECUTED)
{
#ifdef ASM_OUTPUT_MAX_SKIP_ALIGN