1*404b540aSrobert /* Hooks for cfg representation specific functions. 2*404b540aSrobert Copyright (C) 2003, 2004, 2005 Free Software Foundation, Inc. 3*404b540aSrobert Contributed by Sebastian Pop <s.pop@laposte.net> 4*404b540aSrobert 5*404b540aSrobert This file is part of GCC. 6*404b540aSrobert 7*404b540aSrobert GCC is free software; you can redistribute it and/or modify 8*404b540aSrobert it under the terms of the GNU General Public License as published by 9*404b540aSrobert the Free Software Foundation; either version 2, or (at your option) 10*404b540aSrobert any later version. 11*404b540aSrobert 12*404b540aSrobert GCC is distributed in the hope that it will be useful, 13*404b540aSrobert but WITHOUT ANY WARRANTY; without even the implied warranty of 14*404b540aSrobert MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15*404b540aSrobert GNU General Public License for more details. 16*404b540aSrobert 17*404b540aSrobert You should have received a copy of the GNU General Public License 18*404b540aSrobert along with GCC; see the file COPYING. If not, write to 19*404b540aSrobert the Free Software Foundation, 51 Franklin Street, Fifth Floor, 20*404b540aSrobert Boston, MA 02110-1301, USA. */ 21*404b540aSrobert 22*404b540aSrobert #ifndef GCC_CFGHOOKS_H 23*404b540aSrobert #define GCC_CFGHOOKS_H 24*404b540aSrobert 25*404b540aSrobert struct cfg_hooks 26*404b540aSrobert { 27*404b540aSrobert /* Name of the corresponding ir. */ 28*404b540aSrobert const char *name; 29*404b540aSrobert 30*404b540aSrobert /* Debugging. */ 31*404b540aSrobert int (*verify_flow_info) (void); 32*404b540aSrobert void (*dump_bb) (basic_block, FILE *, int); 33*404b540aSrobert 34*404b540aSrobert /* Basic CFG manipulation. */ 35*404b540aSrobert 36*404b540aSrobert /* Return new basic block. */ 37*404b540aSrobert basic_block (*create_basic_block) (void *head, void *end, basic_block after); 38*404b540aSrobert 39*404b540aSrobert /* Redirect edge E to the given basic block B and update underlying program 40*404b540aSrobert representation. Returns edge representing redirected branch (that may not 41*404b540aSrobert be equivalent to E in the case of duplicate edges being removed) or NULL 42*404b540aSrobert if edge is not easily redirectable for whatever reason. */ 43*404b540aSrobert edge (*redirect_edge_and_branch) (edge e, basic_block b); 44*404b540aSrobert 45*404b540aSrobert /* Same as the above but allows redirecting of fallthru edges. In that case 46*404b540aSrobert newly created forwarder basic block is returned. The edge must 47*404b540aSrobert not be abnormal. */ 48*404b540aSrobert basic_block (*redirect_edge_and_branch_force) (edge, basic_block); 49*404b540aSrobert 50*404b540aSrobert /* Remove statements corresponding to a given basic block. */ 51*404b540aSrobert void (*delete_basic_block) (basic_block); 52*404b540aSrobert 53*404b540aSrobert /* Creates a new basic block just after basic block B by splitting 54*404b540aSrobert everything after specified instruction I. */ 55*404b540aSrobert basic_block (*split_block) (basic_block b, void * i); 56*404b540aSrobert 57*404b540aSrobert /* Move block B immediately after block A. */ 58*404b540aSrobert bool (*move_block_after) (basic_block b, basic_block a); 59*404b540aSrobert 60*404b540aSrobert /* Return true when blocks A and B can be merged into single basic block. */ 61*404b540aSrobert bool (*can_merge_blocks_p) (basic_block a, basic_block b); 62*404b540aSrobert 63*404b540aSrobert /* Merge blocks A and B. */ 64*404b540aSrobert void (*merge_blocks) (basic_block a, basic_block b); 65*404b540aSrobert 66*404b540aSrobert /* Predict edge E using PREDICTOR to given PROBABILITY. */ 67*404b540aSrobert void (*predict_edge) (edge e, enum br_predictor predictor, int probability); 68*404b540aSrobert 69*404b540aSrobert /* Return true if the one of outgoing edges is already predicted by 70*404b540aSrobert PREDICTOR. */ 71*404b540aSrobert bool (*predicted_by_p) (basic_block bb, enum br_predictor predictor); 72*404b540aSrobert 73*404b540aSrobert /* Return true when block A can be duplicated. */ 74*404b540aSrobert bool (*can_duplicate_block_p) (basic_block a); 75*404b540aSrobert 76*404b540aSrobert /* Duplicate block A. */ 77*404b540aSrobert basic_block (*duplicate_block) (basic_block a); 78*404b540aSrobert 79*404b540aSrobert /* Higher level functions representable by primitive operations above if 80*404b540aSrobert we didn't have some oddities in RTL and Tree representations. */ 81*404b540aSrobert basic_block (*split_edge) (edge); 82*404b540aSrobert void (*make_forwarder_block) (edge); 83*404b540aSrobert 84*404b540aSrobert /* Tries to make the edge fallthru. */ 85*404b540aSrobert void (*tidy_fallthru_edge) (edge); 86*404b540aSrobert 87*404b540aSrobert /* Say whether a block ends with a call, possibly followed by some 88*404b540aSrobert other code that must stay with the call. */ 89*404b540aSrobert bool (*block_ends_with_call_p) (basic_block); 90*404b540aSrobert 91*404b540aSrobert /* Say whether a block ends with a conditional branch. Switches 92*404b540aSrobert and unconditional branches do not qualify. */ 93*404b540aSrobert bool (*block_ends_with_condjump_p) (basic_block); 94*404b540aSrobert 95*404b540aSrobert /* Add fake edges to the function exit for any non constant and non noreturn 96*404b540aSrobert calls, volatile inline assembly in the bitmap of blocks specified by 97*404b540aSrobert BLOCKS or to the whole CFG if BLOCKS is zero. Return the number of blocks 98*404b540aSrobert that were split. 99*404b540aSrobert 100*404b540aSrobert The goal is to expose cases in which entering a basic block does not imply 101*404b540aSrobert that all subsequent instructions must be executed. */ 102*404b540aSrobert int (*flow_call_edges_add) (sbitmap); 103*404b540aSrobert 104*404b540aSrobert /* This function is called immediately after edge E is added to the 105*404b540aSrobert edge vector E->dest->preds. */ 106*404b540aSrobert void (*execute_on_growing_pred) (edge); 107*404b540aSrobert 108*404b540aSrobert /* This function is called immediately before edge E is removed from 109*404b540aSrobert the edge vector E->dest->preds. */ 110*404b540aSrobert void (*execute_on_shrinking_pred) (edge); 111*404b540aSrobert 112*404b540aSrobert /* A hook for duplicating loop in CFG, currently this is used 113*404b540aSrobert in loop versioning. */ 114*404b540aSrobert bool (*cfg_hook_duplicate_loop_to_header_edge) (struct loop *loop, edge e, 115*404b540aSrobert struct loops *loops, 116*404b540aSrobert unsigned int ndupl, 117*404b540aSrobert sbitmap wont_exit, 118*404b540aSrobert edge orig, edge *to_remove, 119*404b540aSrobert unsigned int *n_to_remove, 120*404b540aSrobert int flags); 121*404b540aSrobert 122*404b540aSrobert /* Add condition to new basic block and update CFG used in loop 123*404b540aSrobert versioning. */ 124*404b540aSrobert void (*lv_add_condition_to_bb) (basic_block, basic_block, basic_block, 125*404b540aSrobert void *); 126*404b540aSrobert /* Update the PHI nodes in case of loop versioning. */ 127*404b540aSrobert void (*lv_adjust_loop_header_phi) (basic_block, basic_block, 128*404b540aSrobert basic_block, edge); 129*404b540aSrobert 130*404b540aSrobert /* Given a condition BB extract the true/false taken/not taken edges 131*404b540aSrobert (depending if we are on tree's or RTL). */ 132*404b540aSrobert void (*extract_cond_bb_edges) (basic_block, edge *, edge *); 133*404b540aSrobert 134*404b540aSrobert 135*404b540aSrobert /* Add PHI arguments queued in PENDINT_STMT list on edge E to edge 136*404b540aSrobert E->dest (only in tree-ssa loop versioning. */ 137*404b540aSrobert void (*flush_pending_stmts) (edge); 138*404b540aSrobert }; 139*404b540aSrobert 140*404b540aSrobert extern void verify_flow_info (void); 141*404b540aSrobert extern void dump_bb (basic_block, FILE *, int); 142*404b540aSrobert extern edge redirect_edge_and_branch (edge, basic_block); 143*404b540aSrobert extern basic_block redirect_edge_and_branch_force (edge, basic_block); 144*404b540aSrobert extern edge split_block (basic_block, void *); 145*404b540aSrobert extern edge split_block_after_labels (basic_block); 146*404b540aSrobert extern bool move_block_after (basic_block, basic_block); 147*404b540aSrobert extern void delete_basic_block (basic_block); 148*404b540aSrobert extern basic_block split_edge (edge); 149*404b540aSrobert extern basic_block create_basic_block (void *, void *, basic_block); 150*404b540aSrobert extern basic_block create_empty_bb (basic_block); 151*404b540aSrobert extern bool can_merge_blocks_p (basic_block, basic_block); 152*404b540aSrobert extern void merge_blocks (basic_block, basic_block); 153*404b540aSrobert extern edge make_forwarder_block (basic_block, bool (*)(edge), 154*404b540aSrobert void (*) (basic_block)); 155*404b540aSrobert extern void tidy_fallthru_edge (edge); 156*404b540aSrobert extern void tidy_fallthru_edges (void); 157*404b540aSrobert extern void predict_edge (edge e, enum br_predictor predictor, int probability); 158*404b540aSrobert extern bool predicted_by_p (basic_block bb, enum br_predictor predictor); 159*404b540aSrobert extern bool can_duplicate_block_p (basic_block); 160*404b540aSrobert extern basic_block duplicate_block (basic_block, edge, basic_block); 161*404b540aSrobert extern bool block_ends_with_call_p (basic_block bb); 162*404b540aSrobert extern bool block_ends_with_condjump_p (basic_block bb); 163*404b540aSrobert extern int flow_call_edges_add (sbitmap); 164*404b540aSrobert extern void execute_on_growing_pred (edge); 165*404b540aSrobert extern void execute_on_shrinking_pred (edge); 166*404b540aSrobert extern bool cfg_hook_duplicate_loop_to_header_edge (struct loop *loop, edge, 167*404b540aSrobert struct loops *loops, 168*404b540aSrobert unsigned int ndupl, 169*404b540aSrobert sbitmap wont_exit, 170*404b540aSrobert edge orig, edge *to_remove, 171*404b540aSrobert unsigned int *n_to_remove, 172*404b540aSrobert int flags); 173*404b540aSrobert 174*404b540aSrobert extern void lv_flush_pending_stmts (edge); 175*404b540aSrobert extern void extract_cond_bb_edges (basic_block, edge *, edge*); 176*404b540aSrobert extern void lv_adjust_loop_header_phi (basic_block, basic_block, basic_block, 177*404b540aSrobert edge); 178*404b540aSrobert extern void lv_add_condition_to_bb (basic_block, basic_block, basic_block, 179*404b540aSrobert void *); 180*404b540aSrobert 181*404b540aSrobert /* Hooks containers. */ 182*404b540aSrobert extern struct cfg_hooks tree_cfg_hooks; 183*404b540aSrobert extern struct cfg_hooks rtl_cfg_hooks; 184*404b540aSrobert extern struct cfg_hooks cfg_layout_rtl_cfg_hooks; 185*404b540aSrobert 186*404b540aSrobert /* Declarations. */ 187*404b540aSrobert extern int ir_type (void); 188*404b540aSrobert extern void rtl_register_cfg_hooks (void); 189*404b540aSrobert extern void cfg_layout_rtl_register_cfg_hooks (void); 190*404b540aSrobert extern void tree_register_cfg_hooks (void); 191*404b540aSrobert 192*404b540aSrobert #endif /* GCC_CFGHOOKS_H */ 193