Replace if/else if cascade with switch(opcode)
[libfirm] / ir / ana / vrp.c
1 /*
2  * Copyright (C) 1995-2009 University of Karlsruhe.  All right reserved.
3  *
4  * This file is part of libFirm.
5  *
6  * This file may be distributed and/or modified under the terms of the
7  * GNU General Public License version 2 as published by the Free Software
8  * Foundation and appearing in the file LICENSE.GPL included in the
9  * packaging of this file.
10  *
11  * Licensees holding valid libFirm Professional Edition licenses may use
12  * this file in accordance with the libFirm Commercial License.
13  * Agreement provided with the Software.
14  *
15  * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
16  * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17  * PURPOSE.
18  */
19
20 /**
21  * @file
22  * @brief       analyze graph to provide value range information
23  * @author      Jonas Fietz
24  * @version     $Id$
25  */
26 #include "config.h"
27
28 #include "config.h"
29 #include "irtypes.h"
30 #include "vrp.h"
31 #include "irouts.h"
32 #include "irgraph_t.h"
33 #include "irpass.h"
34 #include "list.h"
35 #include "irgwalk.h"
36 #include "iredges.h"
37 #include "tv.h"
38 #include "irop.h"
39
40
41 static char v;
42 static void *VISITED = &v;
43
44 typedef struct worklist_t worklist_t;
45 struct worklist_t {
46          struct list_head nodes;
47         ir_node *node;
48 };
49
50 struct vrp_env_t {
51         worklist_t *worklist;
52 };
53
54 int update_vrp_data(ir_node *node)
55 {
56
57         tarval *new_bits_set = get_tarval_bad();
58         tarval *new_bits_not_set = get_tarval_bad();
59         tarval *new_range_bottom = get_tarval_bad();
60         tarval *new_range_top = get_tarval_bad();
61         ir_node *new_bits_node = NULL;
62         ir_node *new_range_node = NULL;
63         enum range_types new_range_type = VRP_UNDEFINED;
64         enum range_ops new_range_op = VRP_NONE;
65         int something_changed = 0;
66         tarval *tmp_tv, *tv;
67         ir_node *left, *right, *pred, *bound;
68         int overflow_top, overflow_bottom;
69         tarval *new_top, *new_bottom;
70
71         pn_Cmp cmp;
72
73         node->vrp.valid = 1;
74         /* TODO: Check if all predecessors have valid VRP information*/
75
76
77         if (!mode_is_int(get_irn_mode(node))) {
78                 return 0; /* we don't optimize for non-int-nodes*/
79         }
80
81         switch (get_irn_opcode(node)) {
82         case iro_Const:
83                 tv = get_Const_tarval(node);
84
85                 new_bits_set = tv;
86                 new_bits_not_set = tarval_not(tv);
87                 new_range_bottom = tv;
88                 new_range_top = tv;
89                 new_range_type = VRP_RANGE;
90                 break;
91
92         case iro_And:
93                 left = get_And_left(node);
94                 right = get_And_right(node);
95
96                 new_bits_set = tarval_and(left->vrp.bits_set, right->vrp.bits_set);
97                 new_bits_not_set = tarval_or(left->vrp.bits_not_set, right->vrp.bits_not_set);
98
99                 tmp_tv = tarval_not(left->vrp.bits_set);
100                 tmp_tv = tarval_eor(left->vrp.bits_not_set, tmp_tv);
101                 /*check if one of the predecessors is completely determined*/
102                 if (tarval_is_null(tmp_tv)) {
103                         new_bits_node = right;
104                 }
105
106                 tmp_tv = tarval_not(right->vrp.bits_set);
107                 tmp_tv = tarval_eor(right->vrp.bits_not_set, tmp_tv);
108                 if (tarval_is_null(tmp_tv)) {
109                         new_bits_node = left;
110                 }
111                 break;
112
113         case iro_Add:
114                 left = get_Add_left(node);
115                 right = get_Add_right(node);
116
117
118                 if (left->vrp.range_type == VRP_UNDEFINED || right->vrp.range_type ==
119                                 VRP_UNDEFINED || left->vrp.range_type == VRP_VARYING ||
120                                 right->vrp.range_type == VRP_VARYING) {
121                         return 0;
122                 }
123
124                 new_top = tarval_add(left->vrp.range_top, right->vrp.range_top);
125                 overflow_top = tarval_carry();
126                 new_bottom = tarval_add(left->vrp.range_bottom, right->vrp.range_bottom);
127                 overflow_bottom = tarval_carry();
128
129                 if (!overflow_top && !overflow_bottom && left->vrp.range_type == VRP_RANGE
130                                 &&right->vrp.range_type == VRP_RANGE) {
131                         new_range_bottom = new_bottom;
132                         new_range_top = new_top;
133                         new_range_type = VRP_RANGE;
134                 }
135
136                 if (overflow_top || overflow_bottom) {
137                         /* TODO Implement overflow handling*/
138                         new_range_type = VRP_UNDEFINED;
139                 }
140                 break;
141
142         case iro_Sub:
143                 left = get_Sub_left(node);
144                 right = get_Sub_right(node);
145
146                 if (left->vrp.range_type == VRP_UNDEFINED || right->vrp.range_type ==
147                                 VRP_UNDEFINED) {
148                         return 0;
149                 }
150
151                 new_top = tarval_sub(left->vrp.range_top, right->vrp.range_top, NULL);
152                 overflow_top = tarval_carry();
153                 new_bottom = tarval_sub(left->vrp.range_bottom, right->vrp.range_bottom, NULL);
154                 overflow_bottom = tarval_carry();
155
156                 if (!overflow_top && !overflow_bottom && left->vrp.range_type == VRP_RANGE
157                                 &&right->vrp.range_type == VRP_RANGE) {
158                         new_range_bottom = new_bottom;
159                         new_range_top = new_top;
160                         new_range_type = VRP_RANGE;
161                 }
162
163                 if (overflow_top || overflow_bottom) {
164                         /* TODO Implement overflow handling*/
165                 }
166                 break;
167
168         case iro_Or:
169                 left = get_Or_left(node);
170                 right = get_Or_right(node);
171
172                 new_bits_set = tarval_or(left->vrp.bits_set, right->vrp.bits_set);
173                 new_bits_not_set = tarval_and(left->vrp.bits_not_set, right->vrp.bits_not_set);
174
175                 tmp_tv = tarval_not(left->vrp.bits_set);
176                 tmp_tv = tarval_eor(left->vrp.bits_not_set, tmp_tv);
177                 /*check if one of the predecessors is completely determined*/
178                 if (tarval_is_null(tmp_tv)) {
179                         new_bits_node = right;
180                 }
181
182                 tmp_tv = tarval_not(right->vrp.bits_set);
183                 tmp_tv = tarval_eor(right->vrp.bits_not_set, tmp_tv);
184                 if (tarval_is_null(tmp_tv)) {
185                         new_bits_node = left;
186                 }
187                 break;
188
189         case iro_Rotl:
190                 left = get_Rotl_left(node);
191                 right = get_Rotl_right(node);
192
193                 /* We can only compute this if the right value is a constant*/
194                 if (is_Const(right)) {
195                         tarval *bits_set, *bits_not_set;
196                         bits_set = tarval_rotl(left->vrp.bits_set, get_Const_tarval(right));
197                         bits_not_set = tarval_rotl(left->vrp.bits_not_set, get_Const_tarval(right));
198
199                         new_bits_set = tarval_or(bits_set, node->vrp.bits_set);
200                         new_bits_not_set = tarval_or(bits_not_set, node->vrp.bits_not_set);
201                 }
202                 break;
203
204         case iro_Shl:
205                 left = get_Shl_left(node);
206                 right = get_Shl_right(node);
207
208                 /* We can only compute this if the right value is a constant*/
209                 if (is_Const(right)) {
210                         tarval *bits_set, *bits_not_set;
211                         ir_mode *m = get_tarval_mode(node->vrp.bits_not_set);
212                         bits_set = tarval_shl(left->vrp.bits_set, get_Const_tarval(right));
213                         bits_not_set = tarval_shl(left->vrp.bits_not_set, get_Const_tarval(right));
214
215                         new_bits_set = tarval_or(bits_set, node->vrp.bits_set);
216                         new_bits_not_set = tarval_or(bits_not_set, node->vrp.bits_not_set);
217
218                         bits_not_set = tarval_not( tarval_shl(
219                                                                                 get_mode_all_one(m),
220                                                                                 get_Const_tarval(right)));
221                         new_bits_not_set = tarval_or(bits_not_set, new_bits_not_set);
222
223                 }
224                 break;
225
226         case iro_Shr:
227                 left = get_Shr_left(node);
228                 right = get_Shr_right(node);
229
230                 /* We can only compute this if the right value is a constant*/
231                 if (is_Const(right)) {
232                         tarval *bits_set, *bits_not_set;
233                         ir_mode *m = get_tarval_mode(node->vrp.bits_not_set);
234                         bits_set = tarval_shr(left->vrp.bits_set, get_Const_tarval(right));
235                         bits_not_set = tarval_shr(left->vrp.bits_not_set, get_Const_tarval(right));
236
237                         new_bits_set = tarval_or(bits_set, node->vrp.bits_set);
238                         new_bits_not_set = tarval_or(bits_not_set, node->vrp.bits_not_set);
239
240                         bits_not_set = tarval_not( tarval_shr(
241                                                                                 get_mode_all_one(m),
242                                                                                 get_Const_tarval(right)));
243                         new_bits_not_set = tarval_or(bits_not_set, new_bits_not_set);
244                 }
245                 break;
246
247         case iro_Shrs:
248                 left = get_Shrs_left(node);
249                 right = get_Shrs_right(node);
250
251                 /* We can only compute this if the right value is a constant*/
252                 if (is_Const(right)) {
253                         tarval *bits_set, *bits_not_set;
254                         ir_mode *m = get_tarval_mode(node->vrp.bits_not_set);
255                         bits_set = tarval_shrs(left->vrp.bits_set, get_Const_tarval(right));
256                         bits_not_set = tarval_shrs(left->vrp.bits_not_set, get_Const_tarval(right));
257
258                         new_bits_set = tarval_or(bits_set, node->vrp.bits_set);
259                         new_bits_not_set = tarval_or(bits_not_set, node->vrp.bits_not_set);
260
261                         bits_not_set = tarval_not( tarval_shrs(
262                                                                                 get_mode_all_one(m),
263                                                                                 get_Const_tarval(right)));
264                         new_bits_not_set = tarval_or(bits_not_set, new_bits_not_set);
265                 }
266                 break;
267
268         case iro_Eor:
269                 left = get_Eor_left(node);
270                 right = get_Eor_right(node);
271
272                 tarval *bits_set, *bits_not_set;
273                 bits_not_set = tarval_or(
274                                                         tarval_and(left->vrp.bits_set, right->vrp.bits_set),
275                                                         tarval_and(left->vrp.bits_not_set,
276                                                                 right->vrp.bits_not_set));
277
278                 bits_set = tarval_or(
279                                                 tarval_and(left->vrp.bits_set, right->vrp.bits_not_set),
280                                                 tarval_and(left->vrp.bits_not_set, right->vrp.bits_set));
281
282                 new_bits_set = tarval_or(bits_set, node->vrp.bits_set);
283                 new_bits_not_set = tarval_or(bits_not_set, node->vrp.bits_not_set);
284                 break;
285
286         case iro_Id:
287                 pred = get_Id_pred(node);
288                 new_bits_set = pred->vrp.bits_set;
289                 new_bits_not_set = pred->vrp.bits_not_set;
290                 new_range_top = pred->vrp.range_top;
291                 new_range_bottom = pred->vrp.range_bottom;
292                 new_range_type = pred->vrp.range_type;
293                 break;
294
295         case iro_Not:
296                 pred = get_Not_op(node);
297                 new_bits_set = tarval_or(pred->vrp.bits_not_set, node->vrp.bits_set);
298                 new_bits_not_set = tarval_or(pred->vrp.bits_set, node->vrp.bits_not_set);
299                 break;
300
301         case iro_Conv:
302                 pred = get_Conv_op(node);
303                 ir_mode *old_mode = get_irn_mode(pred);
304                 ir_mode *new_mode;
305
306                 if (!mode_is_int(old_mode))
307                         return 0;
308
309                 new_mode = get_irn_mode(node);
310
311                 /* The second and is needed if target type is smaller*/
312                 bits_not_set = tarval_not(
313                                                         tarval_convert_to(get_mode_all_one(old_mode),
314                                                                 new_mode
315                                                                 ));
316                 bits_not_set = tarval_or(bits_not_set, tarval_convert_to(pred->vrp.bits_not_set, new_mode));
317                 new_bits_not_set = tarval_or(bits_not_set, node->vrp.bits_not_set);
318                 new_bits_set = tarval_and(
319                                 tarval_not(bits_not_set), tarval_convert_to(pred->vrp.bits_set, new_mode));
320
321                 if (tarval_cmp(pred->vrp.range_top, get_mode_max(new_mode)) == pn_Cmp_Le) {
322                         node->vrp.range_top = pred->vrp.range_top;
323                 }
324
325                 if (tarval_cmp(pred->vrp.range_bottom, get_mode_min(new_mode)) == pn_Cmp_Ge) {
326                         node->vrp.range_bottom = pred->vrp.range_bottom;
327                 }
328                 break;
329
330         case iro_Confirm:
331                 cmp = get_Confirm_cmp(node);
332                 bound = get_Confirm_bound(node);
333
334                 /** @todo: Handle non-Const bounds */
335
336                 if (cmp == pn_Cmp_Lg) {
337                         /** @todo: Is there some way to preserve the information? */
338                         new_range_type = VRP_ANTIRANGE;
339                         if (is_Const(bound)) {
340                                 new_range_top = get_Const_tarval(bound);
341                                 new_range_bottom = get_Const_tarval(bound);
342                         }
343                 } else if (cmp == pn_Cmp_Le) {
344                         if (node->vrp.range_type == VRP_UNDEFINED) {
345                                 new_range_type = VRP_RANGE;
346                                 if (is_Const(bound)) {
347                                         new_range_top = get_Const_tarval(bound);
348                                 }
349                                 new_range_bottom = get_tarval_min(get_irn_mode(node));
350                         } else if (node->vrp.range_type == VRP_RANGE) {
351                                 if (is_Const(bound)) {
352                                         if (tarval_cmp(node->vrp.range_top,
353                                                                 get_Const_tarval(bound)) == pn_Cmp_Le) {
354                                                 new_range_top = get_Const_tarval(bound);
355                                         }
356                                         new_range_bottom = get_tarval_min(get_irn_mode(node));
357
358                                 } else if (node->vrp.range_type == VRP_ANTIRANGE) {
359                                         /** @todo: How do we manage not to get a never ending loop? */
360                                 }
361                         }
362                 }
363                 break;
364
365         case iro_Phi:
366                 /* combine all ranges*/
367
368                 pred = get_Phi_pred(node,0);
369                 new_range_top = pred->vrp.range_top;
370                 new_range_bottom = pred->vrp.range_bottom;
371                 new_range_type = pred->vrp.range_type;
372                 new_bits_set = pred->vrp.bits_set;
373                 new_bits_not_set = pred->vrp.bits_not_set;
374
375                 int num = get_Phi_n_preds(node);
376                 pn_Cmp cmp;
377                 int i;
378
379                 assert(num > 0);
380
381
382                 for (i = 1; i < num; i++) {
383                         pred = get_Phi_pred(node, i);
384                         if (new_range_type == VRP_RANGE && pred->vrp.range_type ==
385                                         VRP_RANGE) {
386                                 cmp = tarval_cmp(new_range_top, pred->vrp.range_top);
387                                 if (cmp == pn_Cmp_Lt) {
388                                         new_range_top = pred->vrp.range_top;
389                                 }
390                                 cmp = tarval_cmp(new_range_bottom, pred->vrp.range_bottom);
391                                 if (cmp == pn_Cmp_Gt) {
392                                         new_range_bottom = pred->vrp.range_bottom;
393                                 }
394                         } else {
395                                 new_range_type = VRP_VARYING;
396                                 break;
397                         }
398                 }
399
400                 break;
401
402
403         default:
404                 /* unhandled, therefore never updated */
405                 break;
406         }
407
408
409
410         /* TODO: Check, if there can be information derived from any of these:
411         is_Abs(node) is_Alloc(node) is_Anchor(node) is_Borrow(node) is_Bound(node)
412         is_Break(node) is_Builtin(node) is_Call(node) is_CallBegin(node)
413         is_Carry(node) is_Cast(node) is_Cmp(node) is_Cond(node)
414         is_CopyB(node) is_Div(node) is_DivMod(node) is_Dummy(node)
415         is_End(node) is_EndExcept(node) is_EndReg(node) is_Filter(node) is_Free(node)
416         is_IJmp(node) is_InstOf(node) is_Jmp(node) is_Load(node) is_Minus(node)
417         is_Mod(node) is_Mul(node) is_Mulh(node) is_Mux(node) is_NoMem(node)
418         is_Pin(node) is_Proj(node) is_Quot(node)
419         is_Raise(node) is_Return(node) is_Sel(node) is_Start(node) is_Store(node)
420         is_SymConst(node) is_Sync(node) is_Tuple(node)
421         */
422
423         /* Merge the newly calculated values with those that might already exist*/
424
425         if (new_bits_set != tarval_bad) {
426                 new_bits_set = tarval_or(new_bits_set, node->vrp.bits_set);
427                 if (tarval_cmp(new_bits_set, node->vrp.bits_set) != pn_Cmp_Eq) {
428                         something_changed = 1;
429                         node->vrp.bits_set = new_bits_set;
430                 }
431         }
432
433         if (new_bits_not_set != tarval_bad) {
434                 new_bits_not_set = tarval_or(new_bits_not_set, node->vrp.bits_not_set);
435
436                 if (tarval_cmp(new_bits_not_set, node->vrp.bits_not_set) != pn_Cmp_Eq) {
437                         something_changed = 1;
438                         node->vrp.bits_not_set = new_bits_not_set;
439                 }
440         }
441
442         if (node->vrp.bits_node == NULL && new_bits_node != NULL) {
443                 something_changed = 1;
444                 node->vrp.bits_node = new_bits_node;
445         }
446
447         if (node->vrp.range_type == VRP_UNDEFINED &&
448                         new_range_type != VRP_UNDEFINED) {
449                 something_changed = 1;
450                 node->vrp.range_type = new_range_type;
451                 node->vrp.range_bottom = new_range_bottom;
452                 node->vrp.range_top = new_range_top;
453                 node->vrp.range_op = new_range_op;
454                 node->vrp.range_node = new_range_node;
455
456         } else if (node->vrp.range_type == VRP_RANGE) {
457                 if (new_range_type == VRP_RANGE) {
458                         if ((new_range_node == NULL && node->vrp.range_node == NULL) ||
459                                         (new_range_node == node->vrp.range_node &&
460                                          new_range_op == node->vrp.range_op)) {
461                                 if (tarval_cmp(node->vrp.range_bottom, new_range_bottom) == pn_Cmp_Lt) {
462                                         something_changed = 1;
463                                         node->vrp.range_bottom = new_range_bottom;
464                                 }
465                                 if (tarval_cmp(node->vrp.range_top, new_range_top) == pn_Cmp_Gt) {
466                                         something_changed = 1;
467                                         node->vrp.range_top = new_range_top;
468                                 }
469                         }
470
471                         /* prefer the absolute value*/
472                         if (new_range_node == NULL && node->vrp.range_node != NULL) {
473                                 something_changed = 1;
474                                 node->vrp.range_node = NULL;
475                                 node->vrp.range_top = new_range_top;
476                                 node->vrp.range_bottom = new_range_bottom;
477                         }
478                 }
479
480                 if (new_range_type == VRP_ANTIRANGE) {
481                         /* if they are overlapping, cut the range.*/
482                         /* TODO: Maybe we can preserve more information here*/
483                         if (new_range_node == NULL && node->vrp.range_node == NULL) {
484                                 if (tarval_cmp(node->vrp.range_bottom, new_range_top) == pn_Cmp_Gt &&
485                                                 tarval_cmp(node->vrp.range_bottom, new_range_bottom) == pn_Cmp_Gt) {
486                                         something_changed = 1;
487                                         node->vrp.range_bottom = new_range_top;
488
489                                 } else if (tarval_cmp(node->vrp.range_top, new_range_bottom) == pn_Cmp_Gt &&
490                                                 tarval_cmp(node->vrp.range_top, new_range_top) == pn_Cmp_Lt) {
491                                         something_changed = 1;
492                                         node->vrp.range_top = new_range_bottom;
493                                 }
494
495                                 /* We can not handle the case where the anti range is in the*/
496                                 /* range*/
497                         }
498
499                         /* prefer the absolute value*/
500                         if (new_range_node == NULL && node->vrp.range_node != NULL) {
501                                 something_changed = 1;
502                                 node->vrp.range_node = NULL;
503                                 node->vrp.range_top = new_range_top;
504                                 node->vrp.range_bottom = new_range_bottom;
505                         }
506                 }
507         } else if (node->vrp.range_type == VRP_ANTIRANGE) {
508                 if (new_range_type == VRP_ANTIRANGE) {
509                         if ((new_range_node == NULL && node->vrp.range_node == NULL) ||
510                                         (new_range_node == node->vrp.range_node &&
511                                          new_range_op == node->vrp.range_op)) {
512                                 if (tarval_cmp(node->vrp.range_bottom, new_range_bottom) == pn_Cmp_Gt) {
513                                         something_changed = 1;
514                                         node->vrp.range_bottom = new_range_bottom;
515                                 }
516                                 if (tarval_cmp(node->vrp.range_top, new_range_top) == pn_Cmp_Lt) {
517                                         something_changed = 1;
518                                         node->vrp.range_top = new_range_top;
519                                 }
520                         }
521
522                         /* prefer the absolute value*/
523                         if (new_range_node == NULL && node->vrp.range_node != NULL) {
524                                 something_changed = 1;
525                                 node->vrp.range_node = NULL;
526                                 node->vrp.range_top = new_range_top;
527                                 node->vrp.range_bottom = new_range_bottom;
528                         }
529                 }
530
531                 if (new_range_type == VRP_RANGE) {
532                         if ((new_range_node == NULL && node->vrp.range_node == NULL) ||
533                                         (new_range_node == node->vrp.range_node &&
534                                          new_range_op == node->vrp.range_op)) {
535                                 if (tarval_cmp(node->vrp.range_bottom, new_range_top) == pn_Cmp_Gt) {
536                                         something_changed = 1;
537                                         node->vrp.range_bottom = new_range_top;
538                                 }
539                                 if (tarval_cmp(node->vrp.range_top, new_range_bottom) == pn_Cmp_Lt) {
540                                         something_changed = 1;
541                                         node->vrp.range_top = new_range_bottom;
542                                 }
543                         }
544
545                         /* prefer the absolute value*/
546                         if (new_range_node == NULL && node->vrp.range_node != NULL) {
547                                 something_changed = 1;
548                                 node->vrp.range_node = NULL;
549                                 node->vrp.range_top = new_range_top;
550                                 node->vrp.range_bottom = new_range_bottom;
551                         }
552                 }
553         }
554
555         assert(tarval_is_null(
556                                 tarval_and(node->vrp.bits_set, node->vrp.bits_not_set)));
557
558         return something_changed;
559 }
560
561 void vrp_first_pass(ir_node *n, void *e)
562 {
563         ir_node *succ;
564         worklist_t *tmp_entry;
565         int i;
566         struct vrp_env_t *env = e;
567
568         if (is_Block(n))
569                 return;
570
571         set_irn_link(n, VISITED);
572
573         update_vrp_data(n);
574
575         for (i = get_irn_n_outs(n) - 1; i >=0; --i) {
576                 succ =  get_irn_out(n, i);
577                 if (get_irn_link(succ) == VISITED) {
578                         /* we found a loop*/
579
580                         tmp_entry = XMALLOC(worklist_t);
581                         tmp_entry->node = n;
582                         list_add(&(tmp_entry->nodes), &(env->worklist->nodes));
583
584
585                 }
586         }
587 }
588
589
590 void set_vrp_data(ir_graph *irg)
591 {
592
593         ir_node *succ;
594         int i;
595         worklist_t worklist;
596         worklist_t *tmp_entry, *tmp_entry2;
597         struct vrp_env_t env;
598
599         if (!irg) {
600                 /* no graph, skip */
601                 return;
602         }
603
604         assure_irg_outs(irg); /* ensure that out edges are consistent*/
605
606 /*      edges_activate(irg);*/
607
608         INIT_LIST_HEAD(&worklist.nodes);
609
610         env.worklist = &worklist;
611         irg_walk_graph(irg, NULL, vrp_first_pass, &env);
612
613
614
615         /* while there are entries in the worklist, continue*/
616         while ( !list_empty(&worklist.nodes) ) {
617
618                 list_head *pos, *next;
619                 list_for_each_safe(pos, next, &worklist.nodes) {
620
621                         tmp_entry = list_entry(pos, worklist_t, nodes);
622
623                         if (update_vrp_data(tmp_entry->node)) {
624                                 /* if something changed, add successors to worklist*/
625                                 for (i = get_irn_n_outs(tmp_entry->node) - 1; i >=0; --i) {
626                                         succ =  get_irn_out(tmp_entry->node, i);
627
628                                         tmp_entry2 = XMALLOC(worklist_t);
629                                         tmp_entry2->node = succ;
630                                         list_add(&(tmp_entry2->nodes), &worklist.nodes);
631                                 }
632                         }
633
634                         list_del(pos);
635                         xfree(tmp_entry);
636                 }
637         }
638 }
639
640
641 ir_graph_pass_t *set_vrp_pass(const char *name)
642 {
643         return def_graph_pass(name ? name : "set_vrp", set_vrp_data);
644 }
645
646 pn_Cmp vrp_cmp(ir_node *left, ir_node *right)
647 {
648         if (!left->vrp.valid || !right->vrp.valid) {
649                 return pn_Cmp_False;
650         }
651
652         if (left->vrp.range_type == VRP_RANGE && right->vrp.range_type == VRP_RANGE) {
653                 if (tarval_cmp(left->vrp.range_top, right->vrp.range_bottom) == pn_Cmp_Lt) {
654                         return pn_Cmp_Lt;
655                 }
656                 if (tarval_cmp(left->vrp.range_bottom, right->vrp.range_top) == pn_Cmp_Gt) {
657                         return pn_Cmp_Gt;
658                 }
659         }
660
661         if (!tarval_is_null(tarval_and(left->vrp.bits_set, right->vrp.bits_not_set)) ||
662                         !tarval_is_null(tarval_and(left->vrp.bits_not_set, right->vrp.bits_set))) {
663                 return pn_Cmp_Lg;
664         }
665         /* TODO: We can get way more information here*/
666
667         return pn_Cmp_False;
668 }