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) {
47 struct obstack *obst = env->obst;
50 for (i = 0, n = get_irn_arity(mach_op); i < n; ++i) {
51 ir_node *op = get_irn_n(mach_op, i);
53 if (is_irn_machine_operand(op)) {
54 add_machine_operands(env, insn, op);
55 } else if (arch_irn_consider_in_reg_alloc(env->cls, op)) {
58 /* found a register use, create an operand */
59 o.req = arch_get_register_req(mach_op, i);
64 o.has_constraints = arch_register_req_is(o.req, limited);
65 obstack_grow(obst, &o, sizeof(o));
67 insn->in_constraints |= o.has_constraints;
73 * Create a be_insn_t for an IR node.
75 * @param env the insn construction environment
76 * @param irn the irn for which the be_insn should be build
78 * @return the be_insn for the IR node
80 be_insn_t *be_scan_insn(const be_insn_env_t *env, ir_node *irn)
82 struct obstack *obst = env->obst;
88 insn = OALLOCZ(obst, be_insn_t);
91 insn->next_insn = sched_next(irn);
92 if (get_irn_mode(irn) == mode_T) {
93 const ir_edge_t *edge;
96 /* This instruction might create more than one def. These are handled
97 by Proj's, find them. */
98 foreach_out_edge(irn, edge) {
99 p = get_edge_src_irn(edge);
101 /* did not work if the result is a ProjT. This should NOT happen
102 in the backend, but check it for now. */
103 assert(get_irn_mode(p) != mode_T);
105 if (arch_irn_consider_in_reg_alloc(env->cls, p)) {
106 /* found a def: create a new operand */
107 o.req = arch_get_register_req_out(p);
110 o.pos = -(get_Proj_proj(p) + 1);
112 o.has_constraints = arch_register_req_is(o.req, limited);
113 obstack_grow(obst, &o, sizeof(o));
115 insn->out_constraints |= o.has_constraints;
116 pre_colored += arch_get_irn_register(p) != NULL;
119 } else if (arch_irn_consider_in_reg_alloc(env->cls, irn)) {
120 /* only one def, create one operand */
121 o.req = arch_get_register_req_out(irn);
126 o.has_constraints = arch_register_req_is(o.req, limited);
127 obstack_grow(obst, &o, sizeof(o));
129 insn->out_constraints |= o.has_constraints;
130 pre_colored += arch_get_irn_register(irn) != NULL;
133 if (pre_colored > 0) {
134 assert(pre_colored == insn->n_ops && "partly pre-colored nodes not supported");
135 insn->pre_colored = 1;
137 insn->use_start = insn->n_ops;
139 /* now collect the uses for this node */
140 for (i = 0, n = get_irn_arity(irn); i < n; ++i) {
141 ir_node *op = get_irn_n(irn, i);
143 if (is_irn_machine_operand(op)) {
144 add_machine_operands(env, insn, op);
145 } else if (arch_irn_consider_in_reg_alloc(env->cls, op)) {
146 /* found a register use, create an operand */
147 o.req = arch_get_register_req(irn, i);
152 o.has_constraints = arch_register_req_is(o.req, limited);
153 obstack_grow(obst, &o, sizeof(o));
155 insn->in_constraints |= o.has_constraints;
159 insn->has_constraints = insn->in_constraints | insn->out_constraints;
160 insn->ops = obstack_finish(obst);
162 /* Compute the admissible registers bitsets. */
163 for (i = 0; i < insn->n_ops; ++i) {
164 be_operand_t *op = &insn->ops[i];
165 const arch_register_req_t *req = op->req;
166 const arch_register_class_t *cls = req->cls;
167 arch_register_req_type_t type = req->type;
169 /* If there is no special requirement, we allow current class here */
170 if (cls == NULL && req->type == arch_register_req_type_none) {
172 type = arch_register_req_type_normal;
175 assert(cls == env->cls);
177 op->regs = bitset_obstack_alloc(obst, env->cls->n_regs);
179 if (type & arch_register_req_type_limited) {
180 rbitset_copy_to_bitset(req->limited, op->regs);
182 arch_put_non_ignore_regs(env->cls, op->regs);
183 if (env->ignore_colors)
184 bitset_andnot(op->regs, env->ignore_colors);
191 be_insn_env_t *be_insn_env_init(be_insn_env_t *ie, const be_irg_t *birg,
192 const arch_register_class_t *cls,
193 struct obstack *obst)
197 ie->ignore_colors = bitset_obstack_alloc(obst, cls->n_regs);
198 be_abi_put_ignore_regs(birg->abi, cls, ie->ignore_colors);