cfgbuild.h: New.

2014-10-22  Andrew MacLeod  <amacleod@redhat.com>

	* cfgbuild.h: New.  Add prototypes for cfgbuild.c.
	* cfgcleanup.h: New.  Add prototypes for cfgcleanup.c.
	* cfgloopmanip.h: New.  Add prototypes for cfgloopmanip.c.
	* dominance.h: New.  Add prototypes for dominance.c.
	* cfgloop.h: Move some prototypes/enum to cfgloopmanip.h and include it.
	* cfghooks.h: (struct profile_record) Relocate here.
	Relocate 2 prototypes from basic-block.h.
	* basic-block.h: Move prototypes and struct to new header files.
	Include cfgbuild.h, cfgcleanup.h, and dominance.h.
	* rtl.h: Move a few prototypes to new header files.
	* cfgcleanup.c (merge_memattrs): Make static.
	* genopinit.c (main): Add predict.h to list of includes.
	* predict.h: Update prototype list to match predict.c.
	* predict.c (maybe_hot_count_p): Export.
	(cgraph_edge::maybe_hot_p): Move to cgraph.c.
	(cgraph_node::optimize_for_size_p): Move to cgraph.h.
	* cgraph.h (cgraph_node::optimize_for_size_p): Relocate here.
	* cgraph.c (cgraph_edge::maybe_hot_p): Relocate here.
	* profile.h: Adjust prototypes.
	* ifcvt.h: New.  Relocate struct ce_if_block here.
	* ifcvt.c: Include ifcvt.h.

	* config/frv/frv.c: Include ifcvt.h.
	* config/frv/frv-protos.h: Add 'struct' to ce_if_block * parameters.

From-SVN: r216559
This commit is contained in:
Andrew MacLeod 2014-10-22 14:26:56 +00:00 committed by Andrew Macleod
parent 4a7fca26b4
commit 893479def2
20 changed files with 412 additions and 290 deletions

View File

@ -1,3 +1,29 @@
2014-10-22 Andrew MacLeod <amacleod@redhat.com>
* cfgbuild.h: New. Add prototypes for cfgbuild.c.
* cfgcleanup.h: New. Add prototypes for cfgcleanup.c.
* cfgloopmanip.h: New. Add prototypes for cfgloopmanip.c.
* dominance.h: New. Add prototypes for dominance.c.
* cfgloop.h: Move some prototypes/enum to cfgloopmanip.h and include it.
* cfghooks.h: (struct profile_record) Relocate here.
Relocate 2 prototypes from basic-block.h.
* basic-block.h: Move prototypes and struct to new header files.
Include cfgbuild.h, cfgcleanup.h, and dominance.h.
* rtl.h: Move a few prototypes to new header files.
* cfgcleanup.c (merge_memattrs): Make static.
* genopinit.c (main): Add predict.h to list of includes.
* predict.h: Update prototype list to match predict.c.
* predict.c (maybe_hot_count_p): Export.
(cgraph_edge::maybe_hot_p): Move to cgraph.c.
(cgraph_node::optimize_for_size_p): Move to cgraph.h.
* cgraph.h (cgraph_node::optimize_for_size_p): Relocate here.
* cgraph.c (cgraph_edge::maybe_hot_p): Relocate here.
* profile.h: Adjust prototypes.
* ifcvt.h: New. Relocate struct ce_if_block here.
* ifcvt.c: Include ifcvt.h.
* config/frv/frv.c: Include ifcvt.h.
* config/frv/frv-protos.h: Add 'struct' to ce_if_block * parameters.
2014-10-22 Richard Sandiford <richard.sandiford@arm.com>
* lra.c (lra): Remove call to recog_init.

View File

