bugfix
[libfirm] / ir / ir / irvrfy.c
1 /*
2  * Project:     libFIRM
3  * File name:   ir/ir/irvrfy.c
4  * Purpose:     Check irnodes for correctness.
5  * Author:      Christian Schaefer
6  * Modified by: Goetz Lindenmaier. Till Riedel
7  * Created:
8  * CVS-ID:      $Id$
9  * Copyright:   (c) 1998-2003 Universität Karlsruhe
10  * Licence:     This file protected by GPL -  GNU GENERAL PUBLIC LICENSE.
11  */
12
13 #ifdef HAVE_CONFIG_H
14 # include "config.h"
15 #endif
16
17 # include "irprog.h"
18 # include "irgraph_t.h"
19 # include "ircgcons.h"
20 # include "irvrfy.h"
21 # include "irgwalk.h"
22 # include "irdump.h"
23
24 #ifdef NDEBUG
25 /*
26  * in RELEASE mode, returns ret if the expression expr evaluates to zero
27  * in ASSERT mode, asserts the expression expr (and the string string).
28  */
29 #define ASSERT_AND_RET(expr, string, ret)       if (!(expr)) return (ret)
30
31 /*
32  * in RELEASE mode, returns ret if the expression expr evaluates to zero
33  * in ASSERT mode, executes blk if the expression expr evaluates to zero and asserts expr
34  */
35 #define ASSERT_AND_RET_DBG(expr, string, ret, blk)      if (!(expr)) return (ret)
36 #else
37 #define ASSERT_AND_RET(expr, string, ret) \
38 do { \
39   if (opt_do_node_verification == NODE_VERIFICATION_ON) {\
40     if (!(expr) && current_ir_graph != get_const_code_irg()) \
41     dump_ir_block_graph(current_ir_graph, "-assert"); \
42     assert((expr) && string); } \
43   if (!(expr)) { \
44     if (opt_do_node_verification == NODE_VERIFICATION_REPORT) \
45       fprintf(stderr, #expr " : " string "\n"); \
46     bad_msg = #expr " && " string; \
47     return (ret); \
48   } \
49 } while(0)
50
51 #define ASSERT_AND_RET_DBG(expr, string, ret, blk) \
52 do { \
53   if (!(expr)) { \
54     bad_msg = #expr " && " string; \
55     if (opt_do_node_verification != NODE_VERIFICATION_ERROR_ONLY) { blk; } \
56     if (opt_do_node_verification == NODE_VERIFICATION_REPORT) \
57       fprintf(stderr, #expr " : " string "\n"); \
58     else if (opt_do_node_verification == NODE_VERIFICATION_ON) \
59       assert((expr) && string); \
60     return (ret); \
61   } \
62 } while(0)
63
64 #endif
65
66 /** if this flag is set, verify entity types in Load & Store nodes */
67 static int vrfy_entities = 0;
68
69 /* @@@ replace use of array "in" by access functions. */
70 ir_node **get_irn_in(ir_node *node);
71
72 static node_verification_t opt_do_node_verification = NODE_VERIFICATION_ON;
73 static const char *bad_msg;
74
75 /* enable verification of Load/Store entities */
76 void vrfy_enable_entity_tests(int enable)
77 {
78   vrfy_entities = enable;
79 }
80
81 /**
82  * little helper for NULL modes
83  */
84 static const char *get_mode_name_ex(ir_mode *mode)
85 {
86   if (! mode)
87     return "<no mode>";
88   return get_mode_name(mode);
89 }
90
91 void do_node_verification(node_verification_t mode)
92 {
93   opt_do_node_verification = mode;
94 }
95
96 /**
97  * Prints a failure for a Node
98  */
99 static void show_node_failure(ir_node *n)
100 {
101   fprintf(stderr, "\nFIRM: irn_vrfy_irg() of node %ld %s%s\n" ,
102     get_irn_node_nr(n),
103     get_irn_opname(n), get_irn_modename(n)
104   );
105 }
106
107 /**
108  * Prints a failure message for a binop
109  */
110 static void show_binop_failure(ir_node *n, const char *text)
111 {
112   ir_node *left  = get_binop_left(n);
113   ir_node *right = get_binop_right(n);
114
115   fprintf(stderr, "\nFIRM: irn_vrfy_irg() of node %ld %s%s(%s%s, %s%s) did not match (%s)\n",
116       get_irn_node_nr(n),
117       get_irn_opname(n), get_irn_modename(n),
118       get_irn_opname(left), get_irn_modename(left),
119       get_irn_opname(right), get_irn_modename(right),
120       text);
121 }
122
123 /**
124  * Prints a failure message for an unop
125  */
126 static void show_unop_failure(ir_node *n, const char *text)
127 {
128   ir_node *op  = get_unop_op(n);
129
130   fprintf(stderr, "\nFIRM: irn_vrfy_irg() of node %ld %s%s(%s%s) did not match (%s)\n",
131       get_irn_node_nr(n),
132       get_irn_opname(n), get_irn_modename(n),
133       get_irn_opname(op), get_irn_modename(op),
134       text);
135 }
136
137 /**
138  * Prints a failure message for an op with 3 operands
139  */
140 static void show_triop_failure(ir_node *n, const char *text)
141 {
142   ir_node *op0  = get_irn_n(n, 0);
143   ir_node *op1  = get_irn_n(n, 1);
144   ir_node *op2  = get_irn_n(n, 2);
145
146   fprintf(stderr, "\nFIRM: irn_vrfy_irg() of node %ld %s%s(%s%s, %s%s, %s%s) did not match (%s)\n",
147       get_irn_node_nr(n),
148       get_irn_opname(n), get_irn_modename(n),
149       get_irn_opname(op0), get_irn_modename(op0),
150       get_irn_opname(op1), get_irn_modename(op1),
151       get_irn_opname(op2), get_irn_modename(op2),
152       text);
153 }
154
155 /**
156  * Prints a failure message for a proj
157  */
158 static void show_proj_failure(ir_node *n)
159 {
160   ir_node *op  = get_Proj_pred(n);
161   int proj     = get_Proj_proj(n);
162
163   fprintf(stderr, "\nFIRM: irn_vrfy_irg() of node %ld %s%s %d(%s%s) failed\n" ,
164       get_irn_node_nr(n),
165       get_irn_opname(n), get_irn_modename(n), proj,
166       get_irn_opname(op), get_irn_modename(op));
167 }
168
169 /**
170  * Prints a failure message for a proj
171  */
172 static void show_proj_failure_ent(ir_node *n, entity *ent)
173 {
174   ir_node *op  = get_Proj_pred(n);
175   int proj     = get_Proj_proj(n);
176   ir_mode *m   = get_type_mode(get_entity_type(ent));
177
178   fprintf(stderr, "\nFIRM: irn_vrfy_irg() of node %ld %s%s %d(%s%s) entity %s(type %s mode %s)failed\n" ,
179       get_irn_node_nr(n),
180       get_irn_opname(n), get_irn_modename(n), proj,
181       get_irn_opname(op), get_irn_modename(op),
182       get_entity_name(ent), get_type_name(get_entity_type(ent)),
183       get_mode_name_ex(m));
184 }
185
186 /**
187  * Show a node and a graph
188  */
189 static void show_node_on_graph(ir_graph *irg, ir_node *n)
190 {
191   entity *ent = get_irg_entity(irg);
192
193   if (ent)
194     fprintf(stderr, "\nFIRM: irn_vrfy_irg() of entity %s, node %ld %s%s\n",
195       get_entity_name(ent),
196       get_irn_node_nr(n), get_irn_opname(n), get_irn_modename(n));
197   else
198     fprintf(stderr, "\nFIRM: irn_vrfy_irg() of graph %p, node %ld %s%s\n",
199       (void *)irg,
200       get_irn_node_nr(n), get_irn_opname(n), get_irn_modename(n));
201 }
202
203 /**
204  * Show call params
205  */
206 static void show_call_param(ir_node *n, type *mt)
207 {
208   int i;
209
210   fprintf(stderr, "\nFIRM: irn_vrfy_irg() Call type-check failed: %s(", get_type_name(mt));
211   for (i = 0; i < get_method_n_params(mt); ++i) {
212     fprintf(stderr, "%s ", get_mode_name_ex(get_type_mode(get_method_param_type(mt, i))));
213   }
214   fprintf(stderr, ") != CALL(");
215
216   for (i = 0; i < get_Call_n_params(n); ++i) {
217     fprintf(stderr, "%s ", get_mode_name_ex(get_irn_mode(get_Call_param(n, i))));
218   }
219   fprintf(stderr, ")\n");
220
221 }
222
223 /**
224  * Show return modes
225  */
226 static void show_return_modes(ir_graph *irg, ir_node *n, type *mt, int i)
227 {
228   entity *ent = get_irg_entity(irg);
229
230   fprintf(stderr, "\nFIRM: irn_vrfy_irg() Return node %ld in entity \"%s\" mode %s different from type mode %s\n",
231     get_irn_node_nr(n), get_entity_name(ent),
232     get_mode_name_ex(get_irn_mode(get_Return_res(n, i))),
233     get_mode_name_ex(get_type_mode(get_method_res_type(mt, i)))
234   );
235 }
236
237 /**
238  * Show return number of results
239  */
240 static void show_return_nres(ir_graph *irg, ir_node *n, type *mt)
241 {
242   entity *ent = get_irg_entity(irg);
243
244   fprintf(stderr, "\nFIRM: irn_vrfy_irg() Return node %ld in entity \"%s\" has %d results different from type %d\n",
245     get_irn_node_nr(n), get_entity_name(ent),
246     get_Return_n_ress(n), get_method_n_ress(mt));
247 }
248
249 /**
250  * Show Phi input
251  */
252 static void show_phi_failure(ir_node *phi, ir_node *pred, int pos)
253 {
254   fprintf(stderr, "\nFIRM: irn_vrfy_irg() Phi node %ld has mode %s different from predeccessor node %ld mode %s\n",
255     get_irn_node_nr(phi), get_mode_name_ex(get_irn_mode(phi)),
256     get_irn_node_nr(pred), get_mode_name_ex(get_irn_mode(pred)));
257 }
258
259 /**
260  * Show Phi inputs
261  */
262 static void show_phi_inputs(ir_node *phi, ir_node *block)
263 {
264   fprintf(stderr, "\nFIRM: irn_vrfy_irg() Phi node %ld has %d inputs, its Block %ld has %d\n",
265     get_irn_node_nr(phi),   get_irn_arity(phi),
266     get_irn_node_nr(block), get_irn_arity(block));
267 }
268
269 /* If the address is Sel or SymConst, return the entity. */
270 static entity *get_ptr_entity(ir_node *ptr) {
271   if (get_irn_op(ptr) == op_Sel) {
272     return get_Sel_entity(ptr);
273   } else if ((get_irn_op(ptr) == op_SymConst) && (get_SymConst_kind(ptr) == symconst_addr_ent)) {
274     return get_SymConst_entity(ptr);
275   }
276   return NULL;
277 }
278
279 /**
280  * verify the Proj number
281  */
282 static int
283 vrfy_Proj_proj(ir_node *p, ir_graph *irg) {
284   ir_node *pred;
285   ir_mode *mode;
286   int proj;
287
288   pred = skip_Id(get_Proj_pred(p));
289   ASSERT_AND_RET(get_irn_mode(pred) == mode_T, "mode of a 'projed' node is not Tuple", 0);
290   mode = get_irn_mode(p);
291   proj = get_Proj_proj(p);
292
293   switch (get_irn_opcode(pred)) {
294     case iro_Start:
295       ASSERT_AND_RET_DBG(
296           (
297            (proj == pn_Start_X_initial_exec && mode == mode_X) ||
298            (proj == pn_Start_M         && mode == mode_M) ||
299            (proj == pn_Start_P_frame_base && mode_is_reference(mode)) ||
300            (proj == pn_Start_P_globals && mode_is_reference(mode)) ||
301            (proj == pn_Start_T_args    && mode == mode_T) ||
302            (proj == pn_Start_P_value_arg_base && mode_is_reference(mode)) ||
303            (proj == pn_Start_P_value_arg_base && mode == mode_T)    /* FIXME: only one of those */
304           ),
305           "wrong Proj from Start", 0,
306       show_proj_failure(p);
307       );
308       break;
309
310     case iro_Cond:
311       ASSERT_AND_RET_DBG(
312         (
313           (proj >= 0 && mode == mode_X && get_irn_mode(get_Cond_selector(pred)) == mode_b) ||   /* compare */
314           (mode == mode_X && mode_is_int(get_irn_mode(get_Cond_selector(pred))))                /* switch */
315         ),
316         "wrong Proj from Cond", 0,
317         show_proj_failure(p);
318       );
319       break;
320
321     case iro_Raise:
322       ASSERT_AND_RET_DBG(
323         ((proj == pn_Raise_X && mode == mode_X) || (proj == pn_Raise_M && mode == mode_M)),
324         "wrong Proj from Raise", 0,
325     show_proj_failure(p);
326       );
327       break;
328
329     case iro_InstOf:
330       ASSERT_AND_RET_DBG(
331     (proj >= 0 && mode == mode_X),
332     "wrong Proj from InstOf", 0,
333     show_proj_failure(p);
334       );
335       break;
336
337     case iro_Call:
338       ASSERT_AND_RET_DBG(
339         ((proj == pn_Call_M_regular        && mode == mode_M) ||
340          (proj == pn_Call_X_except         && mode == mode_X) ||
341          (proj == pn_Call_T_result         && mode == mode_T) ||
342          (proj == pn_Call_M_except         && mode == mode_M) ||
343      (proj == pn_Call_P_value_res_base && mode == mode_P)),
344         "wrong Proj from Call", 0,
345         show_proj_failure(p);
346       );
347
348       break;
349
350     case iro_Quot:
351       ASSERT_AND_RET_DBG(
352         ((proj == pn_Quot_M        && mode == mode_M) ||
353          (proj == pn_Quot_X_except && mode == mode_X) ||
354          (proj == pn_Quot_res      && mode_is_float(mode))),
355         "wrong Proj from Quot", 0,
356     show_proj_failure(p);
357       );
358       break;
359
360     case iro_DivMod:
361       ASSERT_AND_RET_DBG(
362         ((proj == pn_DivMod_M        && mode == mode_M) ||
363          (proj == pn_DivMod_X_except && mode == mode_X) ||
364          (proj == pn_DivMod_res_div  && mode_is_int(mode)) ||
365          (proj == pn_DivMod_res_mod  && mode_is_int(mode))),
366         "wrong Proj from DivMod", 0,
367     show_proj_failure(p);
368       );
369       break;
370
371     case iro_Div:
372       ASSERT_AND_RET_DBG(
373         ((proj == pn_Div_M        && mode == mode_M) ||
374          (proj == pn_Div_X_except && mode == mode_X) ||
375          (proj == pn_Div_res      && mode_is_int(mode))),
376         "wrong Proj from Div or Mod", 0,
377         show_proj_failure(p);
378       );
379       break;
380
381     case iro_Mod:
382       ASSERT_AND_RET_DBG(
383         ((proj == pn_Mod_M        && mode == mode_M) ||
384          (proj == pn_Mod_X_except && mode == mode_X) ||
385          (proj == pn_Mod_res      && mode_is_int(mode))),
386         "wrong Proj from Div or Mod", 0,
387     show_proj_failure(p);
388       );
389       break;
390
391     case iro_Cmp:
392       ASSERT_AND_RET_DBG(
393         (proj >= 0 && proj <= 15 && mode == mode_b),
394         "wrong Proj from Cmp", 0,
395     show_proj_failure(p);
396       );
397       break;
398
399     case iro_Load:
400       if (proj == pn_Load_res) {
401         ir_node *ptr = get_Load_ptr(pred);
402         entity *ent = get_ptr_entity(ptr);
403
404         if (vrfy_entities && ent && get_irg_phase_state(current_ir_graph) == phase_high) {
405           /* do NOT check this for lowered phases, see comment on Store */
406           ASSERT_AND_RET_DBG(
407                              (mode == get_type_mode(get_entity_type(ent))),
408                              "wrong data Proj from Load, entity type_mode failed", 0,
409                              show_proj_failure_ent(p, ent);
410                              );
411         }
412         else {
413           ASSERT_AND_RET_DBG(
414                              mode_is_data(mode) && mode == get_Load_mode(pred),
415                              "wrong data Proj from Load", 0,
416                              show_proj_failure(p);
417                              );
418         }
419       } else {
420         ASSERT_AND_RET_DBG(
421                            ((proj == pn_Load_M        && mode == mode_M) ||
422                             (proj == pn_Load_X_except && mode == mode_X)),
423                            "wrong Proj from Load", 0,
424                            show_proj_failure(p);
425                            );
426       }
427       break;
428
429     case iro_Store:
430       ASSERT_AND_RET_DBG(
431         ((proj == pn_Store_M        && mode == mode_M) ||
432          (proj == pn_Store_X_except && mode == mode_X)),
433         "wrong Proj from Store", 0,
434         show_proj_failure(p);
435       );
436       break;
437
438     case iro_Alloc:
439       ASSERT_AND_RET_DBG(
440         (
441          (proj == pn_Alloc_M        && mode == mode_M) ||
442          (proj == pn_Alloc_X_except /* && mode == mode_X*/) ||
443          (proj == pn_Alloc_res      && mode_is_reference(mode))
444         ),
445         "wrong Proj from Alloc", 0,
446         show_proj_failure(p);
447       );
448       break;
449
450     case iro_Proj:
451       {
452         type *mt; /* A method type */
453         long nr = get_Proj_proj(pred);
454
455         pred = skip_Id(get_Proj_pred(pred));
456         ASSERT_AND_RET((get_irn_mode(pred) == mode_T), "Proj from something not a tuple", 0);
457         switch (get_irn_opcode(pred))
458         {
459           case iro_Start:
460             mt = get_entity_type(get_irg_entity(irg));
461
462             if (nr == pn_Start_T_args) {
463                   ASSERT_AND_RET(
464                       (proj >= 0 && mode_is_data(mode)),
465                       "wrong Proj from Proj from Start", 0);
466                   ASSERT_AND_RET(
467                     (proj < get_method_n_params(mt)),
468                     "More Projs for args than args in type", 0
469                   );
470                   if ((mode_is_reference(mode)) && is_compound_type(get_method_param_type(mt, proj)))
471                     /* value argument */ break;
472
473                   ASSERT_AND_RET(
474                       (mode == get_type_mode(get_method_param_type(mt, proj))),
475                       "Mode of Proj from Start doesn't match mode of param type.", 0);
476                 }
477             else if (nr == pn_Start_P_value_arg_base) {
478               ASSERT_AND_RET(
479                       (proj >= 0 && mode_is_reference(mode)),
480                       "wrong Proj from Proj from Start", 0
481                   );
482                   ASSERT_AND_RET(
483                     (proj < get_method_n_params(mt)),
484                     "More Projs for args than args in type", 0
485                   );
486             }
487             break;
488
489           case iro_Call:
490             {
491               ASSERT_AND_RET(
492                   (proj >= 0 && mode_is_data(mode)),
493                   "wrong Proj from Proj from Call", 0);
494               mt = get_Call_type(pred);
495               ASSERT_AND_RET(
496                   (proj < get_method_n_ress(mt)),
497                   "More Projs for results than results in type.", 0);
498               if ((mode_is_reference(mode)) && is_compound_type(get_method_res_type(mt, proj)))
499                 /* value result */ break;
500
501               ASSERT_AND_RET(
502                   (mode == get_type_mode(get_method_res_type(mt, proj))),
503                   "Mode of Proj from Call doesn't match mode of result type.", 0);
504             }
505             break;
506
507           case iro_Tuple:
508             /* We don't test */
509             break;
510
511           case iro_Bad:
512             /* hmm, optimization did not remove it */
513             break;
514
515           default:
516             ASSERT_AND_RET(0, "Unknown opcode", 0);
517         }
518         break;
519
520       }
521     case iro_Tuple:
522       /* We don't test */
523       break;
524
525     case iro_CallBegin:
526       break;
527
528     case iro_EndReg:
529       ASSERT_AND_RET((get_irp_ip_view_state() != ip_view_no),
530                       "EndReg may only appear if ip view is constructed.", 0);
531       break;
532
533     case iro_EndExcept:
534       ASSERT_AND_RET((get_irp_ip_view_state() != ip_view_no),
535                       "EndExcept may only appear if ip view is constructed.", 0);
536       break;
537
538     default:
539       ASSERT_AND_RET(0, "Unknown opcode", 0);
540   }
541
542   /* all went ok */
543   return 1;
544 }
545
546 int irn_vrfy_irg(ir_node *n, ir_graph *irg)
547 {
548   int i;
549   int opcode, opcode1;
550   ir_mode *mymode, *op1mode = NULL, *op2mode, *op3mode;
551   int op_is_symmetric = 1;  /*  0: asymmetric
552                                 1: operands have identical modes
553                                 2: modes of operands == mode of this node */
554   type *mt;                 /* A method type */
555   entity *ent;
556
557   ir_node **in;
558
559   if (!opt_do_node_verification) return 1;
560
561   if (! get_interprocedural_view()) {
562     /*
563      * do NOT check placement in interprocedural view, as we don't always know
564      * the "right" graph ...
565      */
566     ASSERT_AND_RET_DBG(
567                        node_is_in_irgs_storage(irg, n),
568                        "Node is not stored on proper IR graph!", 0,
569                        show_node_on_graph(irg, n);
570                        );
571     assert(get_irn_irg(n) == irg);
572   }
573
574   opcode = get_irn_opcode(n);
575
576   /* We don't want to test nodes whose predecessors are Bad,
577      as we would have to special case that for each operation. */
578   if (opcode != iro_Phi && opcode != iro_Block)
579     for (i = 0; i < get_irn_arity(n); i++) {
580       opcode1 = get_irn_opcode(get_irn_n(n, i));
581       if (opcode1 == iro_Bad)
582         return 1;
583     }
584
585   mymode = get_irn_mode(n);
586   in = get_irn_in(n);
587
588   switch (opcode) {
589
590     case iro_Block:
591       for (i = 0; i < get_Block_n_cfgpreds(n); ++i) {
592         ir_node *pred =  get_Block_cfgpred(n, i);
593         ASSERT_AND_RET(
594                        (is_Bad(pred)     ||
595                         is_Unknown(pred) ||
596                         (get_irn_mode(pred) == mode_X)
597                         ), "Block node", 0);
598       }
599       /*  End block may only have Return, Raise or fragile ops as preds. */
600       if (n == get_irg_end_block(irg))
601         for (i = 0; i < get_Block_n_cfgpreds(n); ++i) {
602           ir_node *pred =  skip_Proj(get_Block_cfgpred(n, i));
603           if (is_Proj(pred) || get_irn_op(pred) == op_Tuple)
604             break;   /*  We can not test properly.  How many tuples are there? */
605           ASSERT_AND_RET(((get_irn_op(pred) == op_Return) ||
606                           is_Bad(pred)                    ||
607                           (get_irn_op(pred) == op_Raise)  ||
608                           is_fragile_op(pred)               ),
609                          "End Block node", 0);
610         }
611       /*  irg attr must == graph we are in. */
612       if (! get_interprocedural_view()) {
613         ASSERT_AND_RET(((get_irn_irg(n) && get_irn_irg(n) == irg)), "Block node has wrong irg attribute", 0);
614       }
615
616       break;
617
618     case iro_Start:
619       ASSERT_AND_RET(
620                      /* Start: BB --> X x M x ref x data1 x ... x datan x ref */
621                      mymode == mode_T, "Start node", 0
622                      );
623       break;
624
625     case iro_Jmp:
626       ASSERT_AND_RET(
627                      /* Jmp: BB --> X */
628                      mymode == mode_X, "Jmp node", 0
629                      );
630       break;
631
632     case iro_Break:
633       ASSERT_AND_RET((get_irp_ip_view_state() != ip_view_no),
634                       "Break may only appear if ip view is constructed.", 0);
635       ASSERT_AND_RET(
636                      /* Jmp: BB --> X */
637                      mymode == mode_X, "Break node", 0
638                      );
639
640       break;
641
642     case iro_Cond:
643       op1mode = get_irn_mode(in[1]);
644       ASSERT_AND_RET(
645                      /* Cond: BB x b --> X x X */
646                      (op1mode == mode_b ||
647                       /* Cond: BB x int --> X^n */
648                       mode_is_int(op1mode) ),  "Cond node", 0
649                      );
650       ASSERT_AND_RET(mymode == mode_T, "Cond mode is not a tuple", 0);
651       break;
652
653     case iro_Return:
654       op1mode = get_irn_mode(in[1]);
655       /* Return: BB x M x data1 x ... x datan --> X */
656       /* printf("mode: %s, code %s\n", ID_TO_STR(n->mode->name), ID_TO_STR(n->op->name));*/
657       ASSERT_AND_RET( op1mode == mode_M, "Return node", 0 );  /* operand M */
658       for (i = 2; i < get_irn_arity(n); i++) {
659         ASSERT_AND_RET( mode_is_data(get_irn_mode(in[i])), "Return node", 0 );  /* operand datai */
660       };
661       ASSERT_AND_RET( mymode == mode_X, "Result X", 0 );   /* result X */
662       /* Compare returned results with result types of method type */
663       mt = get_entity_type(get_irg_entity(irg));
664       ASSERT_AND_RET_DBG( get_Return_n_ress(n) == get_method_n_ress(mt),
665         "Number of results for Return doesn't match number of results in type.", 0,
666       show_return_nres(irg, n, mt););
667       for (i = 0; i < get_Return_n_ress(n); i++) {
668         type *res_type = get_method_res_type(mt, i);
669
670         if (is_atomic_type(res_type)) {
671           ASSERT_AND_RET_DBG(
672             get_irn_mode(get_Return_res(n, i)) == get_type_mode(res_type),
673             "Mode of result for Return doesn't match mode of result type.", 0,
674             show_return_modes(irg, n, mt, i);
675           );
676         }
677         else {
678           ASSERT_AND_RET_DBG(
679             mode_is_reference(get_irn_mode(get_Return_res(n, i))),
680             "Mode of result for Return doesn't match mode of result type.", 0,
681             show_return_modes(irg, n, mt, i);
682           );
683         }
684       }
685       break;
686
687     case iro_Raise:
688       op1mode = get_irn_mode(in[1]);
689       op2mode = get_irn_mode(in[2]);
690       ASSERT_AND_RET(
691                      /* Sel: BB x M x ref --> X x M */
692                      op1mode == mode_M && mode_is_reference(op2mode) &&
693                      mymode == mode_T, "Raise node", 0
694                      );
695       break;
696
697     case iro_Const: {
698       ASSERT_AND_RET(
699                      /* Const: BB --> data */
700                      (mode_is_data (mymode) ||
701                       mymode == mode_b)      /* we want boolean constants for static evaluation */
702                      ,"Const node", 0        /* of Cmp. */
703                      );
704       } break;
705     case iro_SymConst:
706       if (get_SymConst_kind(n) == symconst_addr_ent) {
707         entity *ent = get_SymConst_entity(n);
708         if (is_Method_type(get_entity_type(ent)) &&
709             get_irn_irg(n) != get_const_code_irg()) {
710 #if 1
711           ASSERT_AND_RET((get_entity_peculiarity(ent) != peculiarity_description),
712                          "A constant must address an existing method.", 0);
713 #endif
714         }
715       }
716       ASSERT_AND_RET(
717                      /* SymConst: BB --> int*/
718                      (mode_is_int(mymode) ||
719                       /* SymConst: BB --> ref */
720                       mode_is_reference(mymode))
721                      ,"SymConst node", 0);
722       break;
723
724     case iro_Sel:
725       op1mode = get_irn_mode(in[1]);
726       op2mode = get_irn_mode(in[2]);
727       ASSERT_AND_RET_DBG(
728                          /* Sel: BB x M x ref x int^n --> ref */
729                          (op1mode == mode_M && op2mode == mymode && mode_is_reference(mymode)),
730                          "Sel node", 0, show_node_failure(n)
731                          );
732       for (i=3; i < get_irn_arity(n); i++)
733         {
734           ASSERT_AND_RET_DBG(mode_is_int(get_irn_mode(in[i])), "Sel node", 0, show_node_failure(n));
735         }
736       ent = get_Sel_entity(n);
737       ASSERT_AND_RET_DBG(ent, "Sel node with empty entity", 0, show_node_failure(n));
738       break;
739
740     case iro_InstOf:
741       ASSERT_AND_RET(mode_T == mymode, "mode of Instof is not a tuple", 0);
742       ASSERT_AND_RET(mode_is_data(op1mode), "Instof not on data", 0);
743       break;
744
745     case iro_Call:
746       op1mode = get_irn_mode(in[1]);
747       op2mode = get_irn_mode(in[2]);
748       /* Call: BB x M x ref x data1 x ... x datan
749          --> M x datan+1 x ... x data n+m */
750       ASSERT_AND_RET( op1mode == mode_M && mode_is_reference(op2mode), "Call node", 0 );  /* operand M x ref */
751
752       mt = get_Call_type(n);
753       if(get_unknown_type() == mt) {
754         break;
755       }
756
757       for (i=3; i < get_irn_arity(n); i++) {
758         ASSERT_AND_RET( mode_is_data(get_irn_mode(in[i])), "Call node", 0 );  /* operand datai */
759       };
760       ASSERT_AND_RET( mymode == mode_T, "Call result not a tuple", 0 );   /* result T */
761       /* Compare arguments of node with those of type */
762
763       if (get_method_variadicity(mt) == variadicity_variadic) {
764         ASSERT_AND_RET_DBG(
765                            get_Call_n_params(n) >= get_method_n_params(mt),
766                            "Number of args for Call doesn't match number of args in variadic type.",
767                            0,
768                            fprintf(stderr, "Call has %d params, method %s type %d\n",
769                                    get_Call_n_params(n), get_type_name(mt), get_method_n_params(mt));
770                            );
771       }
772       else {
773         ASSERT_AND_RET(
774                        get_Call_n_params(n) == get_method_n_params(mt),
775                        "Number of args for Call doesn't match number of args in non variadic type.",
776                        0);
777       }
778
779       for (i = 0; i < get_method_n_params(mt); i++) {
780         type *t = get_method_param_type(mt, i);
781
782         if (is_atomic_type(t)) {
783           ASSERT_AND_RET_DBG(
784                              get_irn_mode(get_Call_param(n, i)) == get_type_mode(t),
785                              "Mode of arg for Call doesn't match mode of arg type.", 0,
786                              show_call_param(n, mt);
787                              );
788         }
789         else {
790           /* call with a compound type, mode must be reference */
791           ASSERT_AND_RET_DBG(
792                              mode_is_reference(get_irn_mode(get_Call_param(n, i))),
793                              "Mode of arg for Call doesn't match mode of arg type.", 0,
794                              show_call_param(n, mt);
795                              );
796         }
797       }
798
799 #if 0
800       if (Call_has_callees(n)) {
801         for (i = 0; i < get_Call_n_callees(n); i++) {
802           ASSERT_AND_RET(is_entity(get_Call_callee(n, i)), "callee array must contain entities.", 0);
803         }
804       }
805 #endif
806       break;
807
808     case iro_Add:
809       op1mode = get_irn_mode(in[1]);
810       op2mode = get_irn_mode(in[2]);
811       ASSERT_AND_RET_DBG(
812                          (
813                           /* common Add: BB x numP x numP --> numP */
814                           (op1mode == mymode && op2mode == op1mode && mode_is_numP(mymode)) ||
815                           /* Pointer Add: BB x ref x int --> ref */
816                           (mode_is_reference(op1mode) && mode_is_int(op2mode) && op1mode == mymode) ||
817                           /* Pointer Add: BB x int x ref --> ref */
818                           (mode_is_int(op1mode) && op2mode == mymode && mode_is_reference(mymode))
819                           ),
820                          "Add node", 0,
821                          show_binop_failure(n, "/* common Add: BB x numP x numP --> numP */ |\n"
822                                             "/* Pointer Add: BB x ref x int --> ref */   |\n"
823                                             "/* Pointer Add: BB x int x ref --> ref */");
824                          );
825       if (mode_is_reference(op1mode) != mode_is_reference(op2mode)) {
826         /* BB x ref x int --> ref or BB x int x ref --> ref */
827         op_is_symmetric = 0;
828       } else {
829         /* BB x num x num --> num or BB x ref x ref */
830         op_is_symmetric = 2;
831       }
832       break;
833
834     case iro_Sub:
835       op1mode = get_irn_mode(in[1]);
836       op2mode = get_irn_mode(in[2]);
837       ASSERT_AND_RET_DBG(
838                          /* common Sub: BB x numP x numP --> numP */
839                          ((mymode ==op1mode && mymode == op2mode && mode_is_numP(op1mode)) ||
840                           /* Pointer Sub: BB x ref x int --> ref */
841                           (op1mode == mymode && mode_is_int(op2mode) && mode_is_reference(mymode)) ||
842                           /* Pointer Sub: BB x int x ref --> ref */
843                           (mode_is_int(op1mode) && op2mode == mymode && mode_is_reference(mymode)) ||
844                           /* Pointer Sub: BB x ref x ref --> int */
845                           (op1mode == op2mode && mode_is_reference(op2mode) && mode_is_int(mymode))),
846                          "Sub node", 0,
847                          show_binop_failure(n, "/* common Sub: BB x numP x numP --> numP */ |\n"
848                                             "/* Pointer Sub: BB x ref x int --> ref */   |\n"
849                                             "/* Pointer Sub: BB x int x ref --> ref */   |\n"
850                                             "/* Pointer Sub: BB x ref x ref --> int */" );
851                          );
852       if (mode_is_reference(op1mode) != mode_is_reference(op2mode)) {
853         op_is_symmetric = 0;
854       } else {
855         op_is_symmetric = 2;
856       }
857       break;
858
859     case iro_Minus:
860       op1mode = get_irn_mode(in[1]);
861       ASSERT_AND_RET_DBG(
862                          /* Minus: BB x num --> num */
863                          op1mode == mymode && mode_is_num(op1mode), "Minus node", 0,
864                          show_unop_failure(n , "/* Minus: BB x num --> num */");
865                          );
866       op_is_symmetric = 2;
867       break;
868
869     case iro_Mul:
870       op1mode = get_irn_mode(in[1]);
871       op2mode = get_irn_mode(in[2]);
872       ASSERT_AND_RET_DBG(
873                          /* Mul: BB x int1 x int1 --> int2 */
874                          ((mode_is_int(op1mode)   && op2mode == op1mode && mode_is_int(mymode)) ||
875                          /* Mul: BB x float x float --> float */
876                           (mode_is_float(op1mode) && op2mode == op1mode && mymode == op1mode)),
877                          "Mul node",0,
878                          show_binop_failure(n, "/* Mul: BB x int1 x int1 --> int2 */ |\n"
879                                                "/* Mul: BB x float x float --> float */");
880                          );
881       op_is_symmetric = 2;
882       break;
883
884     case iro_Quot:
885       op1mode = get_irn_mode(in[1]);
886       op2mode = get_irn_mode(in[2]);
887       op3mode = get_irn_mode(in[3]);
888       ASSERT_AND_RET_DBG(
889                          /* Quot: BB x M x float x float --> M x X x float */
890                          op1mode == mode_M && op2mode == op3mode &&
891                          get_mode_sort(op2mode) == irms_float_number &&
892                          mymode == mode_T,
893                          "Quot node",0,
894                          show_binop_failure(n, "/* Quot: BB x M x float x float --> M x X x float */");
895                          );
896       op_is_symmetric = 2;
897       break;
898
899     case iro_DivMod:
900       op1mode = get_irn_mode(in[1]);
901       op2mode = get_irn_mode(in[2]);
902       op3mode = get_irn_mode(in[3]);
903       ASSERT_AND_RET(
904                      /* DivMod: BB x M x int x int --> M x X x int x int */
905                      op1mode == mode_M &&
906                      mode_is_int(op2mode) &&
907                      op3mode == op2mode &&
908                      mymode == mode_T,
909                      "DivMod node", 0
910                      );
911       op_is_symmetric = 1;
912       break;
913
914     case iro_Div:
915     case iro_Mod:
916       op1mode = get_irn_mode(in[1]);
917       op2mode = get_irn_mode(in[2]);
918       op3mode = get_irn_mode(in[3]);
919       ASSERT_AND_RET(
920                      /* Div or Mod: BB x M x int x int --> M x X x int */
921                      op1mode == mode_M &&
922                      op2mode == op3mode &&
923                      mode_is_int(op2mode) &&
924                      mymode == mode_T,
925                      "Div or Mod node", 0
926                      );
927       op_is_symmetric = 1;
928       break;
929
930     case iro_Abs:
931       op1mode = get_irn_mode(in[1]);
932       ASSERT_AND_RET_DBG(
933                          /* Abs: BB x num --> num */
934                          op1mode == mymode &&
935                          mode_is_num (op1mode),
936                          "Abs node", 0,
937                          show_unop_failure(n, "/* Abs: BB x num --> num */");
938                          );
939       op_is_symmetric = 2;
940       break;
941
942     case iro_And:
943     case iro_Or:
944     case iro_Eor:
945       op1mode = get_irn_mode(in[1]);
946       op2mode = get_irn_mode(in[2]);
947       ASSERT_AND_RET_DBG(
948                          /* And or Or or Eor: BB x int x int --> int */
949                          mode_is_int(mymode) &&
950                          op2mode == op1mode &&
951                          mymode == op2mode,
952                          "And, Or or Eor node", 0,
953                          show_binop_failure(n, "/* And or Or or Eor: BB x int x int --> int */");
954                          );
955       op_is_symmetric = 2;
956       break;
957
958     case iro_Not:
959       op1mode = get_irn_mode(in[1]);
960       ASSERT_AND_RET_DBG(
961                          /* Not: BB x int --> int */
962                          mode_is_int(mymode) &&
963                          mymode == op1mode,
964                          "Not node", 0,
965                          show_unop_failure(n, "/* Not: BB x int --> int */");
966                          );
967       op_is_symmetric = 2;
968       break;
969
970
971     case iro_Cmp:
972       op1mode = get_irn_mode(in[1]);
973       op2mode = get_irn_mode(in[2]);
974       ASSERT_AND_RET_DBG(
975                          /* Cmp: BB x datab x datab --> b16 */
976                          mode_is_data (op1mode) &&
977                          op2mode == op1mode &&
978                          mymode == mode_T,
979                          "Cmp node", 0,
980                          show_binop_failure(n, "/* Cmp: BB x datab x datab --> b16 */");
981                          );
982       break;
983
984     case iro_Shl:
985     case iro_Shr:
986     case iro_Shrs:
987       op1mode = get_irn_mode(in[1]);
988       op2mode = get_irn_mode(in[2]);
989       ASSERT_AND_RET_DBG(
990                          /* Shl, Shr or Shrs: BB x int x int_u --> int */
991                          mode_is_int(op1mode) &&
992                          mode_is_int(op2mode) &&
993                          !mode_is_signed(op2mode) &&
994                          mymode == op1mode,
995                          "Shl, Shr, Shr or Rot node", 0,
996                          show_binop_failure(n, "/* Shl, Shr or Shrs: BB x int x int_u --> int */");
997                          );
998       break;
999
1000     case iro_Rot:
1001       op1mode = get_irn_mode(in[1]);
1002       op2mode = get_irn_mode(in[2]);
1003       ASSERT_AND_RET_DBG(
1004                          /* Rot: BB x int x int --> int */
1005                          mode_is_int(op1mode) &&
1006                          mode_is_int(op2mode) &&
1007                          mymode == op1mode,
1008                          "Rot node", 0,
1009                          show_binop_failure(n, "/* Rot: BB x int x int --> int */");
1010                          );
1011       break;
1012
1013     case iro_Conv:
1014       op1mode = get_irn_mode(in[1]);
1015       ASSERT_AND_RET_DBG(
1016                          /* Conv: BB x datab1 --> datab2 */
1017                          mode_is_datab(op1mode) && mode_is_data(mymode),
1018                          "Conv node", 0,
1019                          show_unop_failure(n, "/* Conv: BB x datab1 --> datab2 */");
1020                          );
1021       break;
1022
1023     case iro_Cast:
1024       op1mode = get_irn_mode(in[1]);
1025       ASSERT_AND_RET_DBG(
1026                          /* Conv: BB x datab1 --> datab2 */
1027                          mode_is_data(op1mode) && op1mode == mymode,
1028                          "Cast node", 0,
1029                          show_unop_failure(n, "/* Conv: BB x datab1 --> datab2 */");
1030                          );
1031       break;
1032
1033
1034     case iro_Phi:
1035     {
1036       ir_node *block = get_nodes_block(n);
1037
1038       if (! is_Bad(block) && get_irg_phase_state(get_irn_irg(n)) != phase_building) {
1039         /* a Phi node MUST have the same number of inputs as its block */
1040         ASSERT_AND_RET_DBG(
1041           get_irn_arity(n) == get_irn_arity(block),
1042           "wrong number of inputs in Phi node", 0,
1043           show_phi_inputs(n, block);
1044         );
1045       }
1046
1047       /* Phi: BB x dataM^n --> dataM */
1048       for (i = 1; i < get_irn_arity(n); i++) {
1049         if (!is_Bad(in[i]) && (get_irn_op(in[i]) != op_Unknown))
1050           ASSERT_AND_RET_DBG(
1051                              get_irn_mode(in[i]) == mymode,
1052                              "Phi node", 0,
1053                              show_phi_failure(n, in[i], i);
1054                              );
1055       };
1056       ASSERT_AND_RET( mode_is_dataM(mymode), "Phi node", 0 );
1057       break;
1058     }
1059     case iro_Filter:
1060       ASSERT_AND_RET((get_irp_ip_view_state() != ip_view_no),
1061                     "Filter may only appear if ip view is constructed.", 0);
1062       /* We should further do tests as for Proj and Phi. */
1063       break;
1064     case iro_Load:
1065       op1mode = get_irn_mode(in[1]);
1066       op2mode = get_irn_mode(in[2]);
1067       ASSERT_AND_RET(
1068                      /* Load: BB x M x ref --> M x X x data */
1069                      op1mode == mode_M && mode_is_reference(op2mode),
1070                      "Load node", 0
1071                      );
1072       ASSERT_AND_RET( mymode == mode_T, "Load node", 0 );
1073
1074       /*
1075        * jack's gen_add_firm_code:simpleSel seems to build Load (Load
1076        * (Proj (Proj))) sometimes ...
1077
1078        * interprete.c:ai_eval seems to assume that this happens, too
1079
1080        * obset.c:get_abstval_any can't deal with this if the load has
1081        * mode_T
1082        *
1083       {
1084         entity *ent = hunt_for_entity (get_Load_ptr (n), n);
1085         assert ((NULL != ent) || (mymode != mode_T));
1086       }
1087       */
1088
1089       break;
1090
1091     case iro_Store: {
1092       entity *target;
1093
1094       op1mode = get_irn_mode(in[1]);
1095       op2mode = get_irn_mode(in[2]);
1096       op3mode = get_irn_mode(in[3]);
1097       ASSERT_AND_RET(
1098                      /* Load: BB x M x ref data --> M x X */
1099                      op1mode == mode_M && mode_is_reference(op2mode) && mode_is_data(op3mode),
1100                      "Store node", 0
1101                      );
1102       ASSERT_AND_RET(mymode == mode_T, "Store node", 0);
1103
1104       target = get_ptr_entity(in[2]);
1105       if (vrfy_entities && target && get_irg_phase_state(current_ir_graph) == phase_high) {
1106         /*
1107          * If lowered code, any Sels that add 0 may be removed, causing
1108          * an direct access to entities of array or compound type.
1109          * Prevent this by checking the phase.
1110          */
1111         ASSERT_AND_RET( op3mode == get_type_mode(get_entity_type(target)),
1112                         "Store node", 0);
1113       }
1114
1115       break;
1116     }
1117
1118     case iro_Alloc:
1119       op1mode = get_irn_mode(in[1]);
1120       op2mode = get_irn_mode(in[2]);
1121       ASSERT_AND_RET_DBG(
1122                          /* Alloc: BB x M x int_u --> M x X x ref */
1123                          op1mode == mode_M &&
1124                          mode_is_int(op2mode) &&
1125                          !mode_is_signed(op2mode) &&
1126                          mymode == mode_T,
1127                          "Alloc node", 0,
1128                          show_binop_failure(n, "/* Alloc: BB x M x int_u --> M x X x ref */");
1129                          );
1130       break;
1131
1132     case iro_Free:
1133       op1mode = get_irn_mode(in[1]);
1134       op2mode = get_irn_mode(in[2]);
1135       op3mode = get_irn_mode(in[3]);
1136       ASSERT_AND_RET_DBG(
1137                          /* Free: BB x M x ref x int_u --> M */
1138                          op1mode == mode_M && mode_is_reference(op2mode) &&
1139                          mode_is_int(op3mode) &&
1140                          !mode_is_signed(op3mode) &&
1141                          mymode == mode_M,
1142                          "Free node", 0,
1143                          show_triop_failure(n, "/* Free: BB x M x ref x int_u --> M */");
1144                          );
1145       break;
1146
1147     case iro_Sync:
1148       /* Sync: BB x M^n --> M */
1149       for (i=1; i < get_irn_arity(n); i++) {
1150         ASSERT_AND_RET( get_irn_mode(in[i]) == mode_M, "Sync node", 0 );
1151       };
1152       ASSERT_AND_RET( mymode == mode_M, "Sync node", 0 );
1153       break;
1154
1155     case iro_Proj:
1156       return vrfy_Proj_proj(n, irg);
1157       break;
1158
1159     case iro_Confirm:
1160       op1mode = get_irn_mode(in[1]);
1161       op2mode = get_irn_mode(in[2]);
1162       ASSERT_AND_RET_DBG(
1163                          /* Confirm: BB x T x T --> T */
1164                          op1mode == mymode &&
1165                          op2mode == mymode,
1166                          "Confirm node", 0,
1167                          show_binop_failure(n, "/* Confirm: BB x T x T --> T */");
1168                          );
1169       break;
1170
1171     case iro_Mux:
1172       op1mode = get_irn_mode(in[1]);
1173       op2mode = get_irn_mode(in[2]);
1174       op3mode = get_irn_mode(in[3]);
1175       ASSERT_AND_RET(
1176                          /* Mux: BB x b x numP x numP --> numP */
1177                          op1mode == mode_b &&
1178                          op2mode == mymode &&
1179                          op3mode == mymode &&
1180                          mode_is_numP(mymode),
1181                          "Mux node", 0
1182                          );
1183       break;
1184
1185     default:
1186       break;
1187     }
1188
1189   /* All went ok */
1190   return 1;
1191 }
1192
1193 int irn_vrfy(ir_node *n)
1194 {
1195   int res = 1;
1196 #ifdef DEBUG_libfirm
1197   res = irn_vrfy_irg(n, current_ir_graph);
1198 #endif
1199   return res;
1200 }
1201
1202 /*-----------------------------------------------------------------*/
1203 /* Verify the whole graph.                                         */
1204 /*-----------------------------------------------------------------*/
1205
1206 /* This *is* used, except gcc doesn't notice that */
1207 static void vrfy_wrap(ir_node *node, void *env)
1208 {
1209   int *res = env;
1210
1211   *res = irn_vrfy(node);
1212 }
1213
1214 int irg_vrfy(ir_graph *irg)
1215 {
1216   int res = 1;
1217 #ifdef DEBUG_libfirm
1218   ir_graph *rem;
1219
1220   rem = current_ir_graph;
1221   current_ir_graph = irg;
1222
1223   assert(get_irg_pinned(irg) == op_pin_state_pinned);
1224
1225   irg_walk_graph(irg, vrfy_wrap, NULL, &res);
1226
1227   current_ir_graph = rem;
1228
1229   if (opt_do_node_verification == NODE_VERIFICATION_REPORT && ! res) {
1230     entity *ent = get_irg_entity(current_ir_graph);
1231
1232     if (ent)
1233       fprintf(stderr, "irg_verify: Verifying graph %s failed\n", get_entity_name(ent));
1234     else
1235       fprintf(stderr, "irg_verify: Verifying graph %p failed\n", (void *)current_ir_graph);
1236   }
1237
1238 #endif
1239   return res;
1240 }
1241
1242 int irn_vrfy_irg_dump(ir_node *n, ir_graph *irg, const char **bad_string)
1243 {
1244   int res;
1245   node_verification_t old = opt_do_node_verification;
1246
1247   bad_msg = NULL;
1248   opt_do_node_verification = NODE_VERIFICATION_ERROR_ONLY;
1249   res = irn_vrfy_irg(n, irg);
1250   opt_do_node_verification = old;
1251   *bad_string = bad_msg;
1252
1253   return res;
1254 }
1255
1256
1257 typedef struct _vrfy_bad_env_t {
1258   int flags;
1259   int res;
1260 } vrfy_bad_env_t;
1261
1262 static void check_bads(ir_node *node, void *env)
1263 {
1264   vrfy_bad_env_t *venv = env;
1265   int i, arity = get_irn_arity(node);
1266
1267   if (is_Block(node)) {
1268     if ((venv->flags & BAD_CF) == 0) {
1269
1270       /* check for Bad Block predecessor */
1271       for (i = 0; i < arity; ++i) {
1272         ir_node *pred = get_irn_n(node, i);
1273
1274         if (is_Bad(pred)) {
1275           venv->res |= BAD_CF;
1276
1277           if (opt_do_node_verification == NODE_VERIFICATION_REPORT) {
1278             fprintf(stderr, "irg_vrfy_bads: Block %ld has Bad predecessor\n", get_irn_node_nr(node));
1279           }
1280           if (opt_do_node_verification == NODE_VERIFICATION_ON) {
1281             assert(0 && "Bad CF detected");
1282           }
1283         }
1284       }
1285     }
1286   }
1287   else {
1288     if ((venv->flags & BAD_BLOCK) == 0) {
1289
1290       /* check for Bad Block */
1291       if (is_Bad(get_nodes_block(node))) {
1292         venv->res |= BAD_BLOCK;
1293
1294         if (opt_do_node_verification == NODE_VERIFICATION_REPORT) {
1295           fprintf(stderr, "irg_vrfy_bads: node %ld has Bad Block\n", get_irn_node_nr(node));
1296         }
1297         if (opt_do_node_verification == NODE_VERIFICATION_ON) {
1298           assert(0 && "Bad CF detected");
1299         }
1300       }
1301     }
1302
1303     if ((venv->flags & TUPLE) == 0) {
1304       if (get_irn_op(node) == op_Tuple) {
1305         venv->res |= TUPLE;
1306
1307         if (opt_do_node_verification == NODE_VERIFICATION_REPORT) {
1308           fprintf(stderr, "irg_vrfy_bads: node %ld is a Tuple\n", get_irn_node_nr(node));
1309         }
1310         if (opt_do_node_verification == NODE_VERIFICATION_ON) {
1311           assert(0 && "Tuple detected");
1312         }
1313       }
1314     }
1315
1316     for (i = 0; i < arity; ++i) {
1317       ir_node *pred = get_irn_n(node, i);
1318
1319       if (is_Bad(pred)) {
1320         /* check for Phi with Bad inputs */
1321         if (is_Phi(node) && !is_Bad(get_nodes_block(node)) && is_Bad(get_irn_n(get_nodes_block(node), i))) {
1322           if (venv->flags & BAD_CF)
1323             continue;
1324           else {
1325             venv->res |= BAD_CF;
1326
1327             if (opt_do_node_verification == NODE_VERIFICATION_REPORT) {
1328               fprintf(stderr, "irg_vrfy_bads: Phi %ld has Bad Input\n", get_irn_node_nr(node));
1329             }
1330             if (opt_do_node_verification == NODE_VERIFICATION_ON) {
1331               assert(0 && "Bad CF detected");
1332             }
1333           }
1334         }
1335
1336         /* Bad node input */
1337         if ((venv->flags & BAD_DF) == 0) {
1338           venv->res |= BAD_DF;
1339
1340           if (opt_do_node_verification == NODE_VERIFICATION_REPORT) {
1341             fprintf(stderr, "irg_vrfy_bads: node %ld has Bad Input\n", get_irn_node_nr(node));
1342           }
1343           if (opt_do_node_verification == NODE_VERIFICATION_ON) {
1344             assert(0 && "Bad NON-CF detected");
1345           }
1346         }
1347       }
1348     }
1349   }
1350 }
1351
1352 /*
1353  * verify occurance of bad nodes
1354  */
1355 int irg_vrfy_bads(ir_graph *irg, int flags)
1356 {
1357   vrfy_bad_env_t env;
1358
1359   env.flags = flags;
1360   env.res   = 0;
1361
1362   irg_walk_graph(irg, check_bads, NULL, &env);
1363
1364   return env.res;
1365 }