cleanup: Remove duplicate MIN/MAX macros.
[libfirm] / ir / ana / irbackedge.c
1 /*
2  * This file is part of libFirm.
3  * Copyright (C) 2012 University of Karlsruhe.
4  */
5
6 /**
7  * @file
8  * @brief     Access function for backedges.
9  * @author    Goetz Lindenmaier
10  * @date      7.2002
11  */
12 #include "config.h"
13
14 #include "irnode_t.h"
15 #include "irgraph_t.h"
16 #include "array.h"
17 #include "irbackedge_t.h"
18
19 /*--------------------------------------------------------------------*/
20 /* Backedge information.                                              */
21 /*--------------------------------------------------------------------*/
22
23
24 /**
25  * Returns backarray if the node can have backedges, else returns
26  * NULL.
27  *
28  * Does not assert whether the backarray is correct -- use
29  * very careful!
30  */
31 static bitset_t *mere_get_backarray(const ir_node *n)
32 {
33         switch (get_irn_opcode(n)) {
34         case iro_Block:
35                 if (!get_Block_matured(n)) return NULL;
36
37                 assert(n->attr.block.backedge && "backedge array not allocated!");
38                 return n->attr.block.backedge;
39         case iro_Phi:
40                 assert(n->attr.phi.u.backedge && "backedge array not allocated!");
41                 return n->attr.phi.u.backedge;
42         default:
43                 break;
44         }
45         return NULL;
46 }
47
48 /**
49  * Returns backarray if the node can have backedges, else returns
50  * NULL.
51  */
52 static bitset_t *get_backarray(const ir_node *n)
53 {
54         bitset_t *ba = mere_get_backarray(n);
55
56 #ifndef NDEBUG
57         if (ba) {
58                 size_t bal = bitset_size(ba);  /* avoid macro expansion in assertion. */
59                 size_t inl = get_irn_arity(n);
60                 assert(bal == inl && "backedge array with faulty length");
61         }
62 #endif
63
64         return ba;
65 }
66
67 #ifndef NDEBUG
68 /**
69  * Returns non-zero if node has no backarray, or
70  *                  if size of backarray == size of in array.
71  */
72 static int legal_backarray(const ir_node *n)
73 {
74         bitset_t *ba = mere_get_backarray(n);
75         if (ba && (bitset_size(ba) != (unsigned) get_irn_arity(n)))
76                 return 0;
77         return 1;
78 }
79 #endif
80
81 void fix_backedges(struct obstack *obst, ir_node *n)
82 {
83         bitset_t *arr = mere_get_backarray(n);
84         unsigned opc;
85         int arity;
86
87         if (! arr)
88                 return;
89
90         arity = get_irn_arity(n);
91         if (bitset_size(arr) != (unsigned) arity) {
92                 arr = new_backedge_arr(obst, arity);
93
94                 opc = get_irn_opcode(n);
95                 if (opc == iro_Phi)
96                         n->attr.phi.u.backedge = arr;
97                 else if (opc == iro_Block) {
98                         n->attr.block.backedge = arr;
99                 }
100         }
101
102         assert(legal_backarray(n));
103 }
104
105 int is_backedge(const ir_node *n, int pos)
106 {
107         bitset_t *ba = get_backarray(n);
108         if (ba)
109                 return bitset_is_set(ba, pos);
110         return 0;
111 }
112
113 void set_backedge(ir_node *n, int pos)
114 {
115         bitset_t *ba = get_backarray(n);
116         assert(ba && "can only set backedges at Phi, Block nodes.");
117         bitset_set(ba, pos);
118 }
119
120 void set_not_backedge(ir_node *n, int pos)
121 {
122         bitset_t *ba = get_backarray(n);
123         assert(ba && "can only set backedges at Phi, Block nodes.");
124         bitset_clear(ba, pos);
125 }
126
127 int has_backedges(const ir_node *n)
128 {
129         bitset_t *ba = get_backarray(n);
130         if (ba != NULL) {
131                 return !bitset_is_empty(ba);
132         }
133         return 0;
134 }
135
136 void clear_backedges(ir_node *n)
137 {
138         bitset_t *ba = get_backarray(n);
139         if (ba != NULL) {
140                 bitset_clear_all(ba);
141         }
142 }
143
144 bitset_t *new_backedge_arr(struct obstack *obst, size_t size)
145 {
146         return bitset_obstack_alloc(obst, size);
147 }