A walker that visites all firm constructs.
[libfirm] / ir / common / firmwalk.h
1 /**
2  *  @file firmwalk.h
3  *
4  *  Firm walker over intermediate representation.
5  *
6  *  To initialize the walker, call firm_walk_init(). This function
7  *  collects all specific data from the firm represenation. After
8  *  building the walker information firm_walk() could be called
9  *  serveral times with different flags (options) from specific walker
10  *  or dumper. At least firm_walk_finalizer() should be called to free
11  *  the stored data.
12  *
13  *  This walker could be used for a dumper e.g. a vcg or xml dumper.
14  *
15  *  @note If a specific walker or dumper which uses the link field
16  *        of any firm node, the the wrapper functions set_firm_walk_link()
17  *        and get_firm_walk_link() should be used, because the firm walker
18  *        make use of the link field to store its own data.
19  */
20 #ifndef _FIRM_WALK_H_
21 #define _FIRM_WALK_H_
22
23 #include "type.h"
24 #include "irgraph.h"
25 #include "typewalk.h"
26
27 /** Returns the link of a firm node.
28  *  Possible firm structures are: entity, type, ir_graph, ir_node and
29  *  ir_mode. Otherwise this function has no effect
30  *
31  *  Derived walker or dumper have to call this function to store data
32  *  to a firm structure. The real link field of firm structure is used
33  *  by this firm walker to collect walking data.
34  *
35  *  @param thing Pointer to a firm structure
36  *  @retrun Link pointer
37  *
38  *  @note After calling firm_walk_finalize() the stored link
39  *        information may be invalid. */
40 void *get_firm_walk_link(void *thing);
41
42 /** Set the link field of a firm structure.
43  *  Possible firm structures are: entity, type, ir_graph, ir_node and
44  *  ir_mode. Otherwise this function has no effect
45  *
46  *  Derived walker or dumper have to call this function to store data
47  *  to a firm structure. The real link field of firm structure is used
48  *  by this firm walker to collect walking data.
49  *
50  *  @param thing firm structur
51  *  @param link Pointer to link field
52  *
53  *  @note After calling firm_walk_finalize() the stored link
54  *        information may be invalid. */
55 void set_firm_walk_link(void *thing, void *link);
56
57 /** Initialisation function for firm walker callbacks */
58 typedef void firm_walk_init_func(void *env);
59 /** Finalisation function for firm walker callbacks */
60 typedef void firm_walk_finalize_func(void *env);
61
62 /** Mode callback function definition */
63 typedef void firm_walk_mode_func(ir_mode *mode, void *env);
64 /** Type callback function definition */
65 typedef void firm_walk_type_func(type *tp, void *env);
66 /** Entity callback function definition */
67 typedef void firm_walk_entity_func(entity *ent, void *env);
68 /** Graph callback function definition */
69 typedef void firm_walk_graph_func(ir_graph *irg, void *env);
70 //@{
71 /** Block callback function definition */
72 typedef void firm_walk_block_init_func(ir_graph *irg, void *env);
73 typedef void firm_walk_block_func(ir_node *block, void *env);
74 typedef void firm_walk_block_finalize_func(ir_graph *irg, void *env);
75 //@}
76 /** Node callback function definition */
77 typedef void firm_walk_node_func (ir_node *irn, void *env);
78
79 /** @enum firm_walk_flags
80  *
81  *  Flags for the firm walker to modify some dumping behavior
82  */
83 typedef enum
84 {
85   FGD_WITH_ALL_TYPES     = 1<<0, /**< Collect and dump all types, especially
86                                       unused types.
87                                       @note This flag could be set in
88                                       firm_dumper_init() and is unused in
89                                       firm_dump() */
90   FGD_WITH_DOMINATOR     = 1<<1, /**< nyi */
91   FGD_WITH_OUTEDGES      = 1<<2, /**< nyi */
92   FGD_WITH_LOOPS         = 1<<3, /**< nyi */
93   FGD_DUMP_BLOCK_AS_IRN  = 1<<4, /**< Dump all block nodes as irn nodes
94                                       additionally */
95   FGD_DUMP_IRN_IN_PREFIX = 1<<5, /**< Dumps all ir nodes in prefix order
96                                       according to the internal firm graph
97                                       structure */
98 } firm_walk_flags;
99
100 /** Interface of the firm walker */
101 typedef struct
102 {
103   //@{
104   /** Interface function to dump all used and internal modes.
105       Internal modes are: BB, X, M and T */
106   firm_walk_init_func *do_mode_init;
107   firm_walk_mode_func *do_mode;
108   firm_walk_finalize_func *do_mode_finalize;
109   //@}
110
111   //@{
112   /** Interface to dump all collected types.
113    *
114    *  @node To dump all (not only used types by default) a special walk
115    *        flag must be set for the walker initializer */
116   firm_walk_init_func *do_type_init;
117   firm_walk_type_func *do_type;
118   firm_walk_finalize_func *do_type_finalize;
119   //@}
120
121   //@{
122   /** Dumping interface for entities */
123   firm_walk_init_func *do_entity_init;
124   firm_walk_entity_func *do_entity;
125   firm_walk_finalize_func *do_entity_finalize;
126   //@}
127
128   /** Dumps all graphs and subnodes.
129    *
130    *  The firm walker dump a graph with its blocks and nodes nested.
131    *  Fist do_graph_init will be called (if defined). For each graph
132    *  do_graph will be call in a loop. After dumped all graphs,
133    *  do_graph_finalize will be called.
134    *
135    *  Within do_graph each block will be dumped. First do_block_init,
136    *  for each block do_block and after all dumped blocks
137    *  do_block_finalize.
138    *
139    *  The ir nodes are dumped nested in their blocks as well. Within
140    *  do_block, for each ir node do_node is called in postfix order
141    *  according to the internal firm representation. By changing the
142    *  walking flag, a prefix order is also possible. */
143   firm_walk_init_func *do_graph_init;
144   firm_walk_graph_func *do_graph;
145   firm_walk_finalize_func *do_graph_finalize;
146
147   //@{
148   /** Dumping interface for blocks. If blocks should be handled like
149    *  like a normal ir node, a special walker flag could be set.
150    *  @see do_graph */
151   firm_walk_block_init_func *do_block_init;
152   firm_walk_block_func *do_block;
153   firm_walk_block_finalize_func *do_block_finalize;
154   //@}
155
156   /** Dumping interface for ir nodes
157    *  @see do_graph */
158   firm_walk_node_func *do_node;
159   /* dominator */
160   /* procedures */
161   /* loop */
162   firm_walk_flags flags;
163   /* pointer to environment of interface */
164   void *env;
165 } firm_walk_interface;
166
167
168 /** Initialize the dumper und collect all data from the firm intermediate
169  *  representation
170  *
171  *  @param flags flags */
172 void firm_walk_init(firm_walk_flags flags);
173
174 /** Walker of the firm intermediate representation.
175  *
176  *  The callback functions of the interface will be called nested, e.g. for
177  *  each block: init function of block, do_block, nested function of nodes,
178  *  finalize function of block.
179  *
180  *  - modes
181  *  - types
182  *  - entities
183  *  - ir graphs
184  *    - procedures
185  *    - blocks
186  *    - nodes. Options: dominator, outedges
187  *
188  *  @param wif Stucture of walker interface. In this struct the used callback
189  *             functions are defined.
190  */
191 void firm_walk(firm_walk_interface *wif);
192
193 /** Finalize the walker and frees all stored data for dumping */
194 void firm_walk_finalize(void);
195
196 #endif /* _FIRM_WALK_H_ */