another bug. allocated several start nodes.
[libfirm] / ir / ir / irvrfy.c
1 /* Copyright (C) 1998 - 2000 by Universitaet Karlsruhe
2 ** All rights reserved.
3 **
4 ** Authors: Christian Schaefer
5 **
6 x**
7 */
8
9 #ifdef HAVE_CONFIG_H
10 # include <config.h>
11 #endif
12
13 # include "irgraph_t.h"
14 # include "irvrfy.h"
15 # include "irgwalk.h"
16
17 void
18 irn_vrfy (ir_node *n)
19 {
20   int i;
21   int opcode;
22   ir_mode *mymode, *op1mode, *op2mode, *op3mode;
23   int op_is_symmetric = 1;      /* 0: asymmetric
24                                    1: operands have identical modes
25                                    2: modes of operands == mode of this node */
26
27   ir_node **in;
28
29   opcode = get_irn_opcode (n);
30   mymode = get_irn_mode (n);
31   in = get_irn_in (n);
32
33   switch (opcode) {
34
35   case iro_Start:
36     assert (
37             /* Start: BB --> X x M x P x data1 x ... x datan */
38             mymode == mode_T
39            );
40     break;
41   case iro_Jmp:
42     assert (
43             /* Jmp: BB --> X */
44             mymode == mode_X
45            );
46     break;
47   case iro_Cond:
48     op1mode = get_irn_mode(in[1]);
49     assert (
50             /* Cond: BB x b --> X x X */
51             (op1mode == mode_b
52             /* Cond: BB x Iu --> X^n */
53             || op1mode == mode_I)
54            );
55             assert (mymode == mode_T);
56     break;
57   case iro_Return:
58     op1mode = get_irn_mode(in[1]);
59     /* Return: BB x M x data1 x ... x datan --> X */
60     /* printf("mode: %s, code %s\n", ID_TO_STR(n->mode->name), ID_TO_STR(n->op->name));*/
61     assert ( op1mode == mode_M );  /* operand M */
62     for (i=2; i < get_irn_arity(n); i++) {
63       assert ( mode_is_data(get_irn_mode(in[i])) );  /* operand datai */
64     };
65     assert ( mymode == mode_X );   /* result X */
66     break;
67   case iro_Raise:
68     op1mode = get_irn_mode(in[1]);
69     op2mode = get_irn_mode(in[2]);
70     assert (
71             /* Sel: BB x M x P --> X x M */
72             op1mode == mode_M && op2mode == mode_p
73             && mymode == mode_T
74            );
75     break;
76   case iro_Const:
77     assert (
78             /* Const: BB --> data */
79             mode_is_data (mymode) ||
80             mymode == mode_b      /* we want boolean constants for static evaluation
81                                      of Cmp. */
82            );
83     break;
84   case iro_SymConst:
85     assert (
86             /* SymConst: BB --> Iu or
87                          BB --> P */
88             (mymode == mode_I) || (mymode == mode_p)
89            );
90     break;
91   case iro_Sel:
92     op1mode = get_irn_mode(in[1]);
93     op2mode = get_irn_mode(in[2]);
94     assert (
95             /* Sel: BB x M x P x Iu^n --> P */
96             op1mode == mode_M && op2mode == mode_p
97             && mymode == mode_p
98            );
99     for (i=3; i < get_irn_arity(n); i++) {
100             assert (get_irn_mode(in[i]) == mode_I); }
101     break;
102   case iro_Call:
103     op1mode = get_irn_mode(in[1]);
104     op2mode = get_irn_mode(in[2]);
105       /* Call: BB x M x P x data1 x ... x datan
106                  --> M x datan+1 x ... x data n+m */
107     assert ( op1mode == mode_M && op2mode == mode_p );  /* operand M x P */
108     for (i=3; i < get_irn_arity(n); i++) {
109       assert ( mode_is_data(get_irn_mode(in[i])) );  /* operand datai */
110     };
111     assert ( mymode == mode_T );   /* result T */
112     break;
113   case iro_Add:
114     op1mode = get_irn_mode(in[1]);
115     op2mode = get_irn_mode(in[2]);
116     assert (
117             /* common Add: BB x num x num --> num */
118             (mymode == op1mode && mymode == op2mode
119              && mode_is_num(mymode))
120             ||  /* Pointer Add: BB x P x Is --> P */
121             (op1mode == mode_p && op2mode == mode_i && mymode == mode_p)
122             ||  /* Pointer Add: BB x Is x P --> P */
123             (op1mode == mode_i && op2mode == mode_p && mymode == mode_p)
124            );
125       if (op1mode == mode_p || op2mode == mode_p) {
126         /* BB x P x Is --> P or BB x Is x P --> P */
127         op_is_symmetric = 0; /* ArmRoq */
128       } else {
129         /* BB x num x num --> num */
130         op_is_symmetric = 2;
131       }
132     break;
133   case iro_Sub:
134     op1mode = get_irn_mode(in[1]);
135     op2mode = get_irn_mode(in[2]);
136     assert (
137             /* common Sub: BB x num x num --> num */
138             (mymode ==op1mode && mymode == op2mode
139              && mode_is_num(op1mode))
140             ||  /* Pointer Sub: BB x P x Is --> P */
141             (op1mode == mode_p && op2mode == mode_i && mymode == mode_p)
142             ||  /* Pointer Sub: BB x Is x P --> P */
143             (op1mode == mode_i && op2mode == mode_p && mymode == mode_p)
144             ||  /* Pointer Sub: BB x P x P --> Is */
145             (op1mode == mode_p && op2mode == mode_p && mymode == mode_i)
146            );
147       if (op1mode == mode_p && op2mode == mode_p) {
148         op_is_symmetric = 1; /* ArmRoq */
149       } else if (op1mode == mode_p || op2mode == mode_p) {
150         op_is_symmetric = 0; /* ArmRoq */
151       } else {
152         op_is_symmetric = 2;
153       }
154     break;
155   case iro_Minus:
156     op1mode = get_irn_mode(in[1]);
157     assert (
158             /* Minus: BB x float --> float */
159             op1mode == mymode && mode_is_float (op1mode)
160            );
161     op_is_symmetric = 2;
162     break;
163   case iro_Mul:
164     op1mode = get_irn_mode(in[1]);
165     op2mode = get_irn_mode(in[2]);
166     assert (
167             /* Mul: BB x num x num --> num */
168             mymode == op1mode && mymode == op2mode
169             && mode_is_num (op1mode)
170            );
171     op_is_symmetric = 2;
172     break;
173   case iro_Quot:
174     op1mode = get_irn_mode(in[1]);
175     op2mode = get_irn_mode(in[2]);
176     op3mode = get_irn_mode(in[3]);
177     assert (
178             /* Quot: BB x M x float x float --> M x X x float */
179             op1mode == mode_M && op2mode == op3mode
180             && mode_is_float(op2mode) && mymode == mode_T
181            );
182     op_is_symmetric = 2;
183     break;
184   case iro_DivMod:;
185     op1mode = get_irn_mode(in[1]);
186     op2mode = get_irn_mode(in[2]);
187     op3mode = get_irn_mode(in[3]);
188     assert (
189             /* DivMod: BB x M x num x num --> M x X x Is x Is */
190             op1mode == mode_M && op2mode == op3mode
191             && mode_is_num (op2mode) && mymode == mode_T
192            );
193     op_is_symmetric = 1;
194     break;
195   case iro_Div:
196   case iro_Mod:
197     op1mode = get_irn_mode(in[1]);
198     op2mode = get_irn_mode(in[2]);
199     op3mode = get_irn_mode(in[3]);
200     assert (
201             /* Div or Mod: BB x M x num x num --> M x X x Is */
202             op1mode == mode_M && op2mode == op3mode &&
203             mode_is_num (op2mode) && mymode == mode_T
204            );
205     op_is_symmetric = 1;
206     break;
207   case iro_Abs:
208     op1mode = get_irn_mode(in[1]);
209     assert (
210             /* Abs: BB x num --> num */
211             op1mode == mymode && mode_is_num (op1mode)
212            );
213     op_is_symmetric = 2;
214     break;
215   case iro_And:
216   case iro_Or:
217   case iro_Eor:
218     op1mode = get_irn_mode(in[1]);
219     op2mode = get_irn_mode(in[2]);
220     assert(
221            /* And or Or or Eor: BB x int x int --> int */
222            mymode == op1mode && mymode == op2mode
223            && mode_is_int (mymode)
224           );
225     op_is_symmetric = 2;
226     break;
227   case iro_Not:
228     op1mode = get_irn_mode(in[1]);
229     assert(
230            /* Not: BB x int --> int */
231            mymode == op1mode
232            && mode_is_int (mymode)
233           );
234     op_is_symmetric = 2;
235     break;
236
237   case iro_Cmp:
238     op1mode = get_irn_mode(in[1]);
239     op2mode = get_irn_mode(in[2]);
240     assert(
241            /* Cmp: BB x datab x datab --> b16 */
242            op1mode == op2mode && mode_is_data (op1mode)
243            && mymode == mode_T
244           );
245     break;
246   case iro_Shl:
247   case iro_Shr:
248   case iro_Shrs:
249   case iro_Rot:
250     op1mode = get_irn_mode(in[1]);
251     op2mode = get_irn_mode(in[2]);
252     assert(
253            /* Shl, Shr, Shrs or Rot: BB x int x Iu --> int */
254            mode_is_int (op1mode) && op2mode == mode_I
255            && op1mode == mymode
256           );
257     break;
258   case iro_Conv:
259     op1mode = get_irn_mode(in[1]);
260     assert(
261            /* Conv: BB x datab1 --> datab2 */
262            mode_is_datab (op1mode)
263            && mode_is_data (mymode)
264           );
265     break;
266   case iro_Phi:
267            /* Phi: BB x dataM^n --> dataM */
268     /* for some reason "<=" aborts. Is there a problem with get_store? */
269     for (i=1; i < get_irn_arity(n); i++) {
270       if (!is_Bad(in[i]))
271         assert ( get_irn_mode(in[i]) == mymode );
272     };
273     assert ( mode_is_dataM(mymode) );
274     break;
275   case iro_Load:
276     op1mode = get_irn_mode(in[1]);
277     op2mode = get_irn_mode(in[2]);
278     assert(
279            /* Load: BB x M x P --> M x X x data */
280            op1mode == mode_M && op2mode == mode_p
281           );
282     assert ( mymode == mode_T );
283     break;
284   case iro_Store:
285     op1mode = get_irn_mode(in[1]);
286     op2mode = get_irn_mode(in[2]);
287     op3mode = get_irn_mode(in[3]);
288     assert(
289            /* Load: BB x M x P x data --> M x X */
290            op1mode == mode_M && op2mode == mode_p
291            && mode_is_data (op3mode)
292           );
293     assert(mymode == mode_T);
294     break;
295   case iro_Alloc:
296     op1mode = get_irn_mode(in[1]);
297     op2mode = get_irn_mode(in[2]);
298     assert(
299            /* Alloc: BB x M x Iu --> M x X x P */
300            op1mode == mode_M && op2mode == mode_I
301            && mymode == mode_T
302           );
303     break;
304   case iro_Free:
305     op1mode = get_irn_mode(in[1]);
306     op2mode = get_irn_mode(in[2]);
307     op3mode = get_irn_mode(in[3]);
308     assert(
309            /* Free: BB x M x P x Iu --> M */
310            op1mode == mode_M && op2mode == mode_p && op3mode == mode_I
311            && mymode == mode_M
312           );
313     break;
314   case iro_Sync:
315            /* Sync: BB x M^n --> M */
316     for (i=1; i < get_irn_arity(n); i++) {
317       assert ( get_irn_mode(in[i]) == mode_M );
318     };
319     assert ( mymode == mode_M );
320     break;
321
322   default: ;
323   }
324 }
325
326 /*******************************************************************/
327 /* Verify the whole graph.                                         */
328 /*******************************************************************/
329
330 void
331 vrfy_wrap (ir_node *node, void *env) {
332   irn_vrfy(node);
333 }
334
335 void
336 irg_vrfy (ir_graph *irg)
337 {
338   ir_graph *rem;
339   rem = current_ir_graph;
340   current_ir_graph = irg;
341
342   irg_walk(irg->end, vrfy_wrap, NULL, NULL);
343
344   current_ir_graph = rem;
345 }