DEF_VEC_ALLOC_P(edge,gc);
DEF_VEC_ALLOC_P(edge,heap);
-#define EDGE_FALLTHRU 1 /* 'Straight line' flow */
-#define EDGE_ABNORMAL 2 /* Strange flow, like computed
+/* Always update the table in cfg.c dump_edge_info. */
+#define EDGE_FALLTHRU 0x0001 /* 'Straight line' flow */
+#define EDGE_ABNORMAL 0x0002 /* Strange flow, like computed
label, or eh */
-#define EDGE_ABNORMAL_CALL 4 /* Call with abnormal exit
+#define EDGE_ABNORMAL_CALL 0x0004 /* Call with abnormal exit
like an exception, or sibcall */
-#define EDGE_EH 8 /* Exception throw */
-#define EDGE_FAKE 16 /* Not a real edge (profile.c) */
-#define EDGE_DFS_BACK 32 /* A backwards edge */
-#define EDGE_CAN_FALLTHRU 64 /* Candidate for straight line
+#define EDGE_EH 0x0008 /* Exception throw */
+#define EDGE_FAKE 0x0010 /* Not a real edge (profile.c) */
+#define EDGE_DFS_BACK 0x0020 /* A backwards edge */
+#define EDGE_CAN_FALLTHRU 0x0040 /* Candidate for straight line
flow. */
-#define EDGE_IRREDUCIBLE_LOOP 128 /* Part of irreducible loop. */
-#define EDGE_SIBCALL 256 /* Edge from sibcall to exit. */
-#define EDGE_LOOP_EXIT 512 /* Exit of a loop. */
-#define EDGE_TRUE_VALUE 1024 /* Edge taken when controlling
+#define EDGE_IRREDUCIBLE_LOOP 0x0080 /* Part of irreducible loop. */
+#define EDGE_SIBCALL 0x0100 /* Edge from sibcall to exit. */
+#define EDGE_LOOP_EXIT 0x0200 /* Exit of a loop. */
+#define EDGE_TRUE_VALUE 0x0400 /* Edge taken when controlling
predicate is nonzero. */
-#define EDGE_FALSE_VALUE 2048 /* Edge taken when controlling
+#define EDGE_FALSE_VALUE 0x0800 /* Edge taken when controlling
predicate is zero. */
-#define EDGE_EXECUTABLE 4096 /* Edge is executable. Only
+#define EDGE_EXECUTABLE 0x1000 /* Edge is executable. Only
valid during SSA-CCP. */
-#define EDGE_CROSSING 8192 /* Edge crosses between hot
+#define EDGE_CROSSING 0x2000 /* Edge crosses between hot
and cold sections, when we
do partitioning. */
-#define EDGE_ALL_FLAGS 16383
+#define EDGE_PRESERVE 0x4000 /* Never merge blocks via this edge. */
+#define EDGE_ALL_FLAGS 0x7fff
-#define EDGE_COMPLEX (EDGE_ABNORMAL | EDGE_ABNORMAL_CALL | EDGE_EH)
+#define EDGE_COMPLEX \
+ (EDGE_ABNORMAL | EDGE_ABNORMAL_CALL | EDGE_EH | EDGE_PRESERVE)
/* Counter summary from the last set of coverage counts read by
profile.c. */
struct loop;
/* Declared in tree-flow.h. */
-struct edge_prediction;
struct rtl_bb_info;
/* A basic block is a sequence of instructions with only entry and
the compilation, so they are never cleared.
All other flags may be cleared by clear_bb_flags(). It is generally
- a bad idea to rely on any flags being up-to-date. */
+ a bad idea to rely on any flags being up-to-date.
+
+ Always update the table in cfg.c dump_bb_info. */
enum bb_flags
{
/* Set on blocks that cannot be threaded through.
Only used in cfgcleanup.c. */
- BB_NONTHREADABLE_BLOCK = 1 << 11
+ BB_NONTHREADABLE_BLOCK = 1 << 11,
+
+ /* Set on blocks that were modified in some way. This bit is set in
+ df_set_bb_dirty, but not cleared by df_analyze, so it can be used
+ to test whether a block has been modified prior to a df_analyze
+ call. */
+ BB_MODIFIED = 1 << 12
};
/* Dummy flag for convenience in the hot/cold partitioning code. */
{
PROFILE_ABSENT,
PROFILE_GUESSED,
- PROFILE_READ
+ PROFILE_READ,
+ PROFILE_LAST /* Last value, used by profile streaming. */
};
/* A structure to group all the per-function control flow graph data.
static inline edge
single_succ_edge (const_basic_block bb)
{
-#ifdef ENABLE_CHECKING
- gcc_assert (single_succ_p (bb));
-#endif
+ gcc_checking_assert (single_succ_p (bb));
return EDGE_SUCC (bb, 0);
}
static inline edge
single_pred_edge (const_basic_block bb)
{
-#ifdef ENABLE_CHECKING
- gcc_assert (single_pred_p (bb));
-#endif
+ gcc_checking_assert (single_pred_p (bb));
return EDGE_PRED (bb, 0);
}
static inline VEC(edge,gc) *
ei_container (edge_iterator i)
{
-#ifdef ENABLE_CHECKING
- gcc_assert (i.container);
-#endif
+ gcc_checking_assert (i.container);
return *i.container;
}
static inline void
ei_next (edge_iterator *i)
{
-#ifdef ENABLE_CHECKING
- gcc_assert (i->index < EDGE_COUNT (ei_container (*i)));
-#endif
+ gcc_checking_assert (i->index < EDGE_COUNT (ei_container (*i)));
i->index++;
}
static inline void
ei_prev (edge_iterator *i)
{
-#ifdef ENABLE_CHECKING
- gcc_assert (i->index > 0);
-#endif
+ gcc_checking_assert (i->index > 0);
i->index--;
}
extern void unlink_block (basic_block);
extern void compact_blocks (void);
extern basic_block alloc_block (void);
-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);
extern void flow_edge_list_print (const char *, const edge *, int, FILE *);
/* In cfgrtl.c */
-extern basic_block force_nonfallthru (edge);
extern rtx block_label (basic_block);
extern bool purge_all_dead_edges (void);
extern bool purge_dead_edges (basic_block);
+extern bool fixup_abnormal_edges (void);
+extern basic_block force_nonfallthru_and_redirect (edge, basic_block, rtx);
/* 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 *, rtx *);
+extern int flow_find_cross_jump (basic_block, basic_block, rtx *, rtx *,
+ enum replace_direction*);
extern int flow_find_head_matching_sequence (basic_block, basic_block,
rtx *, rtx *, int);
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 inside_basic_block_p (const_rtx);
extern bool control_flow_insn_p (const_rtx);
extern rtx get_last_bb_insn (basic_block);
extern VEC (basic_block, heap) *get_dominated_by_region (enum cdi_direction,
basic_block *,
unsigned);
+extern VEC (basic_block, heap) *get_dominated_to_depth (enum cdi_direction,
+ basic_block, int);
extern VEC (basic_block, heap) *get_all_dominated_blocks (enum cdi_direction,
basic_block);
extern void add_to_dominance_info (enum cdi_direction, basic_block);
void set_loop_copy (struct loop *, struct loop *);
struct loop *get_loop_copy (struct loop *);
-
-extern rtx insert_insn_end_bb_new (rtx, basic_block);
-
#include "cfghooks.h"
/* Return true when one of the predecessor edges of BB is marked with EDGE_EH. */
return false;
}
+/* Return the fallthru edge in EDGES if it exists, NULL otherwise. */
+static inline edge
+find_fallthru_edge (VEC(edge,gc) *edges)
+{
+ edge e;
+ edge_iterator ei;
+
+ FOR_EACH_EDGE (e, ei, edges)
+ if (e->flags & EDGE_FALLTHRU)
+ break;
+
+ return e;
+}
+
/* In cfgloopmanip.c. */
extern edge mfb_kj_edge;
extern bool mfb_keep_just (edge);