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