move util.h to private API, harmonize SIZ(array) vs. ARR_SIZE(array) vs. array_size...
[libfirm] / ir / opt / iropt_dbg.h
1 /*
2  * Copyright (C) 1995-2008 University of Karlsruhe.  All right reserved.
3  *
4  * This file is part of libFirm.
5  *
6  * This file may be distributed and/or modified under the terms of the
7  * GNU General Public License version 2 as published by the Free Software
8  * Foundation and appearing in the file LICENSE.GPL included in the
9  * packaging of this file.
10  *
11  * Licensees holding valid libFirm Professional Edition licenses may use
12  * this file in accordance with the libFirm Commercial License.
13  * Agreement provided with the Software.
14  *
15  * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
16  * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17  * PURPOSE.
18  */
19
20 /**
21  * @file
22  * @brief   Debug macros used in iropt.
23  * @author  Goetz Lindenmaier, Michael Beck
24  * @version $Id$
25  */
26 #ifndef FIRM_IR_IROPT_DBG_H
27 #define FIRM_IR_IROPT_DBG_H
28
29 #include "dbginfo_t.h"
30 #include "irhooks.h"
31 #include "firmstat.h"
32 #include "util.h"
33
34 /**
35  * Merge the debug info due to dead block elimination.
36  *
37  * @param oldn  the block that it is eliminated
38  * @param n     the new node for this block, may be equal to oldn
39  */
40 #define DBG_OPT_DEAD_BLOCK(oldn, n)                           \
41         do {                                                      \
42           hook_merge_nodes(&n, 1, &oldn, 1, HOOK_OPT_DEAD_BLOCK); \
43           __dbg_info_merge_pair(n, oldn, dbg_dead_code);          \
44         } while(0)
45
46
47 /**
48  * Merge the debug info due to a straightening optimization.
49  * Block oldn is merged with n.
50  *
51  * @param oldn  the old block
52  * @param n     the new block the merges with oldn
53  */
54 #define DBG_OPT_STG(oldn, n)                                                 \
55         do {                                                                     \
56           ir_node *ons[2];                                                       \
57           ons[0] = oldn;                                                         \
58           ons[1] = get_Block_cfgpred(oldn, 0);                                   \
59           hook_merge_nodes(&n, 1, ons, ARRAY_SIZE(ons), HOOK_OPT_STG);           \
60           __dbg_info_merge_sets(&n, 1, ons, ARRAY_SIZE(ons), dbg_straightening); \
61         } while(0)
62
63 /**
64  * Merge the debug info due to an if simplification.
65  *
66  * @param oldn   the old Block
67  * @param proj1  the first ProjX predecessor
68  * @param proj2  the second ProjX predecessor
69  * @param n      the new Block
70  */
71 #define DBG_OPT_IFSIM1(oldn, proj1, proj2, n)                        \
72         do {                                                             \
73           ir_node *ons[4];                                               \
74           ons[0] = oldn;                                                 \
75           ons[1] = proj1;                                                \
76           ons[2] = proj2;                                                \
77           ons[3] = get_Proj_pred(proj1);                                 \
78           hook_merge_nodes(&n, 1, ons, ARRAY_SIZE(ons), HOOK_OPT_IFSIM); \
79           __dbg_info_merge_sets(&n, 1, ons, ARRAY_SIZE(ons), dbg_if_simplification); \
80         } while(0)
81
82 /**
83  * Merge the debug info due to an if simplification.
84  * @param oldn   the old Cond
85  * @param n      the new Jmp
86  */
87 #define DBG_OPT_IFSIM2(oldn, n)                              \
88         do {                                                     \
89           hook_merge_nodes(&n, 1, &oldn, 1, HOOK_OPT_IFSIM);     \
90           __dbg_info_merge_pair(n, oldn, dbg_if_simplification); \
91         } while(0)
92
93 /**
94  * Merge the debug info due to an algebraic_simplification.
95  * A node could be evaluated into a Constant.
96  *
97  * @param oldn  the node
98  * @param n     the new constant holding the value
99  */
100 #define DBG_OPT_CSTEVAL(oldn, n)                                  \
101         do {                                                          \
102           hook_merge_nodes(&n, 1, &oldn, 1, HOOK_OPT_CONST_EVAL);     \
103           __dbg_info_merge_pair(n, oldn, dbg_const_eval);             \
104         } while(0)
105
106 /**
107  * Merge the debug info due to an algebraic_simplification.
108  *
109  * @param oldn  the old node
110  * @param n     the new node replacing oldn
111  * @param flag  firm statistics option
112  */
113 #define DBG_OPT_ALGSIM0(oldn, n, flag)                              \
114         do {                                                            \
115           hook_merge_nodes(&n, 1, &oldn, 1, flag);                      \
116           __dbg_info_merge_pair(n, oldn, dbg_algebraic_simplification); \
117         } while(0)
118
119 /**
120  * Merge the debug info due to an algebraic_simplification.
121  *
122  * @param oldn  the old node
123  * @param a     a predecessor of oldn
124  * @param b     a predecessor of oldn
125  * @param n     the new node replacing oldn
126  * @param flag  firm statistics option
127  */
128 #define DBG_OPT_ALGSIM1(oldn, a, b, n, flag)                      \
129         do {                                                          \
130           ir_node *ons[3];                                            \
131           ons[0] = oldn;                                              \
132           ons[1] = a;                                                 \
133           ons[2] = b;                                                 \
134           hook_merge_nodes(&n, 1, ons, ARRAY_SIZE(ons), flag);        \
135           __dbg_info_merge_sets(&n, 1, ons, ARRAY_SIZE(ons), dbg_algebraic_simplification); \
136         } while(0)
137
138 /**
139  * Merge the debug info due to an algebraic_simplification.
140  *
141  * @param oldn  the old node
142  * @param pred  the predecessor of oldn
143  * @param n     the new node replacing oldn
144  * @param flag  firm statistics option
145  */
146 #define DBG_OPT_ALGSIM2(oldn, pred, n, flag)                      \
147         do {                                                          \
148           ir_node *ons[3];                                            \
149           ons[0] = oldn;                                              \
150           ons[1] = pred;                                              \
151           ons[2] = n;                                                 \
152           hook_merge_nodes(&n, 1, ons, ARRAY_SIZE(ons), flag);        \
153           __dbg_info_merge_sets(&n, 1, ons, ARRAY_SIZE(ons), dbg_algebraic_simplification); \
154         } while(0)
155
156 /**
157  * Merge the debug info due to an algebraic_simplification.
158  */
159 #define DBG_OPT_ALGSIM3(oldn, a, n, flag)                         \
160         do {                                                          \
161           ir_node *ons[2];                                            \
162           ons[0] = oldn;                                              \
163           ons[1] = a;                                                 \
164           hook_merge_nodes(&n, 1, ons, ARRAY_SIZE(ons), flag);        \
165           __dbg_info_merge_sets(&n, 1, ons, ARRAY_SIZE(ons), dbg_algebraic_simplification); \
166         } while(0)
167
168 /**
169  * Merge the debug info due to a Phi optimization.
170  * A Phi node was replaced by one of its input (the only meaningful)
171  *
172  * @param phi  the Phi node that will be replaced
173  * @param n    in Phi Input that will replace Phi
174  */
175 #define DBG_OPT_PHI(phi, n)                                      \
176         do {                                                         \
177           hook_merge_nodes(&n, 1, &phi, 1, HOOK_OPT_PHI);            \
178           __dbg_info_merge_sets(&n, 1, &phi, 1, dbg_opt_ssa);        \
179         } while(0)
180
181
182 /**
183  * Merge the debug info due to a Sync optimization.
184  * A Sync node was replaced by one of its input (the only meaningful)
185  *
186  * @param sync  the Sync node that will be replaced
187  * @param n     in Sync Input that will replace Sync
188  */
189 #define DBG_OPT_SYNC(sync, n)                                     \
190         do {                                                          \
191           hook_merge_nodes(&n, 1, &sync, 1, HOOK_OPT_SYNC);           \
192           __dbg_info_merge_sets(&n, 1, &sync, 1, dbg_opt_ssa);        \
193         } while(0)
194
195
196 /**
197  * Merge the debug info due to Write-after-Write optimization:
198  * Store oldst will be removed, because Store st overwrites it.
199  *
200  * @param oldst  the old store that will be removed
201  * @param st     the other store that overwrites oldst
202  */
203 #define DBG_OPT_WAW(oldst, st)                                      \
204         do {                                                            \
205           ir_node *ons[2];                                              \
206           ons[0] = oldst;                                               \
207           ons[1] = st;                                                  \
208           hook_merge_nodes(&st, 1, ons, ARRAY_SIZE(ons), HOOK_OPT_WAW); \
209           __dbg_info_merge_sets(&st, 1, ons, ARRAY_SIZE(ons), dbg_write_after_write); \
210         } while(0)
211
212 /**
213  * Merge the debug info due to Write-after-Read optimization:
214  * A store will be removed because it rite a value just read back.
215  *
216  * @param store  the store that will be removed
217  * @param load   the load that produces the value that store will write back
218  */
219 #define DBG_OPT_WAR(store, load)                                      \
220         do {                                                              \
221           ir_node *ons[2];                                                \
222           ons[0] = store;                                                 \
223           ons[1] = load;                                                  \
224           hook_merge_nodes(&load, 1, ons, ARRAY_SIZE(ons), HOOK_OPT_WAR); \
225           __dbg_info_merge_sets(&load, 1, ons, ARRAY_SIZE(ons), dbg_write_after_read); \
226         } while(0)
227
228 /**
229  * Merge the debug info due to Read-after-Write optimization:
230  * A load will be replaced by a value that was just stored.
231  *
232  * @param load   the load that will be replaced
233  * @param value  the value that will replace the load
234  */
235 #define DBG_OPT_RAW(load, value)                                       \
236         do {                                                               \
237           ir_node *ons[2];                                                 \
238           ons[0] = load;                                                   \
239           ons[1] = value;                                                  \
240           hook_merge_nodes(&value, 1, ons, ARRAY_SIZE(ons), HOOK_OPT_RAW); \
241           __dbg_info_merge_sets(&value, 1, ons, ARRAY_SIZE(ons), dbg_read_after_write); \
242         } while(0)
243
244 /**
245  * Merge the debug info due to Read-after-Read optimization:
246  * Load oldld will be replace by a reference to Load ld.
247  *
248  * @param oldld  the old load that can be replaced
249  * @param ld     the load that produces the same values
250  */
251 #define DBG_OPT_RAR(oldld, ld)                                      \
252         do {                                                            \
253           ir_node *ons[2];                                              \
254           ons[0] = oldld;                                               \
255           ons[1] = ld;                                                  \
256           hook_merge_nodes(&ld, 1, ons, ARRAY_SIZE(ons), HOOK_OPT_RAR); \
257           __dbg_info_merge_sets(&ld, 1, ons, ARRAY_SIZE(ons), dbg_read_after_read); \
258         } while(0)
259
260 /**
261  * Merge the debug info due to Read-a-Const optimization:
262  * Load ld will be replace by a Constant if the value that
263  * will be loaded is known and immutable.
264  *
265  * @param ld  the load
266  * @param c   the constant value that will replace the load's result
267  */
268 #define DBG_OPT_RC(ld, c)                                         \
269         do {                                                          \
270           ir_node *ons[2];                                            \
271           ons[0] = ld;                                                \
272           ons[1] = c;                                                 \
273           hook_merge_nodes(&c, 1, ons, ARRAY_SIZE(ons), HOOK_OPT_RC); \
274           __dbg_info_merge_sets(&ld, 1, ons, ARRAY_SIZE(ons), dbg_read_a_const); \
275         } while(0)
276
277 /**
278  * Merge the debug info after a tuple optimization.
279  * a Proj(Tuple) is replaced by the associated tuple value.
280  *
281  * @param proj   the Proj node
282  * @param tuple  the Tuple node
283  * @param n      the Proj(Tuple) value
284  */
285 #define DBG_OPT_TUPLE(proj, tuple, n)                                      \
286         do {                                                                   \
287           ir_node *ons[3];                                                     \
288           ons[0] = proj;                                                       \
289           ons[1] = tuple;                                                      \
290           ons[2] = n;                                                          \
291           hook_merge_nodes(&n, 1, ons, ARRAY_SIZE(ons), HOOK_OPT_TUPLE);       \
292           __dbg_info_merge_sets(&n, 1, ons, ARRAY_SIZE(ons), dbg_opt_auxnode); \
293         } while(0)
294
295 /**
296  * Merge the debug info after an Id optimization.
297  * An Id node was replaced by its non-Id predecessor.
298  *
299  * @param id  the Id node
300  * @param n   the predecessor
301  */
302 #define DBG_OPT_ID(id, n)                                                  \
303         do {                                                                   \
304           ir_node *ons[2];                                                     \
305           ons[0] = id;                                                         \
306           ons[1] = n;                                                          \
307           hook_merge_nodes(&n, 1, ons, ARRAY_SIZE(ons), HOOK_OPT_ID);          \
308           __dbg_info_merge_sets(&n, 1, ons, ARRAY_SIZE(ons), dbg_opt_auxnode); \
309         } while(0)
310
311 /**
312  * Merge the debug info due to common-subexpression elimination.
313  *
314  * @param oldn  the old node
315  * @param n     the node that replaces oldn
316  */
317 #define DBG_OPT_CSE(oldn, n)                                           \
318         do {                                                               \
319           ir_node *ons[2];                                                 \
320           ons[0] = oldn;                                                   \
321           ons[1] = n;                                                      \
322           hook_merge_nodes(&n, 1, ons, ARRAY_SIZE(ons), HOOK_OPT_CSE);     \
323           __dbg_info_merge_sets(&n, 1, ons, ARRAY_SIZE(ons), dbg_opt_cse); \
324         } while(0)
325
326 /**
327  * Merge the debug info due to polymorphic call optimization.
328  * A Sel node was replaced by a constant.
329  *
330  * @param sel   the Sel node that will be replaced.
331  * @param c     the constant node that replaces sel
332  */
333 #define DBG_OPT_POLY(sel, c)                                                 \
334         do {                                                                     \
335           ir_node *ons[3];                                                       \
336           ons[0] = sel;                                                          \
337           ons[1] = skip_Proj(get_Sel_ptr(sel));                                  \
338           ons[2] = c;                                                            \
339           hook_merge_nodes(&c, 1, ons, ARRAY_SIZE(ons), HOOK_OPT_POLY_CALL);     \
340           __dbg_info_merge_sets(&c, 1, ons, ARRAY_SIZE(ons), dbg_rem_poly_call); \
341         } while(0)
342
343 /**
344  * A node was replaced by another node due to a Confirmation.
345  *
346  * @param oldn  the old node
347  * @param n     the new node
348  */
349 #define DBG_OPT_CONFIRM(oldn, n)                                  \
350         do {                                                          \
351           hook_merge_nodes(&n, 1, &oldn, 1, HOOK_OPT_CONFIRM);        \
352           __dbg_info_merge_pair(n, oldn, dbg_opt_confirm);            \
353         } while(0)
354
355 /**
356  * A node was replaced by a constant due to a Confimation.
357  *
358  * @param oldn  the old node
359  * @param c     the new constant node
360  */
361 #define DBG_OPT_CONFIRM_C(oldn, c)                                \
362         do {                                                          \
363           hook_merge_nodes(&c, 1, &oldn, 1, HOOK_OPT_CONFIRM_C);      \
364           __dbg_info_merge_pair(c, oldn, dbg_opt_confirm);            \
365         } while(0)
366
367 /**
368  * A exception exdge was removed due to a Confirmation prove.
369  *
370  * @param oldn  the old node
371  */
372 #define DBG_OPT_EXC_REM(oldn)                                     \
373         do {                                                          \
374           hook_merge_nodes(NULL, 0, &oldn, 1, HOOK_OPT_EXC_REM);      \
375         } while(0)
376
377 /**
378  * A node could be evaluated to a value due to a Confirm.
379  * This will lead to a constant evaluation.
380  *
381  * @param n  the node that could be evaluated
382  */
383 #define DBG_EVAL_CONFIRM(n)                                    \
384         do {                                                       \
385           hook_merge_nodes(NULL, 0, &n, 1, HOOK_OPT_CONFIRM_E);    \
386         } while(0)
387
388 /**
389  * Merge the debug info due to a GVN-PRE result.
390  *
391  * @param oldn  the old node
392  * @param n     the new node replacing oldn
393  * @param flag  firm statistics option
394  */
395 #define DBG_OPT_GVN_PRE(oldn, n, flag)             \
396         do {                                           \
397           hook_merge_nodes(&n, 1, &oldn, 1, flag);     \
398           __dbg_info_merge_pair(n, oldn, dbg_gvn_pre); \
399         } while(0)
400
401 /**
402  * Merge the debug info due to a combo result.
403  *
404  * @param oldn  the old node
405  * @param n     the new node replacing oldn
406  * @param flag  firm statistics option
407  */
408 #define DBG_OPT_COMBO(oldn, n, flag)             \
409         do {                                         \
410           hook_merge_nodes(&n, 1, &oldn, 1, flag);   \
411           __dbg_info_merge_pair(n, oldn, dbg_combo); \
412         } while(0)
413
414 /**
415  * Merge the debug info due to a jump threading result.
416  *
417  * @param oldn  the old control flow node
418  * @param n     the new control flow node replacing oldn
419  */
420 #define DBG_OPT_JUMPTHREADING(oldn, n)                         \
421         do {                                                   \
422           hook_merge_nodes(&n, 1, &oldn, 1, FS_OPT_JUMPTHREADING); \
423           __dbg_info_merge_pair(n, oldn, dbg_jumpthreading);       \
424         } while(0)
425
426 #endif