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