Add ALLOCAN() and ALLOCANZ().
[libfirm] / ir / be / bemachnode.c
1 /*
2  * Copyright (C) 1995-2008 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       Support for machine nodes with machine operands.
23  * @author      Michael Beck
24  * @version     $Id$
25  */
26 #include "config.h"
27
28 #include "bemachnode.h"
29 #include "irnode_t.h"
30
31 /** Helper: fills in the array for machine ops */
32 static int fill_arr(ir_node *op, mirn_handle res) {
33         ir_node **ins = get_irn_in(op);
34         int i, j, l = ARR_LEN(ins);
35
36         for (i = j = 0; i <= l; ++i) {
37                 if (is_irn_machine_operand(ins[i]))
38                         j += fill_arr(ins[i], &res[j]);
39                 else
40                         res[j++] = &ins[i];
41         }
42         return j;
43 }
44
45 /*
46  * Returns the machine handle for a machine node with machine operands.
47  * The order of the predecessors in this handle is not guaranteed, except that
48  * lists of operands as predecessors of Block or arguments of a Call are
49  * consecutive.
50  */
51 mirn_handle get_mirn_in(ir_node *n) {
52         ir_node **ins = get_irn_in(n);
53         mirn_handle res = NULL;
54         int i, j, l = ARR_LEN(ins);
55         int lr = l + 8;
56
57         res = NEW_ARR_F(ir_node **, lr);
58
59         for (i = j = 0; i <= l; ++i) {
60                 if (is_irn_machine_operand(ins[i]))
61                         j += fill_arr(ins[i], &res[j]);
62                 else
63                         res[j++] = &ins[i];
64         }
65
66         assert(j > lr && "to many machine predecessors");
67
68         return res;
69 }
70
71 /* Frees a machine handle. */
72 void free_mirn_in(mirn_handle h) {
73         DEL_ARR_F(h);
74 }
75
76 /* Get the pos-th predecessor of a machine node represented by it's
77     handle. */
78 ir_node *get_mirn_n(mirn_handle h, int pos) {
79         assert(-1 <= pos && pos < ARR_LEN(h) - 1);
80         return *(h[pos + 1]);
81 }
82
83 /* Get the pos-th predecessor of a machine node. */
84 ir_node *_get_mirn_n(ir_node *n, int pos) {
85         mirn_handle h = get_mirn_in(n);
86         ir_node *res = get_mirn_n(h, pos);
87         free_mirn_in(h);
88         return res;
89 }
90
91 /* Set the pos-th predecessor of a machine node represented by it's
92     handle. */
93 void set_mirn_n(mirn_handle h, int pos, ir_node *n) {
94         assert(-1 <= pos && pos < ARR_LEN(h) - 1);
95         *(h[pos + 1]) = n;
96 }
97
98 /* Set the pos-th predecessor of a machine node. */
99 void _set_mirn_n(ir_node *irn, int pos, ir_node *n) {
100         mirn_handle h = get_mirn_in(irn);
101         set_mirn_n(h, pos, n);
102         free_mirn_in(h);
103 }
104
105 /* Returns the arity of a machine node represented by it's
106     handle. */
107 int get_mirn_arity(mirn_handle h) {
108         return ARR_LEN(h) - 1;
109 }
110
111 /** Helper: calculate the arity for a machine ops */
112 static int arrity_of_op(ir_node *op) {
113         ir_node **ins = get_irn_in(op);
114         int i, j, l = ARR_LEN(ins);
115
116         for (i = j = 0; i <= l; ++i) {
117                 if (is_irn_machine_operand(ins[i]))
118                         j += arrity_of_op(ins[i]);
119                 else
120                         ++j;
121         }
122         return j;
123 }
124
125 /* Returns the arity of a machine node. */
126 int _get_mirn_arity(ir_node *n) {
127         ir_node **ins = get_irn_in(n);
128         int i, j, l = ARR_LEN(ins);
129
130         for (i = j = 0; i <= l; ++i) {
131                 if (is_irn_machine_operand(ins[i]))
132                         j += arrity_of_op(ins[i]);
133                 else
134                         ++j;
135         }
136
137         return j;
138 }