* predict.c (always_optimize_for_size_p): New function.
(optimize_bb_for_size_p, optimize_bb_for_speed_p,
optimize_edge_for_size_p, optimize_edge_for_speed_p,
optimize_insn_for_size_p, optimize_insn_for_speed_p): New global
functions.
(rtl_profile_for_bb, rtl_profile_for_edge, rtl_default_profile): New.
* function.c (prepare_function_start): Set default profile.
* function.h (rtl_data): Add maybe_hot_insn_p.
* cfgexpand.c (expand_gimple_basic_block): Set RTL profile.
(construct_exit_block): Likewise.
(tree_expand_cfg): Likewise.
* basic-block.h
(optimize_bb_for_size_p, optimize_bb_for_speed_p,
optimize_edge_for_size_p, optimize_edge_for_speed_p,
optimize_insn_for_size_p, optimize_insn_for_speed_p): Declare.
(rtl_profile_for_bb, rtl_profile_for_edge, default_rtl_profile):
Declare.
From-SVN: r138237
+2008-07-29 Jan HUbicka <jh@suse.cz>
+
+ * predict.c (always_optimize_for_size_p): New function.
+ (optimize_bb_for_size_p, optimize_bb_for_speed_p,
+ optimize_edge_for_size_p, optimize_edge_for_speed_p,
+ optimize_insn_for_size_p, optimize_insn_for_speed_p): New global
+ functions.
+ (rtl_profile_for_bb, rtl_profile_for_edge, rtl_default_profile): New.
+ * function.c (prepare_function_start): Set default profile.
+ * function.h (rtl_data): Add maybe_hot_insn_p.
+ * cfgexpand.c (expand_gimple_basic_block): Set RTL profile.
+ (construct_exit_block): Likewise.
+ (tree_expand_cfg): Likewise.
+ * basic-block.h
+ (optimize_bb_for_size_p, optimize_bb_for_speed_p,
+ optimize_edge_for_size_p, optimize_edge_for_speed_p,
+ optimize_insn_for_size_p, optimize_insn_for_speed_p): Declare.
+ (rtl_profile_for_bb, rtl_profile_for_edge, default_rtl_profile):
+ Declare.
+
2008-07-29 Manuel Lopez-Ibanez <manu@gcc.gnu.org>
PR 34985
extern bool maybe_hot_edge_p (edge);
extern bool probably_cold_bb_p (const_basic_block);
extern bool probably_never_executed_bb_p (const_basic_block);
+extern bool optimize_bb_for_size_p (basic_block);
+extern bool optimize_bb_for_speed_p (basic_block);
+extern bool optimize_edge_for_size_p (edge);
+extern bool optimize_edge_for_speed_p (edge);
+extern bool optimize_insn_for_size_p (void);
+extern bool optimize_insn_for_speed_p (void);
extern bool gimple_predicted_by_p (const_basic_block, enum br_predictor);
extern bool rtl_predicted_by_p (const_basic_block, enum br_predictor);
extern void gimple_predict_edge (edge, enum br_predictor, int);
/* In cfgloopmanip.c. */
extern edge mfb_kj_edge;
-bool mfb_keep_just (edge);
+extern bool mfb_keep_just (edge);
+
+/* In cfgexpand.c. */
+extern void rtl_profile_for_bb (basic_block);
+extern void rtl_profile_for_edge (edge);
+extern void default_rtl_profile (void);
#endif /* GCC_BASIC_BLOCK_H */
access the BB sequence directly. */
stmts = bb_seq (bb);
bb->il.gimple = NULL;
+ rtl_profile_for_bb (bb);
init_rtl_bb_info (bb);
bb->flags |= BB_RTL;
edge_iterator ei;
rtx orig_end = BB_END (EXIT_BLOCK_PTR->prev_bb);
+ rtl_profile_for_bb (EXIT_BLOCK_PTR);
+
/* Make sure the locus is set to the end of the function, so that
epilogue line numbers and warnings are set properly. */
if (cfun->function_end_locus != UNKNOWN_LOCATION)
/* Some backends want to know that we are expanding to RTL. */
currently_expanding_to_rtl = 1;
+ rtl_profile_for_bb (ENTRY_BLOCK_PTR);
+
insn_locators_alloc ();
if (!DECL_BUILT_IN (current_function_decl))
set_curr_insn_source_location (DECL_SOURCE_LOCATION (current_function_decl));
lab_rtx_for_bb = pointer_map_create ();
FOR_BB_BETWEEN (bb, init_block->next_bb, EXIT_BLOCK_PTR, next_bb)
bb = expand_gimple_basic_block (bb);
+
+ /* Expansion is used by optimization passes too, set maybe_hot_insn_p
+ conservatively to true until they are all profile aware. */
pointer_map_destroy (lab_rtx_for_bb);
free_histograms ();
/* Tag the blocks with a depth number so that change_scope can find
the common parent easily. */
set_block_levels (DECL_INITIAL (cfun->decl), 0);
+ default_rtl_profile ();
return 0;
}
/* For XFmode constants, try to find a special 80387 instruction when
optimizing for size or on those CPUs that benefit from them. */
if (mode == XFmode
- && (optimize_size || TARGET_EXT_80387_CONSTANTS))
+ && (optimize_insn_for_size_p () || TARGET_EXT_80387_CONSTANTS))
{
int i;
|| (alg != rep_prefix_1_byte \
&& alg != rep_prefix_4_byte \
&& alg != rep_prefix_8_byte))
+ const struct processor_costs *cost;
+
+ cost = optimize_insn_for_size_p () ? &size_cost : ix86_cost;
*dynamic_check = -1;
if (memset)
- algs = &ix86_cost->memset[TARGET_64BIT != 0];
+ algs = &cost->memset[TARGET_64BIT != 0];
else
- algs = &ix86_cost->memcpy[TARGET_64BIT != 0];
+ algs = &cost->memcpy[TARGET_64BIT != 0];
if (stringop_alg != no_stringop && ALG_USABLE_P (stringop_alg))
return stringop_alg;
/* rep; movq or rep; movl is the smallest variant. */
init_emit ();
init_varasm_status ();
init_expr ();
+ default_rtl_profile ();
cse_not_expected = ! optimize;
Set in stmt.c if anything is allocated on the stack there.
Set in reload1.c if anything is allocated on the stack there. */
bool frame_pointer_needed;
+
+ /* When set, expand should optimize for speed. */
+ bool maybe_hot_insn_p;
};
#define return_label (crtl->x_return_label)
return false;
}
+/* Return true when current function should always be optimized for size. */
+
+static bool
+always_optimize_for_size_p (void)
+{
+ return (optimize_size
+ || cfun->function_frequency == FUNCTION_FREQUENCY_UNLIKELY_EXECUTED);
+}
+
+/* Return TRUE when BB should be optimized for size. */
+
+bool
+optimize_bb_for_size_p (basic_block bb)
+{
+ return always_optimize_for_size_p () || !maybe_hot_bb_p (bb);
+}
+
+/* Return TRUE when BB should be optimized for speed. */
+
+bool
+optimize_bb_for_speed_p (basic_block bb)
+{
+ return !optimize_bb_for_size_p (bb);
+}
+
+/* Return TRUE when BB should be optimized for size. */
+
+bool
+optimize_edge_for_size_p (edge e)
+{
+ return always_optimize_for_size_p () || !maybe_hot_edge_p (e);
+}
+
+/* Return TRUE when BB should be optimized for speed. */
+
+bool
+optimize_edge_for_speed_p (edge e)
+{
+ return !optimize_edge_for_size_p (e);
+}
+
+/* Return TRUE when BB should be optimized for size. */
+
+bool
+optimize_insn_for_size_p (void)
+{
+ return always_optimize_for_size_p () || !crtl->maybe_hot_insn_p;
+}
+
+/* Return TRUE when BB should be optimized for speed. */
+
+bool
+optimize_insn_for_speed_p (void)
+{
+ return !optimize_insn_for_size_p ();
+}
+
+/* Set RTL expansion for BB profile. */
+
+void
+rtl_profile_for_bb (basic_block bb)
+{
+ crtl->maybe_hot_insn_p = maybe_hot_bb_p (bb);
+}
+
+/* Set RTL expansion for edge profile. */
+
+void
+rtl_profile_for_edge (edge e)
+{
+ crtl->maybe_hot_insn_p = maybe_hot_edge_p (e);
+}
+
+/* Set RTL expansion to default mode (i.e. when profile info is not known). */
+void
+default_rtl_profile (void)
+{
+ crtl->maybe_hot_insn_p = true;
+}
+
/* Return true if the one of outgoing edges is already predicted by
PREDICTOR. */