@ -33,6 +33,9 @@ along with GCC; see the file COPYING3. If not see
#include "cfg.h"
#include "cfganal.h"
#include "lcm.h"
#include "cfgbuild.h"
#include "cfgcleanup.h"
#include "dominance.h"
/* Use gcov_type to hold basic block counters. Should be at least
64bit. Although a counter cannot be negative, we use a signed
@ -85,38 +88,6 @@ enum cfg_edge_flags {
#define EDGE_COMPLEX \
(EDGE_ABNORMAL | EDGE_ABNORMAL_CALL | EDGE_EH | EDGE_PRESERVE)
/* Structure to gather statistic about profile consistency, per pass.
An array of this structure, indexed by pass static number, is allocated
in passes.c. The structure is defined here so that different CFG modes
can do their book-keeping via CFG hooks.
For every field[2], field[0] is the count before the pass runs, and
field[1] is the post-pass count. This allows us to monitor the effect
of each individual pass on the profile consistency.
This structure is not supposed to be used by anything other than passes.c
and one CFG hook per CFG mode. */
struct profile_record
{
/* The number of basic blocks where sum(freq) of the block's predecessors
doesn't match reasonably well with the incoming frequency. */
int num_mismatched_freq_in[2];
/* Likewise for a basic block's successors. */
int num_mismatched_freq_out[2];
/* The number of basic blocks where sum(count) of the block's predecessors
doesn't match reasonably well with the incoming frequency. */
int num_mismatched_count_in[2];
/* Likewise for a basic block's successors. */
int num_mismatched_count_out[2];
/* A weighted cost of the run-time of the function body. */
gcov_type time[2];
/* A weighted cost of the size of the function body. */
int size[2];
/* True iff this pass actually was run. */
bool run;
};
struct GTY(()) rtl_bb_info {
/* The first insn of the block is embedded into bb->il.x. */
/* The last insn of the block. */
@ -249,15 +220,6 @@ enum cfg_bb_flags
#define BB_COPY_PARTITION(dstbb, srcbb) \
BB_SET_PARTITION (dstbb, BB_PARTITION (srcbb))
/* State of dominance information. */
enum dom_state
{
DOM_NONE, /* Not computed at all. */
DOM_NO_FAST_QUERY, /* The data is OK, but the fast query data are not usable. */
DOM_OK /* Everything is ok. */
};
/* What sort of profiling information we have. */
enum profile_status_d
{
@ -383,31 +345,6 @@ struct GTY(()) control_flow_graph {
/* The two blocks that are always in the cfg. */
#define NUM_FIXED_BLOCKS (2)
extern edge redirect_edge_succ_nodup (edge, basic_block);
/* Structure to group all of the information to process IF-THEN and
IF-THEN-ELSE blocks for the conditional execution support. This
needs to be in a public file in case the IFCVT macros call
functions passing the ce_if_block data structure. */
struct ce_if_block
{
basic_block test_bb; /* First test block. */
basic_block then_bb; /* THEN block. */
basic_block else_bb; /* ELSE block or NULL. */
basic_block join_bb; /* Join THEN/ELSE blocks. */
basic_block last_test_bb; /* Last bb to hold && or || tests. */
int num_multiple_test_blocks; /* # of && and || basic blocks. */
int num_and_and_blocks; /* # of && blocks. */
int num_or_or_blocks; /* # of || blocks. */
int num_multiple_test_insns; /* # of insns in && and || blocks. */
int and_and_p; /* Complex test is &&. */
int num_then_insns; /* # of insns in THEN block. */
int num_else_insns; /* # of insns in ELSE block. */
int pass; /* Pass number. */
};
/* The base value for branch probability notes and edge probabilities. */
#define REG_BR_PROB_BASE 10000
@ -649,97 +586,6 @@ ei_cond (edge_iterator ei, edge *p)
#define CLEANUP_CFGLAYOUT 32 /* Do cleanup in cfglayout mode. */
#define CLEANUP_CFG_CHANGED 64 /* The caller changed the CFG. */
extern void dump_flow_info (FILE *, int);
/* In predict.c */
extern bool maybe_hot_count_p (struct function *, gcov_type);
extern bool maybe_hot_bb_p (struct function *, const_basic_block);
extern bool maybe_hot_edge_p (edge);
extern bool probably_never_executed_bb_p (struct function *, const_basic_block);
extern bool probably_never_executed_edge_p (struct function *, edge);
extern bool optimize_bb_for_size_p (const_basic_block);
extern bool optimize_bb_for_speed_p (const_basic_block);
extern bool optimize_edge_for_size_p (edge);
extern bool optimize_edge_for_speed_p (edge);
extern bool optimize_loop_for_size_p (struct loop *);
extern bool optimize_loop_for_speed_p (struct loop *);
extern bool optimize_loop_nest_for_size_p (struct loop *);
extern bool optimize_loop_nest_for_speed_p (struct loop *);
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);
extern void rtl_predict_edge (edge, enum br_predictor, int);
extern void predict_edge_def (edge, enum br_predictor, enum prediction);
extern void guess_outgoing_edge_probabilities (basic_block);
extern void remove_predictions_associated_with_edge (edge);
extern bool edge_probability_reliable_p (const_edge);
extern bool br_prob_note_reliable_p (const_rtx);
extern bool predictable_edge_p (edge);
/* In cfgbuild.c. */
extern void find_many_sub_basic_blocks (sbitmap);
extern void rtl_make_eh_edge (sbitmap, basic_block, rtx);
enum replace_direction { dir_none, dir_forward, dir_backward, dir_both };
/* In cfgcleanup.c. */
extern bool cleanup_cfg (int);
extern int flow_find_cross_jump (basic_block, basic_block, rtx_insn **,
rtx_insn **, enum replace_direction*);
extern int flow_find_head_matching_sequence (basic_block, basic_block,
rtx_insn **, rtx_insn **, int);
extern bool delete_unreachable_blocks (void);
extern bool inside_basic_block_p (const rtx_insn *);
extern bool control_flow_insn_p (const rtx_insn *);
extern rtx_insn *get_last_bb_insn (basic_block);
/* In dominance.c */
enum cdi_direction
{
CDI_DOMINATORS = 1,
CDI_POST_DOMINATORS = 2
};
extern enum dom_state dom_info_state (function *, enum cdi_direction);
extern enum dom_state dom_info_state (enum cdi_direction);
extern void set_dom_info_availability (enum cdi_direction, enum dom_state);
extern bool dom_info_available_p (function *, enum cdi_direction);
extern bool dom_info_available_p (enum cdi_direction);
extern void calculate_dominance_info (enum cdi_direction);
extern void free_dominance_info (function *, enum cdi_direction);
extern void free_dominance_info (enum cdi_direction);
extern basic_block nearest_common_dominator (enum cdi_direction,
basic_block, basic_block);
extern basic_block nearest_common_dominator_for_set (enum cdi_direction,
bitmap);
extern void set_immediate_dominator (enum cdi_direction, basic_block,
basic_block);
extern basic_block get_immediate_dominator (enum cdi_direction, basic_block);
extern bool dominated_by_p (enum cdi_direction, const_basic_block, const_basic_block);
extern vec<basic_block> get_dominated_by (enum cdi_direction, basic_block);
extern vec<basic_block> get_dominated_by_region (enum cdi_direction,
basic_block *,
unsigned);
extern vec<basic_block> get_dominated_to_depth (enum cdi_direction,
basic_block, int);
extern vec<basic_block> get_all_dominated_blocks (enum cdi_direction,
basic_block);
extern void add_to_dominance_info (enum cdi_direction, basic_block);
extern void delete_from_dominance_info (enum cdi_direction, basic_block);
basic_block recompute_dominator (enum cdi_direction, basic_block);
extern void redirect_immediate_dominators (enum cdi_direction, basic_block,
basic_block);
extern void iterate_fix_dominators (enum cdi_direction,
vec<basic_block> , bool);
extern void verify_dominators (enum cdi_direction);
extern basic_block first_dom_son (enum cdi_direction, basic_block);
extern basic_block next_dom_son (enum cdi_direction, basic_block);
unsigned bb_dom_dfs_in (enum cdi_direction, basic_block);
unsigned bb_dom_dfs_out (enum cdi_direction, basic_block);
#include "cfghooks.h"
/* Return true if BB is in a transaction. */
@ -794,20 +640,6 @@ find_fallthru_edge (vec<edge, va_gc> *edges)
return e;
}
/* In cfgloopmanip.c. */
extern edge mfb_kj_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);
/* In profile.c. */
typedef struct gcov_working_set_info gcov_working_set_t;
extern gcov_working_set_t *find_working_set (unsigned pct_times_10);
extern void add_working_set (gcov_working_set_t *);
/* Check tha probability is sane. */
static inline void

