xref: /openbsd/gnu/gcc/gcc/cfghooks.h (revision 404b540a)
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