/* Define control and data flow tables, and regsets.
- Copyright (C) 1987, 1997, 1998, 1999, 2000, 2001, 2002, 2003
+ Copyright (C) 1987, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004
Free Software Foundation, Inc.
This file is part of GCC.
#define REGNO_REG_SET_P(TO, REG) bitmap_bit_p (TO, REG)
/* Copy the hard registers in a register set to the hard register set. */
-extern void reg_set_to_hard_reg_set PARAMS ((HARD_REG_SET *, bitmap));
+extern void reg_set_to_hard_reg_set (HARD_REG_SET *, bitmap);
#define REG_SET_TO_HARD_REG_SET(TO, FROM) \
do { \
CLEAR_HARD_REG_SET (TO); \
#define EDGE_CAN_FALLTHRU 64 /* Candidate for straight line
flow. */
#define EDGE_IRREDUCIBLE_LOOP 128 /* Part of irreducible loop. */
-#define EDGE_ALL_FLAGS 255
+#define EDGE_SIBCALL 256 /* Edge from sibcall to exit. */
+#define EDGE_LOOP_EXIT 512 /* Exit of a loop. */
+#define EDGE_ALL_FLAGS 1023
#define EDGE_COMPLEX (EDGE_ABNORMAL | EDGE_ABNORMAL_CALL | EDGE_EH)
+/* Counter summary from the last set of coverage counts read by
+ profile.c. */
+extern const struct gcov_ctr_summary *profile_info;
+
/* Declared in cfgloop.h. */
struct loop;
struct loops;
/* Basic block information indexed by block number. */
typedef struct basic_block_def {
/* The first and last insns of the block. */
- rtx head, end;
+ rtx head_, end_;
/* The first and last trees of the block. */
tree head_tree;
/* Outermost loop containing the block. */
struct loop *loop_father;
+ /* The dominance and postdominance information node. */
+ struct et_node *dom[2];
+
/* Expected number of executions: calculated in profile.c. */
gcov_type count;
/* Various flags. See BB_* below. */
int flags;
+
+ /* Additional data maintained by cfg_layout routines. */
+ struct reorder_block_def *rbi;
} *basic_block;
#define BB_FREQ_MAX 10000
#define FOR_EACH_BB_REVERSE(BB) \
FOR_BB_BETWEEN (BB, EXIT_BLOCK_PTR->prev_bb, ENTRY_BLOCK_PTR, prev_bb)
+/* For iterating over insns in basic block. */
+#define FOR_BB_INSNS(BB, INSN) \
+ for ((INSN) = BB_HEAD (BB); \
+ (INSN) != NEXT_INSN (BB_END (BB)); \
+ (INSN) = NEXT_INSN (INSN))
+
+#define FOR_BB_INSNS_REVERSE(BB, INSN) \
+ for ((INSN) = BB_END (BB); \
+ (INSN) != PREV_INSN (BB_HEAD (BB)); \
+ (INSN) = PREV_INSN (INSN))
+
/* Cycles through _all_ basic blocks, even the fake ones (entry and
exit block). */
\f
/* Stuff for recording basic block info. */
-#define BLOCK_HEAD(B) (BASIC_BLOCK (B)->head)
-#define BLOCK_END(B) (BASIC_BLOCK (B)->end)
-
-#define BLOCK_HEAD_TREE(B) (BASIC_BLOCK (B)->head_tree)
-#define BLOCK_END_TREE(B) (BASIC_BLOCK (B)->end_tree)
+#define BB_HEAD(B) (B)->head_
+#define BB_END(B) (B)->end_
/* Special block numbers [markers] for entry and exit. */
#define ENTRY_BLOCK (-1)
#define BLOCK_NUM(INSN) (BLOCK_FOR_INSN (INSN)->index + 0)
#define set_block_for_insn(INSN, BB) (BLOCK_FOR_INSN (INSN) = BB)
-extern void compute_bb_for_insn PARAMS ((void));
-extern void free_bb_for_insn PARAMS ((void));
-extern void update_bb_for_insn PARAMS ((basic_block));
-
-extern void free_basic_block_vars PARAMS ((int));
-
-extern edge split_block PARAMS ((basic_block, rtx));
-extern basic_block split_edge PARAMS ((edge));
-extern void insert_insn_on_edge PARAMS ((rtx, edge));
-
-extern void commit_edge_insertions PARAMS ((void));
-extern void commit_edge_insertions_watch_calls PARAMS ((void));
-
-extern void remove_fake_edges PARAMS ((void));
-extern void add_noreturn_fake_exit_edges PARAMS ((void));
-extern void connect_infinite_loops_to_exit PARAMS ((void));
-extern int flow_call_edges_add PARAMS ((sbitmap));
-extern edge cached_make_edge PARAMS ((sbitmap *, basic_block,
- basic_block, int));
-extern edge make_edge PARAMS ((basic_block,
- basic_block, int));
-extern edge make_single_succ_edge PARAMS ((basic_block,
- basic_block, int));
-extern void remove_edge PARAMS ((edge));
-extern void redirect_edge_succ PARAMS ((edge, basic_block));
-extern edge redirect_edge_succ_nodup PARAMS ((edge, basic_block));
-extern void redirect_edge_pred PARAMS ((edge, basic_block));
-extern basic_block create_basic_block_structure PARAMS ((rtx, rtx, rtx, basic_block));
-extern basic_block create_basic_block PARAMS ((rtx, rtx, basic_block));
-extern int flow_delete_block PARAMS ((basic_block));
-extern int flow_delete_block_noexpunge PARAMS ((basic_block));
-extern void clear_bb_flags PARAMS ((void));
-extern void merge_blocks_nomove PARAMS ((basic_block, basic_block));
-extern void tidy_fallthru_edge PARAMS ((edge, basic_block,
- basic_block));
-extern void tidy_fallthru_edges PARAMS ((void));
-extern void flow_reverse_top_sort_order_compute PARAMS ((int *));
-extern int flow_depth_first_order_compute PARAMS ((int *, int *));
-extern void flow_preorder_transversal_compute PARAMS ((int *));
-extern int dfs_enumerate_from PARAMS ((basic_block, int,
- bool (*)(basic_block, void *),
- basic_block *, int, void *));
-extern void dump_edge_info PARAMS ((FILE *, edge, int));
-extern void clear_edges PARAMS ((void));
-extern void mark_critical_edges PARAMS ((void));
-extern rtx first_insn_after_basic_block_note PARAMS ((basic_block));
-
-/* Dominator information for basic blocks. */
-
-typedef struct dominance_info *dominance_info;
+extern void compute_bb_for_insn (void);
+extern void free_bb_for_insn (void);
+extern void update_bb_for_insn (basic_block);
+
+extern void free_basic_block_vars (int);
+
+extern void insert_insn_on_edge (rtx, edge);
+bool safe_insert_insn_on_edge (rtx, edge);
+
+extern void commit_edge_insertions (void);
+extern void commit_edge_insertions_watch_calls (void);
+
+extern void remove_fake_edges (void);
+extern void add_noreturn_fake_exit_edges (void);
+extern void connect_infinite_loops_to_exit (void);
+extern int flow_call_edges_add (sbitmap);
+extern edge unchecked_make_edge (basic_block, basic_block, int);
+extern edge cached_make_edge (sbitmap *, basic_block, basic_block, int);
+extern edge make_edge (basic_block, basic_block, int);
+extern edge make_single_succ_edge (basic_block, basic_block, int);
+extern void remove_edge (edge);
+extern void redirect_edge_succ (edge, basic_block);
+extern edge redirect_edge_succ_nodup (edge, basic_block);
+extern void redirect_edge_pred (edge, basic_block);
+extern basic_block create_basic_block_structure (rtx, rtx, rtx, basic_block);
+extern void clear_bb_flags (void);
+extern void flow_reverse_top_sort_order_compute (int *);
+extern int flow_depth_first_order_compute (int *, int *);
+extern void flow_preorder_transversal_compute (int *);
+extern int dfs_enumerate_from (basic_block, int,
+ bool (*)(basic_block, void *),
+ basic_block *, int, void *);
+extern void dump_edge_info (FILE *, edge, int);
+extern void clear_edges (void);
+extern void mark_critical_edges (void);
+extern rtx first_insn_after_basic_block_note (basic_block);
/* Structure to group all of the information to process IF-THEN and
IF-THEN-ELSE blocks for the conditional execution support. This
#define EDGE_CRITICAL_P(e) ((e)->src->succ->succ_next \
&& (e)->dest->pred->pred_next)
-struct edge_list * create_edge_list PARAMS ((void));
-void free_edge_list PARAMS ((struct edge_list *));
-void print_edge_list PARAMS ((FILE *, struct edge_list *));
-void verify_edge_list PARAMS ((FILE *, struct edge_list *));
-int find_edge_index PARAMS ((struct edge_list *,
- basic_block, basic_block));
+struct edge_list * create_edge_list (void);
+void free_edge_list (struct edge_list *);
+void print_edge_list (FILE *, struct edge_list *);
+void verify_edge_list (FILE *, struct edge_list *);
+int find_edge_index (struct edge_list *, basic_block, basic_block);
enum update_life_extent
#define PROP_AUTOINC 64 /* Create autoinc mem references. */
#define PROP_EQUAL_NOTES 128 /* Take into account REG_EQUAL notes. */
#define PROP_SCAN_DEAD_STORES 256 /* Scan for dead code. */
+#define PROP_ASM_SCAN 512 /* Internal flag used within flow.c
+ to flag analysis of asms. */
#define PROP_FINAL (PROP_DEATH_NOTES | PROP_LOG_LINKS \
| PROP_REG_INFO | PROP_KILL_DEAD_CODE \
| PROP_SCAN_DEAD_CODE | PROP_AUTOINC \
| PROP_ALLOW_CFG_CHANGES \
| PROP_SCAN_DEAD_STORES)
+#define PROP_POSTRELOAD (PROP_DEATH_NOTES \
+ | PROP_KILL_DEAD_CODE \
+ | PROP_SCAN_DEAD_CODE | PROP_AUTOINC \
+ | PROP_SCAN_DEAD_STORES)
-#define CLEANUP_EXPENSIVE 1 /* Do relativly expensive optimizations
+#define CLEANUP_EXPENSIVE 1 /* Do relatively expensive optimizations
except for edge forwarding */
#define CLEANUP_CROSSJUMP 2 /* Do crossjumping. */
#define CLEANUP_POST_REGSTACK 4 /* We run after reg-stack and need
#define CLEANUP_THREADING 64 /* Do jump threading. */
#define CLEANUP_NO_INSN_DEL 128 /* Do not try to delete trivially dead
insns. */
-extern void life_analysis PARAMS ((rtx, FILE *, int));
-extern int update_life_info PARAMS ((sbitmap, enum update_life_extent,
- int));
-extern int update_life_info_in_dirty_blocks PARAMS ((enum update_life_extent,
- int));
-extern int count_or_remove_death_notes PARAMS ((sbitmap, int));
-extern int propagate_block PARAMS ((basic_block, regset, regset, regset,
- int));
+#define CLEANUP_CFGLAYOUT 256 /* Do cleanup in cfglayout mode. */
+#define CLEANUP_LOG_LINKS 512 /* Update log links. */
+extern void life_analysis (rtx, FILE *, int);
+extern int update_life_info (sbitmap, enum update_life_extent, int);
+extern int update_life_info_in_dirty_blocks (enum update_life_extent, int);
+extern int count_or_remove_death_notes (sbitmap, int);
+extern int propagate_block (basic_block, regset, regset, regset, int);
struct propagate_block_info;
-extern rtx propagate_one_insn PARAMS ((struct propagate_block_info *, rtx));
+extern rtx propagate_one_insn (struct propagate_block_info *, rtx);
extern struct propagate_block_info *init_propagate_block_info
- PARAMS ((basic_block, regset, regset, regset, int));
-extern void free_propagate_block_info PARAMS ((struct propagate_block_info *));
+ (basic_block, regset, regset, regset, int);
+extern void free_propagate_block_info (struct propagate_block_info *);
/* In lcm.c */
-extern struct edge_list *pre_edge_lcm PARAMS ((FILE *, int, sbitmap *,
- sbitmap *, sbitmap *,
- sbitmap *, sbitmap **,
- sbitmap **));
-extern struct edge_list *pre_edge_rev_lcm PARAMS ((FILE *, int, sbitmap *,
- sbitmap *, sbitmap *,
- sbitmap *, sbitmap **,
- sbitmap **));
-extern void compute_available PARAMS ((sbitmap *, sbitmap *,
- sbitmap *, sbitmap *));
-extern int optimize_mode_switching PARAMS ((FILE *));
+extern struct edge_list *pre_edge_lcm (FILE *, int, sbitmap *, sbitmap *,
+ sbitmap *, sbitmap *, sbitmap **,
+ sbitmap **);
+extern struct edge_list *pre_edge_rev_lcm (FILE *, int, sbitmap *,
+ sbitmap *, sbitmap *,
+ sbitmap *, sbitmap **,
+ sbitmap **);
+extern void compute_available (sbitmap *, sbitmap *, sbitmap *, sbitmap *);
+extern int optimize_mode_switching (FILE *);
/* In emit-rtl.c. */
-extern rtx emit_block_insn_after PARAMS ((rtx, rtx, basic_block));
-extern rtx emit_block_insn_before PARAMS ((rtx, rtx, basic_block));
+extern rtx emit_block_insn_after (rtx, rtx, basic_block);
+extern rtx emit_block_insn_before (rtx, rtx, basic_block);
/* In predict.c */
-extern void estimate_probability PARAMS ((struct loops *));
-extern void note_prediction_to_br_prob PARAMS ((void));
-extern void expected_value_to_br_prob PARAMS ((void));
-extern void note_prediction_to_br_prob PARAMS ((void));
-extern bool maybe_hot_bb_p PARAMS ((basic_block));
-extern bool probably_cold_bb_p PARAMS ((basic_block));
-extern bool probably_never_executed_bb_p PARAMS ((basic_block));
+extern void estimate_probability (struct loops *);
+extern void note_prediction_to_br_prob (void);
+extern void expected_value_to_br_prob (void);
+extern bool maybe_hot_bb_p (basic_block);
+extern bool probably_cold_bb_p (basic_block);
+extern bool probably_never_executed_bb_p (basic_block);
/* In flow.c */
-extern void init_flow PARAMS ((void));
-extern void reorder_basic_blocks PARAMS ((void));
-extern void dump_bb PARAMS ((basic_block, FILE *));
-extern void debug_bb PARAMS ((basic_block));
-extern basic_block debug_bb_n PARAMS ((int));
-extern void dump_regset PARAMS ((regset, FILE *));
-extern void debug_regset PARAMS ((regset));
-extern void allocate_reg_life_data PARAMS ((void));
-extern void allocate_bb_life_data PARAMS ((void));
-extern void expunge_block PARAMS ((basic_block));
-extern void link_block PARAMS ((basic_block, basic_block));
-extern void unlink_block PARAMS ((basic_block));
-extern void compact_blocks PARAMS ((void));
-extern basic_block alloc_block PARAMS ((void));
-extern void find_unreachable_blocks PARAMS ((void));
-extern int delete_noop_moves PARAMS ((rtx));
-extern basic_block redirect_edge_and_branch_force PARAMS ((edge, basic_block));
-extern basic_block force_nonfallthru PARAMS ((edge));
-extern bool redirect_edge_and_branch PARAMS ((edge, basic_block));
-extern rtx block_label PARAMS ((basic_block));
-extern bool forwarder_block_p PARAMS ((basic_block));
-extern bool purge_all_dead_edges PARAMS ((int));
-extern bool purge_dead_edges PARAMS ((basic_block));
-extern void find_sub_basic_blocks PARAMS ((basic_block));
-extern void find_many_sub_basic_blocks PARAMS ((sbitmap));
-extern bool can_fallthru PARAMS ((basic_block, basic_block));
-extern void flow_nodes_print PARAMS ((const char *, const sbitmap,
- FILE *));
-extern void flow_edge_list_print PARAMS ((const char *, const edge *,
- int, FILE *));
-extern void alloc_aux_for_block PARAMS ((basic_block, int));
-extern void alloc_aux_for_blocks PARAMS ((int));
-extern void clear_aux_for_blocks PARAMS ((void));
-extern void free_aux_for_blocks PARAMS ((void));
-extern void alloc_aux_for_edge PARAMS ((edge, int));
-extern void alloc_aux_for_edges PARAMS ((int));
-extern void clear_aux_for_edges PARAMS ((void));
-extern void free_aux_for_edges PARAMS ((void));
-
-/* This function is always defined so it can be called from the
- debugger, and it is declared extern so we don't get warnings about
- it being unused. */
-extern void verify_flow_info PARAMS ((void));
+extern void init_flow (void);
+extern void debug_bb (basic_block);
+extern basic_block debug_bb_n (int);
+extern void dump_regset (regset, FILE *);
+extern void debug_regset (regset);
+extern void allocate_reg_life_data (void);
+extern void allocate_bb_life_data (void);
+extern void expunge_block (basic_block);
+extern void link_block (basic_block, basic_block);
+extern void unlink_block (basic_block);
+extern void compact_blocks (void);
+extern basic_block alloc_block (void);
+extern void find_unreachable_blocks (void);
+extern int delete_noop_moves (rtx);
+extern basic_block force_nonfallthru (edge);
+extern rtx block_label (basic_block);
+extern bool forwarder_block_p (basic_block);
+extern bool purge_all_dead_edges (int);
+extern bool purge_dead_edges (basic_block);
+extern void find_sub_basic_blocks (basic_block);
+extern void find_many_sub_basic_blocks (sbitmap);
+extern void make_eh_edge (sbitmap *, basic_block, rtx);
+extern bool can_fallthru (basic_block, basic_block);
+extern void flow_nodes_print (const char *, const sbitmap, FILE *);
+extern void flow_edge_list_print (const char *, const edge *, int, FILE *);
+extern void alloc_aux_for_block (basic_block, int);
+extern void alloc_aux_for_blocks (int);
+extern void clear_aux_for_blocks (void);
+extern void free_aux_for_blocks (void);
+extern void alloc_aux_for_edge (edge, int);
+extern void alloc_aux_for_edges (int);
+extern void clear_aux_for_edges (void);
+extern void free_aux_for_edges (void);
typedef struct conflict_graph_def *conflict_graph;
/* Callback function when enumerating conflicts. The arguments are
the smaller and larger regno in the conflict. Returns zero if
enumeration is to continue, nonzero to halt enumeration. */
-typedef int (*conflict_graph_enum_fn) PARAMS ((int, int, void *));
+typedef int (*conflict_graph_enum_fn) (int, int, void *);
/* Prototypes of operations on conflict graphs. */
extern conflict_graph conflict_graph_new
- PARAMS ((int));
-extern void conflict_graph_delete PARAMS ((conflict_graph));
-extern int conflict_graph_add PARAMS ((conflict_graph,
- int, int));
-extern int conflict_graph_conflict_p PARAMS ((conflict_graph,
- int, int));
-extern void conflict_graph_enum PARAMS ((conflict_graph, int,
- conflict_graph_enum_fn,
- void *));
-extern void conflict_graph_merge_regs PARAMS ((conflict_graph, int,
- int));
-extern void conflict_graph_print PARAMS ((conflict_graph, FILE*));
-extern conflict_graph conflict_graph_compute
- PARAMS ((regset,
- partition));
-extern bool mark_dfs_back_edges PARAMS ((void));
-extern void set_edge_can_fallthru_flag PARAMS ((void));
-extern void update_br_prob_note PARAMS ((basic_block));
-extern void fixup_abnormal_edges PARAMS ((void));
-extern bool can_hoist_insn_p PARAMS ((rtx, rtx, regset));
-extern rtx hoist_insn_after PARAMS ((rtx, rtx, rtx, rtx));
-extern rtx hoist_insn_to_edge PARAMS ((rtx, edge, rtx, rtx));
-extern bool inside_basic_block_p PARAMS ((rtx));
-extern bool control_flow_insn_p PARAMS ((rtx));
+ (int);
+extern void conflict_graph_delete (conflict_graph);
+extern int conflict_graph_add (conflict_graph, int, int);
+extern int conflict_graph_conflict_p (conflict_graph, int, int);
+extern void conflict_graph_enum (conflict_graph, int, conflict_graph_enum_fn,
+ void *);
+extern void conflict_graph_merge_regs (conflict_graph, int, int);
+extern void conflict_graph_print (conflict_graph, FILE*);
+extern conflict_graph conflict_graph_compute (regset, partition);
+extern bool mark_dfs_back_edges (void);
+extern void set_edge_can_fallthru_flag (void);
+extern void update_br_prob_note (basic_block);
+extern void fixup_abnormal_edges (void);
+extern bool can_hoist_insn_p (rtx, rtx, regset);
+extern rtx hoist_insn_after (rtx, rtx, rtx, rtx);
+extern rtx hoist_insn_to_edge (rtx, edge, rtx, rtx);
+extern bool inside_basic_block_p (rtx);
+extern bool control_flow_insn_p (rtx);
+
+/* In bb-reorder.c */
+extern void reorder_basic_blocks (void);
/* In dominance.c */
CDI_POST_DOMINATORS
};
-extern dominance_info calculate_dominance_info PARAMS ((enum cdi_direction));
-extern void free_dominance_info PARAMS ((dominance_info));
-extern basic_block nearest_common_dominator PARAMS ((dominance_info,
- basic_block, basic_block));
-extern void set_immediate_dominator PARAMS ((dominance_info,
- basic_block, basic_block));
-extern basic_block get_immediate_dominator PARAMS ((dominance_info,
- basic_block));
-extern bool dominated_by_p PARAMS ((dominance_info, basic_block, basic_block));
-extern int get_dominated_by PARAMS ((dominance_info, basic_block, basic_block **));
-extern void add_to_dominance_info PARAMS ((dominance_info, basic_block));
-extern void delete_from_dominance_info PARAMS ((dominance_info, basic_block));
-basic_block recount_dominator PARAMS ((dominance_info, basic_block));
-extern void redirect_immediate_dominators PARAMS ((dominance_info, basic_block,
- basic_block));
-void iterate_fix_dominators PARAMS ((dominance_info, basic_block *, int));
-extern void verify_dominators PARAMS ((dominance_info));
+enum dom_state
+{
+ DOM_NONE, /* Not computed at all. */
+ DOM_CONS_OK, /* The data is conservatively OK, i.e. if it says you that A dominates B,
+ it indeed does. */
+ DOM_NO_FAST_QUERY, /* The data is OK, but the fast query data are not usable. */
+ DOM_OK /* Everything is ok. */
+};
+
+extern enum dom_state dom_computed[2];
+
+extern void calculate_dominance_info (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 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, basic_block, basic_block);
+extern int get_dominated_by (enum cdi_direction, basic_block, 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 recount_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, basic_block *, int);
+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);
+extern bool try_redirect_by_replacing_jump (edge, basic_block, bool);
+extern void break_superblocks (void);
+
+#include "cfghooks.h"
+
#endif /* GCC_BASIC_BLOCK_H */