28
gcc/cfgbuild.h Normal file
View File

@ -0,0 +1,28 @@
/* Control flow graph building header file.
Copyright (C) 2014 Free Software Foundation, Inc.
This file is part of GCC.
GCC is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free
Software Foundation; either version 3, or (at your option) any later
version.
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING3. If not see
<http://www.gnu.org/licenses/>. */
#ifndef GCC_CFGBUILD_H
#define GCC_CFGBUILD_H
extern bool inside_basic_block_p (const rtx_insn *);
extern bool control_flow_insn_p (const rtx_insn *);
extern void rtl_make_eh_edge (sbitmap, basic_block, rtx);
extern void find_many_sub_basic_blocks (sbitmap);
#endif /* GCC_CFGBUILD_H */

View File

@ -872,7 +872,7 @@ merge_blocks_move (edge e, basic_block b, basic_block c, int mode)
/* Removes the memory attributes of MEM expression
if they are not equal. */
void
static void
merge_memattrs (rtx x, rtx y)
{
int i;

34
gcc/cfgcleanup.h Normal file
View File

@ -0,0 +1,34 @@
/* Control flow optimization header file.
Copyright (C) 2014 Free Software Foundation, Inc.
This file is part of GCC.
GCC is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free
Software Foundation; either version 3, or (at your option) any later
version.
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING3. If not see
<http://www.gnu.org/licenses/>. */
#ifndef GCC_CFGCLEANUP_H
#define GCC_CFGCLEANUP_H
enum replace_direction { dir_none, dir_forward, dir_backward, dir_both };
extern int flow_find_cross_jump (basic_block, basic_block, rtx_insn **,
rtx_insn **, enum replace_direction*);
extern int flow_find_head_matching_sequence (basic_block, basic_block,
rtx_insn **, rtx_insn **, int);
extern bool delete_unreachable_blocks (void);
extern void delete_dead_jumptables (void);
extern bool cleanup_cfg (int);
#endif /* GCC_CFGCLEANUP_H */

View File

@ -23,6 +23,38 @@ along with GCC; see the file COPYING3. If not see
/* Only basic-block.h includes this. */
/* Structure to gather statistic about profile consistency, per pass.
An array of this structure, indexed by pass static number, is allocated
in passes.c. The structure is defined here so that different CFG modes
can do their book-keeping via CFG hooks.
For every field[2], field[0] is the count before the pass runs, and
field[1] is the post-pass count. This allows us to monitor the effect
of each individual pass on the profile consistency.
This structure is not supposed to be used by anything other than passes.c
and one CFG hook per CFG mode. */
struct profile_record
{
/* The number of basic blocks where sum(freq) of the block's predecessors
doesn't match reasonably well with the incoming frequency. */
int num_mismatched_freq_in[2];
/* Likewise for a basic block's successors. */
int num_mismatched_freq_out[2];
/* The number of basic blocks where sum(count) of the block's predecessors
doesn't match reasonably well with the incoming frequency. */
int num_mismatched_count_in[2];
/* Likewise for a basic block's successors. */
int num_mismatched_count_out[2];
/* A weighted cost of the run-time of the function body. */
gcov_type time[2];
/* A weighted cost of the size of the function body. */
int size[2];
/* True iff this pass actually was run. */
bool run;
};
struct cfg_hooks
{
/* Name of the corresponding ir. */
@ -156,9 +188,11 @@ struct cfg_hooks
extern void verify_flow_info (void);
extern void dump_bb (FILE *, basic_block, int, int);
extern void dump_bb_for_graph (pretty_printer *, basic_block);
extern void dump_flow_info (FILE *, int);
extern edge redirect_edge_and_branch (edge, basic_block);
extern basic_block redirect_edge_and_branch_force (edge, basic_block);
extern edge redirect_edge_succ_nodup (edge, basic_block);
extern bool can_remove_branch_p (const_edge);
extern void remove_branch (edge);
extern void remove_edge (edge);

View File

@ -32,6 +32,7 @@ along with GCC; see the file COPYING3. If not see
#include "hard-reg-set.h"
#include "input.h"
#include "function.h"
#include "cfgloopmanip.h"
/* Structure to hold decision about unrolling/peeling. */
enum lpt_dec
@ -271,8 +272,6 @@ void rescan_loop_exit (edge, bool, bool);
/* Loop data structure manipulation/querying. */
extern void flow_loop_tree_node_add (struct loop *, struct loop *);
extern void flow_loop_tree_node_remove (struct loop *);
extern void place_new_loop (struct function *, struct loop *);
extern void add_loop (struct loop *, struct loop *);
extern bool flow_loop_nested_p (const struct loop *, const struct loop *);
extern bool flow_bb_inside_loop_p (const struct loop *, const_basic_block);
extern struct loop * find_common_loop (struct loop *, struct loop *);
@ -310,15 +309,6 @@ extern void remove_bb_from_loops (basic_block);
extern void cancel_loop_tree (struct loop *);
extern void delete_loop (struct loop *);
enum
{
CP_SIMPLE_PREHEADERS = 1,
CP_FALLTHRU_PREHEADERS = 2
};
basic_block create_preheader (struct loop *, int);
extern void create_preheaders (int);
extern void force_single_succ_latches (void);
extern void verify_loop_structure (void);
@ -328,37 +318,8 @@ gcov_type expected_loop_iterations_unbounded (const struct loop *);
extern unsigned expected_loop_iterations (const struct loop *);
extern rtx doloop_condition_get (rtx);
/* Loop manipulation. */
extern bool can_duplicate_loop_p (const struct loop *loop);
#define DLTHE_FLAG_UPDATE_FREQ 1 /* Update frequencies in
duplicate_loop_to_header_edge. */
#define DLTHE_RECORD_COPY_NUMBER 2 /* Record copy number in the aux
field of newly create BB. */
#define DLTHE_FLAG_COMPLETTE_PEEL 4 /* Update frequencies expecting
a complete peeling. */
extern edge create_empty_if_region_on_edge (edge, tree);
extern struct loop *create_empty_loop_on_edge (edge, tree, tree, tree, tree,
tree *, tree *, struct loop *);
extern struct loop * duplicate_loop (struct loop *, struct loop *);
extern void copy_loop_info (struct loop *loop, struct loop *target);
extern void duplicate_subloops (struct loop *, struct loop *);
extern bool duplicate_loop_to_header_edge (struct loop *, edge,
unsigned, sbitmap, edge,
vec<edge> *, int);
extern struct loop *loopify (edge, edge,
basic_block, edge, edge, bool,
unsigned, unsigned);
struct loop * loop_version (struct loop *, void *,
basic_block *, unsigned, unsigned, unsigned, bool);
extern bool remove_path (edge);
extern void unloop (struct loop *, bool *, bitmap);
extern void scale_loop_frequencies (struct loop *, int, int);
void mark_loop_for_removal (loop_p);
/* Induction variable analysis. */
/* The description of induction variable. The things are a bit complicated
@ -742,7 +703,6 @@ enum
extern void doloop_optimize_loops (void);
extern void move_loop_invariants (void);
extern void scale_loop_profile (struct loop *loop, int scale, gcov_type iteration_bound);
extern vec<basic_block> get_loop_hot_path (const struct loop *loop);
/* Returns the outermost loop of the loop nest that contains LOOP.*/

63
gcc/cfgloopmanip.h Normal file
View File

@ -0,0 +1,63 @@
/* Loop manipulation header.
Copyright (C) 2014 Free Software Foundation, Inc.
This file is part of GCC.
GCC is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free
Software Foundation; either version 3, or (at your option) any later
version.
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING3. If not see
<http://www.gnu.org/licenses/>. */
#ifndef GCC_CFGLOOPMANIP_H
#define GCC_CFGLOOPMANIP_H
enum
{
CP_SIMPLE_PREHEADERS = 1,
CP_FALLTHRU_PREHEADERS = 2
};
#define DLTHE_FLAG_UPDATE_FREQ 1 /* Update frequencies in
duplicate_loop_to_header_edge. */
#define DLTHE_RECORD_COPY_NUMBER 2 /* Record copy number in the aux
field of newly create BB. */
#define DLTHE_FLAG_COMPLETTE_PEEL 4 /* Update frequencies expecting
a complete peeling. */
extern edge mfb_kj_edge;
extern bool remove_path (edge);
extern void place_new_loop (struct function *, struct loop *);
extern void add_loop (struct loop *, struct loop *);
extern void scale_loop_frequencies (struct loop *, int, int);
extern void scale_loop_profile (struct loop *, int, gcov_type);
extern edge create_empty_if_region_on_edge (edge, tree);
extern struct loop *create_empty_loop_on_edge (edge, tree, tree, tree, tree,
tree *, tree *, struct loop *);
extern struct loop *loopify (edge, edge,
basic_block, edge, edge, bool,
unsigned, unsigned);
extern void unloop (struct loop *, bool *, bitmap);
extern void copy_loop_info (struct loop *loop, struct loop *target);
extern struct loop * duplicate_loop (struct loop *, struct loop *);
extern void duplicate_subloops (struct loop *, struct loop *);
extern bool can_duplicate_loop_p (const struct loop *loop);
extern bool duplicate_loop_to_header_edge (struct loop *, edge,
unsigned, sbitmap, edge,
vec<edge> *, int);
extern bool mfb_keep_just (edge);
basic_block create_preheader (struct loop *, int);
extern void create_preheaders (int);
extern void force_single_succ_latches (void);
struct loop * loop_version (struct loop *, void *,
basic_block *, unsigned, unsigned, unsigned, bool);
#endif /* GCC_CFGLOOPMANIP_H */

View File

@ -64,6 +64,8 @@ along with GCC; see the file COPYING3. If not see
#include "gimple-pretty-print.h"
#include "expr.h"
#include "tree-dfa.h"
#include "profile.h"
#include "params.h"
/* FIXME: Only for PROP_loops, but cgraph shouldn't have to know about this. */
#include "tree-pass.h"
@ -2310,6 +2312,38 @@ cgraph_edge::cannot_lead_to_return_p (void)
return callee->cannot_return_p ();
}
/* Return true if the call can be hot. */
bool
cgraph_edge::maybe_hot_p (void)
{
if (profile_info && flag_branch_probabilities
&& !maybe_hot_count_p (NULL, count))
return false;
if (caller->frequency == NODE_FREQUENCY_UNLIKELY_EXECUTED
|| (callee
&& callee->frequency == NODE_FREQUENCY_UNLIKELY_EXECUTED))
return false;
if (caller->frequency > NODE_FREQUENCY_UNLIKELY_EXECUTED
&& (callee
&& callee->frequency <= NODE_FREQUENCY_EXECUTED_ONCE))
return false;
if (optimize_size) return false;
if (caller->frequency == NODE_FREQUENCY_HOT)
return true;
if (caller->frequency == NODE_FREQUENCY_EXECUTED_ONCE
&& frequency < CGRAPH_FREQ_BASE * 3 / 2)
return false;
if (flag_guess_branch_prob)
{
if (PARAM_VALUE (HOT_BB_FREQUENCY_FRACTION) == 0
|| frequency <= (CGRAPH_FREQ_BASE
/ PARAM_VALUE (HOT_BB_FREQUENCY_FRACTION)))
return false;
}
return true;
}
/* Return true when function can be removed from callgraph
if all direct calls are eliminated. */

View File

@ -2708,6 +2708,19 @@ cgraph_node::mark_force_output (void)
gcc_checking_assert (!global.inlined_to);
}
/* Return true if function should be optimized for size. */
inline bool
cgraph_node::optimize_for_size_p (void)
{
if (optimize_size)
return true;
if (frequency == NODE_FREQUENCY_UNLIKELY_EXECUTED)
return true;
else
return false;
}
inline symtab_node * symtab_node::get_create (tree node)
{
if (TREE_CODE (node) == VAR_DECL)

View File

@ -62,14 +62,14 @@ extern rtx frv_split_abs (rtx *);
extern void frv_split_double_load (rtx, rtx);
extern void frv_split_double_store (rtx, rtx);
#ifdef BB_HEAD
extern void frv_ifcvt_init_extra_fields (ce_if_block *);
extern void frv_ifcvt_modify_tests (ce_if_block *, rtx *, rtx *);
extern void frv_ifcvt_init_extra_fields (struct ce_if_block *);
extern void frv_ifcvt_modify_tests (struct ce_if_block *, rtx *, rtx *);
extern void frv_ifcvt_modify_multiple_tests
(ce_if_block *, basic_block,
(struct ce_if_block *, basic_block,
rtx *, rtx *);
extern rtx frv_ifcvt_modify_insn (ce_if_block *, rtx, rtx);
extern void frv_ifcvt_modify_final (ce_if_block *);
extern void frv_ifcvt_modify_cancel (ce_if_block *);
extern rtx frv_ifcvt_modify_insn (struct ce_if_block *, rtx, rtx);
extern void frv_ifcvt_modify_final (struct ce_if_block *);
extern void frv_ifcvt_modify_cancel (struct ce_if_block *);
#endif
extern enum reg_class frv_secondary_reload_class
(enum reg_class,

View File

@ -57,6 +57,7 @@ along with GCC; see the file COPYING3. If not see
#include "df.h"
#include "dumpfile.h"
#include "builtins.h"
#include "ifcvt.h"
#ifndef FRV_INLINE
#define FRV_INLINE inline

78
gcc/dominance.h Normal file
View File

@ -0,0 +1,78 @@
/* Calculate (post)dominators header file.
Copyright (C) 2014 Free Software Foundation, Inc.
This file is part of GCC.
GCC is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3, or (at your option)
any later version.
GCC is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
License for more details.
You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING3. If not see
<http://www.gnu.org/licenses/>. */
#ifndef GCC_DOMINANCE_H
#define GCC_DOMINANCE_H
enum cdi_direction
{
CDI_DOMINATORS = 1,
CDI_POST_DOMINATORS = 2
};
/* State of dominance information. */
enum dom_state
{
DOM_NONE, /* Not computed at all. */
DOM_NO_FAST_QUERY, /* The data is OK, but the fast query data are not usable. */
DOM_OK /* Everything is ok. */
};
extern void calculate_dominance_info (enum cdi_direction);
extern void free_dominance_info (function *, enum cdi_direction);
extern void free_dominance_info (enum cdi_direction);
extern basic_block get_immediate_dominator (enum cdi_direction, basic_block);
extern void set_immediate_dominator (enum cdi_direction, basic_block,
basic_block);
extern vec<basic_block> get_dominated_by (enum cdi_direction, basic_block);
extern vec<basic_block> get_dominated_by_region (enum cdi_direction,
basic_block *,
unsigned);
extern vec<basic_block> get_dominated_to_depth (enum cdi_direction,
basic_block, int);
extern vec<basic_block> get_all_dominated_blocks (enum cdi_direction,
basic_block);
extern void redirect_immediate_dominators (enum cdi_direction, basic_block,
basic_block);
extern basic_block nearest_common_dominator (enum cdi_direction,
basic_block, basic_block);
extern basic_block nearest_common_dominator_for_set (enum cdi_direction,
bitmap);
extern bool dominated_by_p (enum cdi_direction, const_basic_block,
const_basic_block);
unsigned bb_dom_dfs_in (enum cdi_direction, basic_block);
unsigned bb_dom_dfs_out (enum cdi_direction, basic_block);
extern void verify_dominators (enum cdi_direction);
basic_block recompute_dominator (enum cdi_direction, basic_block);
extern void iterate_fix_dominators (enum cdi_direction,
vec<basic_block> , bool);
extern void add_to_dominance_info (enum cdi_direction, basic_block);
extern void delete_from_dominance_info (enum cdi_direction, basic_block);
extern basic_block first_dom_son (enum cdi_direction, basic_block);
extern basic_block next_dom_son (enum cdi_direction, basic_block);
extern enum dom_state dom_info_state (function *, enum cdi_direction);
extern enum dom_state dom_info_state (enum cdi_direction);
extern void set_dom_info_availability (enum cdi_direction, enum dom_state);
extern bool dom_info_available_p (function *, enum cdi_direction);
extern bool dom_info_available_p (enum cdi_direction);
#endif /* GCC_DOMINANCE_H */

View File

@ -408,6 +408,7 @@ main (int argc, char **argv)
"#include \"stor-layout.h\"\n"
"#include \"calls.h\"\n"
"#include \"rtl.h\"\n"
"#include \"predict.h\"\n"
"#include \"tm_p.h\"\n"
"#include \"flags.h\"\n"
"#include \"insn-config.h\"\n"

View File

@ -47,6 +47,7 @@
#include "df.h"
#include "dbgcnt.h"
#include "shrink-wrap.h"
#include "ifcvt.h"
#ifndef HAVE_conditional_move
#define HAVE_conditional_move 0

43
gcc/ifcvt.h Normal file
View File

@ -0,0 +1,43 @@
/* If-conversion header file.
Copyright (C) 2014 Free Software Foundation, Inc.
This file is part of GCC.
GCC is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3, or (at your option)
any later version.
GCC is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
License for more details.
You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING3. If not see
<http://www.gnu.org/licenses/>. */
#ifndef GCC_IFCVT_H
#define GCC_IFCVT_H
/* Structure to group all of the information to process IF-THEN and
IF-THEN-ELSE blocks for the conditional execution support. */
struct ce_if_block
{
basic_block test_bb; /* First test block. */
basic_block then_bb; /* THEN block. */
basic_block else_bb; /* ELSE block or NULL. */
basic_block join_bb; /* Join THEN/ELSE blocks. */
basic_block last_test_bb; /* Last bb to hold && or || tests. */
int num_multiple_test_blocks; /* # of && and || basic blocks. */
int num_and_and_blocks; /* # of && blocks. */
int num_or_or_blocks; /* # of || blocks. */
int num_multiple_test_insns; /* # of insns in && and || blocks. */
int and_and_p; /* Complex test is &&. */
int num_then_insns; /* # of insns in THEN block. */
int num_else_insns; /* # of insns in ELSE block. */
int pass; /* Pass number. */
};
#endif /* GCC_IFCVT_H */

View File

@ -190,39 +190,6 @@ maybe_hot_bb_p (struct function *fun, const_basic_block bb)
return maybe_hot_frequency_p (fun, bb->frequency);
}
/* Return true if the call can be hot. */
bool
cgraph_edge::maybe_hot_p (void)
{
if (profile_info && flag_branch_probabilities
&& !maybe_hot_count_p (NULL, count))
return false;
if (caller->frequency == NODE_FREQUENCY_UNLIKELY_EXECUTED
|| (callee
&& callee->frequency == NODE_FREQUENCY_UNLIKELY_EXECUTED))
return false;
if (caller->frequency > NODE_FREQUENCY_UNLIKELY_EXECUTED
&& (callee
&& callee->frequency <= NODE_FREQUENCY_EXECUTED_ONCE))
return false;
if (optimize_size)
return false;
if (caller->frequency == NODE_FREQUENCY_HOT)
return true;
if (caller->frequency == NODE_FREQUENCY_EXECUTED_ONCE
&& frequency < CGRAPH_FREQ_BASE * 3 / 2)
return false;
if (flag_guess_branch_prob)
{
if (PARAM_VALUE (HOT_BB_FREQUENCY_FRACTION) == 0
|| frequency <= (CGRAPH_FREQ_BASE
/ PARAM_VALUE (HOT_BB_FREQUENCY_FRACTION)))
return false;
}
return true;
}
/* Return true in case BB can be CPU intensive and should be optimized
for maximal performance. */
@ -234,8 +201,6 @@ maybe_hot_edge_p (edge e)
return maybe_hot_frequency_p (cfun, EDGE_FREQUENCY (e));
}
/* Return true if profile COUNT and FREQUENCY, or function FUN static
node frequency reflects never being executed. */
@ -304,19 +269,6 @@ probably_never_executed_edge_p (struct function *fun, edge e)
return probably_never_executed (fun, e->count, EDGE_FREQUENCY (e));
}
/* Return true if function should be optimized for size. */
bool
cgraph_node::optimize_for_size_p (void)
{
if (optimize_size)
return true;
if (frequency == NODE_FREQUENCY_UNLIKELY_EXECUTED)
return true;
else
return false;
}
/* Return true when current function should always be optimized for size. */
bool

