Implement access functions for machine nodes with machine operands
[libfirm] / ir / be / bemachnode.c
1 #include "bemachnode.h"
2 #include "irnode_t.h"
3
4 typedef ir_node *** mirn_handle;
5
6 /** Helper: fills in the array for machine ops */
7 static int fill_arr(ir_node *op, mirn_handle res) {
8         ir_node **ins = get_irn_in(op);
9         int i, j, l = ARR_LEN(ins);
10
11         for (i = j = 0; i <= l; ++i) {
12                 if (is_irn_machine_operand(ins[i]))
13                         j += fill_arr(ins[i], &res[j]);
14                 else
15                         res[j++] = &ins[i];
16         }
17         return j;
18 }
19
20 /*
21  * Returns the machine handle for a machine node with machine operands.
22  * The order of the predecessors in this handle is not guaranteed, except that
23  * lists of operands as predecessors of Block or arguments of a Call are
24  * consecutive.
25  */
26 mirn_handle get_mirn_in(ir_node *n) {
27         ir_node **ins = get_irn_in(n);
28         mirn_handle res = NULL;
29         int i, j, l = ARR_LEN(ins);
30         int lr = l + 8;
31
32         res = NEW_ARR_F(ir_node **, lr);
33
34         for (i = j = 0; i <= l; ++i) {
35                 if (is_irn_machine_operand(ins[i]))
36                         j += fill_arr(ins[i], &res[j]);
37                 else
38                         res[j++] = &ins[i];
39         }
40
41         assert(j > lr && "to many machine predecessors");
42
43         return res;
44 }
45
46 /* Frees a machine handle. */
47 void free_mirn_in(mirn_handle h) {
48         DEL_ARR_F(h);
49 }
50
51 /* Get the pos-th predecessor of a machine node represented by it's
52     handle. */
53 ir_node *get_mirn_n(mirn_handle h, int pos) {
54         assert(-1 <= pos && pos < ARR_LEN(h) - 1);
55         return *(h[pos + 1]);
56 }
57
58 /* Get the pos-th predecessor of a machine node. */
59 ir_node *_get_mirn_n(ir_node *n, int pos) {
60         mirn_handle h = get_mirn_in(n);
61         ir_node *res = get_mirn_n(h, pos);
62         free_mirn_in(h);
63         return res;
64 }
65
66 /* Set the pos-th predecessor of a machine node represented by it's
67     handle. */
68 void set_mirn_n(mirn_handle h, int pos, ir_node *n) {
69         assert(-1 <= pos && pos < ARR_LEN(h) - 1);
70         *(h[pos + 1]) = n;
71 }
72
73 /* Set the pos-th predecessor of a machine node. */
74 void _set_mirn_n(ir_node *irn, int pos, ir_node *n) {
75         mirn_handle h = get_mirn_in(irn);
76         set_mirn_n(h, pos, n);
77         free_mirn_in(h);
78 }
79
80 /* Returns the arity of a machine node represented by it's
81     handle. */
82 int get_mirn_arity(mirn_handle h) {
83         return ARR_LEN(h) - 1;
84 }
85
86 /** Helper: calculate the arity for a machine ops */
87 static int arrity_of_op(ir_node *op) {
88         ir_node **ins = get_irn_in(op);
89         int i, j, l = ARR_LEN(ins);
90
91         for (i = j = 0; i <= l; ++i) {
92                 if (is_irn_machine_operand(ins[i]))
93                         j += arrity_of_op(ins[i]);
94                 else
95                         ++j;
96         }
97         return j;
98 }
99
100 /* Returns the arity of a machine node. */
101 int _get_mirn_arity(ir_node *n) {
102         ir_node **ins = get_irn_in(n);
103         int i, j, l = ARR_LEN(ins);
104
105         for (i = j = 0; i <= l; ++i) {
106                 if (is_irn_machine_operand(ins[i]))
107                         j += arrity_of_op(ins[i]);
108                 else
109                         ++j;
110         }
111
112         return j;
113 }