110d565efSmrg /* Define control flow data structures for the CFG.
2*ec02198aSmrg Copyright (C) 1987-2020 Free Software Foundation, Inc.
310d565efSmrg
410d565efSmrg This file is part of GCC.
510d565efSmrg
610d565efSmrg GCC is free software; you can redistribute it and/or modify it under
710d565efSmrg the terms of the GNU General Public License as published by the Free
810d565efSmrg Software Foundation; either version 3, or (at your option) any later
910d565efSmrg version.
1010d565efSmrg
1110d565efSmrg GCC is distributed in the hope that it will be useful, but WITHOUT ANY
1210d565efSmrg WARRANTY; without even the implied warranty of MERCHANTABILITY or
1310d565efSmrg FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
1410d565efSmrg for more details.
1510d565efSmrg
1610d565efSmrg You should have received a copy of the GNU General Public License
1710d565efSmrg along with GCC; see the file COPYING3. If not see
1810d565efSmrg <http://www.gnu.org/licenses/>. */
1910d565efSmrg
2010d565efSmrg #ifndef GCC_BASIC_BLOCK_H
2110d565efSmrg #define GCC_BASIC_BLOCK_H
2210d565efSmrg
23c7a68eb7Smrg #include <profile-count.h>
2410d565efSmrg
2510d565efSmrg /* Control flow edge information. */
class(user)26*ec02198aSmrg class GTY((user)) edge_def {
27*ec02198aSmrg public:
2810d565efSmrg /* The two blocks at the ends of the edge. */
2910d565efSmrg basic_block src;
3010d565efSmrg basic_block dest;
3110d565efSmrg
3210d565efSmrg /* Instructions queued on the edge. */
3310d565efSmrg union edge_def_insns {
3410d565efSmrg gimple_seq g;
3510d565efSmrg rtx_insn *r;
3610d565efSmrg } insns;
3710d565efSmrg
3810d565efSmrg /* Auxiliary info specific to a pass. */
3910d565efSmrg PTR aux;
4010d565efSmrg
4110d565efSmrg /* Location of any goto implicit in the edge. */
4210d565efSmrg location_t goto_locus;
4310d565efSmrg
4410d565efSmrg /* The index number corresponding to this edge in the edge vector
4510d565efSmrg dest->preds. */
4610d565efSmrg unsigned int dest_idx;
4710d565efSmrg
4810d565efSmrg int flags; /* see cfg-flags.def */
49c7a68eb7Smrg profile_probability probability;
50c7a68eb7Smrg
51c7a68eb7Smrg /* Return count of edge E. */
52c7a68eb7Smrg inline profile_count count () const;
5310d565efSmrg };
5410d565efSmrg
5510d565efSmrg /* Masks for edge.flags. */
5610d565efSmrg #define DEF_EDGE_FLAG(NAME,IDX) EDGE_##NAME = 1 << IDX ,
5710d565efSmrg enum cfg_edge_flags {
5810d565efSmrg #include "cfg-flags.def"
5910d565efSmrg LAST_CFG_EDGE_FLAG /* this is only used for EDGE_ALL_FLAGS */
6010d565efSmrg };
6110d565efSmrg #undef DEF_EDGE_FLAG
6210d565efSmrg
6310d565efSmrg /* Bit mask for all edge flags. */
6410d565efSmrg #define EDGE_ALL_FLAGS ((LAST_CFG_EDGE_FLAG - 1) * 2 - 1)
6510d565efSmrg
6610d565efSmrg /* The following four flags all indicate something special about an edge.
6710d565efSmrg Test the edge flags on EDGE_COMPLEX to detect all forms of "strange"
6810d565efSmrg control flow transfers. */
6910d565efSmrg #define EDGE_COMPLEX \
7010d565efSmrg (EDGE_ABNORMAL | EDGE_ABNORMAL_CALL | EDGE_EH | EDGE_PRESERVE)
7110d565efSmrg
7210d565efSmrg struct GTY(()) rtl_bb_info {
7310d565efSmrg /* The first insn of the block is embedded into bb->il.x. */
7410d565efSmrg /* The last insn of the block. */
7510d565efSmrg rtx_insn *end_;
7610d565efSmrg
7710d565efSmrg /* In CFGlayout mode points to insn notes/jumptables to be placed just before
7810d565efSmrg and after the block. */
7910d565efSmrg rtx_insn *header_;
8010d565efSmrg rtx_insn *footer_;
8110d565efSmrg };
8210d565efSmrg
8310d565efSmrg struct GTY(()) gimple_bb_info {
8410d565efSmrg /* Sequence of statements in this block. */
8510d565efSmrg gimple_seq seq;
8610d565efSmrg
8710d565efSmrg /* PHI nodes for this block. */
8810d565efSmrg gimple_seq phi_nodes;
8910d565efSmrg };
9010d565efSmrg
9110d565efSmrg /* A basic block is a sequence of instructions with only one entry and
9210d565efSmrg only one exit. If any one of the instructions are executed, they
9310d565efSmrg will all be executed, and in sequence from first to last.
9410d565efSmrg
9510d565efSmrg There may be COND_EXEC instructions in the basic block. The
9610d565efSmrg COND_EXEC *instructions* will be executed -- but if the condition
9710d565efSmrg is false the conditionally executed *expressions* will of course
9810d565efSmrg not be executed. We don't consider the conditionally executed
9910d565efSmrg expression (which might have side-effects) to be in a separate
10010d565efSmrg basic block because the program counter will always be at the same
10110d565efSmrg location after the COND_EXEC instruction, regardless of whether the
10210d565efSmrg condition is true or not.
10310d565efSmrg
10410d565efSmrg Basic blocks need not start with a label nor end with a jump insn.
10510d565efSmrg For example, a previous basic block may just "conditionally fall"
10610d565efSmrg into the succeeding basic block, and the last basic block need not
10710d565efSmrg end with a jump insn. Block 0 is a descendant of the entry block.
10810d565efSmrg
10910d565efSmrg A basic block beginning with two labels cannot have notes between
11010d565efSmrg the labels.
11110d565efSmrg
11210d565efSmrg Data for jump tables are stored in jump_insns that occur in no
11310d565efSmrg basic block even though these insns can follow or precede insns in
11410d565efSmrg basic blocks. */
11510d565efSmrg
11610d565efSmrg /* Basic block information indexed by block number. */
11710d565efSmrg struct GTY((chain_next ("%h.next_bb"), chain_prev ("%h.prev_bb"))) basic_block_def {
11810d565efSmrg /* The edges into and out of the block. */
11910d565efSmrg vec<edge, va_gc> *preds;
12010d565efSmrg vec<edge, va_gc> *succs;
12110d565efSmrg
12210d565efSmrg /* Auxiliary info specific to a pass. */
12310d565efSmrg PTR GTY ((skip (""))) aux;
12410d565efSmrg
12510d565efSmrg /* Innermost loop containing the block. */
126*ec02198aSmrg class loop *loop_father;
12710d565efSmrg
12810d565efSmrg /* The dominance and postdominance information node. */
12910d565efSmrg struct et_node * GTY ((skip (""))) dom[2];
13010d565efSmrg
13110d565efSmrg /* Previous and next blocks in the chain. */
13210d565efSmrg basic_block prev_bb;
13310d565efSmrg basic_block next_bb;
13410d565efSmrg
13510d565efSmrg union basic_block_il_dependent {
13610d565efSmrg struct gimple_bb_info GTY ((tag ("0"))) gimple;
13710d565efSmrg struct {
13810d565efSmrg rtx_insn *head_;
13910d565efSmrg struct rtl_bb_info * rtl;
14010d565efSmrg } GTY ((tag ("1"))) x;
14110d565efSmrg } GTY ((desc ("((%1.flags & BB_RTL) != 0)"))) il;
14210d565efSmrg
14310d565efSmrg /* Various flags. See cfg-flags.def. */
14410d565efSmrg int flags;
14510d565efSmrg
14610d565efSmrg /* The index of this block. */
14710d565efSmrg int index;
14810d565efSmrg
14910d565efSmrg /* Expected number of executions: calculated in profile.c. */
150c7a68eb7Smrg profile_count count;
15110d565efSmrg
15210d565efSmrg /* The discriminator for this block. The discriminator distinguishes
15310d565efSmrg among several basic blocks that share a common locus, allowing for
15410d565efSmrg more accurate sample-based profiling. */
15510d565efSmrg int discriminator;
15610d565efSmrg };
15710d565efSmrg
15810d565efSmrg /* This ensures that struct gimple_bb_info is smaller than
15910d565efSmrg struct rtl_bb_info, so that inlining the former into basic_block_def
16010d565efSmrg is the better choice. */
16110d565efSmrg typedef int __assert_gimple_bb_smaller_rtl_bb
16210d565efSmrg [(int) sizeof (struct rtl_bb_info)
16310d565efSmrg - (int) sizeof (struct gimple_bb_info)];
16410d565efSmrg
16510d565efSmrg
16610d565efSmrg #define BB_FREQ_MAX 10000
16710d565efSmrg
16810d565efSmrg /* Masks for basic_block.flags. */
16910d565efSmrg #define DEF_BASIC_BLOCK_FLAG(NAME,IDX) BB_##NAME = 1 << IDX ,
17010d565efSmrg enum cfg_bb_flags
17110d565efSmrg {
17210d565efSmrg #include "cfg-flags.def"
17310d565efSmrg LAST_CFG_BB_FLAG /* this is only used for BB_ALL_FLAGS */
17410d565efSmrg };
17510d565efSmrg #undef DEF_BASIC_BLOCK_FLAG
17610d565efSmrg
17710d565efSmrg /* Bit mask for all basic block flags. */
17810d565efSmrg #define BB_ALL_FLAGS ((LAST_CFG_BB_FLAG - 1) * 2 - 1)
17910d565efSmrg
18010d565efSmrg /* Bit mask for all basic block flags that must be preserved. These are
18110d565efSmrg the bit masks that are *not* cleared by clear_bb_flags. */
18210d565efSmrg #define BB_FLAGS_TO_PRESERVE \
18310d565efSmrg (BB_DISABLE_SCHEDULE | BB_RTL | BB_NON_LOCAL_GOTO_TARGET \
18410d565efSmrg | BB_HOT_PARTITION | BB_COLD_PARTITION)
18510d565efSmrg
18610d565efSmrg /* Dummy bitmask for convenience in the hot/cold partitioning code. */
18710d565efSmrg #define BB_UNPARTITIONED 0
18810d565efSmrg
18910d565efSmrg /* Partitions, to be used when partitioning hot and cold basic blocks into
19010d565efSmrg separate sections. */
19110d565efSmrg #define BB_PARTITION(bb) ((bb)->flags & (BB_HOT_PARTITION|BB_COLD_PARTITION))
19210d565efSmrg #define BB_SET_PARTITION(bb, part) do { \
19310d565efSmrg basic_block bb_ = (bb); \
19410d565efSmrg bb_->flags = ((bb_->flags & ~(BB_HOT_PARTITION|BB_COLD_PARTITION)) \
19510d565efSmrg | (part)); \
19610d565efSmrg } while (0)
19710d565efSmrg
19810d565efSmrg #define BB_COPY_PARTITION(dstbb, srcbb) \
19910d565efSmrg BB_SET_PARTITION (dstbb, BB_PARTITION (srcbb))
20010d565efSmrg
20110d565efSmrg /* Defines for accessing the fields of the CFG structure for function FN. */
20210d565efSmrg #define ENTRY_BLOCK_PTR_FOR_FN(FN) ((FN)->cfg->x_entry_block_ptr)
20310d565efSmrg #define EXIT_BLOCK_PTR_FOR_FN(FN) ((FN)->cfg->x_exit_block_ptr)
20410d565efSmrg #define basic_block_info_for_fn(FN) ((FN)->cfg->x_basic_block_info)
20510d565efSmrg #define n_basic_blocks_for_fn(FN) ((FN)->cfg->x_n_basic_blocks)
20610d565efSmrg #define n_edges_for_fn(FN) ((FN)->cfg->x_n_edges)
20710d565efSmrg #define last_basic_block_for_fn(FN) ((FN)->cfg->x_last_basic_block)
20810d565efSmrg #define label_to_block_map_for_fn(FN) ((FN)->cfg->x_label_to_block_map)
20910d565efSmrg #define profile_status_for_fn(FN) ((FN)->cfg->x_profile_status)
21010d565efSmrg
21110d565efSmrg #define BASIC_BLOCK_FOR_FN(FN,N) \
21210d565efSmrg ((*basic_block_info_for_fn (FN))[(N)])
21310d565efSmrg #define SET_BASIC_BLOCK_FOR_FN(FN,N,BB) \
21410d565efSmrg ((*basic_block_info_for_fn (FN))[(N)] = (BB))
21510d565efSmrg
21610d565efSmrg /* For iterating over basic blocks. */
21710d565efSmrg #define FOR_BB_BETWEEN(BB, FROM, TO, DIR) \
21810d565efSmrg for (BB = FROM; BB != TO; BB = BB->DIR)
21910d565efSmrg
22010d565efSmrg #define FOR_EACH_BB_FN(BB, FN) \
22110d565efSmrg FOR_BB_BETWEEN (BB, (FN)->cfg->x_entry_block_ptr->next_bb, (FN)->cfg->x_exit_block_ptr, next_bb)
22210d565efSmrg
22310d565efSmrg #define FOR_EACH_BB_REVERSE_FN(BB, FN) \
22410d565efSmrg FOR_BB_BETWEEN (BB, (FN)->cfg->x_exit_block_ptr->prev_bb, (FN)->cfg->x_entry_block_ptr, prev_bb)
22510d565efSmrg
22610d565efSmrg /* For iterating over insns in basic block. */
22710d565efSmrg #define FOR_BB_INSNS(BB, INSN) \
22810d565efSmrg for ((INSN) = BB_HEAD (BB); \
22910d565efSmrg (INSN) && (INSN) != NEXT_INSN (BB_END (BB)); \
23010d565efSmrg (INSN) = NEXT_INSN (INSN))
23110d565efSmrg
23210d565efSmrg /* For iterating over insns in basic block when we might remove the
23310d565efSmrg current insn. */
23410d565efSmrg #define FOR_BB_INSNS_SAFE(BB, INSN, CURR) \
23510d565efSmrg for ((INSN) = BB_HEAD (BB), (CURR) = (INSN) ? NEXT_INSN ((INSN)): NULL; \
23610d565efSmrg (INSN) && (INSN) != NEXT_INSN (BB_END (BB)); \
23710d565efSmrg (INSN) = (CURR), (CURR) = (INSN) ? NEXT_INSN ((INSN)) : NULL)
23810d565efSmrg
23910d565efSmrg #define FOR_BB_INSNS_REVERSE(BB, INSN) \
24010d565efSmrg for ((INSN) = BB_END (BB); \
24110d565efSmrg (INSN) && (INSN) != PREV_INSN (BB_HEAD (BB)); \
24210d565efSmrg (INSN) = PREV_INSN (INSN))
24310d565efSmrg
24410d565efSmrg #define FOR_BB_INSNS_REVERSE_SAFE(BB, INSN, CURR) \
24510d565efSmrg for ((INSN) = BB_END (BB),(CURR) = (INSN) ? PREV_INSN ((INSN)) : NULL; \
24610d565efSmrg (INSN) && (INSN) != PREV_INSN (BB_HEAD (BB)); \
24710d565efSmrg (INSN) = (CURR), (CURR) = (INSN) ? PREV_INSN ((INSN)) : NULL)
24810d565efSmrg
24910d565efSmrg /* Cycles through _all_ basic blocks, even the fake ones (entry and
25010d565efSmrg exit block). */
25110d565efSmrg
25210d565efSmrg #define FOR_ALL_BB_FN(BB, FN) \
25310d565efSmrg for (BB = ENTRY_BLOCK_PTR_FOR_FN (FN); BB; BB = BB->next_bb)
25410d565efSmrg
25510d565efSmrg
25610d565efSmrg /* Stuff for recording basic block info. */
25710d565efSmrg
25810d565efSmrg /* For now, these will be functions (so that they can include checked casts
25910d565efSmrg to rtx_insn. Once the underlying fields are converted from rtx
26010d565efSmrg to rtx_insn, these can be converted back to macros. */
26110d565efSmrg
26210d565efSmrg #define BB_HEAD(B) (B)->il.x.head_
26310d565efSmrg #define BB_END(B) (B)->il.x.rtl->end_
26410d565efSmrg #define BB_HEADER(B) (B)->il.x.rtl->header_
26510d565efSmrg #define BB_FOOTER(B) (B)->il.x.rtl->footer_
26610d565efSmrg
26710d565efSmrg /* Special block numbers [markers] for entry and exit.
26810d565efSmrg Neither of them is supposed to hold actual statements. */
26910d565efSmrg #define ENTRY_BLOCK (0)
27010d565efSmrg #define EXIT_BLOCK (1)
27110d565efSmrg
27210d565efSmrg /* The two blocks that are always in the cfg. */
27310d565efSmrg #define NUM_FIXED_BLOCKS (2)
27410d565efSmrg
27510d565efSmrg /* This is the value which indicates no edge is present. */
27610d565efSmrg #define EDGE_INDEX_NO_EDGE -1
27710d565efSmrg
27810d565efSmrg /* EDGE_INDEX returns an integer index for an edge, or EDGE_INDEX_NO_EDGE
27910d565efSmrg if there is no edge between the 2 basic blocks. */
28010d565efSmrg #define EDGE_INDEX(el, pred, succ) (find_edge_index ((el), (pred), (succ)))
28110d565efSmrg
28210d565efSmrg /* INDEX_EDGE_PRED_BB and INDEX_EDGE_SUCC_BB return a pointer to the basic
28310d565efSmrg block which is either the pred or succ end of the indexed edge. */
28410d565efSmrg #define INDEX_EDGE_PRED_BB(el, index) ((el)->index_to_edge[(index)]->src)
28510d565efSmrg #define INDEX_EDGE_SUCC_BB(el, index) ((el)->index_to_edge[(index)]->dest)
28610d565efSmrg
28710d565efSmrg /* INDEX_EDGE returns a pointer to the edge. */
28810d565efSmrg #define INDEX_EDGE(el, index) ((el)->index_to_edge[(index)])
28910d565efSmrg
29010d565efSmrg /* Number of edges in the compressed edge list. */
29110d565efSmrg #define NUM_EDGES(el) ((el)->num_edges)
29210d565efSmrg
29310d565efSmrg /* BB is assumed to contain conditional jump. Return the fallthru edge. */
29410d565efSmrg #define FALLTHRU_EDGE(bb) (EDGE_SUCC ((bb), 0)->flags & EDGE_FALLTHRU \
29510d565efSmrg ? EDGE_SUCC ((bb), 0) : EDGE_SUCC ((bb), 1))
29610d565efSmrg
29710d565efSmrg /* BB is assumed to contain conditional jump. Return the branch edge. */
29810d565efSmrg #define BRANCH_EDGE(bb) (EDGE_SUCC ((bb), 0)->flags & EDGE_FALLTHRU \
29910d565efSmrg ? EDGE_SUCC ((bb), 1) : EDGE_SUCC ((bb), 0))
30010d565efSmrg
30110d565efSmrg /* Return expected execution frequency of the edge E. */
302c7a68eb7Smrg #define EDGE_FREQUENCY(e) e->count ().to_frequency (cfun)
30310d565efSmrg
30410d565efSmrg /* Compute a scale factor (or probability) suitable for scaling of
30510d565efSmrg gcov_type values via apply_probability() and apply_scale(). */
30610d565efSmrg #define GCOV_COMPUTE_SCALE(num,den) \
30710d565efSmrg ((den) ? RDIV ((num) * REG_BR_PROB_BASE, (den)) : REG_BR_PROB_BASE)
30810d565efSmrg
30910d565efSmrg /* Return nonzero if edge is critical. */
31010d565efSmrg #define EDGE_CRITICAL_P(e) (EDGE_COUNT ((e)->src->succs) >= 2 \
31110d565efSmrg && EDGE_COUNT ((e)->dest->preds) >= 2)
31210d565efSmrg
31310d565efSmrg #define EDGE_COUNT(ev) vec_safe_length (ev)
31410d565efSmrg #define EDGE_I(ev,i) (*ev)[(i)]
31510d565efSmrg #define EDGE_PRED(bb,i) (*(bb)->preds)[(i)]
31610d565efSmrg #define EDGE_SUCC(bb,i) (*(bb)->succs)[(i)]
31710d565efSmrg
31810d565efSmrg /* Returns true if BB has precisely one successor. */
31910d565efSmrg
32010d565efSmrg static inline bool
single_succ_p(const_basic_block bb)32110d565efSmrg single_succ_p (const_basic_block bb)
32210d565efSmrg {
32310d565efSmrg return EDGE_COUNT (bb->succs) == 1;
32410d565efSmrg }
32510d565efSmrg
32610d565efSmrg /* Returns true if BB has precisely one predecessor. */
32710d565efSmrg
32810d565efSmrg static inline bool
single_pred_p(const_basic_block bb)32910d565efSmrg single_pred_p (const_basic_block bb)
33010d565efSmrg {
33110d565efSmrg return EDGE_COUNT (bb->preds) == 1;
33210d565efSmrg }
33310d565efSmrg
33410d565efSmrg /* Returns the single successor edge of basic block BB. Aborts if
33510d565efSmrg BB does not have exactly one successor. */
33610d565efSmrg
33710d565efSmrg static inline edge
single_succ_edge(const_basic_block bb)33810d565efSmrg single_succ_edge (const_basic_block bb)
33910d565efSmrg {
34010d565efSmrg gcc_checking_assert (single_succ_p (bb));
34110d565efSmrg return EDGE_SUCC (bb, 0);
34210d565efSmrg }
34310d565efSmrg
34410d565efSmrg /* Returns the single predecessor edge of basic block BB. Aborts
34510d565efSmrg if BB does not have exactly one predecessor. */
34610d565efSmrg
34710d565efSmrg static inline edge
single_pred_edge(const_basic_block bb)34810d565efSmrg single_pred_edge (const_basic_block bb)
34910d565efSmrg {
35010d565efSmrg gcc_checking_assert (single_pred_p (bb));
35110d565efSmrg return EDGE_PRED (bb, 0);
35210d565efSmrg }
35310d565efSmrg
35410d565efSmrg /* Returns the single successor block of basic block BB. Aborts
35510d565efSmrg if BB does not have exactly one successor. */
35610d565efSmrg
35710d565efSmrg static inline basic_block
single_succ(const_basic_block bb)35810d565efSmrg single_succ (const_basic_block bb)
35910d565efSmrg {
36010d565efSmrg return single_succ_edge (bb)->dest;
36110d565efSmrg }
36210d565efSmrg
36310d565efSmrg /* Returns the single predecessor block of basic block BB. Aborts
36410d565efSmrg if BB does not have exactly one predecessor.*/
36510d565efSmrg
36610d565efSmrg static inline basic_block
single_pred(const_basic_block bb)36710d565efSmrg single_pred (const_basic_block bb)
36810d565efSmrg {
36910d565efSmrg return single_pred_edge (bb)->src;
37010d565efSmrg }
37110d565efSmrg
37210d565efSmrg /* Iterator object for edges. */
37310d565efSmrg
37410d565efSmrg struct edge_iterator {
37510d565efSmrg unsigned index;
37610d565efSmrg vec<edge, va_gc> **container;
37710d565efSmrg };
37810d565efSmrg
37910d565efSmrg static inline vec<edge, va_gc> *
ei_container(edge_iterator i)38010d565efSmrg ei_container (edge_iterator i)
38110d565efSmrg {
38210d565efSmrg gcc_checking_assert (i.container);
38310d565efSmrg return *i.container;
38410d565efSmrg }
38510d565efSmrg
38610d565efSmrg #define ei_start(iter) ei_start_1 (&(iter))
38710d565efSmrg #define ei_last(iter) ei_last_1 (&(iter))
38810d565efSmrg
38910d565efSmrg /* Return an iterator pointing to the start of an edge vector. */
39010d565efSmrg static inline edge_iterator
ei_start_1(vec<edge,va_gc> ** ev)39110d565efSmrg ei_start_1 (vec<edge, va_gc> **ev)
39210d565efSmrg {
39310d565efSmrg edge_iterator i;
39410d565efSmrg
39510d565efSmrg i.index = 0;
39610d565efSmrg i.container = ev;
39710d565efSmrg
39810d565efSmrg return i;
39910d565efSmrg }
40010d565efSmrg
40110d565efSmrg /* Return an iterator pointing to the last element of an edge
40210d565efSmrg vector. */
40310d565efSmrg static inline edge_iterator
ei_last_1(vec<edge,va_gc> ** ev)40410d565efSmrg ei_last_1 (vec<edge, va_gc> **ev)
40510d565efSmrg {
40610d565efSmrg edge_iterator i;
40710d565efSmrg
40810d565efSmrg i.index = EDGE_COUNT (*ev) - 1;
40910d565efSmrg i.container = ev;
41010d565efSmrg
41110d565efSmrg return i;
41210d565efSmrg }
41310d565efSmrg
41410d565efSmrg /* Is the iterator `i' at the end of the sequence? */
41510d565efSmrg static inline bool
ei_end_p(edge_iterator i)41610d565efSmrg ei_end_p (edge_iterator i)
41710d565efSmrg {
41810d565efSmrg return (i.index == EDGE_COUNT (ei_container (i)));
41910d565efSmrg }
42010d565efSmrg
42110d565efSmrg /* Is the iterator `i' at one position before the end of the
42210d565efSmrg sequence? */
42310d565efSmrg static inline bool
ei_one_before_end_p(edge_iterator i)42410d565efSmrg ei_one_before_end_p (edge_iterator i)
42510d565efSmrg {
42610d565efSmrg return (i.index + 1 == EDGE_COUNT (ei_container (i)));
42710d565efSmrg }
42810d565efSmrg
42910d565efSmrg /* Advance the iterator to the next element. */
43010d565efSmrg static inline void
ei_next(edge_iterator * i)43110d565efSmrg ei_next (edge_iterator *i)
43210d565efSmrg {
43310d565efSmrg gcc_checking_assert (i->index < EDGE_COUNT (ei_container (*i)));
43410d565efSmrg i->index++;
43510d565efSmrg }
43610d565efSmrg
43710d565efSmrg /* Move the iterator to the previous element. */
43810d565efSmrg static inline void
ei_prev(edge_iterator * i)43910d565efSmrg ei_prev (edge_iterator *i)
44010d565efSmrg {
44110d565efSmrg gcc_checking_assert (i->index > 0);
44210d565efSmrg i->index--;
44310d565efSmrg }
44410d565efSmrg
44510d565efSmrg /* Return the edge pointed to by the iterator `i'. */
44610d565efSmrg static inline edge
ei_edge(edge_iterator i)44710d565efSmrg ei_edge (edge_iterator i)
44810d565efSmrg {
44910d565efSmrg return EDGE_I (ei_container (i), i.index);
45010d565efSmrg }
45110d565efSmrg
45210d565efSmrg /* Return an edge pointed to by the iterator. Do it safely so that
45310d565efSmrg NULL is returned when the iterator is pointing at the end of the
45410d565efSmrg sequence. */
45510d565efSmrg static inline edge
ei_safe_edge(edge_iterator i)45610d565efSmrg ei_safe_edge (edge_iterator i)
45710d565efSmrg {
45810d565efSmrg return !ei_end_p (i) ? ei_edge (i) : NULL;
45910d565efSmrg }
46010d565efSmrg
46110d565efSmrg /* Return 1 if we should continue to iterate. Return 0 otherwise.
46210d565efSmrg *Edge P is set to the next edge if we are to continue to iterate
46310d565efSmrg and NULL otherwise. */
46410d565efSmrg
46510d565efSmrg static inline bool
ei_cond(edge_iterator ei,edge * p)46610d565efSmrg ei_cond (edge_iterator ei, edge *p)
46710d565efSmrg {
46810d565efSmrg if (!ei_end_p (ei))
46910d565efSmrg {
47010d565efSmrg *p = ei_edge (ei);
47110d565efSmrg return 1;
47210d565efSmrg }
47310d565efSmrg else
47410d565efSmrg {
47510d565efSmrg *p = NULL;
47610d565efSmrg return 0;
47710d565efSmrg }
47810d565efSmrg }
47910d565efSmrg
48010d565efSmrg /* This macro serves as a convenient way to iterate each edge in a
48110d565efSmrg vector of predecessor or successor edges. It must not be used when
48210d565efSmrg an element might be removed during the traversal, otherwise
48310d565efSmrg elements will be missed. Instead, use a for-loop like that shown
48410d565efSmrg in the following pseudo-code:
48510d565efSmrg
48610d565efSmrg FOR (ei = ei_start (bb->succs); (e = ei_safe_edge (ei)); )
48710d565efSmrg {
48810d565efSmrg IF (e != taken_edge)
48910d565efSmrg remove_edge (e);
49010d565efSmrg ELSE
49110d565efSmrg ei_next (&ei);
49210d565efSmrg }
49310d565efSmrg */
49410d565efSmrg
49510d565efSmrg #define FOR_EACH_EDGE(EDGE,ITER,EDGE_VEC) \
49610d565efSmrg for ((ITER) = ei_start ((EDGE_VEC)); \
49710d565efSmrg ei_cond ((ITER), &(EDGE)); \
49810d565efSmrg ei_next (&(ITER)))
49910d565efSmrg
50010d565efSmrg #define CLEANUP_EXPENSIVE 1 /* Do relatively expensive optimizations
50110d565efSmrg except for edge forwarding */
50210d565efSmrg #define CLEANUP_CROSSJUMP 2 /* Do crossjumping. */
50310d565efSmrg #define CLEANUP_POST_REGSTACK 4 /* We run after reg-stack and need
50410d565efSmrg to care REG_DEAD notes. */
50510d565efSmrg #define CLEANUP_THREADING 8 /* Do jump threading. */
50610d565efSmrg #define CLEANUP_NO_INSN_DEL 16 /* Do not try to delete trivially dead
50710d565efSmrg insns. */
50810d565efSmrg #define CLEANUP_CFGLAYOUT 32 /* Do cleanup in cfglayout mode. */
50910d565efSmrg #define CLEANUP_CFG_CHANGED 64 /* The caller changed the CFG. */
510c7a68eb7Smrg #define CLEANUP_NO_PARTITIONING 128 /* Do not try to fix partitions. */
511*ec02198aSmrg #define CLEANUP_FORCE_FAST_DCE 0x100 /* Force run_fast_dce to be called
512*ec02198aSmrg at least once. */
51310d565efSmrg
51410d565efSmrg /* Return true if BB is in a transaction. */
51510d565efSmrg
51610d565efSmrg static inline bool
bb_in_transaction(basic_block bb)51710d565efSmrg bb_in_transaction (basic_block bb)
51810d565efSmrg {
51910d565efSmrg return bb->flags & BB_IN_TRANSACTION;
52010d565efSmrg }
52110d565efSmrg
52210d565efSmrg /* Return true when one of the predecessor edges of BB is marked with EDGE_EH. */
52310d565efSmrg static inline bool
bb_has_eh_pred(basic_block bb)52410d565efSmrg bb_has_eh_pred (basic_block bb)
52510d565efSmrg {
52610d565efSmrg edge e;
52710d565efSmrg edge_iterator ei;
52810d565efSmrg
52910d565efSmrg FOR_EACH_EDGE (e, ei, bb->preds)
53010d565efSmrg {
53110d565efSmrg if (e->flags & EDGE_EH)
53210d565efSmrg return true;
53310d565efSmrg }
53410d565efSmrg return false;
53510d565efSmrg }
53610d565efSmrg
53710d565efSmrg /* Return true when one of the predecessor edges of BB is marked with EDGE_ABNORMAL. */
53810d565efSmrg static inline bool
bb_has_abnormal_pred(basic_block bb)53910d565efSmrg bb_has_abnormal_pred (basic_block bb)
54010d565efSmrg {
54110d565efSmrg edge e;
54210d565efSmrg edge_iterator ei;
54310d565efSmrg
54410d565efSmrg FOR_EACH_EDGE (e, ei, bb->preds)
54510d565efSmrg {
54610d565efSmrg if (e->flags & EDGE_ABNORMAL)
54710d565efSmrg return true;
54810d565efSmrg }
54910d565efSmrg return false;
55010d565efSmrg }
55110d565efSmrg
55210d565efSmrg /* Return the fallthru edge in EDGES if it exists, NULL otherwise. */
55310d565efSmrg static inline edge
find_fallthru_edge(vec<edge,va_gc> * edges)55410d565efSmrg find_fallthru_edge (vec<edge, va_gc> *edges)
55510d565efSmrg {
55610d565efSmrg edge e;
55710d565efSmrg edge_iterator ei;
55810d565efSmrg
55910d565efSmrg FOR_EACH_EDGE (e, ei, edges)
56010d565efSmrg if (e->flags & EDGE_FALLTHRU)
56110d565efSmrg break;
56210d565efSmrg
56310d565efSmrg return e;
56410d565efSmrg }
56510d565efSmrg
56610d565efSmrg /* Check tha probability is sane. */
56710d565efSmrg
56810d565efSmrg static inline void
check_probability(int prob)56910d565efSmrg check_probability (int prob)
57010d565efSmrg {
57110d565efSmrg gcc_checking_assert (prob >= 0 && prob <= REG_BR_PROB_BASE);
57210d565efSmrg }
57310d565efSmrg
57410d565efSmrg /* Given PROB1 and PROB2, return PROB1*PROB2/REG_BR_PROB_BASE.
57510d565efSmrg Used to combine BB probabilities. */
57610d565efSmrg
57710d565efSmrg static inline int
combine_probabilities(int prob1,int prob2)57810d565efSmrg combine_probabilities (int prob1, int prob2)
57910d565efSmrg {
58010d565efSmrg check_probability (prob1);
58110d565efSmrg check_probability (prob2);
58210d565efSmrg return RDIV (prob1 * prob2, REG_BR_PROB_BASE);
58310d565efSmrg }
58410d565efSmrg
58510d565efSmrg /* Apply scale factor SCALE on frequency or count FREQ. Use this
58610d565efSmrg interface when potentially scaling up, so that SCALE is not
58710d565efSmrg constrained to be < REG_BR_PROB_BASE. */
58810d565efSmrg
58910d565efSmrg static inline gcov_type
apply_scale(gcov_type freq,gcov_type scale)59010d565efSmrg apply_scale (gcov_type freq, gcov_type scale)
59110d565efSmrg {
59210d565efSmrg return RDIV (freq * scale, REG_BR_PROB_BASE);
59310d565efSmrg }
59410d565efSmrg
59510d565efSmrg /* Apply probability PROB on frequency or count FREQ. */
59610d565efSmrg
59710d565efSmrg static inline gcov_type
apply_probability(gcov_type freq,int prob)59810d565efSmrg apply_probability (gcov_type freq, int prob)
59910d565efSmrg {
60010d565efSmrg check_probability (prob);
60110d565efSmrg return apply_scale (freq, prob);
60210d565efSmrg }
60310d565efSmrg
60410d565efSmrg /* Return inverse probability for PROB. */
60510d565efSmrg
60610d565efSmrg static inline int
inverse_probability(int prob1)60710d565efSmrg inverse_probability (int prob1)
60810d565efSmrg {
60910d565efSmrg check_probability (prob1);
61010d565efSmrg return REG_BR_PROB_BASE - prob1;
61110d565efSmrg }
61210d565efSmrg
61310d565efSmrg /* Return true if BB has at least one abnormal outgoing edge. */
61410d565efSmrg
61510d565efSmrg static inline bool
has_abnormal_or_eh_outgoing_edge_p(basic_block bb)61610d565efSmrg has_abnormal_or_eh_outgoing_edge_p (basic_block bb)
61710d565efSmrg {
61810d565efSmrg edge e;
61910d565efSmrg edge_iterator ei;
62010d565efSmrg
62110d565efSmrg FOR_EACH_EDGE (e, ei, bb->succs)
62210d565efSmrg if (e->flags & (EDGE_ABNORMAL | EDGE_EH))
62310d565efSmrg return true;
62410d565efSmrg
62510d565efSmrg return false;
62610d565efSmrg }
62710d565efSmrg
62810d565efSmrg /* Return true when one of the predecessor edges of BB is marked with
62910d565efSmrg EDGE_ABNORMAL_CALL or EDGE_EH. */
63010d565efSmrg
63110d565efSmrg static inline bool
has_abnormal_call_or_eh_pred_edge_p(basic_block bb)63210d565efSmrg has_abnormal_call_or_eh_pred_edge_p (basic_block bb)
63310d565efSmrg {
63410d565efSmrg edge e;
63510d565efSmrg edge_iterator ei;
63610d565efSmrg
63710d565efSmrg FOR_EACH_EDGE (e, ei, bb->preds)
63810d565efSmrg if (e->flags & (EDGE_ABNORMAL_CALL | EDGE_EH))
63910d565efSmrg return true;
64010d565efSmrg
64110d565efSmrg return false;
64210d565efSmrg }
64310d565efSmrg
644c7a68eb7Smrg /* Return count of edge E. */
count()645c7a68eb7Smrg inline profile_count edge_def::count () const
646c7a68eb7Smrg {
647c7a68eb7Smrg return src->count.apply_probability (probability);
648c7a68eb7Smrg }
649c7a68eb7Smrg
65010d565efSmrg #endif /* GCC_BASIC_BLOCK_H */
651