Dump special characters in string intializers properly, e.g. tab as \t.
[libfirm] / ir / ana / vrp.c
1 /*
2  * Copyright (C) 1995-2010 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 "irtypes.h"
29 #include "vrp.h"
30 #include "iroptimize.h"
31 #include "irouts.h"
32 #include "irgraph_t.h"
33 #include "irgopt.h"
34 #include "irpass.h"
35 #include "irgwalk.h"
36 #include "iredges.h"
37 #include "tv.h"
38 #include "irop.h"
39 #include "pdeq.h"
40 #include "irnodemap.h"
41 #include "irhooks.h"
42 #include "bitset.h"
43 #include "debug.h"
44
45 DEBUG_ONLY(static firm_dbg_module_t *dbg;)
46
47 typedef struct vrp_env_t {
48         waitq       *workqueue;
49         bitset_t    *visited;
50         ir_vrp_info *info;
51 } vrp_env_t;
52
53 static vrp_attr *vrp_get_or_set_info(ir_vrp_info *info, const ir_node *node)
54 {
55         vrp_attr *attr = ir_nodemap_get(&info->infos, node);
56         if (attr == NULL) {
57                 ir_mode *mode = get_irn_mode(node);
58                 assert(mode_is_int(mode));
59
60                 attr = obstack_alloc(&info->obst, sizeof(*attr));
61                 memset(attr, 0, sizeof(*attr));
62                 attr->range_type   = VRP_UNDEFINED;
63                 attr->bits_set     = get_mode_null(mode);
64                 attr->bits_not_set = get_mode_all_one(mode);
65                 attr->range_bottom = get_tarval_top();
66                 attr->range_top    = get_tarval_top();
67
68                 ir_nodemap_insert(&info->infos, node, attr);
69         }
70         return attr;
71 }
72
73 vrp_attr *vrp_get_info(const ir_node *node)
74 {
75         ir_graph *irg = get_irn_irg(node);
76         if (irg->vrp.infos.data == NULL)
77                 return NULL;
78         return (vrp_attr*) ir_nodemap_get(&irg->vrp.infos, node);
79 }
80
81 static int vrp_update_node(ir_vrp_info *info, ir_node *node)
82 {
83         ir_tarval *new_bits_set = get_tarval_bad();
84         ir_tarval *new_bits_not_set = get_tarval_bad();
85         ir_tarval *new_range_bottom = get_tarval_bad();
86         ir_tarval *new_range_top = get_tarval_bad();
87         enum range_types new_range_type = VRP_UNDEFINED;
88         int something_changed = 0;
89         vrp_attr *vrp;
90
91         if (!mode_is_int(get_irn_mode(node))) {
92                 return 0; /* we don't optimize for non-int-nodes*/
93         }
94
95         vrp = vrp_get_or_set_info(info, node);
96
97         /* TODO: Check if all predecessors have valid VRP information*/
98
99         switch (get_irn_opcode(node)) {
100         case iro_Const: {
101                 ir_tarval *tv = get_Const_tarval(node);
102                 new_bits_set = tv;
103                 new_bits_not_set = tv;
104                 new_range_bottom = tv;
105                 new_range_top = tv;
106                 new_range_type = VRP_RANGE;
107                 break;
108         }
109         case iro_And: {
110                 const vrp_attr *vrp_left, *vrp_right;
111                 const ir_node *left, *right;
112
113                 left = get_And_left(node);
114                 right = get_And_right(node);
115                 vrp_left = vrp_get_or_set_info(info, left);
116                 vrp_right = vrp_get_or_set_info(info, right);
117                 new_bits_set = tarval_and(vrp_left->bits_set, vrp_right->bits_set);
118                 new_bits_not_set = tarval_and(vrp_left->bits_not_set, vrp_right->bits_not_set);
119
120                 break;
121         }
122
123         case iro_Add: {
124                 int overflow_top, overflow_bottom;
125                 ir_tarval *new_top, *new_bottom;
126                 const vrp_attr *vrp_left, *vrp_right;
127                 vrp_left = vrp_get_or_set_info(info, get_Add_left(node));
128                 vrp_right = vrp_get_or_set_info(info, get_Add_right(node));
129
130                 if (vrp_left->range_type == VRP_UNDEFINED || vrp_right->range_type ==
131                                 VRP_UNDEFINED || vrp_left->range_type == VRP_VARYING ||
132                                 vrp_right->range_type == VRP_VARYING) {
133                         return 0;
134                 }
135
136                 new_top = tarval_add(vrp_left->range_top, vrp_right->range_top);
137                 overflow_top = tarval_carry();
138                 new_bottom = tarval_add(vrp_left->range_bottom, vrp_right->range_bottom);
139                 overflow_bottom = tarval_carry();
140
141                 if (!overflow_top && !overflow_bottom && vrp_left->range_type == VRP_RANGE
142                                 &&vrp_right->range_type == VRP_RANGE) {
143                         new_range_bottom = new_bottom;
144                         new_range_top = new_top;
145                         new_range_type = VRP_RANGE;
146                 }
147
148                 if (overflow_top || overflow_bottom) {
149                         /* TODO Implement overflow handling*/
150                         new_range_type = VRP_UNDEFINED;
151                 }
152                 break;
153         }
154
155         case iro_Sub: {
156                 ir_node *left  = get_Sub_left(node);
157                 ir_node *right = get_Sub_right(node);
158                 int overflow_top, overflow_bottom;
159                 ir_tarval *new_top, *new_bottom;
160                 const vrp_attr *vrp_left, *vrp_right;
161
162                 if (!mode_is_int(get_irn_mode(left)))
163                         return 0;
164
165                 vrp_left  = vrp_get_or_set_info(info, left);
166                 vrp_right = vrp_get_or_set_info(info, right);
167
168                 if (vrp_left->range_type == VRP_UNDEFINED || vrp_right->range_type ==
169                                 VRP_UNDEFINED || vrp_left->range_type == VRP_VARYING ||
170                                 vrp_right->range_type == VRP_VARYING) {
171                         return 0;
172                 }
173
174                 new_top = tarval_sub(vrp_left->range_top, vrp_right->range_top, NULL);
175                 overflow_top = tarval_carry();
176                 new_bottom = tarval_sub(vrp_left->range_bottom, vrp_right->range_bottom, NULL);
177                 overflow_bottom = tarval_carry();
178
179                 if (!overflow_top && !overflow_bottom && vrp_left->range_type == VRP_RANGE
180                                 &&vrp_right->range_type == VRP_RANGE) {
181                         new_range_bottom = new_bottom;
182                         new_range_top = new_top;
183                         new_range_type = VRP_RANGE;
184                 }
185
186                 if (overflow_top || overflow_bottom) {
187                         /* TODO Implement overflow handling*/
188                 }
189                 break;
190         }
191
192         case iro_Or: {
193                 const vrp_attr *vrp_left, *vrp_right;
194
195                 vrp_left = vrp_get_or_set_info(info, get_Or_left(node));
196                 vrp_right = vrp_get_or_set_info(info, get_Or_right(node));
197
198                 new_bits_set = tarval_or(vrp_left->bits_set, vrp_right->bits_set);
199                 new_bits_not_set = tarval_or(vrp_left->bits_not_set, vrp_right->bits_not_set);
200
201                 break;
202         }
203
204         case iro_Rotl: {
205                 const vrp_attr *vrp_left;
206                 const ir_node *right = get_Rotl_right(node);
207
208                 vrp_left = vrp_get_or_set_info(info, get_Rotl_left(node));
209
210                 /* We can only compute this if the right value is a constant*/
211                 if (is_Const(right)) {
212                         new_bits_set = tarval_rotl(vrp_left->bits_set, get_Const_tarval(right));
213                         new_bits_not_set = tarval_rotl(vrp_left->bits_not_set, get_Const_tarval(right));
214                 }
215                 break;
216         }
217
218         case iro_Shl: {
219                 const vrp_attr *vrp_left;
220                 const ir_node *right = get_Shl_right(node);
221                 vrp_left = vrp_get_or_set_info(info, get_Shl_left(node));
222
223                 /* We can only compute this if the right value is a constant*/
224                 if (is_Const(right)) {
225                         new_bits_set = tarval_shl(vrp_left->bits_set, get_Const_tarval(right));
226                         new_bits_not_set = tarval_shl(vrp_left->bits_not_set, get_Const_tarval(right));
227                 }
228                 break;
229         }
230
231         case iro_Shr: {
232                 const vrp_attr *vrp_left;
233                 const ir_node *right = get_Shr_right(node);
234
235                 vrp_left = vrp_get_or_set_info(info, get_Shr_left(node));
236
237                 /* We can only compute this if the right value is a constant*/
238                 if (is_Const(right)) {
239                         new_bits_set = tarval_shr(vrp_left->bits_set, get_Const_tarval(right));
240                         new_bits_not_set = tarval_shr(vrp_left->bits_not_set, get_Const_tarval(right));
241                 }
242                 break;
243         }
244
245         case iro_Shrs: {
246                 const vrp_attr *vrp_left;
247                 const ir_node *right = get_Shrs_right(node);
248
249                 vrp_left = vrp_get_or_set_info(info, get_Shrs_left(node));
250
251                 /* We can only compute this if the right value is a constant*/
252                 if (is_Const(right)) {
253                         new_bits_set = tarval_shrs(vrp_left->bits_set, get_Const_tarval(right));
254                         new_bits_not_set = tarval_shrs(vrp_left->bits_not_set, get_Const_tarval(right));
255                 }
256                 break;
257         }
258
259         case iro_Eor: {
260                 const vrp_attr *vrp_left, *vrp_right;
261
262                 vrp_left = vrp_get_or_set_info(info, get_Eor_left(node));
263                 vrp_right = vrp_get_or_set_info(info, get_Eor_right(node));
264
265                 new_bits_set = tarval_or(
266                                                 tarval_and(vrp_left->bits_set, tarval_not(vrp_right->bits_not_set)),
267                                                 tarval_and(tarval_not(vrp_left->bits_not_set), vrp_right->bits_set));
268
269                 new_bits_not_set = tarval_not(tarval_or(
270                                 tarval_and(vrp_left->bits_set,vrp_right->bits_set),
271                                                         tarval_and(tarval_not(vrp_left->bits_not_set),
272                                                                 tarval_not(vrp_right->bits_not_set))));
273
274                 break;
275         }
276
277         case iro_Id: {
278                 const vrp_attr *vrp_pred = vrp_get_or_set_info(info, get_Id_pred(node));
279                 new_bits_set = vrp_pred->bits_set;
280                 new_bits_not_set = vrp_pred->bits_not_set;
281                 new_range_top = vrp_pred->range_top;
282                 new_range_bottom = vrp_pred->range_bottom;
283                 new_range_type = vrp_pred->range_type;
284                 break;
285         }
286
287         case iro_Not: {
288                 const vrp_attr *vrp_pred = vrp_get_or_set_info(info, get_Not_op(node));
289                 new_bits_set = tarval_not(vrp_pred->bits_not_set);
290                 new_bits_not_set = tarval_not(vrp_pred->bits_set);
291                 break;
292         }
293
294         case iro_Conv: {
295                 const ir_node *pred = get_Conv_op(node);
296                 ir_mode *old_mode = get_irn_mode(pred);
297                 const vrp_attr *vrp_pred;
298
299                 ir_mode *new_mode;
300
301                 if (!mode_is_int(old_mode))
302                         return 0;
303
304                 vrp_pred = vrp_get_or_set_info(info, pred);
305                 new_mode = get_irn_mode(node);
306
307                 /* The second and is needed if target type is smaller*/
308                 new_bits_not_set = tarval_convert_to(get_mode_all_one(old_mode), new_mode);
309                 new_bits_not_set = tarval_and(new_bits_not_set, tarval_convert_to(vrp_pred->bits_not_set, new_mode));
310                 new_bits_set = tarval_and(
311                                 new_bits_not_set, tarval_convert_to(vrp_pred->bits_set, new_mode));
312
313                 /* Matze: TODO, BUGGY, tarval_cmp never returns ir_relation_less_equal */
314                 if (tarval_cmp(vrp_pred->range_top, get_mode_max(new_mode)) == ir_relation_less_equal) {
315                         vrp->range_top = vrp_pred->range_top;
316                 }
317
318                 /* Matze: TODO, BUGGY, tarval_cmp never returns ir_relation_greater_equal */
319                 if (tarval_cmp(vrp_pred->range_bottom, get_mode_min(new_mode)) == ir_relation_greater_equal) {
320                         vrp->range_bottom = vrp_pred->range_bottom;
321                 }
322                 break;
323         }
324
325         case iro_Confirm: {
326                 const ir_relation relation = get_Confirm_relation(node);
327                 const ir_node    *bound    = get_Confirm_bound(node);
328
329
330                 if (relation == ir_relation_less_greater) {
331                         /** @todo: Handle non-Const bounds */
332                         if (is_Const(bound)) {
333                                 new_range_type = VRP_ANTIRANGE;
334                                 new_range_top = get_Const_tarval(bound);
335                                 new_range_bottom = get_Const_tarval(bound);
336                         }
337                 } else if (relation == ir_relation_less_equal) {
338                         if (is_Const(bound)) {
339                                 new_range_type = VRP_RANGE;
340                                 new_range_top = get_Const_tarval(bound);
341                                 new_range_bottom = get_tarval_min(get_irn_mode(node));
342                         }
343                 }
344                 break;
345         }
346
347         case iro_Phi: {
348                 /* combine all ranges*/
349
350                 int num = get_Phi_n_preds(node);
351                 ir_relation relation;
352                 int i;
353
354                 const ir_node *pred = get_Phi_pred(node,0);
355                 const vrp_attr *vrp_pred = vrp_get_or_set_info(info, pred);
356                 new_range_top = vrp_pred->range_top;
357                 new_range_bottom = vrp_pred->range_bottom;
358                 new_range_type = vrp_pred->range_type;
359                 new_bits_set = vrp_pred->bits_set;
360                 new_bits_not_set = vrp_pred->bits_not_set;
361
362                 assert(num > 0);
363
364                 for (i = 1; i < num; i++) {
365                         pred = get_Phi_pred(node, i);
366                         vrp_pred = vrp_get_or_set_info(info, pred);
367                         if (new_range_type == VRP_RANGE && vrp_pred->range_type ==
368                                         VRP_RANGE) {
369                                 relation = tarval_cmp(new_range_top, vrp_pred->range_top);
370                                 if (relation == ir_relation_less) {
371                                         new_range_top = vrp_pred->range_top;
372                                 }
373                                 relation = tarval_cmp(new_range_bottom, vrp_pred->range_bottom);
374                                 if (relation == ir_relation_greater) {
375                                         new_range_bottom = vrp_pred->range_bottom;
376                                 }
377                         } else {
378                                 new_range_type = VRP_VARYING;
379                         }
380                         new_bits_set = tarval_and(new_bits_set, vrp_pred->bits_set);
381                         new_bits_not_set = tarval_or(new_bits_not_set,
382                                         vrp_pred->bits_not_set);
383                 }
384
385                 break;
386         }
387         default:
388                 /* unhandled, therefore never updated */
389                 break;
390         }
391
392
393
394         /* TODO: Check, if there can be information derived from any of these:
395         is_Abs(node) is_Alloc(node) is_Anchor(node) is_Borrow(node) is_Bound(node)
396         is_Break(node) is_Builtin(node) is_Call(node)
397         is_Carry(node) is_Cast(node) is_Cmp(node) is_Cond(node)
398         is_CopyB(node) is_Div(node) is_Dummy(node)
399         is_End(node) is_Free(node)
400         is_IJmp(node) is_InstOf(node) is_Jmp(node) is_Load(node) is_Minus(node)
401         is_Mod(node) is_Mul(node) is_Mulh(node) is_Mux(node) is_NoMem(node)
402         is_Pin(node) is_Proj(node)
403         is_Raise(node) is_Return(node) is_Sel(node) is_Start(node) is_Store(node)
404         is_SymConst(node) is_Sync(node) is_Tuple(node)
405         */
406
407         /* @todo: At this place, we check if the mode of the variable changed. A
408          * better place for this might be in the convopt.c file
409          */
410
411         if (new_bits_set != tarval_bad && get_tarval_mode(new_bits_set) != get_tarval_mode(vrp->bits_set)) {
412                 vrp->bits_set = tarval_convert_to(vrp->bits_set, get_irn_mode(node));
413         }
414         if (new_bits_not_set != tarval_bad && get_tarval_mode(new_bits_not_set) != get_tarval_mode(vrp->bits_not_set)) {
415                 vrp->bits_not_set = tarval_convert_to(vrp->bits_not_set, get_irn_mode(node));
416         }
417
418         if (vrp->range_type != VRP_UNDEFINED && new_range_type != VRP_UNDEFINED && get_tarval_mode(new_range_top) != get_tarval_mode(vrp->range_top)) {
419                 /* @todo: We might be able to preserve this range information if it
420                  * fits in */
421                 vrp->range_type = VRP_VARYING;
422         }
423
424         /* Merge the newly calculated values with those that might already exist*/
425         if (new_bits_set != tarval_bad) {
426                 new_bits_set = tarval_or(new_bits_set, vrp->bits_set);
427                 if (new_bits_set != vrp->bits_set) {
428                         something_changed = 1;
429                         vrp->bits_set = new_bits_set;
430                 }
431         }
432         if (new_bits_not_set != tarval_bad) {
433                 new_bits_not_set = tarval_and(new_bits_not_set, vrp->bits_not_set);
434
435                 if (new_bits_not_set != vrp->bits_not_set) {
436                         something_changed = 1;
437                         vrp->bits_not_set = new_bits_not_set;
438                 }
439         }
440
441         if (vrp->range_type == VRP_UNDEFINED &&
442                         new_range_type != VRP_UNDEFINED) {
443                 something_changed = 1;
444                 vrp->range_type = new_range_type;
445                 vrp->range_bottom = new_range_bottom;
446                 vrp->range_top = new_range_top;
447
448         } else if (vrp->range_type == VRP_RANGE) {
449                 if (new_range_type == VRP_RANGE) {
450                         if (tarval_cmp(vrp->range_bottom, new_range_bottom) == ir_relation_less) {
451                                 something_changed = 1;
452                                 vrp->range_bottom = new_range_bottom;
453                         }
454                         if (tarval_cmp(vrp->range_top, new_range_top) == ir_relation_greater) {
455                                 something_changed = 1;
456                                 vrp->range_top = new_range_top;
457                         }
458                 }
459
460                 if (new_range_type == VRP_ANTIRANGE) {
461                         /* if they are overlapping, cut the range.*/
462                         /* TODO: Maybe we can preserve more information here*/
463                         if (tarval_cmp(vrp->range_bottom, new_range_top) == ir_relation_greater &&
464                                         tarval_cmp(vrp->range_bottom, new_range_bottom) == ir_relation_greater) {
465                                 something_changed = 1;
466                                 vrp->range_bottom = new_range_top;
467
468                         } else if (tarval_cmp(vrp->range_top, new_range_bottom) == ir_relation_greater &&
469                                         tarval_cmp(vrp->range_top, new_range_top) == ir_relation_less) {
470                                 something_changed = 1;
471                                 vrp->range_top = new_range_bottom;
472                         }
473
474                         /* We can not handle the case where the anti range is in the*/
475                         /* range*/
476
477                 }
478         } else if (vrp->range_type == VRP_ANTIRANGE) {
479                 if (new_range_type == VRP_ANTIRANGE) {
480                         if (tarval_cmp(vrp->range_bottom, new_range_bottom) == ir_relation_greater) {
481                                 something_changed = 1;
482                                 vrp->range_bottom = new_range_bottom;
483                         }
484                         if (tarval_cmp(vrp->range_top, new_range_top) == ir_relation_less) {
485                                 something_changed = 1;
486                                 vrp->range_top = new_range_top;
487                         }
488                 }
489
490                 if (new_range_type == VRP_RANGE) {
491                         if (tarval_cmp(vrp->range_bottom, new_range_top) == ir_relation_greater) {
492                                 something_changed = 1;
493                                 vrp->range_bottom = new_range_top;
494                         }
495                         if (tarval_cmp(vrp->range_top, new_range_bottom) == ir_relation_less) {
496                                 something_changed = 1;
497                                 vrp->range_top = new_range_bottom;
498                         }
499                 }
500         }
501
502         assert(tarval_is_null(
503                                 tarval_and(vrp->bits_set, tarval_not(vrp->bits_not_set))));
504         return something_changed;
505 }
506
507 static void vrp_first_pass(ir_node *n, void *e)
508 {
509         int i;
510         vrp_env_t *env = (vrp_env_t*) e;
511
512         if (is_Block(n))
513                 return;
514
515         bitset_set(env->visited, get_irn_idx(n));
516
517         vrp_update_node(env->info, n);
518
519         assure_irg_outs(get_current_ir_graph());
520         for (i = get_irn_n_outs(n) - 1; i >=0; --i) {
521                 ir_node *succ = get_irn_out(n, i);
522                 if (bitset_is_set(env->visited, get_irn_idx(succ))) {
523                         /* we found a loop*/
524                         waitq_put(env->workqueue, succ);
525                 }
526         }
527 }
528
529 static void dump_vrp_info(void *ctx, FILE *F, const ir_node *node)
530 {
531         vrp_attr *vrp;
532
533         (void) ctx;
534         if (!mode_is_int(get_irn_mode(node)))
535                 return;
536
537         vrp = vrp_get_info(node);
538         if (vrp == NULL)
539                 return;
540
541         fprintf(F, "vrp range type: %d\n", (int) vrp->range_type);
542         if (vrp->range_type == VRP_RANGE || vrp->range_type == VRP_ANTIRANGE) {
543                 ir_fprintf(F, "vrp range bottom: %T\n",vrp->range_bottom);
544                 ir_fprintf(F, "vrp range top: %T\n", vrp->range_top);
545         }
546         ir_fprintf(F, "vrp bits set: %T\n", vrp->bits_set);
547         ir_fprintf(F, "vrp bits not set: %T\n", vrp->bits_not_set);
548 }
549
550 static hook_entry_t dump_hook;
551
552 void set_vrp_data(ir_graph *irg)
553 {
554         ir_node *succ, *node;
555         int i;
556         vrp_env_t *env;
557         ir_vrp_info *info;
558
559         if (irg->vrp.infos.data != NULL)
560                 free_vrp_data(irg);
561
562         FIRM_DBG_REGISTER(dbg, "ir.ana.vrp");
563
564         assure_irg_outs(irg); /* ensure that out edges are consistent*/
565         ir_nodemap_init(&irg->vrp.infos, irg);
566         obstack_init(&irg->vrp.obst);
567         info = &irg->vrp;
568
569         if (dump_hook.hook._hook_node_info == NULL) {
570                 dump_hook.hook._hook_node_info = dump_vrp_info;
571                 register_hook(hook_node_info, &dump_hook);
572         }
573
574         env = obstack_alloc(&irg->vrp.obst, sizeof(*env));
575         env->workqueue = new_waitq();
576         env->info      = info;
577
578         env->visited = bitset_malloc(get_irg_last_idx(irg));
579         irg_walk_graph(irg, NULL, vrp_first_pass, env);
580         bitset_free(env->visited);
581
582         /* while there are entries in the worklist, continue*/
583         while (!waitq_empty(env->workqueue)) {
584                 node = (ir_node*) waitq_get(env->workqueue);
585
586                 if (vrp_update_node(info, node)) {
587                         /* if something changed, add successors to worklist*/
588                         for (i = get_irn_n_outs(node) - 1; i >= 0; --i) {
589                                 succ =  get_irn_out(node, i);
590                                 waitq_put(env->workqueue, succ);
591                         }
592                 }
593         }
594         del_waitq(env->workqueue);
595 }
596
597 void free_vrp_data(ir_graph *irg)
598 {
599         if (irg->vrp.infos.data == NULL)
600                 return;
601         obstack_free(&irg->vrp.obst, NULL);
602         ir_nodemap_destroy(&irg->vrp.infos);
603 }
604
605 ir_graph_pass_t *set_vrp_pass(const char *name)
606 {
607         return def_graph_pass(name ? name : "set_vrp", set_vrp_data);
608 }
609
610 ir_relation vrp_cmp(const ir_node *left, const ir_node *right)
611 {
612         vrp_attr *vrp_left, *vrp_right;
613
614         if (!mode_is_int(get_irn_mode(left)))
615                 return ir_relation_true;
616
617         vrp_left = vrp_get_info(left);
618         vrp_right = vrp_get_info(right);
619
620         if (!vrp_left || !vrp_right)
621                 return ir_relation_true;
622
623         if (vrp_left->range_type == VRP_RANGE && vrp_right->range_type == VRP_RANGE) {
624                 if (tarval_cmp(vrp_left->range_top, vrp_right->range_bottom) == ir_relation_less) {
625                         return ir_relation_less;
626                 }
627                 if (tarval_cmp(vrp_left->range_bottom, vrp_right->range_top) == ir_relation_greater) {
628                         return ir_relation_greater;
629                 }
630         }
631
632         if (!tarval_is_null(tarval_and(vrp_left->bits_set, tarval_not(vrp_right->bits_not_set))) ||
633                         !tarval_is_null(tarval_and(tarval_not(vrp_left->bits_not_set), vrp_right->bits_set))) {
634                 return ir_relation_less_greater;
635         }
636
637         /* TODO: We can get way more information here*/
638         return ir_relation_true;
639 }