a38f29b96b267de6d6750fcc3499ce189022f72f
[libfirm] / ir / ir / irverify.c
1 /*
2  * This file is part of libFirm.
3  * Copyright (C) 2012 University of Karlsruhe.
4  */
5
6 /**
7  * @file
8  * @brief    Check irnodes for correctness.
9  * @author   Christian Schaefer, Goetz Lindenmaier, Till Riedel, Michael Beck
10  */
11 #include "config.h"
12
13 #include "irnode_t.h"
14 #include "irprog.h"
15 #include "irop_t.h"
16 #include "irgraph_t.h"
17 #include "irverify_t.h"
18 #include "irgwalk.h"
19 #include "irdump.h"
20 #include "irdom_t.h"
21 #include "irprintf.h"
22 #include "irouts.h"
23 #include "irflag_t.h"
24 #include "irpass_t.h"
25 #include "irnodeset.h"
26 #include "ircons.h"
27
28 const char *firm_verify_failure_msg;
29
30 #ifndef NDEBUG
31
32 /**
33  * little helper for NULL modes
34  */
35 static const char *get_mode_name_ex(ir_mode *mode)
36 {
37         if (! mode)
38                 return "<no mode>";
39         return get_mode_name(mode);
40 }
41
42 /** the last IRG, on which a verification error was found */
43 static ir_graph *last_irg_error = NULL;
44
45 /**
46  * print the name of the entity of an verification failure
47  *
48  * @param node  the node caused the failure
49  */
50 static void show_entity_failure(const ir_node *node)
51 {
52         ir_graph *irg = get_irn_irg(node);
53
54         if (last_irg_error == irg)
55                 return;
56
57         last_irg_error = irg;
58
59         if (irg == get_const_code_irg()) {
60                 fprintf(stderr, "\nFIRM: irn_verify_irg() <of CONST_CODE_IRG> failed\n");
61         } else {
62                 ir_entity *ent = get_irg_entity(irg);
63
64                 if (ent) {
65                         ir_type *ent_type = get_entity_owner(ent);
66                         ir_fprintf(stderr, "\nFIRM: irn_verify_irg() %+F::%s failed\n", ent_type, get_entity_name(ent));
67                 } else {
68                         fprintf(stderr, "\nFIRM: irn_verify_irg() <IRG %p> failed\n", (void *)irg);
69                 }
70         }
71 }
72
73 static const char *get_irn_modename(const ir_node *node)
74 {
75         ir_mode *mode = get_irn_mode(node);
76         return get_mode_name(mode);
77 }
78
79 /**
80  * Prints a failure for a Node
81  */
82 static void show_node_failure(const ir_node *n)
83 {
84         show_entity_failure(n);
85         fprintf(stderr, "  node %ld %s%s\n" ,
86                 get_irn_node_nr(n),
87                 get_irn_opname(n), get_irn_modename(n)
88         );
89 }
90
91 /**
92  * Prints a failure message for a binop
93  */
94 static void show_binop_failure(const ir_node *n, const char *text)
95 {
96         ir_node *left  = get_binop_left(n);
97         ir_node *right = get_binop_right(n);
98
99         show_entity_failure(n);
100         fprintf(stderr, "  node %ld %s%s(%s%s, %s%s) did not match (%s)\n",
101                 get_irn_node_nr(n),
102                 get_irn_opname(n), get_irn_modename(n),
103                 get_irn_opname(left), get_irn_modename(left),
104                 get_irn_opname(right), get_irn_modename(right),
105                 text);
106 }
107
108 /**
109  * Prints a failure message for an unop
110  */
111 static void show_unop_failure(const ir_node *n, const char *text)
112 {
113         ir_node *op  = get_unop_op(n);
114
115         show_entity_failure(n);
116         fprintf(stderr, "  node %ld %s%s(%s%s) did not match (%s)\n",
117                 get_irn_node_nr(n),
118                 get_irn_opname(n), get_irn_modename(n),
119                 get_irn_opname(op), get_irn_modename(op),
120                 text);
121 }
122
123 /**
124  * Prints a failure message for an op with 3 operands
125  */
126 static void show_triop_failure(const ir_node *n, const char *text)
127 {
128         ir_node *op0  = get_irn_n(n, 0);
129         ir_node *op1  = get_irn_n(n, 1);
130         ir_node *op2  = get_irn_n(n, 2);
131
132         show_entity_failure(n);
133         fprintf(stderr, "  of node %ld %s%s(%s%s, %s%s, %s%s) did not match (%s)\n",
134                 get_irn_node_nr(n),
135                 get_irn_opname(n), get_irn_modename(n),
136                 get_irn_opname(op0), get_irn_modename(op0),
137                 get_irn_opname(op1), get_irn_modename(op1),
138                 get_irn_opname(op2), get_irn_modename(op2),
139                 text);
140 }
141
142 /**
143  * Prints a failure message for a proj
144  */
145 static void show_proj_failure(const ir_node *n)
146 {
147         ir_node *op  = get_Proj_pred(n);
148         int proj     = get_Proj_proj(n);
149
150         show_entity_failure(n);
151         fprintf(stderr, "  node %ld %s%s %d(%s%s) failed\n" ,
152                 get_irn_node_nr(n),
153                 get_irn_opname(n), get_irn_modename(n), proj,
154                 get_irn_opname(op), get_irn_modename(op));
155 }
156
157 /**
158  * Prints a failure message for a proj from Start
159  */
160 static void show_proj_mode_failure(const ir_node *n, ir_type *ty)
161 {
162         long proj  = get_Proj_proj(n);
163         ir_mode *m = get_type_mode(ty);
164         char type_name[256];
165         ir_print_type(type_name, sizeof(type_name), ty);
166
167         show_entity_failure(n);
168         fprintf(stderr, "  Proj %ld mode %s proj %ld (type %s mode %s) failed\n" ,
169                 get_irn_node_nr(n),
170                 get_irn_modename(n),
171                 proj,
172                 type_name,
173                 get_mode_name_ex(m));
174 }
175
176 /**
177  * Show a node and a graph
178  */
179 static void show_node_on_graph(const ir_graph *irg, const ir_node *n)
180 {
181         ir_fprintf(stderr, "\nFIRM: irn_verify_irg() of %+F, node %+F\n", irg, n);
182 }
183
184 /**
185  * Show call parameters
186  */
187 static void show_call_param(const ir_node *n, ir_type *mt)
188 {
189         char type_name[256];
190         ir_print_type(type_name, sizeof(type_name), mt);
191
192         show_entity_failure(n);
193         fprintf(stderr, "  Call type-check failed: %s(", type_name);
194         size_t n_method_params = get_method_n_params(mt);
195         for (size_t i = 0; i < n_method_params; ++i) {
196                 fprintf(stderr, "%s ", get_mode_name_ex(get_type_mode(get_method_param_type(mt, i))));
197         }
198         fprintf(stderr, ") != CALL(");
199
200         int n_params = get_Call_n_params(n);
201         for (int i = 0; i < n_params; ++i) {
202                 fprintf(stderr, "%s ", get_mode_name_ex(get_irn_mode(get_Call_param(n, i))));
203         }
204         fprintf(stderr, ")\n");
205 }
206
207 /**
208  * Show return modes
209  */
210 static void show_return_modes(const ir_graph *irg, const ir_node *n,
211                               ir_type *mt, int i)
212 {
213         ir_entity *ent = get_irg_entity(irg);
214
215         show_entity_failure(n);
216         fprintf(stderr, "  Return node %ld in entity \"%s\" mode %s different from type mode %s\n",
217                 get_irn_node_nr(n), get_entity_name(ent),
218                 get_mode_name_ex(get_irn_mode(get_Return_res(n, i))),
219                 get_mode_name_ex(get_type_mode(get_method_res_type(mt, i)))
220         );
221 }
222
223 /**
224  * Show return number of results
225  */
226 static void show_return_nres(const ir_graph *irg, const ir_node *n, ir_type *mt)
227 {
228         ir_entity *ent = get_irg_entity(irg);
229
230         show_entity_failure(n);
231         fprintf(stderr, "  Return node %ld in entity \"%s\" has %lu results different from type %lu\n",
232                 get_irn_node_nr(n), get_entity_name(ent),
233                 (unsigned long) get_Return_n_ress(n),
234                 (unsigned long) get_method_n_ress(mt));
235 }
236
237 /**
238  * Show Phi input
239  */
240 static void show_phi_failure(const ir_node *phi, const ir_node *pred, int pos)
241 {
242         (void) pos;
243         show_entity_failure(phi);
244         fprintf(stderr, "  Phi node %ld has mode %s different from predeccessor node %ld mode %s\n",
245                 get_irn_node_nr(phi), get_mode_name_ex(get_irn_mode(phi)),
246                 get_irn_node_nr(pred), get_mode_name_ex(get_irn_mode(pred)));
247 }
248
249 /**
250  * Show Phi inputs
251  */
252 static void show_phi_inputs(const ir_node *phi, const ir_node *block)
253 {
254         show_entity_failure(phi);
255         fprintf(stderr, "  Phi node %ld has %d inputs, its Block %ld has %d\n",
256                 get_irn_node_nr(phi),   get_irn_arity(phi),
257                 get_irn_node_nr(block), get_irn_arity(block));
258 }
259
260 #endif /* #ifndef NDEBUG */
261
262 /**
263  * verify a Proj(Start) node
264  */
265 static int verify_node_Proj_Start(const ir_node *p)
266 {
267         ir_mode *mode = get_irn_mode(p);
268         long proj     = get_Proj_proj(p);
269
270         ASSERT_AND_RET_DBG(
271                 (
272                         (proj == pn_Start_X_initial_exec && mode == mode_X) ||
273                         (proj == pn_Start_M              && mode == mode_M) ||
274                         (proj == pn_Start_P_frame_base   && mode_is_reference(mode)) ||
275                         (proj == pn_Start_T_args         && mode == mode_T)
276                 ),
277                 "wrong Proj from Start", 0,
278                 show_proj_failure(p);
279         );
280         return 1;
281 }
282
283 /**
284  * verify a Proj(Cond) node
285  */
286 static int verify_node_Proj_Cond(const ir_node *p)
287 {
288         ir_mode *mode = get_irn_mode(p);
289         long     proj = get_Proj_proj(p);
290
291         ASSERT_AND_RET_DBG(
292                 mode == mode_X && (proj == pn_Cond_false || proj == pn_Cond_true),
293                 "wrong Proj from Cond", 0,
294                 show_proj_failure(p);
295         );
296         return 1;
297 }
298
299 static int verify_node_Proj_Switch(const ir_node *p)
300 {
301         ir_mode *mode = get_irn_mode(p);
302         long     pn   = get_Proj_proj(p);
303         ir_node *pred = get_Proj_pred(p);
304         ASSERT_AND_RET_DBG(
305                 mode == mode_X && (pn >= 0 && pn < (long)get_Switch_n_outs(pred)),
306                 "wrong Proj from Switch", 0,
307                 show_proj_failure(p);
308         );
309         return 1;
310 }
311
312 /**
313  * verify a Proj(Raise) node
314  */
315 static int verify_node_Proj_Raise(const ir_node *p)
316 {
317         ir_mode *mode = get_irn_mode(p);
318         long proj     = get_Proj_proj(p);
319
320         ASSERT_AND_RET_DBG(
321                 ((proj == pn_Raise_X && mode == mode_X) || (proj == pn_Raise_M && mode == mode_M)),
322                 "wrong Proj from Raise", 0,
323                 show_proj_failure(p);
324         );
325         return 1;
326 }
327
328 /**
329  * verify a Proj(InstOf) node
330  */
331 static int verify_node_Proj_InstOf(const ir_node *p)
332 {
333         ir_mode *mode = get_irn_mode(p);
334         long proj     = get_Proj_proj(p);
335
336         ASSERT_AND_RET_DBG(
337                 (
338                         (proj == pn_InstOf_M         && mode == mode_M) ||
339                         (proj == pn_InstOf_X_regular && mode == mode_X) ||
340                         (proj == pn_InstOf_X_except  && mode == mode_X) ||
341                         (proj == pn_InstOf_res       && mode_is_reference(mode))
342                 ),
343                 "wrong Proj from InstOf", 0,
344                 show_proj_failure(p);
345         );
346         return 1;
347 }
348
349 /**
350  * verify a Proj(Call) node
351  */
352 static int verify_node_Proj_Call(const ir_node *p)
353 {
354         ir_mode *mode = get_irn_mode(p);
355         ir_node *n    = get_Proj_pred(p);
356         long proj     = get_Proj_proj(p);
357
358         ASSERT_AND_RET_DBG(
359                 (
360                         (proj == pn_Call_M                && mode == mode_M) ||
361                         (proj == pn_Call_X_regular        && mode == mode_X) ||
362                         (proj == pn_Call_X_except         && mode == mode_X) ||
363                         (proj == pn_Call_T_result         && mode == mode_T)
364                 ),
365                 "wrong Proj from Call", 0,
366                 show_proj_failure(p);
367         );
368         /* if we have exception flow, we must have a real Memory input */
369         if (proj == pn_Call_X_regular)
370                 ASSERT_AND_RET(
371                         !is_NoMem(get_Call_mem(n)),
372                         "Regular Proj from FunctionCall", 0);
373         else if (proj == pn_Call_X_except)
374                 ASSERT_AND_RET(
375                         !is_NoMem(get_Call_mem(n)),
376                         "Exception Proj from FunctionCall", 0);
377         return 1;
378 }
379
380 /**
381  * verify a Proj(Div) node
382  */
383 static int verify_node_Proj_Div(const ir_node *p)
384 {
385         ir_mode *mode = get_irn_mode(p);
386         ir_node *n    = get_Proj_pred(p);
387         long proj     = get_Proj_proj(p);
388
389         ASSERT_AND_RET_DBG(
390                 (
391                         (proj == pn_Div_M         && mode == mode_M) ||
392                         (proj == pn_Div_X_regular && mode == mode_X) ||
393                         (proj == pn_Div_X_except  && mode == mode_X) ||
394                         (proj == pn_Div_res       && mode == get_Div_resmode(n))
395                 ),
396                 "wrong Proj from Div", 0,
397                 show_proj_failure(p);
398         );
399         if (proj == pn_Div_X_regular)
400                 ASSERT_AND_RET(
401                         get_irn_pinned(n) == op_pin_state_pinned,
402                         "Regular Proj from unpinned Div", 0);
403         else if (proj == pn_Div_X_except)
404                 ASSERT_AND_RET(
405                         get_irn_pinned(n) == op_pin_state_pinned,
406                         "Exception Proj from unpinned Div", 0);
407         else if (proj == pn_Div_M)
408                 ASSERT_AND_RET(
409                         get_irn_pinned(n) == op_pin_state_pinned,
410                         "Memory Proj from unpinned Div", 0);
411         return 1;
412 }
413
414 /**
415  * verify a Proj(Mod) node
416  */
417 static int verify_node_Proj_Mod(const ir_node *p)
418 {
419         ir_mode *mode = get_irn_mode(p);
420         ir_node *n    = get_Proj_pred(p);
421         long proj     = get_Proj_proj(p);
422
423         ASSERT_AND_RET_DBG(
424                 (
425                         (proj == pn_Mod_M         && mode == mode_M) ||
426                         (proj == pn_Mod_X_regular && mode == mode_X) ||
427                         (proj == pn_Mod_X_except  && mode == mode_X) ||
428                         (proj == pn_Mod_res       && mode == get_Mod_resmode(n))
429                 ),
430                 "wrong Proj from Mod", 0,
431                 show_proj_failure(p);
432         );
433         if (proj == pn_Mod_X_regular)
434                 ASSERT_AND_RET(
435                         get_irn_pinned(n) == op_pin_state_pinned,
436                         "Regular Proj from unpinned Mod", 0);
437         else if (proj == pn_Mod_X_except)
438                 ASSERT_AND_RET(
439                         get_irn_pinned(n) == op_pin_state_pinned,
440                         "Exception Proj from unpinned Mod", 0);
441         else if (proj == pn_Mod_M)
442                 ASSERT_AND_RET(
443                         get_irn_pinned(n) == op_pin_state_pinned,
444                         "Memory Proj from unpinned Div", 0);
445         return 1;
446 }
447
448 /**
449  * verify a Proj(Load) node
450  */
451 static int verify_node_Proj_Load(const ir_node *p)
452 {
453         ir_mode *mode = get_irn_mode(p);
454         ir_node *n    = get_Proj_pred(p);
455         long proj     = get_Proj_proj(p);
456
457         if (proj == pn_Load_res) {
458                 ASSERT_AND_RET_DBG(
459                         mode_is_data(mode) && mode == get_Load_mode(n),
460                         "wrong data Proj from Load", 0,
461                         show_proj_failure(p);
462                 );
463         } else {
464                 ASSERT_AND_RET_DBG(
465                         (
466                                 (proj == pn_Load_M         && mode == mode_M) ||
467                                 (proj == pn_Load_X_regular && mode == mode_X) ||
468                                 (proj == pn_Load_X_except  && mode == mode_X)
469                         ),
470                         "wrong Proj from Load", 0,
471                         show_proj_failure(p);
472                 );
473         }
474         if (proj == pn_Load_X_regular) {
475                 ASSERT_AND_RET(
476                         get_irn_pinned(n) == op_pin_state_pinned,
477                         "Regular Proj from unpinned Load", 0);
478         } else if (proj == pn_Load_X_except) {
479                 ASSERT_AND_RET(
480                         get_irn_pinned(n) == op_pin_state_pinned,
481                         "Exception Proj from unpinned Load", 0);
482         }
483         return 1;
484 }
485
486 /**
487  * verify a Proj(Store) node
488  */
489 static int verify_node_Proj_Store(const ir_node *p)
490 {
491         ir_mode *mode = get_irn_mode(p);
492         ir_node *n    = get_Proj_pred(p);
493         long proj     = get_Proj_proj(p);
494
495         ASSERT_AND_RET_DBG(
496                 (
497                         (proj == pn_Store_M         && mode == mode_M) ||
498                         (proj == pn_Store_X_regular && mode == mode_X) ||
499                         (proj == pn_Store_X_except  && mode == mode_X)
500                 ),
501                 "wrong Proj from Store", 0,
502                 show_proj_failure(p);
503         );
504         if (proj == pn_Store_X_regular) {
505                 ASSERT_AND_RET(
506                         get_irn_pinned(n) == op_pin_state_pinned,
507                         "Regular Proj from unpinned Store", 0);
508         } else if (proj == pn_Store_X_except) {
509                 ASSERT_AND_RET(
510                         get_irn_pinned(n) == op_pin_state_pinned,
511                         "Exception Proj from unpinned Store", 0);
512         }
513         return 1;
514 }
515
516 /**
517  * verify a Proj(Alloc) node
518  */
519 static int verify_node_Proj_Alloc(const ir_node *p)
520 {
521         ir_mode *mode = get_irn_mode(p);
522         long proj     = get_Proj_proj(p);
523
524         ASSERT_AND_RET_DBG(
525                 (
526                         (proj == pn_Alloc_M         && mode == mode_M) ||
527                         (proj == pn_Alloc_X_regular && mode == mode_X) ||
528                         (proj == pn_Alloc_X_except  && mode == mode_X) ||
529                         (proj == pn_Alloc_res       && mode_is_reference(mode))
530                 ),
531                 "wrong Proj from Alloc", 0,
532                 show_proj_failure(p);
533         );
534         return 1;
535 }
536
537 /**
538  * verify a Proj(Proj) node
539  */
540 static int verify_node_Proj_Proj(const ir_node *p)
541 {
542         ir_mode *mode     = get_irn_mode(p);
543         ir_node *pred     = get_Proj_pred(p);
544         ir_node *predpred = get_Proj_pred(pred);
545         long     proj     = get_Proj_proj(p);
546         long     nr       = get_Proj_proj(pred);
547
548         switch (get_irn_opcode(predpred)) {
549         case iro_Start: {
550                 ir_graph *irg = get_irn_irg(p);
551                 ir_type  *mt  = get_entity_type(get_irg_entity(irg));
552
553                 if (nr == pn_Start_T_args) {
554                         ASSERT_AND_RET(
555                                 (proj >= 0 && mode_is_datab(mode)),
556                                 "wrong Proj from Proj from Start", 0);
557                         ASSERT_AND_RET(
558                                 (proj < (int)get_method_n_params(mt)),
559                                 "More Projs for args than args in type", 0
560                                 );
561                         ir_type *param_type = get_method_param_type(mt, proj);
562                         if (!irg_is_constrained(irg, IR_GRAPH_CONSTRAINT_BACKEND)) {
563                                 ASSERT_AND_RET_DBG(
564                                                 (mode == get_type_mode(param_type)),
565                                                 "Mode of Proj from Start doesn't match mode of param type.", 0,
566                                                 show_proj_mode_failure(p, get_method_param_type(mt, proj));
567                                                 );
568                         }
569                 }
570                 break;
571         }
572
573         case iro_Call:
574                 {
575                         ASSERT_AND_RET(
576                                 (proj >= 0 && mode_is_datab(mode)),
577                                 "wrong Proj from Proj from Call", 0);
578                         mt = get_Call_type(predpred);
579                         ASSERT_AND_RET(is_unknown_type(mt) || is_Method_type(mt),
580                                         "wrong call type on call", 0);
581                         ASSERT_AND_RET(
582                                 (proj < (int)get_method_n_ress(mt)),
583                                 "More Projs for results than results in type.", 0);
584                         ir_type *res_type = get_method_res_type(mt, proj);
585                         /* value result */
586                         if ((mode_is_reference(mode)) &&
587                                 (is_compound_type(res_type) || is_Array_type(res_type)))
588                                 break;
589
590                         ASSERT_AND_RET(
591                                 (mode == get_type_mode(get_method_res_type(mt, proj))),
592                                 "Mode of Proj from Call doesn't match mode of result type.", 0);
593                 }
594                 break;
595
596         case iro_Tuple:
597                 /* We don't test */
598                 break;
599
600         default:
601                 /* ASSERT_AND_RET(0, "Unknown opcode", 0); */
602                 break;
603         }
604         return 1;
605 }
606
607 /**
608  * verify a Proj(Tuple) node
609  */
610 static int verify_node_Proj_Tuple(const ir_node *p)
611 {
612         (void) p;
613         /* We don't test */
614         return 1;
615 }
616
617 /**
618  * verify a Proj(CopyB) node
619  */
620 static int verify_node_Proj_CopyB(const ir_node *p)
621 {
622         ir_mode *mode = get_irn_mode(p);
623         ir_node *n    = get_Proj_pred(p);
624         long proj     = get_Proj_proj(p);
625
626         ASSERT_AND_RET_DBG(
627                 (
628                         (proj == pn_CopyB_M         && mode == mode_M) ||
629                         (proj == pn_CopyB_X_regular && mode == mode_X) ||
630                         (proj == pn_CopyB_X_except  && mode == mode_X)
631                 ),
632                 "wrong Proj from CopyB", 0,
633                 show_proj_failure(p);
634         );
635         if (proj == pn_CopyB_X_regular)
636                 ASSERT_AND_RET(
637                         get_irn_pinned(n) == op_pin_state_pinned,
638                         "Regular Proj from unpinned CopyB", 0);
639         else if (proj == pn_CopyB_X_except)
640                 ASSERT_AND_RET(
641                         get_irn_pinned(n) == op_pin_state_pinned,
642                         "Exception Proj from unpinned CopyB", 0);
643         return 1;
644 }
645
646 static int verify_node_Proj_fragile(const ir_node *node)
647 {
648         ir_node *pred             = get_Proj_pred(node);
649         int      throws_exception = ir_throws_exception(pred);
650         ASSERT_AND_RET((!is_x_except_Proj(node) || throws_exception)
651             && (!is_x_regular_Proj(node) || throws_exception),
652             "X_except und X_regular Proj only allowed when throws_exception is set",
653             0);
654         return 1;
655 }
656
657 /**
658  * verify a Proj node
659  */
660 static int verify_node_Proj(const ir_node *p)
661 {
662         ir_graph *irg = get_irn_irg(p);
663         ir_node *pred;
664         ir_op *op;
665
666         pred = skip_Id(get_Proj_pred(p));
667         ASSERT_AND_RET(get_irn_mode(pred) == mode_T, "mode of a 'projed' node is not Tuple", 0);
668         ASSERT_AND_RET(get_irg_pinned(irg) == op_pin_state_floats || get_nodes_block(pred) == get_nodes_block(p), "Proj must be in same block as its predecessor", 0);
669
670         if (is_fragile_op(pred)) {
671                 int res = verify_node_Proj_fragile(p);
672                 if (res != 1)
673                         return res;
674         }
675
676         op = get_irn_op(pred);
677         if (op->ops.verify_proj_node)
678                 return op->ops.verify_proj_node(p);
679
680         /* all went ok */
681         return 1;
682 }
683
684 /**
685  * verify a Block node
686  */
687 static int verify_node_Block(const ir_node *n)
688 {
689         ir_graph *irg = get_irn_irg(n);
690         int i;
691
692         for (i = get_Block_n_cfgpreds(n) - 1; i >= 0; --i) {
693                 ir_node *pred         = get_Block_cfgpred(n, i);
694                 ir_node *skipped_pred = skip_Proj(skip_Tuple(pred));
695                 ASSERT_AND_RET(get_irn_mode(pred) == mode_X,
696                         "Block node must have a mode_X predecessor", 0);
697                 ASSERT_AND_RET(is_cfop(skipped_pred) || is_Bad(skipped_pred), "Block predecessor must be a cfop (or Bad)", 0);
698         }
699
700         if (n == get_irg_start_block(irg)) {
701                 ASSERT_AND_RET(get_Block_n_cfgpreds(n) == 0, "Start Block node", 0);
702         }
703
704         if (n == get_irg_end_block(irg) && !irg_is_constrained(irg, IR_GRAPH_CONSTRAINT_BACKEND)) {
705                 /* End block may only have Return, Raise or fragile ops as preds. */
706                 for (i = get_Block_n_cfgpreds(n) - 1; i >= 0; --i) {
707                         ir_node *pred =  skip_Proj(get_Block_cfgpred(n, i));
708                         if (is_Proj(pred) || is_Tuple(pred))
709                                 break;   /*  We can not test properly.  How many tuples are there? */
710                         ASSERT_AND_RET(
711                                 (
712                                         is_Return(pred) ||
713                                         is_Bad(pred)    ||
714                                         is_Raise(pred)  ||
715                                         is_fragile_op(pred)
716                                 ),
717                                 "End Block node", 0);
718                 }
719         }
720         /*  irg attr must == graph we are in. */
721         ASSERT_AND_RET(((get_irn_irg(n) && get_irn_irg(n) == irg)), "Block node has wrong irg attribute", 0);
722         return 1;
723 }
724
725 /**
726  * verify a Start node
727  */
728 static int verify_node_Start(const ir_node *n)
729 {
730         ir_mode *mymode = get_irn_mode(n);
731
732         ASSERT_AND_RET(
733                 /* Start: BB --> X x M x ref x data1 x ... x datan x ref */
734                 mymode == mode_T, "Start node", 0
735                 );
736         return 1;
737 }
738
739 /**
740  * verify a Jmp node
741  */
742 static int verify_node_Jmp(const ir_node *n)
743 {
744         ir_mode *mymode = get_irn_mode(n);
745
746         ASSERT_AND_RET(
747                 /* Jmp: BB --> X */
748                 mymode == mode_X, "Jmp node", 0
749         );
750         return 1;
751 }
752
753 /**
754  * verify an IJmp node
755  */
756 static int verify_node_IJmp(const ir_node *n)
757 {
758         ir_mode *mymode  = get_irn_mode(n);
759         ir_mode *op1mode = get_irn_mode(get_IJmp_target(n));
760
761         ASSERT_AND_RET(
762                 /* IJmp: BB x ref --> X */
763                 mymode == mode_X && mode_is_reference(op1mode), "IJmp node", 0
764         );
765         return 1;
766 }
767
768 /**
769  * verify a Cond node
770  */
771 static int verify_node_Cond(const ir_node *n)
772 {
773         ir_mode *mymode  = get_irn_mode(n);
774         ir_mode *op1mode = get_irn_mode(get_Cond_selector(n));
775
776         ASSERT_AND_RET(op1mode == mode_b, "Cond operand not mode_b", 0);
777         ASSERT_AND_RET(mymode == mode_T, "Cond mode is not a tuple", 0);
778         return 1;
779 }
780
781 static int verify_switch_table(const ir_node *n)
782 {
783         const ir_switch_table *table     = get_Switch_table(n);
784         unsigned               n_outs    = get_Switch_n_outs(n);
785         ir_node               *selector  = get_Switch_selector(n);
786         ir_mode               *mode      = get_irn_mode(selector);
787         size_t                 n_entries;
788         size_t                 e;
789
790         ASSERT_AND_RET(table != NULL, "switch table is NULL", 0);
791
792         n_entries = ir_switch_table_get_n_entries(table);
793         for (e = 0; e < n_entries; ++e) {
794                 const ir_switch_table_entry *entry
795                         = ir_switch_table_get_entry_const(table, e);
796                 if (entry->pn == 0)
797                         continue;
798                 ASSERT_AND_RET(entry->min != NULL && entry->max != NULL,
799                                "switch table entry without min+max value", 0);
800                 ASSERT_AND_RET(get_tarval_mode(entry->min) == mode &&
801                                get_tarval_mode(entry->max) == mode,
802                                "switch table entry with wrong modes", 0);
803                 ASSERT_AND_RET(tarval_cmp(entry->min, entry->max) != ir_relation_greater,
804                                "switch table entry without min+max value", 0);
805                 ASSERT_AND_RET(entry->pn >= 0 && entry->pn < (long)n_outs,
806                                            "switch table entry with invalid proj number", 0);
807         }
808         return 1;
809 }
810
811 static int verify_node_Switch(const ir_node *n)
812 {
813         ir_mode *mymode  = get_irn_mode(n);
814         ir_mode *op1mode = get_irn_mode(get_Switch_selector(n));
815         if (!verify_switch_table(n))
816                 return 0;
817
818         ASSERT_AND_RET(mode_is_int(op1mode), "Switch operand not integer", 0);
819         ASSERT_AND_RET(mymode == mode_T, "Switch mode is not a tuple", 0);
820         return 1;
821 }
822
823 /**
824  * verify a Return node
825  */
826 static int verify_node_Return(const ir_node *n)
827 {
828         ir_graph *irg      = get_irn_irg(n);
829         ir_mode  *mymode   = get_irn_mode(n);
830         ir_mode  *mem_mode = get_irn_mode(get_Return_mem(n));
831         ir_type  *mt;
832         int       i;
833
834         /* Return: BB x M x data1 x ... x datan --> X */
835
836         ASSERT_AND_RET( mem_mode == mode_M, "Return node", 0 );  /* operand M */
837
838         for (i = get_Return_n_ress(n) - 1; i >= 0; --i) {
839                 ASSERT_AND_RET( mode_is_datab(get_irn_mode(get_Return_res(n, i))), "Return node", 0 );  /* operand datai */
840         }
841         ASSERT_AND_RET( mymode == mode_X, "Result X", 0 );   /* result X */
842         /* Compare returned results with result types of method type */
843         mt = get_entity_type(get_irg_entity(irg));
844         ASSERT_AND_RET_DBG((size_t)get_Return_n_ress(n) == get_method_n_ress(mt),
845                 "Number of results for Return doesn't match number of results in type.", 0,
846                 show_return_nres(irg, n, mt););
847         for (i = get_Return_n_ress(n) - 1; i >= 0; --i) {
848                 ir_type *res_type = get_method_res_type(mt, i);
849
850                 if (irg_is_constrained(irg, IR_GRAPH_CONSTRAINT_BACKEND)) {
851                         if (is_atomic_type(res_type)) {
852                                 ASSERT_AND_RET_DBG(
853                                         get_irn_mode(get_Return_res(n, i)) == get_type_mode(res_type),
854                                         "Mode of result for Return doesn't match mode of result type.", 0,
855                                         show_return_modes(irg, n, mt, i);
856                                 );
857                         } else {
858                                 ASSERT_AND_RET_DBG(
859                                         mode_is_reference(get_irn_mode(get_Return_res(n, i))),
860                                         "Mode of result for Return doesn't match mode of result type.", 0,
861                                         show_return_modes(irg, n, mt, i);
862                                 );
863                         }
864                 }
865         }
866         return 1;
867 }
868
869 /**
870  * verify a Raise node
871  */
872 static int verify_node_Raise(const ir_node *n)
873 {
874         ir_mode *mymode  = get_irn_mode(n);
875         ir_mode *op1mode = get_irn_mode(get_Raise_mem(n));
876         ir_mode *op2mode = get_irn_mode(get_Raise_exo_ptr(n));
877
878         ASSERT_AND_RET(
879                 /* Sel: BB x M x ref --> X x M */
880                 op1mode == mode_M && mode_is_reference(op2mode) &&
881                 mymode == mode_T, "Raise node", 0
882         );
883         return 1;
884 }
885
886 /**
887  * verify a Const node
888  */
889 static int verify_node_Const(const ir_node *n)
890 {
891         ir_mode *mymode = get_irn_mode(n);
892
893         ASSERT_AND_RET(
894                 /* Const: BB --> data */
895                 (mode_is_data(mymode) ||
896                 mymode == mode_b)      /* we want boolean constants for static evaluation */
897                 ,"Const node", 0       /* of Cmp. */
898         );
899         ASSERT_AND_RET(
900                 /* the modes of the constant and teh tarval must match */
901                 mymode == get_tarval_mode(get_Const_tarval(n)),
902                 "Const node, tarval and node mode mismatch", 0
903         );
904         return 1;
905 }
906
907 /**
908  * verify a SymConst node
909  */
910 static int verify_node_SymConst(const ir_node *n)
911 {
912         ir_mode *mymode = get_irn_mode(n);
913
914         ASSERT_AND_RET(
915                 /* SymConst: BB --> int*/
916                 (mode_is_int(mymode) ||
917                 /* SymConst: BB --> ref */
918                 mode_is_reference(mymode))
919                 ,"SymConst node", 0);
920         if (SYMCONST_HAS_ENT(get_SymConst_kind(n))) {
921                 ir_entity *ent = get_SymConst_entity(n);
922                 /* the is_method_entity(ent) exception is for nested functions... */
923                 ASSERT_AND_RET_DBG((get_entity_owner(ent)->flags & tf_segment)
924                                    || is_method_entity(ent),
925                                    "SymConst node with non-segment entity", 0,
926                                    show_node_failure(n););
927         }
928         return 1;
929 }
930
931 /**
932  * verify a Sel node
933  */
934 static int verify_node_Sel(const ir_node *n)
935 {
936         int i;
937         ir_mode *mymode  = get_irn_mode(n);
938         ir_mode *op1mode = get_irn_mode(get_Sel_mem(n));
939         ir_mode *op2mode = get_irn_mode(get_Sel_ptr(n));
940         ir_entity *ent;
941
942         ASSERT_AND_RET_DBG(
943                 /* Sel: BB x M x ref x int^n --> ref */
944                 (op1mode == mode_M && op2mode == mymode && mode_is_reference(mymode)),
945                 "Sel node", 0, show_node_failure(n);
946         );
947
948         for (i = get_Sel_n_indexs(n) - 1; i >= 0; --i) {
949                 ASSERT_AND_RET_DBG(mode_is_int(get_irn_mode(get_Sel_index(n, i))), "Sel node", 0, show_node_failure(n););
950         }
951         ent = get_Sel_entity(n);
952         ASSERT_AND_RET_DBG(ent, "Sel node with empty entity", 0, show_node_failure(n););
953         ASSERT_AND_RET_DBG(!(get_entity_owner(ent)->flags & tf_segment),
954                            "Sel node with global entity", 0, show_node_failure(n););
955         return 1;
956 }
957
958 /**
959  * verify an InstOf node
960  */
961 static int verify_node_InstOf(const ir_node *n)
962 {
963         ir_mode *mymode  = get_irn_mode(n);
964         ir_mode *op1mode = get_irn_mode(get_InstOf_obj(n));
965
966         ASSERT_AND_RET(mode_T == mymode, "mode of Instof is not a tuple", 0);
967         ASSERT_AND_RET(mode_is_data(op1mode), "Instof not on data", 0);
968         return 1;
969 }
970
971 /**
972  * Check if the pinned state is right.
973  */
974 static int verify_right_pinned(const ir_node *n)
975 {
976         ir_node *mem;
977
978         if (get_irn_pinned(n) == op_pin_state_pinned)
979                 return 1;
980         mem = get_Call_mem(n);
981
982         /* if it's not pinned, its memory predecessor must be NoMem or Pin */
983         if (is_NoMem(mem) || is_Pin(mem))
984                 return 1;
985         return 0;
986 }
987
988 /**
989  * verify a Call node
990  */
991 static int verify_node_Call(const ir_node *n)
992 {
993         ir_graph *irg     = get_irn_irg(n);
994         ir_mode  *mymode  = get_irn_mode(n);
995         ir_mode  *op1mode = get_irn_mode(get_Call_mem(n));
996         ir_mode  *op2mode = get_irn_mode(get_Call_ptr(n));
997         ir_type  *mt;
998         size_t    i;
999         size_t    n_params;
1000
1001         /* Call: BB x M x ref x data1 x ... x datan
1002         --> M x datan+1 x ... x data n+m */
1003         ASSERT_AND_RET( op1mode == mode_M && mode_is_reference(op2mode), "Call node", 0 );  /* operand M x ref */
1004
1005         /* NoMem nodes are only allowed as memory input if the Call is NOT pinned */
1006         ASSERT_AND_RET(verify_right_pinned(n),"Call node with wrong memory input", 0 );
1007
1008         mt = get_Call_type(n);
1009         if (get_unknown_type() == mt) {
1010                 return 1;
1011         }
1012
1013         n_params = get_Call_n_params(n);
1014         for (i = 0; i < n_params; ++i) {
1015                 ASSERT_AND_RET( mode_is_datab(get_irn_mode(get_Call_param(n, i))), "Call node", 0 );  /* operand datai */
1016         }
1017
1018         ASSERT_AND_RET( mymode == mode_T, "Call result not a tuple", 0 );   /* result T */
1019         /* Compare arguments of node with those of type */
1020
1021         if (get_method_variadicity(mt) == variadicity_variadic) {
1022                 ASSERT_AND_RET_DBG(
1023                         (size_t)get_Call_n_params(n) >= get_method_n_params(mt),
1024                         "Number of args for Call doesn't match number of args in variadic type.",
1025                         0,
1026                         ir_fprintf(stderr, "Call %+F has %d params, type %d\n",
1027                         n, get_Call_n_params(n), get_method_n_params(mt));
1028                 );
1029         } else {
1030                 ASSERT_AND_RET_DBG(
1031                         (size_t)get_Call_n_params(n) == get_method_n_params(mt),
1032                         "Number of args for Call doesn't match number of args in non variadic type.",
1033                         0,
1034                         ir_fprintf(stderr, "Call %+F has %d params, type %d\n",
1035                         n, get_Call_n_params(n), get_method_n_params(mt));
1036                 );
1037         }
1038
1039         for (i = 0; i < get_method_n_params(mt); i++) {
1040                 ir_type *t = get_method_param_type(mt, i);
1041
1042                 if (irg_is_constrained(irg, IR_GRAPH_CONSTRAINT_BACKEND)) {
1043                         if (is_atomic_type(t)) {
1044                                 ASSERT_AND_RET_DBG(
1045                                         get_irn_mode(get_Call_param(n, i)) == get_type_mode(t),
1046                                         "Mode of arg for Call doesn't match mode of arg type.", 0,
1047                                         show_call_param(n, mt);
1048                                 );
1049                         } else {
1050                                 /* call with a compound type, mode must be reference */
1051                                 ASSERT_AND_RET_DBG(
1052                                         mode_is_reference(get_irn_mode(get_Call_param(n, i))),
1053                                         "Mode of arg for Call doesn't match mode of arg type.", 0,
1054                                         show_call_param(n, mt);
1055                                 );
1056                         }
1057                 }
1058         }
1059
1060         return 1;
1061 }
1062
1063 /**
1064  * verify an Add node
1065  */
1066 static int verify_node_Add(const ir_node *n)
1067 {
1068         ir_mode *mymode  = get_irn_mode(n);
1069         ir_mode *op1mode = get_irn_mode(get_Add_left(n));
1070         ir_mode *op2mode = get_irn_mode(get_Add_right(n));
1071
1072         ASSERT_AND_RET_DBG(
1073                 (
1074                         /* common Add: BB x numP x numP --> numP */
1075                         (op1mode == mymode && op2mode == op1mode && mode_is_data(mymode)) ||
1076                         /* Pointer Add: BB x ref x int --> ref */
1077                         (mode_is_reference(op1mode) && mode_is_int(op2mode) && op1mode == mymode) ||
1078                         /* Pointer Add: BB x int x ref --> ref */
1079                         (mode_is_int(op1mode) && op2mode == mymode && mode_is_reference(mymode))
1080                 ),
1081                 "Add node", 0,
1082                 show_binop_failure(n, "/* common Add: BB x numP x numP --> numP */ |\n"
1083                         "/* Pointer Add: BB x ref x int --> ref */   |\n"
1084                         "/* Pointer Add: BB x int x ref --> ref */");
1085         );
1086         return 1;
1087 }
1088
1089 /**
1090  * verify a Sub node
1091  */
1092 static int verify_node_Sub(const ir_node *n)
1093 {
1094         ir_mode *mymode  = get_irn_mode(n);
1095         ir_mode *op1mode = get_irn_mode(get_Sub_left(n));
1096         ir_mode *op2mode = get_irn_mode(get_Sub_right(n));
1097
1098         ASSERT_AND_RET_DBG(
1099                 (
1100                         /* common Sub: BB x numP x numP --> numP */
1101                         (mymode ==op1mode && mymode == op2mode && mode_is_data(op1mode)) ||
1102                         /* Pointer Sub: BB x ref x int --> ref */
1103                         (op1mode == mymode && mode_is_int(op2mode) && mode_is_reference(mymode)) ||
1104                         /* Pointer Sub: BB x ref x ref --> int */
1105                         (op1mode == op2mode && mode_is_reference(op2mode) && mode_is_int(mymode))
1106                 ),
1107                 "Sub node", 0,
1108                 show_binop_failure(n, "/* common Sub: BB x numP x numP --> numP */ |\n"
1109                         "/* Pointer Sub: BB x ref x int --> ref */   |\n"
1110                         "/* Pointer Sub: BB x ref x ref --> int */" );
1111                 );
1112         return 1;
1113 }
1114
1115 /**
1116  * verify a Minus node
1117  */
1118 static int verify_node_Minus(const ir_node *n)
1119 {
1120         ir_mode *mymode  = get_irn_mode(n);
1121         ir_mode *op1mode = get_irn_mode(get_Minus_op(n));
1122
1123         ASSERT_AND_RET_DBG(
1124                 /* Minus: BB x num --> num */
1125                 op1mode == mymode && mode_is_num(op1mode), "Minus node", 0,
1126                 show_unop_failure(n , "/* Minus: BB x num --> num */");
1127         );
1128         return 1;
1129 }
1130
1131 /**
1132  * verify a Mul node
1133  */
1134 static int verify_node_Mul(const ir_node *n)
1135 {
1136         ir_mode *mymode  = get_irn_mode(n);
1137         ir_mode *op1mode = get_irn_mode(get_Mul_left(n));
1138         ir_mode *op2mode = get_irn_mode(get_Mul_right(n));
1139
1140         ASSERT_AND_RET_DBG(
1141                 (
1142                         /* Mul: BB x int_n x int_n --> int_n|int_2n */
1143                         (mode_is_int(op1mode)   && op2mode == op1mode && mode_is_int(mymode) &&
1144                          (op1mode == mymode || get_mode_size_bits(op1mode) * 2 == get_mode_size_bits(mymode))) ||
1145                         /* Mul: BB x float x float --> float */
1146                         (mode_is_float(op1mode) && op2mode == op1mode && mymode == op1mode)
1147                 ),
1148                 "Mul node",0,
1149                 show_binop_failure(n, "/* Mul: BB x int_n x int_n --> int_n|int_2n */ |\n"
1150                 "/* Mul: BB x float x float --> float */");
1151         );
1152         return 1;
1153 }
1154
1155 /**
1156  * verify a Mulh node
1157  */
1158 static int verify_node_Mulh(const ir_node *n)
1159 {
1160         ir_mode *mymode  = get_irn_mode(n);
1161         ir_mode *op1mode = get_irn_mode(get_Mulh_left(n));
1162         ir_mode *op2mode = get_irn_mode(get_Mulh_right(n));
1163
1164         ASSERT_AND_RET_DBG(
1165                 (
1166                         /* Mulh: BB x int x int --> int */
1167                         (mode_is_int(op1mode) && op2mode == op1mode && op1mode == mymode)
1168                 ),
1169                 "Mulh node",0,
1170                 show_binop_failure(n, "/* Mulh: BB x int x int --> int */");
1171         );
1172         return 1;
1173 }
1174
1175 /**
1176  * verify a Div node
1177  */
1178 static int verify_node_Div(const ir_node *n)
1179 {
1180         ir_mode *mymode  = get_irn_mode(n);
1181         ir_mode *op1mode = get_irn_mode(get_Div_mem(n));
1182         ir_mode *op2mode = get_irn_mode(get_Div_left(n));
1183         ir_mode *op3mode = get_irn_mode(get_Div_right(n));
1184         ir_mode *resmode = get_Div_resmode(n);
1185
1186         ASSERT_AND_RET(
1187                 /* Div: BB x M x num x num --> M x X x num */
1188                 op1mode == mode_M    &&
1189                 op2mode == resmode   &&
1190                 op3mode == resmode   &&
1191                 mode_is_num(resmode) &&
1192                 mymode == mode_T,
1193                 "Div node", 0
1194                 );
1195         return 1;
1196 }
1197
1198 /**
1199  * verify a Mod node
1200  */
1201 static int verify_node_Mod(const ir_node *n)
1202 {
1203         ir_mode *mymode  = get_irn_mode(n);
1204         ir_mode *op1mode = get_irn_mode(get_Mod_mem(n));
1205         ir_mode *op2mode = get_irn_mode(get_Mod_left(n));
1206         ir_mode *op3mode = get_irn_mode(get_Mod_right(n));
1207         ir_mode *resmode = get_Mod_resmode(n);
1208
1209         ASSERT_AND_RET(
1210                 /* Mod: BB x M x int x int --> M x X x int */
1211                 op1mode == mode_M    &&
1212                 op2mode == resmode   &&
1213                 op3mode == resmode   &&
1214                 mode_is_int(resmode) &&
1215                 mymode == mode_T,
1216                 "Mod node", 0
1217                 );
1218         return 1;
1219 }
1220
1221 /**
1222  * verify a logical And, Or, Eor node
1223  */
1224 static int verify_node_Logic(const ir_node *n)
1225 {
1226         ir_mode *mymode  = get_irn_mode(n);
1227         ir_mode *op1mode = get_irn_mode(get_binop_left(n));
1228         ir_mode *op2mode = get_irn_mode(get_binop_right(n));
1229
1230         ASSERT_AND_RET_DBG(
1231                 /* And or Or or Eor: BB x int x int --> int */
1232                 (mode_is_int(mymode) || mode_is_reference(mymode) || mymode == mode_b) &&
1233                 op2mode == op1mode &&
1234                 mymode == op2mode,
1235                 "And, Or or Eor node", 0,
1236                 show_binop_failure(n, "/* And or Or or Eor: BB x int x int --> int */");
1237         );
1238         return 1;
1239 }
1240
1241 static int verify_node_And(const ir_node *n)
1242 {
1243         return verify_node_Logic(n);
1244 }
1245
1246 static int verify_node_Or(const ir_node *n)
1247 {
1248         return verify_node_Logic(n);
1249 }
1250
1251 static int verify_node_Eor(const ir_node *n)
1252 {
1253         return verify_node_Logic(n);
1254 }
1255
1256 /**
1257  * verify a Not node
1258  */
1259 static int verify_node_Not(const ir_node *n)
1260 {
1261         ir_mode *mymode  = get_irn_mode(n);
1262         ir_mode *op1mode = get_irn_mode(get_Not_op(n));
1263
1264         ASSERT_AND_RET_DBG(
1265                 /* Not: BB x int --> int */
1266                 (mode_is_int(mymode) || mymode == mode_b) &&
1267                 mymode == op1mode,
1268                 "Not node", 0,
1269                 show_unop_failure(n, "/* Not: BB x int --> int */");
1270         );
1271         return 1;
1272 }
1273
1274 /**
1275  * verify a Cmp node
1276  */
1277 static int verify_node_Cmp(const ir_node *n)
1278 {
1279         ir_mode *mymode  = get_irn_mode(n);
1280         ir_mode *op1mode = get_irn_mode(get_Cmp_left(n));
1281         ir_mode *op2mode = get_irn_mode(get_Cmp_right(n));
1282
1283         ASSERT_AND_RET_DBG(
1284                 /* Cmp: BB x datab x datab --> b16 */
1285                 mode_is_datab(op1mode) &&
1286                 op2mode == op1mode &&
1287                 mymode == mode_b,
1288                 "Cmp node", 0,
1289                 show_binop_failure(n, "/* Cmp: BB x datab x datab --> b16 */");
1290         );
1291         return 1;
1292 }
1293
1294 /**
1295  * verify a Shift node
1296  */
1297 static int verify_node_Shift(const ir_node *n)
1298 {
1299         ir_mode *mymode  = get_irn_mode(n);
1300         ir_mode *op1mode = get_irn_mode(get_binop_left(n));
1301         ir_mode *op2mode = get_irn_mode(get_binop_right(n));
1302
1303         ASSERT_AND_RET_DBG(
1304                 /* Shl, Shr or Shrs: BB x int x int_u --> int */
1305                 mode_is_int(op1mode) &&
1306                 mode_is_int(op2mode) &&
1307                 !mode_is_signed(op2mode) &&
1308                 mymode == op1mode,
1309                 "Shl, Shr or Shrs node", 0,
1310                 show_binop_failure(n, "/* Shl, Shr or Shrs: BB x int x int_u --> int */");
1311         );
1312         return 1;
1313 }
1314
1315 static int verify_node_Shl(const ir_node *n)
1316 {
1317         return verify_node_Shift(n);
1318 }
1319
1320 static int verify_node_Shr(const ir_node *n)
1321 {
1322         return verify_node_Shift(n);
1323 }
1324
1325 static int verify_node_Shrs(const ir_node *n)
1326 {
1327         return verify_node_Shift(n);
1328 }
1329
1330 /**
1331  * verify a Rotl node
1332  */
1333 static int verify_node_Rotl(const ir_node *n)
1334 {
1335         ir_mode *mymode  = get_irn_mode(n);
1336         ir_mode *op1mode = get_irn_mode(get_Rotl_left(n));
1337         ir_mode *op2mode = get_irn_mode(get_Rotl_right(n));
1338
1339         ASSERT_AND_RET_DBG(
1340                 /* Rotl: BB x int x int --> int */
1341                 mode_is_int(op1mode) &&
1342                 mode_is_int(op2mode) &&
1343                 mymode == op1mode,
1344                 "Rotl node", 0,
1345                 show_binop_failure(n, "/* Rotl: BB x int x int --> int */");
1346         );
1347         return 1;
1348 }
1349
1350 /**
1351  * verify a Conv node
1352  */
1353 static int verify_node_Conv(const ir_node *n)
1354 {
1355         ir_mode *mymode  = get_irn_mode(n);
1356         ir_mode *op1mode = get_irn_mode(get_Conv_op(n));
1357
1358         ASSERT_AND_RET_DBG(mode_is_data(op1mode) && mode_is_data(mymode),
1359                 "Conv node", 0,
1360                 show_unop_failure(n, "/* Conv: BB x data --> data */");
1361         );
1362         return 1;
1363 }
1364
1365 /**
1366  * verify a Phi node
1367  */
1368 static int verify_node_Phi(const ir_node *n)
1369 {
1370         ir_mode *mymode = get_irn_mode(n);
1371         ir_node *block  = get_nodes_block(n);
1372         int i;
1373
1374         /* a Phi node MUST have the same number of inputs as its block
1375          * Exception is a phi with 0 inputs which is used when (re)constructing the
1376          * SSA form */
1377         if (! is_Bad(block)
1378             && !irg_is_constrained(get_irn_irg(n), IR_GRAPH_CONSTRAINT_CONSTRUCTION)
1379             && get_irn_arity(n) > 0) {
1380                 ASSERT_AND_RET_DBG(
1381                         get_irn_arity(n) == get_irn_arity(block),
1382                         "wrong number of inputs in Phi node", 0,
1383                         show_phi_inputs(n, block);
1384                 );
1385         }
1386
1387         /* Phi: BB x dataM^n --> dataM */
1388         for (i = get_Phi_n_preds(n) - 1; i >= 0; --i) {
1389                 ir_node *pred = get_Phi_pred(n, i);
1390                 ASSERT_AND_RET_DBG(get_irn_mode(pred) == mymode,
1391                                    "Phi node", 0, show_phi_failure(n, pred, i);
1392                 );
1393         }
1394         ASSERT_AND_RET(mode_is_dataM(mymode) || mymode == mode_b, "Phi node", 0 );
1395
1396         return 1;
1397 }
1398
1399 /**
1400  * verify a Load node
1401  */
1402 static int verify_node_Load(const ir_node *n)
1403 {
1404         ir_graph *irg     = get_irn_irg(n);
1405         ir_mode  *mymode  = get_irn_mode(n);
1406         ir_mode  *op1mode = get_irn_mode(get_Load_mem(n));
1407         ir_mode  *op2mode = get_irn_mode(get_Load_ptr(n));
1408
1409         ASSERT_AND_RET(op1mode == mode_M, "Load node", 0);
1410         if (!irg_is_constrained(irg, IR_GRAPH_CONSTRAINT_BACKEND)) {
1411                 ASSERT_AND_RET(mode_is_reference(op2mode), "Load node", 0 );
1412         }
1413         ASSERT_AND_RET( mymode == mode_T, "Load node", 0 );
1414
1415         return 1;
1416 }
1417
1418 /**
1419  * verify a Store node
1420  */
1421 static int verify_node_Store(const ir_node *n)
1422 {
1423         ir_graph  *irg = get_irn_irg(n);
1424
1425         ir_mode *mymode  = get_irn_mode(n);
1426         ir_mode *op1mode = get_irn_mode(get_Store_mem(n));
1427         ir_mode *op2mode = get_irn_mode(get_Store_ptr(n));
1428         ir_mode *op3mode = get_irn_mode(get_Store_value(n));
1429
1430         ASSERT_AND_RET(op1mode == mode_M && mode_is_datab(op3mode), "Store node", 0 );
1431         if (!irg_is_constrained(irg, IR_GRAPH_CONSTRAINT_BACKEND)) {
1432                 ASSERT_AND_RET(mode_is_reference(op2mode), "Store node", 0 );
1433         }
1434         ASSERT_AND_RET(mymode == mode_T, "Store node", 0);
1435
1436         return 1;
1437 }
1438
1439 /**
1440  * verify an Alloc node
1441  */
1442 static int verify_node_Alloc(const ir_node *n)
1443 {
1444         ir_mode *mymode  = get_irn_mode(n);
1445         ir_mode *op1mode = get_irn_mode(get_Alloc_mem(n));
1446         ir_mode *op2mode = get_irn_mode(get_Alloc_count(n));
1447
1448         ASSERT_AND_RET_DBG(
1449                 /* Alloc: BB x M x int_u --> M x X x ref */
1450                 op1mode == mode_M &&
1451                 mode_is_int(op2mode) &&
1452                 !mode_is_signed(op2mode) &&
1453                 mymode == mode_T,
1454                 "Alloc node", 0,
1455                 show_node_failure(n);
1456         );
1457         return 1;
1458 }
1459
1460 /**
1461  * verify a Free node
1462  */
1463 static int verify_node_Free(const ir_node *n)
1464 {
1465         ir_mode *mymode  = get_irn_mode(n);
1466         ir_mode *op1mode = get_irn_mode(get_Free_mem(n));
1467         ir_mode *op2mode = get_irn_mode(get_Free_ptr(n));
1468         ir_mode *op3mode = get_irn_mode(get_Free_count(n));
1469
1470         ASSERT_AND_RET_DBG(
1471                 /* Free: BB x M x ref x int_u --> M */
1472                 op1mode == mode_M && mode_is_reference(op2mode) &&
1473                 mode_is_int(op3mode) &&
1474                 !mode_is_signed(op3mode) &&
1475                 mymode == mode_M,
1476                 "Free node", 0,
1477                 show_triop_failure(n, "/* Free: BB x M x ref x int_u --> M */");
1478         );
1479         return 1;
1480 }
1481
1482 /**
1483  * verify a Sync node
1484  */
1485 static int verify_node_Sync(const ir_node *n)
1486 {
1487         int i;
1488         ir_mode *mymode  = get_irn_mode(n);
1489
1490         /* Sync: BB x M^n --> M */
1491         for (i = get_Sync_n_preds(n) - 1; i >= 0; --i) {
1492                 ASSERT_AND_RET( get_irn_mode(get_Sync_pred(n, i)) == mode_M, "Sync node", 0 );
1493         }
1494         ASSERT_AND_RET( mymode == mode_M, "Sync node", 0 );
1495         return 1;
1496 }
1497
1498 /**
1499  * verify a Confirm node
1500  */
1501 static int verify_node_Confirm(const ir_node *n)
1502 {
1503         ir_mode *mymode  = get_irn_mode(n);
1504         ir_mode *op1mode = get_irn_mode(get_Confirm_value(n));
1505         ir_mode *op2mode = get_irn_mode(get_Confirm_bound(n));
1506
1507         ASSERT_AND_RET_DBG(
1508                 /* Confirm: BB x T x T --> T */
1509                 op1mode == mymode &&
1510                 op2mode == mymode,
1511                 "Confirm node", 0,
1512                 show_binop_failure(n, "/* Confirm: BB x T x T --> T */");
1513         );
1514         return 1;
1515 }
1516
1517 /**
1518  * verify a Mux node
1519  */
1520 static int verify_node_Mux(const ir_node *n)
1521 {
1522         ir_mode *mymode  = get_irn_mode(n);
1523         ir_mode *op1mode = get_irn_mode(get_Mux_sel(n));
1524         ir_mode *op2mode = get_irn_mode(get_Mux_true(n));
1525         ir_mode *op3mode = get_irn_mode(get_Mux_false(n));
1526
1527         ASSERT_AND_RET(
1528                 /* Mux: BB x b x datab x datab --> datab */
1529                 op1mode == mode_b &&
1530                 op2mode == mymode &&
1531                 op3mode == mymode &&
1532                 mode_is_datab(mymode),
1533                 "Mux node", 0
1534                 );
1535         return 1;
1536 }
1537
1538 /**
1539  * verify a CopyB node
1540  */
1541 static int verify_node_CopyB(const ir_node *n)
1542 {
1543         ir_graph *irg     = get_irn_irg(n);
1544         ir_mode  *mymode  = get_irn_mode(n);
1545         ir_mode  *op1mode = get_irn_mode(get_CopyB_mem(n));
1546         ir_mode  *op2mode = get_irn_mode(get_CopyB_dst(n));
1547         ir_mode  *op3mode = get_irn_mode(get_CopyB_src(n));
1548         ir_type  *t = get_CopyB_type(n);
1549
1550         /* CopyB: BB x M x ref x ref --> M x X */
1551         ASSERT_AND_RET(mymode == mode_T && op1mode == mode_M, "CopyB node", 0);
1552         if (!irg_is_constrained(irg, IR_GRAPH_CONSTRAINT_BACKEND)) {
1553                 ASSERT_AND_RET(mode_is_reference(op2mode) && mode_is_reference(op3mode),
1554                         "CopyB node", 0 );
1555         }
1556
1557         ASSERT_AND_RET(
1558                 is_compound_type(t) || is_Array_type(t),
1559                 "CopyB node should copy compound types only", 0 );
1560
1561         /* NoMem nodes are only allowed as memory input if the CopyB is NOT pinned.
1562            This should happen RARELY, as CopyB COPIES MEMORY */
1563         ASSERT_AND_RET(verify_right_pinned(n), "CopyB node with wrong memory input", 0 );
1564         return 1;
1565 }
1566
1567 /**
1568  * Check dominance.
1569  * For each usage of a node, it is checked, if the block of the
1570  * node dominates the block of the usage (for phis: the predecessor
1571  * block of the phi for the corresponding edge).
1572  *
1573  * @return non-zero on success, 0 on dominance error
1574  */
1575 static int check_dominance_for_node(const ir_node *use)
1576 {
1577         /* This won't work for blocks and the end node */
1578         if (!is_Block(use) && !is_End(use) && !is_Anchor(use)) {
1579                 int i;
1580                 ir_node *bl = get_nodes_block(use);
1581
1582                 for (i = get_irn_arity(use) - 1; i >= 0; --i) {
1583                         ir_node  *def    = get_irn_n(use, i);
1584                         ir_node  *def_bl = get_nodes_block(def);
1585                         ir_node  *use_bl = bl;
1586                         ir_graph *irg;
1587
1588                         /* we have no dominance relation for unreachable blocks, so we can't
1589                          * check the dominance property there */
1590                         if (!is_Block(def_bl) || get_Block_dom_depth(def_bl) == -1)
1591                                 continue;
1592
1593                         if (is_Phi(use)) {
1594                                 if (is_Bad(def))
1595                                         continue;
1596                                 use_bl = get_Block_cfgpred_block(bl, i);
1597                         }
1598
1599                         if (!is_Block(use_bl) || get_Block_dom_depth(use_bl) == -1)
1600                                 continue;
1601
1602                         irg = get_irn_irg(use);
1603                         ASSERT_AND_RET_DBG(
1604                                 block_dominates(def_bl, use_bl),
1605                                 "the definition of a value used violates the dominance property", 0,
1606                                 ir_fprintf(stderr,
1607                                 "graph %+F: %+F of %+F must dominate %+F of user %+F input %d\n",
1608                                 irg, def_bl, def, use_bl, use, i
1609                                 );
1610                         );
1611                 }
1612         }
1613         return 1;
1614 }
1615
1616 int irn_verify_irg(const ir_node *n, ir_graph *irg)
1617 {
1618         ir_op *op;
1619
1620         if (!get_node_verification_mode())
1621                 return 1;
1622
1623         /*
1624          * do NOT check placement in interprocedural view, as we don't always
1625          * know the "right" graph ...
1626          */
1627
1628 #ifndef NDEBUG
1629         /* this is an expensive check for large graphs (it has a quadratic
1630          * runtime but with a small constant); so do NOT run it in release mode
1631          */
1632         ASSERT_AND_RET_DBG(
1633                 node_is_in_irgs_storage(irg, n),
1634                 "Node is not stored on proper IR graph!", 0,
1635                 show_node_on_graph(irg, n);
1636         );
1637 #endif
1638         assert(get_irn_irg(n) == irg);
1639         {
1640                 unsigned idx           = get_irn_idx(n);
1641                 ir_node *node_from_map = get_idx_irn(irg, idx);
1642                 ASSERT_AND_RET_DBG(node_from_map == n, "Node index and index map entry differ", 0,
1643                         ir_printf("node %+F node in map %+F(%p)\n", n, node_from_map, node_from_map);
1644                 );
1645         }
1646
1647         op = get_irn_op(n);
1648
1649         if (get_op_pinned(op) >= op_pin_state_exc_pinned) {
1650                 op_pin_state state = get_irn_pinned(n);
1651                 ASSERT_AND_RET_DBG(
1652                         state == op_pin_state_floats ||
1653                         state == op_pin_state_pinned,
1654                         "invalid pin state", 0,
1655                         ir_printf("node %+F", n);
1656                 );
1657         } else if (!is_Block(n) && is_irn_pinned_in_irg(n)
1658                    && irg_has_properties(irg, IR_GRAPH_PROPERTY_NO_BADS)) {
1659                 ASSERT_AND_RET_DBG(is_Block(get_nodes_block(n)) || is_Anchor(n),
1660                                 "block input is not a block", 0,
1661                                 ir_printf("node %+F", n);
1662                 );
1663         }
1664
1665         ASSERT_AND_RET_DBG(
1666                 !is_irn_start_block_placed(n) || get_nodes_block(n) == get_irg_start_block(irg),
1667                 "node should be in start block", 0,
1668                 ir_printf("node %+F", n);
1669         );
1670
1671         if (op->ops.verify_node)
1672                 return op->ops.verify_node(n);
1673
1674         /* All went ok */
1675         return 1;
1676 }
1677
1678 int irn_verify(const ir_node *n)
1679 {
1680 #ifdef DEBUG_libfirm
1681         return irn_verify_irg(n, get_irn_irg(n));
1682 #else
1683         (void)n;
1684         return 1;
1685 #endif
1686 }
1687
1688 /*-----------------------------------------------------------------*/
1689 /* Verify the whole graph.                                         */
1690 /*-----------------------------------------------------------------*/
1691
1692 #ifdef DEBUG_libfirm
1693 /**
1694  * Walker to check every node
1695  */
1696 static void verify_wrap(ir_node *node, void *env)
1697 {
1698         int *res = (int*)env;
1699         *res = irn_verify_irg(node, get_irn_irg(node));
1700 }
1701
1702 /**
1703  * Walker to check every node including SSA property.
1704  * Only called if dominance info is available.
1705  */
1706 static void verify_wrap_ssa(ir_node *node, void *env)
1707 {
1708         int *res = (int*)env;
1709
1710         *res = irn_verify_irg(node, get_irn_irg(node));
1711         if (*res) {
1712                 *res = check_dominance_for_node(node);
1713         }
1714 }
1715
1716 #endif /* DEBUG_libfirm */
1717
1718 typedef struct check_cfg_env_t {
1719         pmap *branch_nodes; /**< map blocks to their branching nodes,
1720                                  map mode_X nodes to the blocks they branch to */
1721         int   res;
1722         ir_nodeset_t reachable_blocks;
1723         ir_nodeset_t kept_nodes;
1724         ir_nodeset_t true_projs;
1725         ir_nodeset_t false_projs;
1726 } check_cfg_env_t;
1727
1728 static int check_block_cfg(const ir_node *block, check_cfg_env_t *env)
1729 {
1730         pmap *branch_nodes;
1731         int   n_cfgpreds;
1732         int   i;
1733
1734         ASSERT_AND_RET_DBG(ir_nodeset_contains(&env->reachable_blocks, block),
1735                            "Block is not reachable by blockwalker (endless loop with no kept block?)", 0,
1736                            ir_printf("block %+F\n", block);
1737         );
1738
1739         n_cfgpreds   = get_Block_n_cfgpreds(block);
1740         branch_nodes = env->branch_nodes;
1741         for (i = 0; i < n_cfgpreds; ++i) {
1742                 /* check that each mode_X node is only connected
1743                  * to 1 user */
1744                 ir_node *branch = get_Block_cfgpred(block, i);
1745                 ir_node *former_dest;
1746                 ir_node *former_branch;
1747                 ir_node *branch_proj;
1748                 ir_node *branch_block;
1749                 branch = skip_Tuple(branch);
1750                 if (is_Bad(branch))
1751                         continue;
1752                 former_dest = pmap_get(ir_node, branch_nodes, branch);
1753                 ASSERT_AND_RET_DBG(former_dest==NULL || is_unknown_jump(skip_Proj(branch)),
1754                                                    "Multiple users on mode_X node", 0,
1755                                                    ir_printf("node %+F\n", branch);
1756                 );
1757                 pmap_insert(branch_nodes, branch, (void*)block);
1758
1759                 /* check that there's only 1 branching instruction in each block */
1760                 branch_block = get_nodes_block(branch);
1761                 branch_proj  = branch;
1762                 if (is_Proj(branch)) {
1763                         branch = skip_Proj(branch);
1764                 }
1765                 former_branch = pmap_get(ir_node, branch_nodes, branch_block);
1766
1767                 ASSERT_AND_RET_DBG(former_branch == NULL || former_branch == branch,
1768                                                    "Multiple branching nodes in a block", 0,
1769                                                    ir_printf("nodes %+F,%+F in block %+F\n",
1770                                                                          branch, former_branch, branch_block);
1771                 );
1772                 pmap_insert(branch_nodes, branch_block, branch);
1773
1774                 if (is_Cond(branch)) {
1775                         long pn = get_Proj_proj(branch_proj);
1776                         if (pn == pn_Cond_true)
1777                                 ir_nodeset_insert(&env->true_projs, branch);
1778                         if (pn == pn_Cond_false)
1779                                 ir_nodeset_insert(&env->false_projs, branch);
1780                 } else if (is_Switch(branch)) {
1781                         long pn = get_Proj_proj(branch_proj);
1782                         if (pn == pn_Switch_default)
1783                                 ir_nodeset_insert(&env->true_projs, branch);
1784                 }
1785         }
1786
1787         return 1;
1788 }
1789
1790 static void check_cfg_walk_func(ir_node *node, void *data)
1791 {
1792         check_cfg_env_t *env = (check_cfg_env_t*)data;
1793         if (!is_Block(node))
1794                 return;
1795         env->res &= check_block_cfg(node, env);
1796 }
1797
1798 static int verify_block_branch(const ir_node *block, check_cfg_env_t *env)
1799 {
1800         ir_node *branch = pmap_get(ir_node, env->branch_nodes, block);
1801         ASSERT_AND_RET_DBG(branch != NULL
1802                            || ir_nodeset_contains(&env->kept_nodes, block)
1803                            || block == get_irg_end_block(get_irn_irg(block)),
1804                            "block contains no cfop", 0,
1805                            ir_printf("block %+F\n", block);
1806         );
1807         return 1;
1808 }
1809
1810 static int verify_cond_projs(const ir_node *cond, check_cfg_env_t *env)
1811 {
1812         ASSERT_AND_RET_DBG(ir_nodeset_contains(&env->true_projs, cond),
1813                                            "Cond node lacks true proj", 0,
1814                                            ir_printf("Cond %+F\n", cond);
1815         );
1816         ASSERT_AND_RET_DBG(ir_nodeset_contains(&env->false_projs, cond),
1817                                            "Cond node lacks false proj", 0,
1818                                            ir_printf("Cond %+F\n", cond);
1819         );
1820         return 1;
1821 }
1822
1823 static int verify_switch_projs(const ir_node *sw, check_cfg_env_t *env)
1824 {
1825         ASSERT_AND_RET_DBG(ir_nodeset_contains(&env->true_projs, sw),
1826                                            "Switch node lacks default Proj", 0,
1827                                            ir_printf("Switch %+F\n", sw);
1828         );
1829         return 1;
1830 }
1831
1832 static void assert_branch(ir_node *node, void *data)
1833 {
1834         check_cfg_env_t *env = (check_cfg_env_t*)data;
1835         if (is_Block(node)) {
1836                 env->res &= verify_block_branch(node, env);
1837         } else if (is_Cond(node)) {
1838                 env->res &= verify_cond_projs(node, env);
1839         } else if (is_Switch(node)) {
1840                 env->res &= verify_switch_projs(node, env);
1841         }
1842 }
1843
1844 static void collect_reachable_blocks(ir_node *block, void *data)
1845 {
1846         ir_nodeset_t *reachable_blocks = (ir_nodeset_t*) data;
1847         ir_nodeset_insert(reachable_blocks, block);
1848 }
1849
1850 /**
1851  * Checks CFG well-formedness
1852  */
1853 static int check_cfg(ir_graph *irg)
1854 {
1855         check_cfg_env_t env;
1856         env.branch_nodes = pmap_create(); /**< map blocks to branch nodes */
1857         env.res          = 1;
1858         ir_nodeset_init(&env.reachable_blocks);
1859         ir_nodeset_init(&env.true_projs);
1860         ir_nodeset_init(&env.false_projs);
1861
1862         irg_block_walk_graph(irg, collect_reachable_blocks, NULL,
1863                              &env.reachable_blocks);
1864
1865         /* note that we do not use irg_walk_block because it will miss these
1866          * invalid blocks without a jump instruction which we want to detect
1867          * here */
1868         irg_walk_graph(irg, check_cfg_walk_func, NULL, &env);
1869
1870         ir_nodeset_init(&env.kept_nodes);
1871         {
1872                 ir_node *end   = get_irg_end(irg);
1873                 int      arity = get_irn_arity(end);
1874                 int      i;
1875                 for (i = 0; i < arity; ++i) {
1876                         ir_node *n = get_irn_n(end, i);
1877                         ir_nodeset_insert(&env.kept_nodes, n);
1878                 }
1879         }
1880         irg_walk_graph(irg, assert_branch, NULL, &env);
1881
1882         ir_nodeset_destroy(&env.false_projs);
1883         ir_nodeset_destroy(&env.true_projs);
1884         ir_nodeset_destroy(&env.kept_nodes);
1885         ir_nodeset_destroy(&env.reachable_blocks);
1886         pmap_destroy(env.branch_nodes);
1887         return env.res;
1888 }
1889
1890 int irg_verify(ir_graph *irg, unsigned flags)
1891 {
1892         int res = 1;
1893 #ifdef DEBUG_libfirm
1894         int pinned = get_irg_pinned(irg) == op_pin_state_pinned;
1895
1896 #ifndef NDEBUG
1897         last_irg_error = NULL;
1898 #endif /* NDEBUG */
1899
1900         if (pinned && !check_cfg(irg))
1901                 res = 0;
1902
1903         if (res == 1 && (flags & VERIFY_ENFORCE_SSA) && pinned)
1904                 compute_doms(irg);
1905
1906         irg_walk_anchors(
1907                 irg,
1908                 pinned && irg_has_properties(irg, IR_GRAPH_PROPERTY_CONSISTENT_DOMINANCE)
1909                         ? verify_wrap_ssa : verify_wrap,
1910                 NULL,
1911                 &res
1912         );
1913
1914         if (get_node_verification_mode() == FIRM_VERIFICATION_REPORT && ! res) {
1915                 ir_entity *ent = get_irg_entity(irg);
1916
1917                 if (ent)
1918                         fprintf(stderr, "irg_verify: Verifying graph %s failed\n", get_entity_name(ent));
1919                 else
1920                         fprintf(stderr, "irg_verify: Verifying graph %p failed\n", (void *)irg);
1921         }
1922
1923 #else
1924         (void)irg;
1925         (void)flags;
1926 #endif /* DEBUG_libfirm */
1927
1928         return res;
1929 }
1930
1931 typedef struct pass_t {
1932         ir_graph_pass_t pass;
1933         unsigned        flags;
1934 } pass_t;
1935
1936 /**
1937  * Wrapper to irg_verify to be run as an ir_graph pass.
1938  */
1939 static int irg_verify_wrapper(ir_graph *irg, void *context)
1940 {
1941         pass_t *pass = (pass_t*)context;
1942         irg_verify(irg, pass->flags);
1943         /* do NOT rerun the pass if verify is ok :-) */
1944         return 0;
1945 }
1946
1947 ir_graph_pass_t *irg_verify_pass(const char *name, unsigned flags)
1948 {
1949         pass_t *pass = XMALLOCZ(pass_t);
1950
1951         def_graph_pass_constructor(
1952                 &pass->pass, name ? name : "irg_verify", irg_verify_wrapper);
1953
1954         /* neither dump for verify */
1955         pass->pass.dump_irg   = (DUMP_ON_IRG_FUNC)ir_prog_no_dump;
1956         pass->pass.verify_irg = (RUN_ON_IRG_FUNC)ir_prog_no_verify;
1957
1958         pass->flags = flags;
1959         return &pass->pass;
1960 }
1961
1962 int irn_verify_irg_dump(const ir_node *n, ir_graph *irg,
1963                         const char **bad_string)
1964 {
1965         int res;
1966         firm_verification_t old = get_node_verification_mode();
1967
1968         firm_verify_failure_msg = NULL;
1969         do_node_verification(FIRM_VERIFICATION_ERROR_ONLY);
1970         res = irn_verify_irg(n, irg);
1971         if (res && irg_has_properties(irg, IR_GRAPH_PROPERTY_CONSISTENT_DOMINANCE) &&
1972             get_irg_pinned(irg) == op_pin_state_pinned)
1973                 res = check_dominance_for_node(n);
1974         do_node_verification(old);
1975         *bad_string = firm_verify_failure_msg;
1976
1977         return res;
1978 }
1979
1980 typedef struct verify_bad_env_t {
1981         int flags;
1982         int res;
1983 } verify_bad_env_t;
1984
1985 /**
1986  * Pre-Walker: check Bad predecessors of node.
1987  */
1988 static void check_bads(ir_node *node, void *env)
1989 {
1990         verify_bad_env_t *venv = (verify_bad_env_t*)env;
1991         int i, arity = get_irn_arity(node);
1992         ir_graph *irg = get_irn_irg(node);
1993
1994         if (is_Block(node)) {
1995                 if ((venv->flags & BAD_CF) == 0) {
1996
1997                         /* check for Bad Block predecessor */
1998                         for (i = 0; i < arity; ++i) {
1999                                 ir_node *pred = get_irn_n(node, i);
2000
2001                                 if (is_Bad(pred)) {
2002                                         venv->res |= BAD_CF;
2003
2004                                         if (get_node_verification_mode() == FIRM_VERIFICATION_REPORT) {
2005                                                 fprintf(stderr, "irg_verify_bads: Block %ld has Bad predecessor\n", get_irn_node_nr(node));
2006                                         }
2007                                         if (get_node_verification_mode() == FIRM_VERIFICATION_ON) {
2008                                                 dump_ir_graph(irg, "assert");
2009                                                 assert(0 && "Bad CF detected");
2010                                         }
2011                                 }
2012                         }
2013                 }
2014         } else {
2015                 if ((venv->flags & BAD_BLOCK) == 0) {
2016
2017                         /* check for Bad Block */
2018                         if (is_Bad(get_nodes_block(node))) {
2019                                 venv->res |= BAD_BLOCK;
2020
2021                                 if (get_node_verification_mode() == FIRM_VERIFICATION_REPORT) {
2022                                         fprintf(stderr, "irg_verify_bads: node %ld has Bad Block\n", get_irn_node_nr(node));
2023                                 }
2024                                 if (get_node_verification_mode() == FIRM_VERIFICATION_ON) {
2025                                         dump_ir_graph(irg, "assert");
2026                                         assert(0 && "Bad CF detected");
2027                                 }
2028                         }
2029                 }
2030
2031                 if ((venv->flags & TUPLE) == 0) {
2032                         if (is_Tuple(node)) {
2033                                 venv->res |= TUPLE;
2034
2035                                 if (get_node_verification_mode() == FIRM_VERIFICATION_REPORT) {
2036                                         fprintf(stderr, "irg_verify_bads: node %ld is a Tuple\n", get_irn_node_nr(node));
2037                                 }
2038                                 if (get_node_verification_mode() == FIRM_VERIFICATION_ON) {
2039                                         dump_ir_graph(irg, "assert");
2040                                         assert(0 && "Tuple detected");
2041                                 }
2042                         }
2043                 }
2044
2045                 for (i = 0; i < arity; ++i) {
2046                         ir_node *pred = get_irn_n(node, i);
2047
2048                         if (is_Bad(pred)) {
2049                                 /* check for Phi with Bad inputs */
2050                                 if (is_Phi(node) && !is_Bad(get_nodes_block(node)) && is_Bad(get_irn_n(get_nodes_block(node), i))) {
2051                                         if (venv->flags & BAD_CF)
2052                                                 continue;
2053                                         else {
2054                                                 venv->res |= BAD_CF;
2055
2056                                                 if (get_node_verification_mode() == FIRM_VERIFICATION_REPORT) {
2057                                                         fprintf(stderr, "irg_verify_bads: Phi %ld has Bad Input\n", get_irn_node_nr(node));
2058                                                 }
2059                                                 if (get_node_verification_mode() == FIRM_VERIFICATION_ON) {
2060                                                         dump_ir_graph(irg, "assert");
2061                                                         assert(0 && "Bad CF detected");
2062                                                 }
2063                                         }
2064                                 }
2065
2066                                 /* Bad node input */
2067                                 if ((venv->flags & BAD_DF) == 0) {
2068                                         venv->res |= BAD_DF;
2069
2070                                         if (get_node_verification_mode() == FIRM_VERIFICATION_REPORT) {
2071                                                 fprintf(stderr, "irg_verify_bads: node %ld has Bad Input\n", get_irn_node_nr(node));
2072                                         }
2073                                         if (get_node_verification_mode() == FIRM_VERIFICATION_ON) {
2074                                                 dump_ir_graph(irg, "assert");
2075                                                 assert(0 && "Bad NON-CF detected");
2076                                         }
2077                                 }
2078                         }
2079                 }
2080         }
2081 }
2082
2083 int irg_verify_bads(ir_graph *irg, int flags)
2084 {
2085         verify_bad_env_t env;
2086
2087         env.flags = flags;
2088         env.res   = 0;
2089
2090         irg_walk_graph(irg, check_bads, NULL, &env);
2091
2092         return env.res;
2093 }
2094
2095 static void register_verify_node_func(ir_op *op, verify_node_func func)
2096 {
2097         op->ops.verify_node = func;
2098 }
2099
2100 static void register_verify_node_func_proj(ir_op *op, verify_node_func func)
2101 {
2102         op->ops.verify_proj_node = func;
2103 }
2104
2105 void ir_register_verify_node_ops(void)
2106 {
2107         register_verify_node_func(op_Add,      verify_node_Add);
2108         register_verify_node_func(op_Alloc,    verify_node_Alloc);
2109         register_verify_node_func(op_And,      verify_node_And);
2110         register_verify_node_func(op_Block,    verify_node_Block);
2111         register_verify_node_func(op_Call,     verify_node_Call);
2112         register_verify_node_func(op_Cmp,      verify_node_Cmp);
2113         register_verify_node_func(op_Cond,     verify_node_Cond);
2114         register_verify_node_func(op_Confirm,  verify_node_Confirm);
2115         register_verify_node_func(op_Const,    verify_node_Const);
2116         register_verify_node_func(op_Conv,     verify_node_Conv);
2117         register_verify_node_func(op_CopyB,    verify_node_CopyB);
2118         register_verify_node_func(op_Div,      verify_node_Div);
2119         register_verify_node_func(op_Eor,      verify_node_Eor);
2120         register_verify_node_func(op_Free,     verify_node_Free);
2121         register_verify_node_func(op_IJmp,     verify_node_IJmp);
2122         register_verify_node_func(op_InstOf,   verify_node_InstOf);
2123         register_verify_node_func(op_Jmp,      verify_node_Jmp);
2124         register_verify_node_func(op_Load,     verify_node_Load);
2125         register_verify_node_func(op_Minus,    verify_node_Minus);
2126         register_verify_node_func(op_Mod,      verify_node_Mod);
2127         register_verify_node_func(op_Mul,      verify_node_Mul);
2128         register_verify_node_func(op_Mulh,     verify_node_Mulh);
2129         register_verify_node_func(op_Mux,      verify_node_Mux);
2130         register_verify_node_func(op_Not,      verify_node_Not);
2131         register_verify_node_func(op_Or,       verify_node_Or);
2132         register_verify_node_func(op_Phi,      verify_node_Phi);
2133         register_verify_node_func(op_Proj,     verify_node_Proj);
2134         register_verify_node_func(op_Raise,    verify_node_Raise);
2135         register_verify_node_func(op_Return,   verify_node_Return);
2136         register_verify_node_func(op_Rotl,     verify_node_Rotl);
2137         register_verify_node_func(op_Sel,      verify_node_Sel);
2138         register_verify_node_func(op_Shl,      verify_node_Shl);
2139         register_verify_node_func(op_Shr,      verify_node_Shr);
2140         register_verify_node_func(op_Shrs,     verify_node_Shrs);
2141         register_verify_node_func(op_Start,    verify_node_Start);
2142         register_verify_node_func(op_Store,    verify_node_Store);
2143         register_verify_node_func(op_Sub,      verify_node_Sub);
2144         register_verify_node_func(op_Switch,   verify_node_Switch);
2145         register_verify_node_func(op_SymConst, verify_node_SymConst);
2146         register_verify_node_func(op_Sync,     verify_node_Sync);
2147
2148         register_verify_node_func_proj(op_Alloc,  verify_node_Proj_Alloc);
2149         register_verify_node_func_proj(op_Call,   verify_node_Proj_Call);
2150         register_verify_node_func_proj(op_Cond,   verify_node_Proj_Cond);
2151         register_verify_node_func_proj(op_CopyB,  verify_node_Proj_CopyB);
2152         register_verify_node_func_proj(op_Div,    verify_node_Proj_Div);
2153         register_verify_node_func_proj(op_InstOf, verify_node_Proj_InstOf);
2154         register_verify_node_func_proj(op_Load,   verify_node_Proj_Load);
2155         register_verify_node_func_proj(op_Mod,    verify_node_Proj_Mod);
2156         register_verify_node_func_proj(op_Proj,   verify_node_Proj_Proj);
2157         register_verify_node_func_proj(op_Raise,  verify_node_Proj_Raise);
2158         register_verify_node_func_proj(op_Start,  verify_node_Proj_Start);
2159         register_verify_node_func_proj(op_Store,  verify_node_Proj_Store);
2160         register_verify_node_func_proj(op_Switch, verify_node_Proj_Switch);
2161         register_verify_node_func_proj(op_Tuple,  verify_node_Proj_Tuple);
2162 }