Code review to compile with -ansi
[libfirm] / ir / ir / irvrfy.c
1 /* Copyright (C) 1998 - 2000 by Universitaet Karlsruhe
2 ** All rights reserved.
3 **
4 ** Authors: Christian Schaefer
5 **
6 **
7 */
8
9 /* $Id$ */
10
11 #ifdef HAVE_CONFIG_H
12 # include <config.h>
13 #endif
14
15 # include "irgraph_t.h"
16 # include "irvrfy.h"
17 # include "irgwalk.h"
18
19 INLINE static void
20 vrfy_Proj_proj(ir_node *p) {
21   ir_node *pred;
22   ir_mode *mode;
23   int proj;
24
25   pred = skip_nop(get_Proj_pred(p));
26   assert(get_irn_mode(pred) == mode_T);
27   mode = get_irn_mode(p);
28   proj = get_Proj_proj(p);
29
30   switch (get_irn_opcode(pred)) {
31   case iro_Start:
32     assert (((proj == 0 && mode == mode_X) ||
33              (proj == 1 && mode == mode_M) ||
34              (proj == 2 && mode == mode_p) ||
35              (proj == 3 && mode == mode_p) ||
36              (proj == 4 && mode == mode_T))   &&
37             "wrong Proj from Start"  );
38     break;
39   case iro_Cond:
40     assert ((proj >= 0 && mode == mode_X) &&
41             "wrong Proj from Cond");
42     break;
43   case iro_Raise:
44     assert (((proj == 0 && mode == mode_X) ||
45              (proj == 1 && mode == mode_M))   &&
46             "wrong Proj from Raise" );
47     break;
48   case iro_InstOf:
49         assert (((proj >= 0 && mode == mode_X) &&
50                          "wrong Proj from InstOf"));
51         break;
52   case iro_Call:
53     assert (((proj == 0 && mode == mode_M) ||
54              (proj == 1 && mode == mode_X) ||
55              (proj == 2 && mode == mode_T) ||
56              (proj == 3 && mode == mode_M))   &&
57             "wrong Proj from Call" );
58     break;
59   case iro_Quot:
60     assert (((proj == 0 && mode == mode_M) ||
61              (proj == 1 && mode == mode_X) ||
62              (proj == 2 && mode_is_float(mode)))  &&
63             "wrong Proj from Quot");
64     break;
65   case iro_DivMod:
66     assert (((proj == 0 && mode == mode_M) ||
67              (proj == 1 && mode == mode_X) ||
68              (proj == 2 && mode == mode_i) ||
69              (proj == 3 && mode == mode_i))   &&
70             "wrong Proj from DivMod" );
71     break;
72   case iro_Div:
73   case iro_Mod:
74     assert (((proj == 0 && mode == mode_M) ||
75              (proj == 1 && mode == mode_X) ||
76              (proj == 2 && mode == mode_i))   &&
77              "wrong Proj from Div or Mod" );
78     break;
79   case iro_Cmp:
80     assert ((proj >= 0 && proj <= 15 && mode == mode_b) &&
81             "wrong Proj from Cmp");
82     break;
83   case iro_Load:
84     assert (((proj == 0 && mode == mode_M) ||
85              (proj == 1 && mode == mode_X) ||
86              (proj == 2 && mode_is_data(mode)))  &&
87             "wrong Proj from Load");
88     break;
89   case iro_Store:
90     assert (((proj == 0 && mode == mode_M) ||
91              (proj == 1 && mode == mode_X))    &&
92             "wrong Proj from Store");
93     break;
94   case iro_Alloc:
95     assert (((proj == 0 && mode == mode_M) ||
96              (proj == 1 /* && mode == mode_X*/) ||
97              (proj == 2 && mode == mode_p))      &&
98             "wrong Proj from Alloc");
99     break;
100   case iro_Proj: {
101     type *mt; /* A method type */
102     pred = skip_nop(get_Proj_pred(pred));
103     assert(get_irn_mode(pred) == mode_T);
104     switch (get_irn_opcode(pred)) {
105     case iro_Start: {
106       assert (proj >= 0 && mode_is_data(mode) &&
107               "wrong Proj from Proj from Start");
108       mt = get_entity_type(get_irg_ent(current_ir_graph));
109       assert(proj < get_method_n_params(mt) &&
110              "More Projs for args than args in type");
111       assert(mode == get_type_mode(get_method_param_type(mt, proj)) &&
112       "Mode of Proj from Start doesn't match mode of param type.");
113     } break;
114     case iro_Call: {
115       assert (proj >= 0 && mode_is_data(mode) &&
116               "wrong Proj from Proj from Call");
117       mt = get_Call_type(pred);
118       assert(proj < get_method_n_res(mt) &&
119              "More Projs for results than results in type.");
120       assert(mode == get_type_mode(get_method_res_type(mt, proj)) &&
121       "Mode of Proj from Call doesn't match mode of result type.");
122     } break;
123     case iro_Tuple: ;
124       /* We don't test */
125       break;
126     default: assert(0);
127     } break;
128   }
129   case iro_Tuple:
130     /* We don't test */
131     break;
132   case iro_CallBegin:
133     break;
134   case iro_EndReg:
135     break;
136   case iro_EndExcept:
137     break;
138   default: assert(0);
139   }
140 }
141
142 void
143 irn_vrfy (ir_node *n)
144 {
145   int i;
146   int opcode;
147   ir_mode *mymode, *op1mode = NULL, *op2mode, *op3mode;
148   int op_is_symmetric = 1;      /* 0: asymmetric
149                                    1: operands have identical modes
150                                    2: modes of operands == mode of this node */
151   type *mt; /* A method type */
152
153   ir_node **in;
154
155   opcode = get_irn_opcode (n);
156
157   if (opcode != iro_Phi && opcode != iro_Block)
158     for (i = 0; i < get_irn_arity(n); i++)
159       if (get_irn_opcode(get_irn_n(n, i)) == iro_Bad
160           || get_irn_opcode(get_irn_n(n, i)) == iro_Unknown)
161         return;
162
163   mymode = get_irn_mode (n);
164   in = get_irn_in (n);
165
166   switch (opcode) {
167
168   case iro_Start:
169     assert (
170             /* Start: BB --> X x M x P x data1 x ... x datan */
171             mymode == mode_T && "Start node"
172            );
173     break;
174   case iro_Jmp:
175     assert (
176             /* Jmp: BB --> X */
177             mymode == mode_X && "Jmp node"
178            );
179     break;
180   case iro_Cond:
181     op1mode = get_irn_mode(in[1]);
182     assert (
183             /* Cond: BB x b --> X x X */
184             (op1mode == mode_b
185             /* Cond: BB x Iu --> X^n */
186             || op1mode == mode_I) && "Cond node"
187            );
188     assert (mymode == mode_T);
189     break;
190   case iro_Return:
191     op1mode = get_irn_mode(in[1]);
192     /* Return: BB x M x data1 x ... x datan --> X */
193     /* printf("mode: %s, code %s\n", ID_TO_STR(n->mode->name), ID_TO_STR(n->op->name));*/
194     assert ( op1mode == mode_M  && "Return node" );  /* operand M */
195     for (i=2; i < get_irn_arity(n); i++) {
196       assert ( mode_is_data(get_irn_mode(in[i]))  && "Return node");  /* operand datai */
197     };
198     assert ( mymode == mode_X );   /* result X */
199     /* Compare returned results with result types of method type */
200     mt = get_entity_type(get_irg_ent(current_ir_graph));
201     assert(get_Return_n_res(n) == get_method_n_res(mt) &&
202              "Number of results for Return doesn't match number of results in type.");
203     for (i = 0; i < get_Return_n_res(n); i++)
204       assert((get_irn_mode(get_Return_res(n, i))
205               == get_type_mode(get_method_res_type(mt, i))) &&
206              "Mode of result for Return doesn't match mode of result type.");
207
208     break;
209   case iro_Raise:
210     op1mode = get_irn_mode(in[1]);
211     op2mode = get_irn_mode(in[2]);
212     assert (
213             /* Sel: BB x M x P --> X x M */
214             op1mode == mode_M && op2mode == mode_p
215             && mymode == mode_T && "Raise node"
216            );
217     break;
218   case iro_Const:
219     assert (
220             /* Const: BB --> data */
221             (mode_is_data (mymode) ||
222              mymode == mode_b)      /* we want boolean constants for static evaluation */
223              && "Const node"        /* of Cmp. */
224            );
225     break;
226   case iro_SymConst:
227     assert (
228             /* SymConst: BB --> Iu or
229                          BB --> P */
230             ((mymode == mode_I) || (mymode == mode_p))  && "SymConst node"
231            );
232     break;
233   case iro_Sel:
234     op1mode = get_irn_mode(in[1]);
235     op2mode = get_irn_mode(in[2]);
236     assert (
237             /* Sel: BB x M x P x Iu^n --> P */
238             op1mode == mode_M && op2mode == mode_p
239             && mymode == mode_p && "Sel node"
240            );
241     for (i=3; i < get_irn_arity(n); i++) {
242             assert (get_irn_mode(in[i]) == mode_I && "Sel node"); }
243     break;
244   case iro_InstOf:
245         assert (mode_T == mymode);
246         assert (mode_is_data (op1mode));
247         break;
248   case iro_Call:
249     op1mode = get_irn_mode(in[1]);
250     op2mode = get_irn_mode(in[2]);
251       /* Call: BB x M x P x data1 x ... x datan
252                  --> M x datan+1 x ... x data n+m */
253     assert ( op1mode == mode_M && op2mode == mode_p  && "Call node");  /* operand M x P */
254     for (i=3; i < get_irn_arity(n); i++) {
255       assert ( mode_is_data(get_irn_mode(in[i])) && "Call node");  /* operand datai */
256     };
257     assert ( mymode == mode_T );   /* result T */
258     /* Compare arguments of node with those of type */
259       mt = get_Call_type(n);
260       assert(get_Call_n_params(n) == get_method_n_params(mt) &&
261              "Number of args for Call doesn't match number of args in type.");
262       for (i = 0; i < get_Call_n_params(n); i++)
263         assert((get_irn_mode(get_Call_param(n, i))
264                 == get_type_mode(get_method_param_type(mt, i))) &&
265                "Mode of arg for Call doesn't match mode of arg type.");
266     break;
267   case iro_Add:
268     op1mode = get_irn_mode(in[1]);
269     op2mode = get_irn_mode(in[2]);
270     assert (
271             /* common Add: BB x num x num --> num */
272             ((mymode == op1mode && mymode == op2mode
273               && mode_is_num(mymode))
274              ||  /* Pointer Add: BB x P x Is --> P */
275              (op1mode == mode_p && op2mode == mode_i && mymode == mode_p)
276              ||  /* Pointer Add: BB x Is x P --> P */
277              (op1mode == mode_i && op2mode == mode_p && mymode == mode_p))
278             && "Add node"
279            );
280       if (op1mode == mode_p || op2mode == mode_p) {
281         /* BB x P x Is --> P or BB x Is x P --> P */
282         op_is_symmetric = 0; /* ArmRoq */
283       } else {
284         /* BB x num x num --> num */
285         op_is_symmetric = 2;
286       }
287     break;
288   case iro_Sub:
289     op1mode = get_irn_mode(in[1]);
290     op2mode = get_irn_mode(in[2]);
291     assert (
292             /* common Sub: BB x num x num --> num */
293             ((mymode ==op1mode && mymode == op2mode
294               && mode_is_num(op1mode))
295              ||  /* Pointer Sub: BB x P x Is --> P */
296              (op1mode == mode_p && op2mode == mode_i && mymode == mode_p)
297              ||  /* Pointer Sub: BB x Is x P --> P */
298              (op1mode == mode_i && op2mode == mode_p && mymode == mode_p)
299              ||  /* Pointer Sub: BB x P x P --> Is */
300              (op1mode == mode_p && op2mode == mode_p && mymode == mode_i))
301             && "Sub node"
302            );
303       if (op1mode == mode_p && op2mode == mode_p) {
304         op_is_symmetric = 1; /* ArmRoq */
305       } else if (op1mode == mode_p || op2mode == mode_p) {
306         op_is_symmetric = 0; /* ArmRoq */
307       } else {
308         op_is_symmetric = 2;
309       }
310     break;
311   case iro_Minus:
312     op1mode = get_irn_mode(in[1]);
313     assert (
314             /* Minus: BB x float --> float */
315             op1mode == mymode && mode_is_float (op1mode)  && "Minus node"
316            );
317     op_is_symmetric = 2;
318     break;
319   case iro_Mul:
320     op1mode = get_irn_mode(in[1]);
321     op2mode = get_irn_mode(in[2]);
322     assert (
323             /* Mul: BB x num x num --> num */
324             mymode == op1mode && mymode == op2mode
325             && mode_is_num (op1mode) && "Mul node"
326            );
327     op_is_symmetric = 2;
328     break;
329   case iro_Quot:
330     op1mode = get_irn_mode(in[1]);
331     op2mode = get_irn_mode(in[2]);
332     op3mode = get_irn_mode(in[3]);
333     assert (
334             /* Quot: BB x M x float x float --> M x X x float */
335             op1mode == mode_M && op2mode == op3mode
336             && mode_is_float(op2mode) && mymode == mode_T && "Quot node"
337            );
338     op_is_symmetric = 2;
339     break;
340   case iro_DivMod:;
341     op1mode = get_irn_mode(in[1]);
342     op2mode = get_irn_mode(in[2]);
343     op3mode = get_irn_mode(in[3]);
344     assert (
345             /* DivMod: BB x M x num x num --> M x X x Is x Is */
346             op1mode == mode_M && op2mode == op3mode
347             && mode_is_num (op2mode) && mymode == mode_T && "DivMod node"
348            );
349     op_is_symmetric = 1;
350     break;
351   case iro_Div:
352   case iro_Mod:
353     op1mode = get_irn_mode(in[1]);
354     op2mode = get_irn_mode(in[2]);
355     op3mode = get_irn_mode(in[3]);
356     assert (
357             /* Div or Mod: BB x M x num x num --> M x X x Is */
358             op1mode == mode_M && op2mode == op3mode &&
359             mode_is_num (op2mode) && mymode == mode_T && "Div or Mod node"
360            );
361     op_is_symmetric = 1;
362     break;
363   case iro_Abs:
364     op1mode = get_irn_mode(in[1]);
365     assert (
366             /* Abs: BB x num --> num */
367             op1mode == mymode && mode_is_num (op1mode) && "Abs node"
368            );
369     op_is_symmetric = 2;
370     break;
371   case iro_And:
372   case iro_Or:
373   case iro_Eor:
374     op1mode = get_irn_mode(in[1]);
375     op2mode = get_irn_mode(in[2]);
376     assert(
377            /* And or Or or Eor: BB x int x int --> int */
378            mymode == op1mode && mymode == op2mode
379            && mode_is_int (mymode) && "And, Or or Eor node"
380           );
381     op_is_symmetric = 2;
382     break;
383   case iro_Not:
384     op1mode = get_irn_mode(in[1]);
385     assert(
386            /* Not: BB x int --> int */
387            mymode == op1mode
388            && mode_is_int (mymode) && "Not node"
389           );
390     op_is_symmetric = 2;
391     break;
392
393   case iro_Cmp:
394     op1mode = get_irn_mode(in[1]);
395     op2mode = get_irn_mode(in[2]);
396     assert(
397            /* Cmp: BB x datab x datab --> b16 */
398            op1mode == op2mode && mode_is_data (op1mode)
399            && mymode == mode_T && "Cmp node"
400           );
401     break;
402   case iro_Shl:
403   case iro_Shr:
404   case iro_Shrs:
405   case iro_Rot:
406     op1mode = get_irn_mode(in[1]);
407     op2mode = get_irn_mode(in[2]);
408     assert(
409            /* Shl, Shr, Shrs or Rot: BB x int x Iu --> int */
410            mode_is_int (op1mode) && op2mode == mode_I
411            && op1mode == mymode && "Shl, Shr, Shr or Rot node"
412           );
413     break;
414   case iro_Conv:
415     op1mode = get_irn_mode(in[1]);
416     assert(
417            /* Conv: BB x datab1 --> datab2 */
418            mode_is_datab (op1mode)
419            && mode_is_data (mymode) && "Conv node"
420           );
421     break;
422   case iro_Phi:
423     /* Phi: BB x dataM^n --> dataM */
424     /* for some reason "<=" aborts. Is there a problem with get_store? */
425     for (i=1; i < get_irn_arity(n); i++) {
426       if (!is_Bad(in[i]))
427         assert ( get_irn_mode(in[i]) == mymode  && "Phi node");
428     };
429     assert ( mode_is_dataM(mymode)  && "Phi node");
430     break;
431   case iro_Load:
432     op1mode = get_irn_mode(in[1]);
433     op2mode = get_irn_mode(in[2]);
434     assert(
435            /* Load: BB x M x P --> M x X x data */
436            op1mode == mode_M && op2mode == mode_p  && "Load node"
437           );
438     assert ( mymode == mode_T  && "Load node");
439     break;
440   case iro_Store:
441     op1mode = get_irn_mode(in[1]);
442     op2mode = get_irn_mode(in[2]);
443     op3mode = get_irn_mode(in[3]);
444     assert(
445            /* Load: BB x M x P x data --> M x X */
446            op1mode == mode_M && op2mode == mode_p
447            && mode_is_data (op3mode) && "Store node"
448           );
449     assert(mymode == mode_T && "Store node");
450     break;
451   case iro_Alloc:
452     op1mode = get_irn_mode(in[1]);
453     op2mode = get_irn_mode(in[2]);
454     assert(
455            /* Alloc: BB x M x Iu --> M x X x P */
456            op1mode == mode_M && op2mode == mode_I
457            && mymode == mode_T && "Alloc node"
458           );
459     break;
460   case iro_Free:
461     op1mode = get_irn_mode(in[1]);
462     op2mode = get_irn_mode(in[2]);
463     op3mode = get_irn_mode(in[3]);
464     assert(
465            /* Free: BB x M x P x Iu --> M */
466            op1mode == mode_M && op2mode == mode_p && op3mode == mode_I
467            && mymode == mode_M && "Free node"
468           );
469     break;
470   case iro_Sync:
471            /* Sync: BB x M^n --> M */
472     for (i=1; i < get_irn_arity(n); i++) {
473       assert ( get_irn_mode(in[i]) == mode_M  && "Sync node");
474     };
475     assert ( mymode == mode_M  && "Sync node");
476     break;
477   case iro_Proj:
478     vrfy_Proj_proj(n);
479     break;
480   default: ;
481   }
482 }
483
484
485 /*******************************************************************/
486 /* Verify the whole graph.                                         */
487 /*******************************************************************/
488
489 void
490 vrfy_wrap (ir_node *node, void *env) {
491   irn_vrfy(node);
492 }
493
494 void irg_vrfy (ir_graph *irg)
495 {
496   ir_graph *rem;
497   rem = current_ir_graph;
498   current_ir_graph = irg;
499
500   assert(get_irg_pinned(irg) == pinned);
501
502   irg_walk(irg->end, vrfy_wrap, NULL, NULL);
503
504   current_ir_graph = rem;
505 }