2 * Copyright (C) 1995-2008 University of Karlsruhe. All right reserved.
4 * This file is part of libFirm.
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.
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.
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
22 * @brief A data structure to treat nodes and node-proj collections uniformly.
23 * @author Sebastian Hack
28 #include "irgraph_t.h"
37 #include "raw_bitset.h"
40 * Add machine operands to the instruction uses.
42 * @param env the insn construction environment
43 * @param insn the be_insn that is build
44 * @param mach_op the machine operand for which uses are added
46 static void add_machine_operands(const be_insn_env_t *env, be_insn_t *insn, ir_node *mach_op)
48 struct obstack *obst = env->obst;
51 for (i = 0, n = get_irn_arity(mach_op); i < n; ++i) {
52 ir_node *op = get_irn_n(mach_op, i);
54 if (is_irn_machine_operand(op)) {
55 add_machine_operands(env, insn, op);
56 } else if (arch_irn_consider_in_reg_alloc(env->cls, op)) {
59 /* found a register use, create an operand */
60 o.req = arch_get_register_req(mach_op, i);
65 o.has_constraints = arch_register_req_is(o.req, limited);
66 obstack_grow(obst, &o, sizeof(o));
68 insn->in_constraints |= o.has_constraints;
74 * Create a be_insn_t for an IR node.
76 * @param env the insn construction environment
77 * @param irn the irn for which the be_insn should be build
79 * @return the be_insn for the IR node
81 be_insn_t *be_scan_insn(const be_insn_env_t *env, ir_node *irn)
83 struct obstack *obst = env->obst;
89 insn = OALLOCZ(obst, be_insn_t);
92 insn->next_insn = sched_next(irn);
93 if (get_irn_mode(irn) == mode_T) {
94 const ir_edge_t *edge;
97 /* This instruction might create more than one def. These are handled
98 by Proj's, find them. */
99 foreach_out_edge(irn, edge) {
100 p = get_edge_src_irn(edge);
102 /* did not work if the result is a ProjT. This should NOT happen
103 in the backend, but check it for now. */
104 assert(get_irn_mode(p) != mode_T);
106 if (arch_irn_consider_in_reg_alloc(env->cls, p)) {
107 /* found a def: create a new operand */
108 o.req = arch_get_register_req_out(p);
111 o.pos = -(get_Proj_proj(p) + 1);
113 o.has_constraints = arch_register_req_is(o.req, limited);
114 obstack_grow(obst, &o, sizeof(o));
116 insn->out_constraints |= o.has_constraints;
117 pre_colored += arch_get_irn_register(p) != NULL;
120 } else if (arch_irn_consider_in_reg_alloc(env->cls, irn)) {
121 /* only one def, create one operand */
122 o.req = arch_get_register_req_out(irn);
127 o.has_constraints = arch_register_req_is(o.req, limited);
128 obstack_grow(obst, &o, sizeof(o));
130 insn->out_constraints |= o.has_constraints;
131 pre_colored += arch_get_irn_register(irn) != NULL;
134 if (pre_colored > 0) {
135 assert(pre_colored == insn->n_ops && "partly pre-colored nodes not supported");
136 insn->pre_colored = 1;
138 insn->use_start = insn->n_ops;
140 /* now collect the uses for this node */
141 for (i = 0, n = get_irn_arity(irn); i < n; ++i) {
142 ir_node *op = get_irn_n(irn, i);
144 if (is_irn_machine_operand(op)) {
145 add_machine_operands(env, insn, op);
146 } else if (arch_irn_consider_in_reg_alloc(env->cls, op)) {
147 /* found a register use, create an operand */
148 o.req = arch_get_register_req(irn, i);
153 o.has_constraints = arch_register_req_is(o.req, limited);
154 obstack_grow(obst, &o, sizeof(o));
156 insn->in_constraints |= o.has_constraints;
160 insn->has_constraints = insn->in_constraints | insn->out_constraints;
161 insn->ops = obstack_finish(obst);
163 /* Compute the admissible registers bitsets. */
164 for (i = 0; i < insn->n_ops; ++i) {
165 be_operand_t *op = &insn->ops[i];
166 const arch_register_req_t *req = op->req;
167 const arch_register_class_t *cls = req->cls;
168 arch_register_req_type_t type = req->type;
170 /* If there is no special requirement, we allow current class here */
171 if (cls == NULL && req->type == arch_register_req_type_none) {
173 type = arch_register_req_type_normal;
176 assert(cls == env->cls);
178 op->regs = bitset_obstack_alloc(obst, env->cls->n_regs);
180 if (type & arch_register_req_type_limited) {
181 rbitset_copy_to_bitset(req->limited, op->regs);
183 arch_put_non_ignore_regs(env->cls, op->regs);
184 if (env->ignore_colors)
185 bitset_andnot(op->regs, env->ignore_colors);
192 be_insn_env_t *be_insn_env_init(be_insn_env_t *ie, const be_irg_t *birg,
193 const arch_register_class_t *cls,
194 struct obstack *obst)
198 ie->ignore_colors = bitset_obstack_alloc(obst, cls->n_regs);
199 be_abi_put_ignore_regs(birg->abi, cls, ie->ignore_colors);