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