+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.
#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
#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. */
#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
{
/* 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
#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. */
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
--- /dev/null
+/* 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 */
/* Removes the memory attributes of MEM expression
if they are not equal. */
-void
+static void
merge_memattrs (rtx x, rtx y)
{
int i;
--- /dev/null
+/* 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 */
/* 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. */
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);
#include "hard-reg-set.h"
#include "input.h"
#include "function.h"
+#include "cfgloopmanip.h"
/* Structure to hold decision about unrolling/peeling. */
enum lpt_dec
/* 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 *);
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);
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
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.*/
--- /dev/null
+/* 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 */
#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"
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. */
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)
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,
#include "df.h"
#include "dumpfile.h"
#include "builtins.h"
+#include "ifcvt.h"
#ifndef FRV_INLINE
#define FRV_INLINE inline
--- /dev/null
+/* 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 */
"#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"
#include "df.h"
#include "dbgcnt.h"
#include "shrink-wrap.h"
+#include "ifcvt.h"
#ifndef HAVE_conditional_move
#define HAVE_conditional_move 0
--- /dev/null
+/* 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 */
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. */
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. */
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
TAKEN
};
+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 int counts_to_freqs (void);
+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 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 tree build_predict_expr (enum br_predictor, enum prediction);
+extern const char *predictor_name (enum br_predictor);
extern void rebuild_frequencies (void);
-extern bool optimize_function_for_size_p (struct function *);
-extern bool optimize_function_for_speed_p (struct function *);
-
#endif /* GCC_PREDICT_H */
#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);
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 */
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);
/* 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);
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 *)