View File

@ -45,17 +45,48 @@ enum prediction
TAKEN
};
extern void predict_insn_def (rtx_insn *, enum br_predictor, enum prediction);
extern int counts_to_freqs (void);
extern void handle_missing_profiles (void);
extern void estimate_bb_frequencies (bool);
extern const char *predictor_name (enum br_predictor);
extern tree build_predict_expr (enum br_predictor, enum prediction);
extern void tree_estimate_probability (void);
extern void compute_function_frequency (void);
extern void rebuild_frequencies (void);
extern gcov_type get_hot_bb_threshold (void);
extern void set_hot_bb_threshold (gcov_type);
extern bool maybe_hot_count_p (struct function *, gcov_type);
extern bool maybe_hot_bb_p (struct function *, const_basic_block);
extern bool maybe_hot_edge_p (edge);
extern bool probably_never_executed_bb_p (struct function *, const_basic_block);
extern bool probably_never_executed_edge_p (struct function *, edge);
extern bool optimize_function_for_size_p (struct function *);
extern bool optimize_function_for_speed_p (struct function *);
extern bool optimize_bb_for_size_p (const_basic_block);
extern bool optimize_bb_for_speed_p (const_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 optimize_loop_for_size_p (struct loop *);
extern bool optimize_loop_for_speed_p (struct loop *);
extern bool optimize_loop_nest_for_speed_p (struct loop *);
extern bool optimize_loop_nest_for_size_p (struct loop *);
extern bool predictable_edge_p (edge);
extern void rtl_profile_for_bb (basic_block);
extern void rtl_profile_for_edge (edge);
extern void default_rtl_profile (void);
extern bool rtl_predicted_by_p (const_basic_block, enum br_predictor);
extern bool gimple_predicted_by_p (const_basic_block, enum br_predictor);
extern bool edge_probability_reliable_p (const_edge);
extern bool br_prob_note_reliable_p (const_rtx);
extern void predict_insn_def (rtx_insn *, enum br_predictor, enum prediction);
extern void rtl_predict_edge (edge, enum br_predictor, int);
extern void gimple_predict_edge (edge, enum br_predictor, int);
extern void remove_predictions_associated_with_edge (edge);
extern void predict_edge_def (edge, enum br_predictor, enum prediction);
extern void invert_br_probabilities (rtx);
extern void guess_outgoing_edge_probabilities (basic_block);
extern void tree_estimate_probability (void);
extern void handle_missing_profiles (void);
extern int counts_to_freqs (void);
extern bool expensive_function_p (int);
extern void estimate_bb_frequencies (bool);
extern void compute_function_frequency (void);
extern tree build_predict_expr (enum br_predictor, enum prediction);
extern const char *predictor_name (enum br_predictor);
extern void rebuild_frequencies (void);
#endif /* GCC_PREDICT_H */

View File

@ -37,6 +37,10 @@ struct edge_profile_info
#define EDGE_INFO(e) ((struct edge_profile_info *) (e)->aux)
typedef struct gcov_working_set_info gcov_working_set_t;
extern gcov_working_set_t *find_working_set (unsigned pct_times_10);
extern void add_working_set (gcov_working_set_t *);
/* Smoothes the initial assigned basic block and edge counts using
a minimum cost flow algorithm. */
extern void mcf_smooth_cfg (void);
@ -52,8 +56,4 @@ extern void get_working_sets (void);
profile.c. */
extern const struct gcov_ctr_summary *profile_info;
/* In predict.c. */
extern gcov_type get_hot_bb_threshold (void);
extern void set_hot_bb_threshold (gcov_type);
#endif /* PROFILE_H */

View File

@ -3388,9 +3388,6 @@ extern void dump_combine_stats (FILE *);
extern void dump_combine_total_stats (FILE *);
extern rtx make_compound_operation (rtx, enum rtx_code);
/* In cfgcleanup.c */
extern void delete_dead_jumptables (void);
/* In sched-rgn.c. */
extern void schedule_insns (void);
@ -3531,10 +3528,6 @@ extern int stack_regs_mentioned (const_rtx insn);
/* In toplev.c */
extern GTY(()) rtx stack_limit_rtx;
/* In predict.c */
extern void invert_br_probabilities (rtx);
extern bool expensive_function_p (int);
/* In var-tracking.c */
extern unsigned int variable_tracking_main (void);
@ -3577,8 +3570,6 @@ extern void insn_locations_init (void);
extern void insn_locations_finalize (void);
extern void set_curr_insn_location (location_t);
extern location_t curr_insn_location (void);
extern bool optimize_insn_for_size_p (void);
extern bool optimize_insn_for_speed_p (void);
/* rtl-error.c */
extern void _fatal_insn_not_found (const_rtx, const char *, int, const char *)