3 * File name: ir/ir/irvrfy.c
4 * Purpose: Check irnodes for correctness.
5 * Author: Christian Schaefer
6 * Modified by: Goetz Lindenmaier. Till Riedel
9 * Copyright: (c) 1998-2003 Universität Karlsruhe
10 * Licence: This file protected by GPL - GNU GENERAL PUBLIC LICENSE.
18 # include "irgraph_t.h"
19 # include "ircgcons.h"
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).
29 #define ASSERT_AND_RET(expr, string, ret) if (!(expr)) return (ret)
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
35 #define ASSERT_AND_RET_DBG(expr, string, ret, blk) if (!(expr)) return (ret)
37 #define ASSERT_AND_RET(expr, string, ret) \
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); } \
44 if (opt_do_node_verification == NODE_VERIFICATION_REPORT) \
45 fprintf(stderr, #expr " : " string "\n"); \
46 bad_msg = #expr " && " string; \
51 #define ASSERT_AND_RET_DBG(expr, string, ret, blk) \
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); \
66 /** if this flag is set, verify entity types in Load & Store nodes */
67 static int vrfy_entities = 0;
69 /* @@@ replace use of array "in" by access functions. */
70 ir_node **get_irn_in(ir_node *node);
72 static node_verification_t opt_do_node_verification = NODE_VERIFICATION_ON;
73 static const char *bad_msg;
75 /* enable verification of Load/Store entities */
76 void vrfy_enable_entity_tests(int enable)
78 vrfy_entities = enable;
82 * little helper for NULL modes
84 static const char *get_mode_name_ex(ir_mode *mode)
88 return get_mode_name(mode);
91 void do_node_verification(node_verification_t mode)
93 opt_do_node_verification = mode;
96 /** the last IRG, on which a verify error was found */
97 static ir_graph *last_irg_error = NULL;
100 * print the name of the entity of an verification failure
102 static void show_entity_failure(ir_node *node)
104 ir_graph *irg = get_irn_irg(node);
106 if (last_irg_error == irg)
109 last_irg_error = irg;
111 if (irg == get_const_code_irg()) {
112 fprintf(stderr, "\nFIRM: irn_vrfy_irg() <of CONST_CODE_IRG> failed\n");
115 entity *ent = get_irg_entity(irg);
118 type *ent_type = get_entity_owner(ent);
121 if (ent_type == get_glob_type())
122 fprintf(stderr, "\nFIRM: irn_vrfy_irg() %s failed\n", get_entity_name(ent));
124 fprintf(stderr, "\nFIRM: irn_vrfy_irg() %s::%s failed\n", get_type_name(ent_type), get_entity_name(ent));
127 fprintf(stderr, "\nFIRM: irn_vrfy_irg() <NULL>::%s failed\n", get_entity_name(ent));
131 fprintf(stderr, "\nFIRM: irn_vrfy_irg() <IRG %p> failed\n", (void *)irg);
137 * Prints a failure for a Node
139 static void show_node_failure(ir_node *n)
141 show_entity_failure(n);
142 fprintf(stderr, " node %ld %s%s\n" ,
144 get_irn_opname(n), get_irn_modename(n)
149 * Prints a failure message for a binop
151 static void show_binop_failure(ir_node *n, const char *text)
153 ir_node *left = get_binop_left(n);
154 ir_node *right = get_binop_right(n);
156 show_entity_failure(n);
157 fprintf(stderr, " node %ld %s%s(%s%s, %s%s) did not match (%s)\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),
166 * Prints a failure message for an unop
168 static void show_unop_failure(ir_node *n, const char *text)
170 ir_node *op = get_unop_op(n);
172 show_entity_failure(n);
173 fprintf(stderr, " node %ld %s%s(%s%s) did not match (%s)\n",
175 get_irn_opname(n), get_irn_modename(n),
176 get_irn_opname(op), get_irn_modename(op),
181 * Prints a failure message for an op with 3 operands
183 static void show_triop_failure(ir_node *n, const char *text)
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);
189 show_entity_failure(n);
190 fprintf(stderr, " of node %ld %s%s(%s%s, %s%s, %s%s) did not match (%s)\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),
200 * Prints a failure message for a proj
202 static void show_proj_failure(ir_node *n)
204 ir_node *op = get_Proj_pred(n);
205 int proj = get_Proj_proj(n);
207 show_entity_failure(n);
208 fprintf(stderr, " node %ld %s%s %d(%s%s) failed\n" ,
210 get_irn_opname(n), get_irn_modename(n), proj,
211 get_irn_opname(op), get_irn_modename(op));
215 * Prints a failure message for a proj from Start
217 static void show_proj_mode_failure(ir_node *n, type *ty)
219 long proj = get_Proj_proj(n);
220 ir_mode *m = get_type_mode(ty);
222 show_entity_failure(n);
223 fprintf(stderr, " Proj %ld mode %s proj %ld (type %s mode %s) failed\n" ,
228 get_mode_name_ex(m));
232 * Prints a failure message for a proj
234 static void show_proj_failure_ent(ir_node *n, entity *ent)
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));
240 show_entity_failure(n);
241 fprintf(stderr, " node %ld %s%s %d(%s%s) entity %s(type %s mode %s)failed\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));
250 * Show a node and a graph
252 static void show_node_on_graph(ir_graph *irg, ir_node *n)
254 entity *ent = get_irg_entity(irg);
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));
261 fprintf(stderr, "\nFIRM: irn_vrfy_irg() of graph %p, node %ld %s%s\n",
263 get_irn_node_nr(n), get_irn_opname(n), get_irn_modename(n));
269 static void show_call_param(ir_node *n, type *mt)
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))));
278 fprintf(stderr, ") != CALL(");
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))));
283 fprintf(stderr, ")\n");
290 static void show_return_modes(ir_graph *irg, ir_node *n, type *mt, int i)
292 entity *ent = get_irg_entity(irg);
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)))
303 * Show return number of results
305 static void show_return_nres(ir_graph *irg, ir_node *n, type *mt)
307 entity *ent = get_irg_entity(irg);
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));
318 static void show_phi_failure(ir_node *phi, ir_node *pred, int pos)
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)));
329 static void show_phi_inputs(ir_node *phi, ir_node *block)
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));
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);
348 * verify the Proj number
351 vrfy_Proj_proj(ir_node *p, ir_graph *irg) {
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);
361 switch (get_irn_opcode(pred)) {
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 */
373 "wrong Proj from Start", 0,
374 show_proj_failure(p);
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 */
384 "wrong Proj from Cond", 0,
385 show_proj_failure(p);
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);
399 (proj >= 0 && mode == mode_X),
400 "wrong Proj from InstOf", 0,
401 show_proj_failure(p);
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);
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);
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);
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);
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);
461 (proj >= 0 && proj <= 15 && mode == mode_b),
462 "wrong Proj from Cmp", 0,
463 show_proj_failure(p);
468 if (proj == pn_Load_res) {
469 ir_node *ptr = get_Load_ptr(pred);
470 entity *ent = get_ptr_entity(ptr);
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 */
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);
482 mode_is_data(mode) && mode == get_Load_mode(pred),
483 "wrong data Proj from Load", 0,
484 show_proj_failure(p);
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);
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);
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))
513 "wrong Proj from Alloc", 0,
514 show_proj_failure(p);
520 type *mt; /* A method type */
521 long nr = get_Proj_proj(pred);
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))
528 mt = get_entity_type(get_irg_entity(irg));
530 if (nr == pn_Start_T_args) {
532 (proj >= 0 && mode_is_data(mode)),
533 "wrong Proj from Proj from Start", 0);
535 (proj < get_method_n_params(mt)),
536 "More Projs for args than args in type", 0
538 if ((mode_is_reference(mode)) && is_compound_type(get_method_param_type(mt, proj)))
539 /* value argument */ break;
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));
547 else if (nr == pn_Start_P_value_arg_base) {
549 (proj >= 0 && mode_is_reference(mode)),
550 "wrong Proj from Proj from Start", 0
553 (proj < get_method_n_params(mt)),
554 "More Projs for args than args in type", 0
562 (proj >= 0 && mode_is_data(mode)),
563 "wrong Proj from Proj from Call", 0);
564 mt = get_Call_type(pred);
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;
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);
582 /* hmm, optimization did not remove it */
586 ASSERT_AND_RET(0, "Unknown opcode", 0);
599 ASSERT_AND_RET((get_irp_ip_view_state() != ip_view_no),
600 "EndReg may only appear if ip view is constructed.", 0);
604 ASSERT_AND_RET((get_irp_ip_view_state() != ip_view_no),
605 "EndExcept may only appear if ip view is constructed.", 0);
609 ASSERT_AND_RET(0, "Unknown opcode", 0);
616 int irn_vrfy_irg(ir_node *n, ir_graph *irg)
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 */
629 if (!opt_do_node_verification) return 1;
631 if (! get_interprocedural_view()) {
633 * do NOT check placement in interprocedural view, as we don't always know
634 * the "right" graph ...
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);
641 assert(get_irn_irg(n) == irg);
644 opcode = get_irn_opcode(n);
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)
655 mymode = get_irn_mode(n);
661 for (i = 0; i < get_Block_n_cfgpreds(n); ++i) {
662 ir_node *pred = get_Block_cfgpred(n, i);
666 (get_irn_mode(pred) == mode_X)
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) ||
677 (get_irn_op(pred) == op_Raise) ||
678 is_fragile_op(pred) ),
679 "End Block node", 0);
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);
690 /* Start: BB --> X x M x ref x data1 x ... x datan x ref */
691 mymode == mode_T, "Start node", 0
698 mymode == mode_X, "Jmp node", 0
703 ASSERT_AND_RET((get_irp_ip_view_state() != ip_view_no),
704 "Break may only appear if ip view is constructed.", 0);
707 mymode == mode_X, "Break node", 0
713 op1mode = get_irn_mode(in[1]);
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
720 ASSERT_AND_RET(mymode == mode_T, "Cond mode is not a tuple", 0);
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 */
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);
740 if (is_atomic_type(res_type)) {
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);
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);
758 op1mode = get_irn_mode(in[1]);
759 op2mode = get_irn_mode(in[2]);
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
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. */
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()) {
781 ASSERT_AND_RET((get_entity_peculiarity(ent) != peculiarity_description),
782 "A constant must address an existing method.", 0);
787 /* SymConst: BB --> int*/
788 (mode_is_int(mymode) ||
789 /* SymConst: BB --> ref */
790 mode_is_reference(mymode))
791 ,"SymConst node", 0);
795 op1mode = get_irn_mode(in[1]);
796 op2mode = get_irn_mode(in[2]);
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)
802 for (i=3; i < get_irn_arity(n); i++)
804 ASSERT_AND_RET_DBG(mode_is_int(get_irn_mode(in[i])), "Sel node", 0, show_node_failure(n));
806 ent = get_Sel_entity(n);
807 ASSERT_AND_RET_DBG(ent, "Sel node with empty entity", 0, show_node_failure(n));
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);
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 */
822 mt = get_Call_type(n);
823 if(get_unknown_type() == mt) {
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 */
830 ASSERT_AND_RET( mymode == mode_T, "Call result not a tuple", 0 ); /* result T */
831 /* Compare arguments of node with those of type */
833 if (get_method_variadicity(mt) == variadicity_variadic) {
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.",
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));
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.",
849 for (i = 0; i < get_method_n_params(mt); i++) {
850 type *t = get_method_param_type(mt, i);
852 if (is_atomic_type(t)) {
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);
860 /* call with a compound type, mode must be reference */
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);
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);
879 op1mode = get_irn_mode(in[1]);
880 op2mode = get_irn_mode(in[2]);
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))
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 */");
895 if (mode_is_reference(op1mode) != mode_is_reference(op2mode)) {
896 /* BB x ref x int --> ref or BB x int x ref --> ref */
899 /* BB x num x num --> num or BB x ref x ref */
905 op1mode = get_irn_mode(in[1]);
906 op2mode = get_irn_mode(in[2]);
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))),
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 */" );
922 if (mode_is_reference(op1mode) != mode_is_reference(op2mode)) {
930 op1mode = get_irn_mode(in[1]);
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 */");
940 op1mode = get_irn_mode(in[1]);
941 op2mode = get_irn_mode(in[2]);
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)),
948 show_binop_failure(n, "/* Mul: BB x int1 x int1 --> int2 */ |\n"
949 "/* Mul: BB x float x float --> float */");
955 op1mode = get_irn_mode(in[1]);
956 op2mode = get_irn_mode(in[2]);
957 op3mode = get_irn_mode(in[3]);
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 &&
964 show_binop_failure(n, "/* Quot: BB x M x float x float --> M x X x float */");
970 op1mode = get_irn_mode(in[1]);
971 op2mode = get_irn_mode(in[2]);
972 op3mode = get_irn_mode(in[3]);
974 /* DivMod: BB x M x int x int --> M x X x int x int */
976 mode_is_int(op2mode) &&
977 op3mode == op2mode &&
986 op1mode = get_irn_mode(in[1]);
987 op2mode = get_irn_mode(in[2]);
988 op3mode = get_irn_mode(in[3]);
990 /* Div or Mod: BB x M x int x int --> M x X x int */
992 op2mode == op3mode &&
993 mode_is_int(op2mode) &&
1001 op1mode = get_irn_mode(in[1]);
1003 /* Abs: BB x num --> num */
1004 op1mode == mymode &&
1005 mode_is_num (op1mode),
1007 show_unop_failure(n, "/* Abs: BB x num --> num */");
1009 op_is_symmetric = 2;
1015 op1mode = get_irn_mode(in[1]);
1016 op2mode = get_irn_mode(in[2]);
1018 /* And or Or or Eor: BB x int x int --> int */
1019 mode_is_int(mymode) &&
1020 op2mode == op1mode &&
1022 "And, Or or Eor node", 0,
1023 show_binop_failure(n, "/* And or Or or Eor: BB x int x int --> int */");
1025 op_is_symmetric = 2;
1029 op1mode = get_irn_mode(in[1]);
1031 /* Not: BB x int --> int */
1032 mode_is_int(mymode) &&
1035 show_unop_failure(n, "/* Not: BB x int --> int */");
1037 op_is_symmetric = 2;
1042 op1mode = get_irn_mode(in[1]);
1043 op2mode = get_irn_mode(in[2]);
1045 /* Cmp: BB x datab x datab --> b16 */
1046 mode_is_data (op1mode) &&
1047 op2mode == op1mode &&
1050 show_binop_failure(n, "/* Cmp: BB x datab x datab --> b16 */");
1057 op1mode = get_irn_mode(in[1]);
1058 op2mode = get_irn_mode(in[2]);
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) &&
1065 "Shl, Shr, Shr or Rot node", 0,
1066 show_binop_failure(n, "/* Shl, Shr or Shrs: BB x int x int_u --> int */");
1071 op1mode = get_irn_mode(in[1]);
1072 op2mode = get_irn_mode(in[2]);
1074 /* Rot: BB x int x int --> int */
1075 mode_is_int(op1mode) &&
1076 mode_is_int(op2mode) &&
1079 show_binop_failure(n, "/* Rot: BB x int x int --> int */");
1084 op1mode = get_irn_mode(in[1]);
1086 /* Conv: BB x datab1 --> datab2 */
1087 mode_is_datab(op1mode) && mode_is_data(mymode),
1089 show_unop_failure(n, "/* Conv: BB x datab1 --> datab2 */");
1094 op1mode = get_irn_mode(in[1]);
1096 /* Conv: BB x datab1 --> datab2 */
1097 mode_is_data(op1mode) && op1mode == mymode,
1099 show_unop_failure(n, "/* Conv: BB x datab1 --> datab2 */");
1106 ir_node *block = get_nodes_block(n);
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 */
1111 get_irn_arity(n) == get_irn_arity(block),
1112 "wrong number of inputs in Phi node", 0,
1113 show_phi_inputs(n, block);
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))
1121 get_irn_mode(in[i]) == mymode,
1123 show_phi_failure(n, in[i], i);
1126 ASSERT_AND_RET( mode_is_dataM(mymode), "Phi node", 0 );
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. */
1135 op1mode = get_irn_mode(in[1]);
1136 op2mode = get_irn_mode(in[2]);
1138 /* Load: BB x M x ref --> M x X x data */
1139 op1mode == mode_M && mode_is_reference(op2mode),
1142 ASSERT_AND_RET( mymode == mode_T, "Load node", 0 );
1145 * jack's gen_add_firm_code:simpleSel seems to build Load (Load
1146 * (Proj (Proj))) sometimes ...
1148 * interprete.c:ai_eval seems to assume that this happens, too
1150 * obset.c:get_abstval_any can't deal with this if the load has
1154 entity *ent = hunt_for_entity (get_Load_ptr (n), n);
1155 assert ((NULL != ent) || (mymode != mode_T));
1164 op1mode = get_irn_mode(in[1]);
1165 op2mode = get_irn_mode(in[2]);
1166 op3mode = get_irn_mode(in[3]);
1168 /* Load: BB x M x ref data --> M x X */
1169 op1mode == mode_M && mode_is_reference(op2mode) && mode_is_data(op3mode),
1172 ASSERT_AND_RET(mymode == mode_T, "Store node", 0);
1174 target = get_ptr_entity(in[2]);
1175 if (vrfy_entities && target && get_irg_phase_state(current_ir_graph) == phase_high) {
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.
1181 ASSERT_AND_RET( op3mode == get_type_mode(get_entity_type(target)),
1189 op1mode = get_irn_mode(in[1]);
1190 op2mode = get_irn_mode(in[2]);
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) &&
1198 show_binop_failure(n, "/* Alloc: BB x M x int_u --> M x X x ref */");
1203 op1mode = get_irn_mode(in[1]);
1204 op2mode = get_irn_mode(in[2]);
1205 op3mode = get_irn_mode(in[3]);
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) &&
1213 show_triop_failure(n, "/* Free: BB x M x ref x int_u --> M */");
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 );
1222 ASSERT_AND_RET( mymode == mode_M, "Sync node", 0 );
1226 return vrfy_Proj_proj(n, irg);
1230 op1mode = get_irn_mode(in[1]);
1231 op2mode = get_irn_mode(in[2]);
1233 /* Confirm: BB x T x T --> T */
1234 op1mode == mymode &&
1237 show_binop_failure(n, "/* Confirm: BB x T x T --> T */");
1242 op1mode = get_irn_mode(in[1]);
1243 op2mode = get_irn_mode(in[2]);
1244 op3mode = get_irn_mode(in[3]);
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),
1263 int irn_vrfy(ir_node *n)
1266 #ifdef DEBUG_libfirm
1267 res = irn_vrfy_irg(n, current_ir_graph);
1272 /*-----------------------------------------------------------------*/
1273 /* Verify the whole graph. */
1274 /*-----------------------------------------------------------------*/
1276 /* This *is* used, except gcc doesn't notice that */
1277 static void vrfy_wrap(ir_node *node, void *env)
1281 *res = irn_vrfy(node);
1284 int irg_vrfy(ir_graph *irg)
1287 #ifdef DEBUG_libfirm
1290 rem = current_ir_graph;
1291 current_ir_graph = irg;
1292 last_irg_error = NULL;
1294 assert(get_irg_pinned(irg) == op_pin_state_pinned);
1296 irg_walk_graph(irg, vrfy_wrap, NULL, &res);
1298 current_ir_graph = rem;
1300 if (opt_do_node_verification == NODE_VERIFICATION_REPORT && ! res) {
1301 entity *ent = get_irg_entity(current_ir_graph);
1304 fprintf(stderr, "irg_verify: Verifying graph %s failed\n", get_entity_name(ent));
1306 fprintf(stderr, "irg_verify: Verifying graph %p failed\n", (void *)current_ir_graph);
1313 int irn_vrfy_irg_dump(ir_node *n, ir_graph *irg, const char **bad_string)
1316 node_verification_t old = opt_do_node_verification;
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;
1328 typedef struct _vrfy_bad_env_t {
1333 static void check_bads(ir_node *node, void *env)
1335 vrfy_bad_env_t *venv = env;
1336 int i, arity = get_irn_arity(node);
1338 if (is_Block(node)) {
1339 if ((venv->flags & BAD_CF) == 0) {
1341 /* check for Bad Block predecessor */
1342 for (i = 0; i < arity; ++i) {
1343 ir_node *pred = get_irn_n(node, i);
1346 venv->res |= BAD_CF;
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));
1351 if (opt_do_node_verification == NODE_VERIFICATION_ON) {
1352 assert(0 && "Bad CF detected");
1359 if ((venv->flags & BAD_BLOCK) == 0) {
1361 /* check for Bad Block */
1362 if (is_Bad(get_nodes_block(node))) {
1363 venv->res |= BAD_BLOCK;
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));
1368 if (opt_do_node_verification == NODE_VERIFICATION_ON) {
1369 assert(0 && "Bad CF detected");
1374 if ((venv->flags & TUPLE) == 0) {
1375 if (get_irn_op(node) == op_Tuple) {
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));
1381 if (opt_do_node_verification == NODE_VERIFICATION_ON) {
1382 assert(0 && "Tuple detected");
1387 for (i = 0; i < arity; ++i) {
1388 ir_node *pred = get_irn_n(node, i);
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)
1396 venv->res |= BAD_CF;
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));
1401 if (opt_do_node_verification == NODE_VERIFICATION_ON) {
1402 assert(0 && "Bad CF detected");
1407 /* Bad node input */
1408 if ((venv->flags & BAD_DF) == 0) {
1409 venv->res |= BAD_DF;
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));
1414 if (opt_do_node_verification == NODE_VERIFICATION_ON) {
1415 assert(0 && "Bad NON-CF detected");
1424 * verify occurance of bad nodes
1426 int irg_vrfy_bads(ir_graph *irg, int flags)
1433 irg_walk_graph(irg, check_bads, NULL, &env);