mirror of
https://gcc.gnu.org/git/gcc.git
synced 2024-11-28 06:14:10 +08:00
tree.h (DECL_HAS_IMPLICIT_SECTION_NAME_P): New macro.
* tree.h (DECL_HAS_IMPLICIT_SECTION_NAME_P): New macro. (tree_decl_with_vis): Add implicit_section_name_p. * targhooks.h (default_function_section): Declare. * target.def (function_section): New hook. * defaults.h (HOT_TEXT_SECTION_NAME, UNLIKELY_EXECUTED_TEXT_SECTION_NAME): Remove. * predict.c (choose_function_section): Remove. (estimate_bb_frequencies): Do not use choose_function_section. * coretypes.h (enum node_frequency): Move here from cgraph.h * cgraph.h (enum node_frequency): Remove. * varasm.c (initialize_cold_section_name, unlikely_text_section, unlikely_text_section_p): Remove. (named_subsection_entry): New structure. (get_text_section): New function. (default_function_section): New function. (function_section_1): Break out from ...; handle profile info. (function_section): ... here. (unlikely_text_section): Remove. (unlikely_text_section_p): Use function_section_1. (assemble_start_function): Do not initialize cold section. (default_section_type_flags): Do not special case cold subsection. (switch_to_section): Likewise. * output.h (get_text_section): Define. * config/i386/winnt.c: Do not special case cold section. * config/darwin-protos.h (darwin_function_section): Declare. * config/microblaze/microblaze.h (HOT_TEXT_SECTION_NAME, UNLIKELY_EXECUTED_TEXT_SECTION_NAME): Remove. * config/ia64/hpux.h (HOT_TEXT_SECTION_NAME, UNLIKELY_EXECUTED_TEXT_SECTION_NAME): Remove. (TARGET_ASM_FUNCTION_SECTION): Define to ia64_hpux_function_section. * config/ia64/ia64.c (ia64_hpux_function_section): New function. * config/darwin.c (machopic_select_section): Use darwin_function_section. (darwin_function_section): New function. * config/darwin.h (HOT_TEXT_SECTION_NAME, UNLIKELY_EXECUTED_TEXT_SECTION_NAME): Remove. (TARGET_ASM_FUNCTION_SECTION): Define. * system.h (HOT_TEXT_SECTION_NAME, UNLIKELY_EXECUTED_TEXT_SECTION_NAME): Poison. From-SVN: r167085
This commit is contained in:
parent
7f814c0bb0
commit
f16d3f392e
@ -1,3 +1,45 @@
|
||||
2010-11-23 Jan Hubicka <jh@suse.cz>
|
||||
|
||||
* tree.h (DECL_HAS_IMPLICIT_SECTION_NAME_P): New macro.
|
||||
(tree_decl_with_vis): Add implicit_section_name_p.
|
||||
* targhooks.h (default_function_section): Declare.
|
||||
* target.def (function_section): New hook.
|
||||
* defaults.h (HOT_TEXT_SECTION_NAME,
|
||||
UNLIKELY_EXECUTED_TEXT_SECTION_NAME): Remove.
|
||||
* predict.c (choose_function_section): Remove.
|
||||
(estimate_bb_frequencies): Do not use choose_function_section.
|
||||
* coretypes.h (enum node_frequency): Move here from cgraph.h
|
||||
* cgraph.h (enum node_frequency): Remove.
|
||||
* varasm.c (initialize_cold_section_name, unlikely_text_section,
|
||||
unlikely_text_section_p): Remove.
|
||||
(named_subsection_entry): New structure.
|
||||
(get_text_section): New function.
|
||||
(default_function_section): New function.
|
||||
(function_section_1): Break out from ...; handle profile info.
|
||||
(function_section): ... here.
|
||||
(unlikely_text_section): Remove.
|
||||
(unlikely_text_section_p): Use function_section_1.
|
||||
(assemble_start_function): Do not initialize cold section.
|
||||
(default_section_type_flags): Do not special case cold subsection.
|
||||
(switch_to_section): Likewise.
|
||||
* output.h (get_text_section): Define.
|
||||
* config/i386/winnt.c: Do not special case cold section.
|
||||
* config/darwin-protos.h (darwin_function_section): Declare.
|
||||
* config/microblaze/microblaze.h (HOT_TEXT_SECTION_NAME,
|
||||
UNLIKELY_EXECUTED_TEXT_SECTION_NAME): Remove.
|
||||
* config/ia64/hpux.h (HOT_TEXT_SECTION_NAME,
|
||||
UNLIKELY_EXECUTED_TEXT_SECTION_NAME): Remove.
|
||||
(TARGET_ASM_FUNCTION_SECTION): Define to ia64_hpux_function_section.
|
||||
* config/ia64/ia64.c (ia64_hpux_function_section): New function.
|
||||
* config/darwin.c (machopic_select_section): Use
|
||||
darwin_function_section.
|
||||
(darwin_function_section): New function.
|
||||
* config/darwin.h (HOT_TEXT_SECTION_NAME,
|
||||
UNLIKELY_EXECUTED_TEXT_SECTION_NAME): Remove.
|
||||
(TARGET_ASM_FUNCTION_SECTION): Define.
|
||||
* system.h (HOT_TEXT_SECTION_NAME,
|
||||
UNLIKELY_EXECUTED_TEXT_SECTION_NAME): Poison.
|
||||
|
||||
2010-11-23 Iain Sandoe <iains@gcc.gnu.org>
|
||||
|
||||
* config/darwin.h (LINK_COMMAND_SPEC_A): Use %(link_gcc_c_sequence).
|
||||
|
14
gcc/cgraph.h
14
gcc/cgraph.h
@ -180,20 +180,6 @@ struct GTY(()) cgraph_clone_info
|
||||
bitmap combined_args_to_skip;
|
||||
};
|
||||
|
||||
enum node_frequency {
|
||||
/* This function most likely won't be executed at all.
|
||||
(set only when profile feedback is available or via function attribute). */
|
||||
NODE_FREQUENCY_UNLIKELY_EXECUTED,
|
||||
/* For functions that are known to be executed once (i.e. constructors, destructors
|
||||
and main function. */
|
||||
NODE_FREQUENCY_EXECUTED_ONCE,
|
||||
/* The default value. */
|
||||
NODE_FREQUENCY_NORMAL,
|
||||
/* Optimize this function hard
|
||||
(set only when profile feedback is available or via function attribute). */
|
||||
NODE_FREQUENCY_HOT
|
||||
};
|
||||
|
||||
|
||||
/* The cgraph data structure.
|
||||
Each function decl has assigned cgraph_node listing callees and callers. */
|
||||
|
@ -1142,6 +1142,10 @@
|
||||
#undef HAVE_LD_DEMANGLE
|
||||
#endif
|
||||
|
||||
/* Define if your linker supports plugin. */
|
||||
#ifndef USED_FOR_TARGET
|
||||
#undef HAVE_LD_PLUGIN
|
||||
#endif
|
||||
|
||||
/* Define if your linker supports --eh-frame-hdr option. */
|
||||
#undef HAVE_LD_EH_FRAME_HDR
|
||||
|
@ -57,6 +57,7 @@ extern section *machopic_select_section (tree, int, unsigned HOST_WIDE_INT);
|
||||
extern section *machopic_select_rtx_section (enum machine_mode, rtx,
|
||||
unsigned HOST_WIDE_INT);
|
||||
|
||||
extern section *darwin_function_section (tree, enum node_frequency, bool, bool);
|
||||
extern void darwin_unique_section (tree decl, int reloc);
|
||||
extern void darwin_asm_named_section (const char *, unsigned int, tree);
|
||||
extern void darwin_non_lazy_pcrel (FILE *, rtx);
|
||||
|
@ -1233,12 +1233,22 @@ machopic_select_section (tree decl,
|
||||
&& DECL_WEAK (decl)
|
||||
&& !lookup_attribute ("weak_import",
|
||||
DECL_ATTRIBUTES (decl)));
|
||||
section *base_section;
|
||||
section *base_section = NULL;
|
||||
|
||||
switch (categorize_decl_for_section (decl, reloc))
|
||||
{
|
||||
case SECCAT_TEXT:
|
||||
base_section = darwin_text_section (reloc, weak);
|
||||
{
|
||||
struct cgraph_node *node;
|
||||
if (decl && TREE_CODE (decl) == FUNCTION_DECL
|
||||
&& (node = cgraph_get_node (decl)) != NULL)
|
||||
base_section = darwin_function_section (decl,
|
||||
node->frequency,
|
||||
node->only_called_at_startup,
|
||||
node->only_called_at_exit);
|
||||
if (!base_section)
|
||||
base_section = darwin_text_section (reloc, weak);
|
||||
}
|
||||
break;
|
||||
|
||||
case SECCAT_RODATA:
|
||||
@ -2362,4 +2372,38 @@ darwin_enter_string_into_cfstring_table (tree str)
|
||||
}
|
||||
}
|
||||
|
||||
/* Choose named function section based on its frequency. */
|
||||
|
||||
section *
|
||||
darwin_function_section (tree decl, enum node_frequency freq,
|
||||
bool startup, bool exit)
|
||||
{
|
||||
/* Startup code should go to startup subsection unless it is
|
||||
unlikely executed (this happens especially with function splitting
|
||||
where we can split away unnecesary parts of static constructors. */
|
||||
if (startup && freq != NODE_FREQUENCY_UNLIKELY_EXECUTED)
|
||||
return get_named_text_section
|
||||
(decl, "__TEXT,__startup,regular,pure_instructions", "_startup");
|
||||
|
||||
/* Similarly for exit. */
|
||||
if (exit && freq != NODE_FREQUENCY_UNLIKELY_EXECUTED)
|
||||
return get_named_text_section (decl,
|
||||
"__TEXT,__exit,regular,pure_instructions",
|
||||
"_exit");
|
||||
|
||||
/* Group cold functions together, similarly for hot code. */
|
||||
switch (freq)
|
||||
{
|
||||
case NODE_FREQUENCY_UNLIKELY_EXECUTED:
|
||||
return get_named_text_section
|
||||
(decl,
|
||||
"__TEXT,__unlikely,regular,pure_instructions", "_unlikely");
|
||||
case NODE_FREQUENCY_HOT:
|
||||
return get_named_text_section
|
||||
(decl, "__TEXT,__hot,regular,pure_instructions", "_hot");
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
#include "gt-darwin.h"
|
||||
|
@ -664,11 +664,6 @@ int darwin_label_is_anonymous_local_objc_name (const char *name);
|
||||
/* The generic version, archs should over-ride where required. */
|
||||
#define MACHOPIC_NL_SYMBOL_PTR_SECTION ".non_lazy_symbol_pointer"
|
||||
|
||||
/* These are used by -fbranch-probabilities */
|
||||
#define HOT_TEXT_SECTION_NAME "__TEXT,__text,regular,pure_instructions"
|
||||
#define UNLIKELY_EXECUTED_TEXT_SECTION_NAME \
|
||||
"__TEXT,__unlikely,regular,pure_instructions"
|
||||
|
||||
/* Declare the section variables. */
|
||||
#ifndef USED_FOR_TARGET
|
||||
enum darwin_section_enum {
|
||||
@ -683,6 +678,8 @@ extern GTY(()) section * darwin_sections[NUM_DARWIN_SECTIONS];
|
||||
#undef TARGET_ASM_SELECT_SECTION
|
||||
#define TARGET_ASM_SELECT_SECTION machopic_select_section
|
||||
#define USE_SELECT_SECTION_FOR_FUNCTIONS
|
||||
#undef TARGET_ASM_FUNCTION_SECTION
|
||||
#define TARGET_ASM_FUNCTION_SECTION darwin_function_section
|
||||
|
||||
#undef TARGET_ASM_SELECT_RTX_SECTION
|
||||
#define TARGET_ASM_SELECT_RTX_SECTION machopic_select_rtx_section
|
||||
|
@ -414,15 +414,6 @@ i386_pe_section_type_flags (tree decl, const char *name, int reloc)
|
||||
flags = SECTION_CODE;
|
||||
else if (decl && decl_readonly_section (decl, reloc))
|
||||
flags = 0;
|
||||
else if (current_function_decl
|
||||
&& cfun
|
||||
&& crtl->subsections.unlikely_text_section_name
|
||||
&& strcmp (name, crtl->subsections.unlikely_text_section_name) == 0)
|
||||
flags = SECTION_CODE;
|
||||
else if (!decl
|
||||
&& (!current_function_decl || !cfun)
|
||||
&& strcmp (name, UNLIKELY_EXECUTED_TEXT_SECTION_NAME) == 0)
|
||||
flags = SECTION_CODE;
|
||||
else
|
||||
{
|
||||
flags = SECTION_WRITE;
|
||||
|
@ -218,8 +218,4 @@ do { \
|
||||
it is fixed, prevent code from being put into .text.unlikely or
|
||||
.text.hot. */
|
||||
|
||||
#undef UNLIKELY_EXECUTED_TEXT_SECTION_NAME
|
||||
#define UNLIKELY_EXECUTED_TEXT_SECTION_NAME ".text"
|
||||
|
||||
#undef HOT_TEXT_SECTION_NAME
|
||||
#define HOT_TEXT_SECTION_NAME ".text"
|
||||
#define TARGET_ASM_FUNCTION_SECTION ia64_hpux_function_section
|
||||
|
@ -336,6 +336,8 @@ static tree ia64_builtin_decl (unsigned, bool);
|
||||
|
||||
static reg_class_t ia64_preferred_reload_class (rtx, reg_class_t);
|
||||
static enum machine_mode ia64_get_reg_raw_mode (int regno);
|
||||
static section * ia64_hpux_function_section (tree, enum node_frequency,
|
||||
bool, bool);
|
||||
|
||||
/* Table of valid machine attributes. */
|
||||
static const struct attribute_spec ia64_attribute_table[] =
|
||||
@ -11022,4 +11024,15 @@ ia64_get_reg_raw_mode (int regno)
|
||||
return default_get_reg_raw_mode(regno);
|
||||
}
|
||||
|
||||
/* Always default to .text section until HP-UX linker is fixed. */
|
||||
|
||||
ATTRIBUTE_UNUSED static section *
|
||||
ia64_hpux_function_section (tree decl ATTRIBUTE_UNUSED,
|
||||
enum node_frequency freq ATTRIBUTE_UNUSED,
|
||||
bool startup ATTRIBUTE_UNUSED,
|
||||
bool exit ATTRIBUTE_UNUSED)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#include "gt-ia64.h"
|
||||
|
@ -880,10 +880,6 @@ do { \
|
||||
#define SBSS_SECTION_ASM_OP "\t.sbss" /* Small RW uninitialized data */
|
||||
#define SBSS2_SECTION_ASM_OP "\t.sbss2" /* Small RO uninitialized data */
|
||||
|
||||
#define HOT_TEXT_SECTION_NAME ".text.hot"
|
||||
#define UNLIKELY_EXECUTED_TEXT_SECTION_NAME \
|
||||
".text.unlikely"
|
||||
|
||||
/* We do this to save a few 10s of code space that would be taken up
|
||||
by the call_FUNC () wrappers, used by the generic CRT_CALL_STATIC_FUNCTION
|
||||
definition in crtstuff.c. */
|
||||
|
@ -3127,6 +3127,28 @@ if test x"$demangler_in_ld" = xyes; then
|
||||
AC_MSG_RESULT($gcc_cv_ld_demangle)
|
||||
fi
|
||||
|
||||
if test x"$linker_plugin_in_ld" = xyes; then
|
||||
AC_MSG_CHECKING(linker support)
|
||||
gcc_cv_ld_plugin=no
|
||||
if test x"$ld_is_gold" = xyes; then
|
||||
gcc_cv_ld_plugin=yes
|
||||
else if test $in_tree_ld = yes; then
|
||||
if test "$gcc_cv_gld_major_version" -eq 2 -a "$gcc_cv_gld_minor_version" -ge 21 -o "$gcc_cv_gld_major_version" -gt 2; then \
|
||||
gcc_cv_ld_plugin=yes
|
||||
fi
|
||||
elif test x$PLUGIN_LD != x -a x"$gnu_ld" = xyes; then
|
||||
# Check if the GNU linker supports --plugin-opt option
|
||||
if $gcc_cv_ld --help 2>/dev/null | grep no-demangle > /dev/null; then
|
||||
gcc_cv_ld_plugin=yes
|
||||
fi
|
||||
fi
|
||||
if test x"$gcc_cv_ld_plugin" = xyes; then
|
||||
AC_DEFINE(HAVE_LD_PLUGIN, 1,
|
||||
[Define if your linker supports plugin.])
|
||||
fi
|
||||
AC_MSG_RESULT($gcc_cv_ld_plugin)
|
||||
fi
|
||||
|
||||
case "$target" in
|
||||
# All TARGET_ABI_OSF targets.
|
||||
alpha*-*-osf* | alpha*-*-linux* | alpha*-*-*bsd*)
|
||||
|
@ -121,6 +121,22 @@ enum unwind_info_type
|
||||
UI_TARGET
|
||||
};
|
||||
|
||||
/* Callgraph node profile representation. */
|
||||
enum node_frequency {
|
||||
/* This function most likely won't be executed at all.
|
||||
(set only when profile feedback is available or via function attribute). */
|
||||
NODE_FREQUENCY_UNLIKELY_EXECUTED,
|
||||
/* For functions that are known to be executed once (i.e. constructors, destructors
|
||||
and main function. */
|
||||
NODE_FREQUENCY_EXECUTED_ONCE,
|
||||
/* The default value. */
|
||||
NODE_FREQUENCY_NORMAL,
|
||||
/* Optimize this function hard
|
||||
(set only when profile feedback is available or via function attribute). */
|
||||
NODE_FREQUENCY_HOT
|
||||
};
|
||||
|
||||
|
||||
struct edge_def;
|
||||
typedef struct edge_def *edge;
|
||||
typedef const struct edge_def *const_edge;
|
||||
|
@ -897,14 +897,6 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
||||
#define TARGET_DEC_EVAL_METHOD 2
|
||||
#endif
|
||||
|
||||
#ifndef HOT_TEXT_SECTION_NAME
|
||||
#define HOT_TEXT_SECTION_NAME ".text.hot"
|
||||
#endif
|
||||
|
||||
#ifndef UNLIKELY_EXECUTED_TEXT_SECTION_NAME
|
||||
#define UNLIKELY_EXECUTED_TEXT_SECTION_NAME ".text.unlikely"
|
||||
#endif
|
||||
|
||||
#ifndef HAS_LONG_COND_BRANCH
|
||||
#define HAS_LONG_COND_BRANCH 0
|
||||
#endif
|
||||
|
@ -7328,6 +7328,16 @@ is non-NULL, it is the @code{VAR_DECL} or @code{FUNCTION_DECL} with which
|
||||
this section is associated.
|
||||
@end deftypefn
|
||||
|
||||
@deftypefn {Target Hook} {section *} TARGET_ASM_FUNCTION_SECTION (tree @var{decl}, enum node_frequency @var{freq}, bool @var{startup}, bool @var{exit})
|
||||
Return preferred text (sub)section for function @var{decl}.
|
||||
Main purpose of this function is to separate cold, normal and hot
|
||||
functions. @var{startup} is true when function is known to be used only
|
||||
at startup (from static constructors or it is @code{main()}).
|
||||
@var{exit} is true when function is known to be used only at exit
|
||||
(from static destructors).
|
||||
Return NULL if function should go to default text section.
|
||||
@end deftypefn
|
||||
|
||||
@deftypevr {Target Hook} bool TARGET_HAVE_NAMED_SECTIONS
|
||||
This flag is true if the target supports @code{TARGET_ASM_NAMED_SECTION}.
|
||||
@end deftypevr
|
||||
|
@ -7303,6 +7303,16 @@ is non-NULL, it is the @code{VAR_DECL} or @code{FUNCTION_DECL} with which
|
||||
this section is associated.
|
||||
@end deftypefn
|
||||
|
||||
@hook TARGET_ASM_FUNCTION_SECTION
|
||||
Return preferred text (sub)section for function @var{decl}.
|
||||
Main purpose of this function is to separate cold, normal and hot
|
||||
functions. @var{startup} is true when function is known to be used only
|
||||
at startup (from static constructors or it is @code{main()}).
|
||||
@var{exit} is true when function is known to be used only at exit
|
||||
(from static destructors).
|
||||
Return NULL if function should go to default text section.
|
||||
@end deftypefn
|
||||
|
||||
@hook TARGET_HAVE_NAMED_SECTIONS
|
||||
This flag is true if the target supports @code{TARGET_ASM_NAMED_SECTION}.
|
||||
@end deftypevr
|
||||
|
@ -226,11 +226,6 @@ struct GTY(()) function_subsections {
|
||||
const char *cold_section_label;
|
||||
const char *hot_section_end_label;
|
||||
const char *cold_section_end_label;
|
||||
|
||||
/* String to be used for name of cold text sections, via
|
||||
targetm.asm_out.named_section. */
|
||||
|
||||
const char *unlikely_text_section_name;
|
||||
};
|
||||
|
||||
/* Describe an empty area of space in the stack frame. These can be chained
|
||||
|
@ -269,6 +269,10 @@ extern bool default_assemble_integer (rtx, unsigned int, int);
|
||||
be outputable. */
|
||||
extern bool assemble_integer (rtx, unsigned, unsigned, int);
|
||||
|
||||
/* Return section for TEXT_SECITON_NAME if DECL or DECL_SECTION_NAME (DECL)
|
||||
is NULL. */
|
||||
extern section *get_named_text_section (tree, const char *, const char *);
|
||||
|
||||
/* An interface to assemble_integer for the common case in which a value is
|
||||
fully aligned and must be printed. VALUE is the value of the integer
|
||||
object and SIZE is the number of bytes it contains. */
|
||||
|
@ -78,7 +78,6 @@ static sreal real_zero, real_one, real_almost_one, real_br_prob_base,
|
||||
static void combine_predictions_for_insn (rtx, basic_block);
|
||||
static void dump_prediction (FILE *, enum br_predictor, int, basic_block, int);
|
||||
static void predict_paths_leading_to (basic_block, enum br_predictor, enum prediction);
|
||||
static void choose_function_section (void);
|
||||
static bool can_predict_insn_p (const_rtx);
|
||||
|
||||
/* Information we hold about each branch predictor.
|
||||
@ -2185,8 +2184,6 @@ estimate_bb_frequencies (void)
|
||||
free_aux_for_edges ();
|
||||
}
|
||||
compute_function_frequency ();
|
||||
if (flag_reorder_functions)
|
||||
choose_function_section ();
|
||||
}
|
||||
|
||||
/* Decide whether function is hot, cold or unlikely executed. */
|
||||
@ -2232,35 +2229,6 @@ compute_function_frequency (void)
|
||||
}
|
||||
}
|
||||
|
||||
/* Choose appropriate section for the function. */
|
||||
static void
|
||||
choose_function_section (void)
|
||||
{
|
||||
struct cgraph_node *node = cgraph_node (current_function_decl);
|
||||
if (DECL_SECTION_NAME (current_function_decl)
|
||||
|| !targetm.have_named_sections
|
||||
/* Theoretically we can split the gnu.linkonce text section too,
|
||||
but this requires more work as the frequency needs to match
|
||||
for all generated objects so we need to merge the frequency
|
||||
of all instances. For now just never set frequency for these. */
|
||||
|| DECL_ONE_ONLY (current_function_decl))
|
||||
return;
|
||||
|
||||
/* If we are doing the partitioning optimization, let the optimization
|
||||
choose the correct section into which to put things. */
|
||||
|
||||
if (flag_reorder_blocks_and_partition)
|
||||
return;
|
||||
|
||||
if (node->frequency == NODE_FREQUENCY_HOT)
|
||||
DECL_SECTION_NAME (current_function_decl) =
|
||||
build_string (strlen (HOT_TEXT_SECTION_NAME), HOT_TEXT_SECTION_NAME);
|
||||
if (node->frequency == NODE_FREQUENCY_UNLIKELY_EXECUTED)
|
||||
DECL_SECTION_NAME (current_function_decl) =
|
||||
build_string (strlen (UNLIKELY_EXECUTED_TEXT_SECTION_NAME),
|
||||
UNLIKELY_EXECUTED_TEXT_SECTION_NAME);
|
||||
}
|
||||
|
||||
static bool
|
||||
gate_estimate_probability (void)
|
||||
{
|
||||
|
@ -725,8 +725,9 @@ extern void fancy_abort (const char *, int, const char *) ATTRIBUTE_NORETURN;
|
||||
OPTIMIZATION_OPTIONS CLASS_LIKELY_SPILLED_P \
|
||||
USING_SJLJ_EXCEPTIONS TARGET_UNWIND_INFO \
|
||||
LABEL_ALIGN_MAX_SKIP LOOP_ALIGN_MAX_SKIP \
|
||||
LABEL_ALIGN_AFTER_BARRIER_MAX_SKIP JUMP_ALIGN_MAX_SKIP \
|
||||
CAN_DEBUG_WITHOUT_FP
|
||||
LABEL_ALIGN_AFTER_BARRIER_MAX_SKIP JUMP_ALIGN_MAX_SKIP \
|
||||
CAN_DEBUG_WITHOUT_FP UNLIKELY_EXECUTED_TEXT_SECTION_NAME \
|
||||
HOT_TEXT_SECTION_NAME
|
||||
|
||||
/* Other obsolete target macros, or macros that used to be in target
|
||||
headers and were not used, and may be obsolete or may never have
|
||||
|
@ -281,6 +281,19 @@ DEFHOOK
|
||||
void, (const char *name, unsigned int flags, tree decl),
|
||||
default_no_named_section)
|
||||
|
||||
/* Return preferred text (sub)section for function DECL.
|
||||
Main purpose of this function is to separate cold, normal and hot
|
||||
functions. STARTUP is true when function is known to be used only
|
||||
at startup (from static constructors or it is main()).
|
||||
EXIT is true when function is known to be used only at exit
|
||||
(from static destructors).
|
||||
Return NULL if function should go to default text section. */
|
||||
DEFHOOK
|
||||
(function_section,
|
||||
"",
|
||||
section *, (tree decl, enum node_frequency freq, bool startup, bool exit),
|
||||
default_function_section)
|
||||
|
||||
/* Return a mask describing how relocations should be treated when
|
||||
selecting sections. Bit 1 should be set if global relocations
|
||||
should be placed in a read-write section; bit 0 should be set if
|
||||
|
@ -171,7 +171,8 @@ extern int default_label_align_after_barrier_max_skip (rtx);
|
||||
extern int default_loop_align_max_skip (rtx);
|
||||
extern int default_label_align_max_skip (rtx);
|
||||
extern int default_jump_align_max_skip (rtx);
|
||||
|
||||
extern section * default_function_section(tree decl, enum node_frequency freq,
|
||||
bool startup, bool exit);
|
||||
extern enum machine_mode default_get_reg_raw_mode(int);
|
||||
|
||||
extern const struct default_options empty_optimization_table[];
|
||||
|
@ -3107,6 +3107,11 @@ struct GTY(()) tree_parm_decl {
|
||||
#define DECL_HAS_INIT_PRIORITY_P(NODE) \
|
||||
(VAR_DECL_CHECK (NODE)->decl_with_vis.init_priority_p)
|
||||
|
||||
/* Specify whether the section name was set by user or by
|
||||
compiler via -ffunction-sections. */
|
||||
#define DECL_HAS_IMPLICIT_SECTION_NAME_P(NODE) \
|
||||
(DECL_WITH_VIS_CHECK (NODE)->decl_with_vis.implicit_section_name_p)
|
||||
|
||||
struct GTY(()) tree_decl_with_vis {
|
||||
struct tree_decl_with_rtl common;
|
||||
tree assembler_name;
|
||||
@ -3135,7 +3140,9 @@ struct GTY(()) tree_decl_with_vis {
|
||||
unsigned init_priority_p : 1;
|
||||
/* Used by C++ only. Might become a generic decl flag. */
|
||||
unsigned shadowed_for_var_p : 1;
|
||||
/* 14 unused bits. */
|
||||
/* When SECTION_NAME is implied by -ffunsection-section. */
|
||||
unsigned implicit_section_name_p : 1;
|
||||
/* 13 unused bits. */
|
||||
};
|
||||
|
||||
extern tree decl_debug_expr_lookup (tree);
|
||||
|
286
gcc/varasm.c
286
gcc/varasm.c
@ -368,69 +368,6 @@ create_block_symbol (const char *label, struct object_block *block,
|
||||
return symbol;
|
||||
}
|
||||
|
||||
static void
|
||||
initialize_cold_section_name (void)
|
||||
{
|
||||
const char *stripped_name;
|
||||
char *name, *buffer;
|
||||
tree dsn;
|
||||
|
||||
gcc_assert (cfun && current_function_decl);
|
||||
if (crtl->subsections.unlikely_text_section_name)
|
||||
return;
|
||||
|
||||
dsn = DECL_SECTION_NAME (current_function_decl);
|
||||
if (flag_function_sections && dsn)
|
||||
{
|
||||
name = (char *) alloca (TREE_STRING_LENGTH (dsn) + 1);
|
||||
memcpy (name, TREE_STRING_POINTER (dsn), TREE_STRING_LENGTH (dsn) + 1);
|
||||
|
||||
stripped_name = targetm.strip_name_encoding (name);
|
||||
|
||||
buffer = ACONCAT ((stripped_name, "_unlikely", NULL));
|
||||
crtl->subsections.unlikely_text_section_name = ggc_strdup (buffer);
|
||||
}
|
||||
else
|
||||
crtl->subsections.unlikely_text_section_name = UNLIKELY_EXECUTED_TEXT_SECTION_NAME;
|
||||
}
|
||||
|
||||
/* Tell assembler to switch to unlikely-to-be-executed text section. */
|
||||
|
||||
section *
|
||||
unlikely_text_section (void)
|
||||
{
|
||||
if (cfun)
|
||||
{
|
||||
if (!crtl->subsections.unlikely_text_section_name)
|
||||
initialize_cold_section_name ();
|
||||
|
||||
return get_named_section (NULL, crtl->subsections.unlikely_text_section_name, 0);
|
||||
}
|
||||
else
|
||||
return get_named_section (NULL, UNLIKELY_EXECUTED_TEXT_SECTION_NAME, 0);
|
||||
}
|
||||
|
||||
/* When called within a function context, return true if the function
|
||||
has been assigned a cold text section and if SECT is that section.
|
||||
When called outside a function context, return true if SECT is the
|
||||
default cold section. */
|
||||
|
||||
bool
|
||||
unlikely_text_section_p (section *sect)
|
||||
{
|
||||
const char *name;
|
||||
|
||||
if (cfun)
|
||||
name = crtl->subsections.unlikely_text_section_name;
|
||||
else
|
||||
name = UNLIKELY_EXECUTED_TEXT_SECTION_NAME;
|
||||
|
||||
return (name
|
||||
&& sect
|
||||
&& SECTION_STYLE (sect) == SECTION_NAMED
|
||||
&& strcmp (name, sect->named.name) == 0);
|
||||
}
|
||||
|
||||
/* Return a section with a particular name and with whatever SECTION_*
|
||||
flags section_type_flags deems appropriate. The name of the section
|
||||
is taken from NAME if nonnull, otherwise it is taken from DECL's
|
||||
@ -462,7 +399,10 @@ resolve_unique_section (tree decl, int reloc ATTRIBUTE_UNUSED,
|
||||
&& targetm.have_named_sections
|
||||
&& (flag_function_or_data_sections
|
||||
|| DECL_ONE_ONLY (decl)))
|
||||
targetm.asm_out.unique_section (decl, reloc);
|
||||
{
|
||||
targetm.asm_out.unique_section (decl, reloc);
|
||||
DECL_HAS_IMPLICIT_SECTION_NAME_P (decl) = true;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef BSS_SECTION_ASM_OP
|
||||
@ -539,6 +479,133 @@ hot_function_section (tree decl)
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Return section for TEXT_SECTION_NAME if DECL or DECL_SECTION_NAME (DECL)
|
||||
is NULL.
|
||||
|
||||
When DECL_SECTION_NAME is non-NULL and it is implicit section and
|
||||
NAMED_SECTION_SUFFIX is non-NULL, then produce section called
|
||||
concatenate the name with NAMED_SECTION_SUFFIX.
|
||||
Otherwise produce "TEXT_SECTION_NAME.IMPLICIT_NAME". */
|
||||
|
||||
section *
|
||||
get_named_text_section (tree decl,
|
||||
const char *text_section_name,
|
||||
const char *named_section_suffix)
|
||||
{
|
||||
if (decl && DECL_SECTION_NAME (decl))
|
||||
{
|
||||
if (named_section_suffix)
|
||||
{
|
||||
tree dsn = DECL_SECTION_NAME (decl);
|
||||
const char *stripped_name;
|
||||
char *name, *buffer;
|
||||
|
||||
name = (char *) alloca (TREE_STRING_LENGTH (dsn) + 1);
|
||||
memcpy (name, TREE_STRING_POINTER (dsn),
|
||||
TREE_STRING_LENGTH (dsn) + 1);
|
||||
|
||||
stripped_name = targetm.strip_name_encoding (name);
|
||||
|
||||
buffer = ACONCAT ((stripped_name, named_section_suffix, NULL));
|
||||
return get_named_section (decl, buffer, 0);
|
||||
}
|
||||
else if (DECL_HAS_IMPLICIT_SECTION_NAME_P (decl))
|
||||
{
|
||||
const char *name;
|
||||
|
||||
/* Do not try to split gnu_linkonce functions. This gets somewhat
|
||||
slipperly. */
|
||||
if (DECL_ONE_ONLY (decl) && !HAVE_COMDAT_GROUP)
|
||||
return NULL;
|
||||
name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
|
||||
name = targetm.strip_name_encoding (name);
|
||||
return get_named_section (decl, ACONCAT ((text_section_name, ".",
|
||||
name, NULL)), 0);
|
||||
}
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
return get_named_section (decl, text_section_name, 0);
|
||||
}
|
||||
|
||||
/* Choose named function section based on its frequency. */
|
||||
|
||||
section *
|
||||
default_function_section (tree decl, enum node_frequency freq,
|
||||
bool startup, bool exit)
|
||||
{
|
||||
/* Startup code should go to startup subsection unless it is
|
||||
unlikely executed (this happens especially with function splitting
|
||||
where we can split away unnecesary parts of static constructors. */
|
||||
if (startup && freq != NODE_FREQUENCY_UNLIKELY_EXECUTED)
|
||||
return get_named_text_section (decl, ".text.startup", NULL);
|
||||
|
||||
/* Similarly for exit. */
|
||||
if (exit && freq != NODE_FREQUENCY_UNLIKELY_EXECUTED)
|
||||
return get_named_text_section (decl, ".text.exit", NULL);
|
||||
|
||||
/* Group cold functions together, similarly for hot code. */
|
||||
switch (freq)
|
||||
{
|
||||
case NODE_FREQUENCY_UNLIKELY_EXECUTED:
|
||||
return get_named_text_section (decl, ".text.unlikely", NULL);
|
||||
case NODE_FREQUENCY_HOT:
|
||||
return get_named_text_section (decl, ".text.hot", NULL);
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* Return the section for function DECL.
|
||||
|
||||
If DECL is NULL_TREE, return the text section. We can be passed
|
||||
NULL_TREE under some circumstances by dbxout.c at least.
|
||||
|
||||
If FORCE_COLD is true, return cold function section ignoring
|
||||
the frequency info of cgraph_node. */
|
||||
|
||||
static section *
|
||||
function_section_1 (tree decl, bool force_cold)
|
||||
{
|
||||
section *section = NULL;
|
||||
enum node_frequency freq = NODE_FREQUENCY_NORMAL;
|
||||
bool startup = false, exit = false;
|
||||
|
||||
if (decl)
|
||||
{
|
||||
struct cgraph_node *node = cgraph_node (decl);
|
||||
|
||||
freq = node->frequency;
|
||||
startup = node->only_called_at_startup;
|
||||
exit = node->only_called_at_exit;
|
||||
}
|
||||
if (force_cold)
|
||||
freq = NODE_FREQUENCY_UNLIKELY_EXECUTED;
|
||||
|
||||
#ifdef USE_SELECT_SECTION_FOR_FUNCTIONS
|
||||
if (decl != NULL_TREE
|
||||
&& DECL_SECTION_NAME (decl) != NULL_TREE)
|
||||
{
|
||||
if (targetm.asm_out.function_section)
|
||||
section = targetm.asm_out.function_section (decl, freq,
|
||||
startup, exit);
|
||||
if (section)
|
||||
return section;
|
||||
return get_named_section (decl, NULL, 0);
|
||||
}
|
||||
else
|
||||
return targetm.asm_out.select_section
|
||||
(decl, freq == NODE_FREQUENCY_UNLIKELY_EXECUTED,
|
||||
DECL_ALIGN (decl));
|
||||
#else
|
||||
if (targetm.asm_out.function_section)
|
||||
section = targetm.asm_out.function_section (decl, freq, startup, exit);
|
||||
if (section)
|
||||
return section;
|
||||
return hot_function_section (decl);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Return the section for function DECL.
|
||||
|
||||
If DECL is NULL_TREE, return the text section. We can be passed
|
||||
@ -547,41 +614,41 @@ hot_function_section (tree decl)
|
||||
section *
|
||||
function_section (tree decl)
|
||||
{
|
||||
int reloc = 0;
|
||||
|
||||
if (first_function_block_is_cold)
|
||||
reloc = 1;
|
||||
|
||||
#ifdef USE_SELECT_SECTION_FOR_FUNCTIONS
|
||||
if (decl != NULL_TREE
|
||||
&& DECL_SECTION_NAME (decl) != NULL_TREE)
|
||||
return reloc ? unlikely_text_section ()
|
||||
: get_named_section (decl, NULL, 0);
|
||||
else
|
||||
return targetm.asm_out.select_section (decl, reloc, DECL_ALIGN (decl));
|
||||
#else
|
||||
return reloc ? unlikely_text_section () : hot_function_section (decl);
|
||||
#endif
|
||||
/* Handle cases where function splitting code decides
|
||||
to put function entry point into unlikely executed section
|
||||
despite the fact that the function itself is not cold
|
||||
(i.e. it is called rarely but contains a hot loop that is
|
||||
better to live in hot subsection for the code locality). */
|
||||
return function_section_1 (decl,
|
||||
first_function_block_is_cold);
|
||||
}
|
||||
|
||||
/* Return the section for the current function, take IN_COLD_SECTION_P
|
||||
into account. */
|
||||
|
||||
section *
|
||||
current_function_section (void)
|
||||
{
|
||||
#ifdef USE_SELECT_SECTION_FOR_FUNCTIONS
|
||||
if (current_function_decl != NULL_TREE
|
||||
&& DECL_SECTION_NAME (current_function_decl) != NULL_TREE)
|
||||
return in_cold_section_p ? unlikely_text_section ()
|
||||
: get_named_section (current_function_decl,
|
||||
NULL, 0);
|
||||
else
|
||||
return targetm.asm_out.select_section (current_function_decl,
|
||||
in_cold_section_p,
|
||||
DECL_ALIGN (current_function_decl));
|
||||
#else
|
||||
return (in_cold_section_p
|
||||
? unlikely_text_section ()
|
||||
: hot_function_section (current_function_decl));
|
||||
#endif
|
||||
return function_section_1 (current_function_decl, in_cold_section_p);
|
||||
}
|
||||
|
||||
/* Tell assembler to switch to unlikely-to-be-executed text section. */
|
||||
|
||||
section *
|
||||
unlikely_text_section (void)
|
||||
{
|
||||
return function_section_1 (current_function_decl, true);
|
||||
}
|
||||
|
||||
/* When called within a function context, return true if the function
|
||||
has been assigned a cold text section and if SECT is that section.
|
||||
When called outside a function context, return true if SECT is the
|
||||
default cold section. */
|
||||
|
||||
bool
|
||||
unlikely_text_section_p (section *sect)
|
||||
{
|
||||
return sect == function_section_1 (current_function_decl, true);
|
||||
}
|
||||
|
||||
/* Return the read-only data section associated with function DECL. */
|
||||
@ -1454,8 +1521,6 @@ assemble_start_function (tree decl, const char *fnname)
|
||||
char tmp_label[100];
|
||||
bool hot_label_written = false;
|
||||
|
||||
crtl->subsections.unlikely_text_section_name = NULL;
|
||||
|
||||
first_function_block_is_cold = false;
|
||||
if (flag_reorder_blocks_and_partition)
|
||||
{
|
||||
@ -1513,16 +1578,10 @@ assemble_start_function (tree decl, const char *fnname)
|
||||
else if (DECL_SECTION_NAME (decl))
|
||||
{
|
||||
/* Calls to function_section rely on first_function_block_is_cold
|
||||
being accurate. The first block may be cold even if we aren't
|
||||
doing partitioning, if the entire function was decided by
|
||||
choose_function_section (predict.c) to be cold. */
|
||||
|
||||
initialize_cold_section_name ();
|
||||
|
||||
if (crtl->subsections.unlikely_text_section_name
|
||||
&& strcmp (TREE_STRING_POINTER (DECL_SECTION_NAME (decl)),
|
||||
crtl->subsections.unlikely_text_section_name) == 0)
|
||||
first_function_block_is_cold = true;
|
||||
being accurate. */
|
||||
first_function_block_is_cold
|
||||
= (cgraph_node (current_function_decl)->frequency
|
||||
== NODE_FREQUENCY_UNLIKELY_EXECUTED);
|
||||
}
|
||||
|
||||
in_cold_section_p = first_function_block_is_cold;
|
||||
@ -5871,15 +5930,6 @@ default_section_type_flags (tree decl, const char *name, int reloc)
|
||||
flags = SECTION_CODE;
|
||||
else if (decl && decl_readonly_section (decl, reloc))
|
||||
flags = 0;
|
||||
else if (current_function_decl
|
||||
&& cfun
|
||||
&& crtl->subsections.unlikely_text_section_name
|
||||
&& strcmp (name, crtl->subsections.unlikely_text_section_name) == 0)
|
||||
flags = SECTION_CODE;
|
||||
else if (!decl
|
||||
&& (!current_function_decl || !cfun)
|
||||
&& strcmp (name, UNLIKELY_EXECUTED_TEXT_SECTION_NAME) == 0)
|
||||
flags = SECTION_CODE;
|
||||
else
|
||||
flags = SECTION_WRITE;
|
||||
|
||||
@ -6810,12 +6860,6 @@ switch_to_section (section *new_section)
|
||||
switch (SECTION_STYLE (new_section))
|
||||
{
|
||||
case SECTION_NAMED:
|
||||
if (cfun
|
||||
&& !crtl->subsections.unlikely_text_section_name
|
||||
&& strcmp (new_section->named.name,
|
||||
UNLIKELY_EXECUTED_TEXT_SECTION_NAME) == 0)
|
||||
crtl->subsections.unlikely_text_section_name = UNLIKELY_EXECUTED_TEXT_SECTION_NAME;
|
||||
|
||||
targetm.asm_out.named_section (new_section->named.name,
|
||||
new_section->named.common.flags,
|
||||
new_section->named.decl);
|
||||
|
Loading…
Reference in New Issue
Block a user