Commit 1631f8ac authored by Sebastian Hack's avatar Sebastian Hack
Browse files

Added included support for be_insn_t

parent a62baf37
......@@ -122,6 +122,7 @@ void be_abi_fix_stack_nodes(be_abi_irg_t *env);
void be_abi_free(be_abi_irg_t *abi);
void be_abi_put_ignore_regs(be_abi_irg_t *abi, const arch_register_class_t *cls, bitset_t *bs);
ir_node *be_abi_get_callee_save_irn(be_abi_irg_t *abi, const arch_register_t *reg);
#define be_abi_reg_map_get(map, reg) pmap_get((map), (void *) (reg))
......
......@@ -46,6 +46,7 @@
#include "bearch.h"
#include "beirgmod.h"
#include "beifg.h"
#include "beinsn_t.h"
#include "bechordal_t.h"
#include "bechordal_draw.h"
......@@ -181,120 +182,7 @@ static int get_next_free_reg(const be_chordal_alloc_env_t *alloc_env, bitset_t *
return bitset_next_clear(tmp, 0);
}
typedef struct _operand_t operand_t;
struct _operand_t {
ir_node *irn;
ir_node *carrier;
operand_t *partner;
bitset_t *regs;
int pos;
arch_register_req_t req;
unsigned has_constraints : 1;
};
typedef struct {
operand_t *ops;
int n_ops;
int use_start;
ir_node *next_insn;
ir_node *irn;
unsigned in_constraints : 1;
unsigned out_constraints : 1;
unsigned has_constraints : 1;
unsigned pre_colored : 1;
} insn_t;
#define insn_n_defs(insn) ((insn)->use_start)
#define insn_n_uses(insn) ((insn)->n_ops - (insn)->use_start)
static insn_t *scan_insn(be_chordal_alloc_env_t *alloc_env, ir_node *irn, struct obstack *obst)
{
const be_chordal_env_t *env = alloc_env->chordal_env;
const arch_env_t *arch_env = env->birg->main_env->arch_env;
operand_t o;
insn_t *insn;
int i, n;
int pre_colored = 0;
insn = obstack_alloc(obst, sizeof(insn[0]));
memset(insn, 0, sizeof(insn[0]));
insn->irn = irn;
insn->next_insn = sched_next(irn);
if(get_irn_mode(irn) == mode_T) {
ir_node *p;
for(p = sched_next(irn); is_Proj(p); p = sched_next(p)) {
if(arch_irn_consider_in_reg_alloc(arch_env, env->cls, p)) {
arch_get_register_req(arch_env, &o.req, p, -1);
o.carrier = p;
o.irn = irn;
o.pos = -(get_Proj_proj(p) + 1);
o.partner = NULL;
o.has_constraints = arch_register_req_is(&o.req, limited);
obstack_grow(obst, &o, sizeof(o));
insn->n_ops++;
insn->out_constraints |= o.has_constraints;
pre_colored += arch_get_irn_register(arch_env, p) != NULL;
}
}
insn->next_insn = p;
}
else if(arch_irn_consider_in_reg_alloc(arch_env, env->cls, irn)) {
arch_get_register_req(arch_env, &o.req, irn, -1);
o.carrier = irn;
o.irn = irn;
o.pos = -1;
o.partner = NULL;
o.has_constraints = arch_register_req_is(&o.req, limited);
obstack_grow(obst, &o, sizeof(o));
insn->n_ops++;
insn->out_constraints |= o.has_constraints;
pre_colored += arch_get_irn_register(arch_env, irn) != NULL;
}
insn->pre_colored = pre_colored == insn->n_ops && insn->n_ops > 0;
insn->use_start = insn->n_ops;
for(i = 0, n = get_irn_arity(irn); i < n; ++i) {
ir_node *op = get_irn_n(irn, i);
if(arch_irn_consider_in_reg_alloc(arch_env, env->cls, op)) {
arch_get_register_req(arch_env, &o.req, irn, i);
o.carrier = op;
o.irn = irn;
o.pos = i;
o.partner = NULL;
o.has_constraints = arch_register_req_is(&o.req, limited);
obstack_grow(obst, &o, sizeof(o));
insn->n_ops++;
insn->in_constraints |= o.has_constraints;
}
}
insn->has_constraints = insn->in_constraints | insn->out_constraints;
insn->ops = obstack_finish(obst);
/* Compute the admissible registers bitsets. */
for(i = 0; i < insn->n_ops; ++i) {
operand_t *op = &insn->ops[i];
assert(op->req.cls == env->cls);
op->regs = bitset_obstack_alloc(obst, env->cls->n_regs);
if(arch_register_req_is(&op->req, limited))
op->req.limited(op->req.limited_env, op->regs);
else
arch_put_non_ignore_regs(env->birg->main_env->arch_env, env->cls, op->regs);
}
return insn;
}
static bitset_t *get_decisive_partner_regs(bitset_t *bs, const operand_t *o1, const operand_t *o2)
static bitset_t *get_decisive_partner_regs(bitset_t *bs, const be_operand_t *o1, const be_operand_t *o2)
{
bitset_t *res = bs;
......@@ -320,12 +208,23 @@ static bitset_t *get_decisive_partner_regs(bitset_t *bs, const operand_t *o1, co
return res;
}
static void pair_up_operands(const be_chordal_alloc_env_t *alloc_env, insn_t *insn)
static be_insn_t *chordal_scan_insn(be_chordal_alloc_env_t *env, ir_node *irn)
{
be_insn_env_t ie;
ie.ignore_colors = env->chordal_env->ignore_colors;
ie.aenv = env->chordal_env->birg->main_env->arch_env;
ie.obst = &env->chordal_env->obst;
ie.cls = env->chordal_env->cls;
return be_scan_insn(&ie, irn);
}
static void pair_up_operands(const be_chordal_alloc_env_t *alloc_env, be_insn_t *insn)
{
const be_chordal_env_t *env = alloc_env->chordal_env;
int n_uses = insn_n_uses(insn);
int n_defs = insn_n_defs(insn);
int n_uses = be_insn_n_uses(insn);
int n_defs = be_insn_n_defs(insn);
bitset_t *bs = bitset_alloca(env->cls->n_regs);
bipartite_t *bp = bipartite_new(n_defs, n_uses);
int *pairing = alloca(MAX(n_defs, n_uses) * sizeof(pairing[0]));
......@@ -337,11 +236,11 @@ static void pair_up_operands(const be_chordal_alloc_env_t *alloc_env, insn_t *in
same register as the out operand.
*/
for(j = 0; j < insn->use_start; ++j) {
operand_t *out_op = &insn->ops[j];
be_operand_t *out_op = &insn->ops[j];
/* Try to find an in operand which has ... */
for(i = insn->use_start; i < insn->n_ops; ++i) {
const operand_t *op = &insn->ops[i];
const be_operand_t *op = &insn->ops[i];
/*
The in operand can only be paired with a def, if the node defining the
......@@ -375,11 +274,11 @@ static void pair_up_operands(const be_chordal_alloc_env_t *alloc_env, insn_t *in
}
static ir_node *pre_process_constraints(be_chordal_alloc_env_t *alloc_env, insn_t **the_insn)
static ir_node *pre_process_constraints(be_chordal_alloc_env_t *alloc_env, be_insn_t **the_insn)
{
be_chordal_env_t *env = alloc_env->chordal_env;
const arch_env_t *aenv = env->birg->main_env->arch_env;
insn_t *insn = *the_insn;
be_insn_t *insn = *the_insn;
ir_node *bl = get_nodes_block(insn->irn);
ir_node *copy = NULL;
ir_node *perm = NULL;
......@@ -398,7 +297,7 @@ static ir_node *pre_process_constraints(be_chordal_alloc_env_t *alloc_env, insn_
be copied.
*/
for(i = 0; i < insn->use_start; ++i) {
operand_t *op = &insn->ops[i];
be_operand_t *op = &insn->ops[i];
if(op->has_constraints)
bitset_or(out_constr, op->regs);
}
......@@ -408,7 +307,7 @@ static ir_node *pre_process_constraints(be_chordal_alloc_env_t *alloc_env, insn_
constraints which are also output constraints.
*/
for(i = insn->use_start; i < insn->n_ops; ++i) {
operand_t *op = &insn->ops[i];
be_operand_t *op = &insn->ops[i];
if(op->has_constraints && (values_interfere(op->carrier, insn->irn) || arch_irn_is(aenv, op->carrier, ignore))) {
bitset_copy(bs, op->regs);
bitset_and(bs, out_constr);
......@@ -449,14 +348,14 @@ static ir_node *pre_process_constraints(be_chordal_alloc_env_t *alloc_env, insn_
*/
be_liveness(env->irg);
obstack_free(&env->obst, insn);
*the_insn = insn = scan_insn(alloc_env, insn->irn, &env->obst);
*the_insn = insn = chordal_scan_insn(alloc_env, insn->irn);
/*
Copy the input constraints of the insn to the Perm as output
constraints. Succeeding phases (coalescing will need that).
*/
for(i = insn->use_start; i < insn->n_ops; ++i) {
operand_t *op = &insn->ops[i];
be_operand_t *op = &insn->ops[i];
ir_node *proj = op->carrier;
/*
Note that the predecessor must not be a Proj of the Perm,
......@@ -475,7 +374,7 @@ static ir_node *handle_constraints(be_chordal_alloc_env_t *alloc_env, ir_node *i
{
be_chordal_env_t *env = alloc_env->chordal_env;
void *base = obstack_base(&env->obst);
insn_t *insn = scan_insn(alloc_env, irn, &env->obst);
be_insn_t *insn = chordal_scan_insn(alloc_env, irn);
ir_node *res = insn->next_insn;
int be_silent = *silent;
......@@ -532,7 +431,7 @@ static ir_node *handle_constraints(be_chordal_alloc_env_t *alloc_env, ir_node *i
to a bipartite graph (left: nodes with partners, right: admissible colors).
*/
for(i = 0, n_alloc = 0; i < insn->n_ops; ++i) {
operand_t *op = &insn->ops[i];
be_operand_t *op = &insn->ops[i];
/*
If the operand has no partner or the partner has not been marked
......
......@@ -94,6 +94,7 @@ alloc ::= node-nr reg-nr .
#include "besched_t.h"
#include "beutil.h"
#include "belive_t.h"
#include "beinsn_t.h"
#define DBG_LEVEL 2
......@@ -193,14 +194,17 @@ static int get_loop_weight(ir_node *irn) {
|_|
*****************************************************************************/
static void handle_constraints_walker(ir_node *irn, void *env) {
be_raext_env_t *raenv = env;
#if 0
static void handle_constraints_insn(be_raext_env_t *raenv, be_insn_t *insn)
{
arch_register_req_t req;
int pos, max;
/* handle output constraints
* user -> irn becomes user -> cpy -> irn
*/
if(get_irn_mode(irn) == mode_T) {
}
arch_get_register_req(raenv->aenv, &req, irn, -1);
if (arch_register_req_is(&req, limited)) {
ir_node *cpy = be_new_Copy(req.cls, raenv->irg, get_nodes_block(irn), irn);
......@@ -230,9 +234,67 @@ static void handle_constraints_walker(ir_node *irn, void *env) {
}
}
}
#endif
static void handle_constraints_insn(be_raext_env_t *env, be_insn_t *insn)
{
ir_node *bl = get_nodes_block(insn->irn);
int i;
for(i = 0; i < insn->use_start; ++i) {
be_operand_t *op = &insn->ops[i];
if(op->has_constraints) {
ir_node *cpy = be_new_Copy(op->req.cls, env->irg, bl, op->carrier);
sched_add_before(insn->next_insn, cpy);
edges_reroute(op->carrier, cpy, env->irg);
}
}
for(i = insn->use_start; i < insn->n_ops; ++i) {
be_operand_t *op = &insn->ops[i];
if(op->has_constraints) {
ir_node *cpy = be_new_Copy(op->req.cls, env->irg, bl, op->carrier);
sched_add_before(insn->irn, cpy);
set_irn_n(insn->irn, op->pos, cpy);
be_set_constr_limited(cpy, BE_OUT_POS(0), &op->req);
}
}
}
static void handle_constraints_block(ir_node *bl, void *data)
{
be_raext_env_t *raenv = data;
int active = bl != get_irg_start_block(raenv->irg);
ir_node *irn;
be_insn_env_t ie;
struct obstack obst;
ie.cls = raenv->cls;
ie.aenv = raenv->aenv;
ie.obst = &obst;
ie.ignore_colors = NULL;
obstack_init(&obst);
irn = sched_first(bl);
while(!sched_is_end(irn)) {
be_insn_t *insn = be_scan_insn(&ie, irn);
if(insn->has_constraints)
handle_constraints_insn(raenv, insn);
if(be_is_Barrier(irn))
active = !active;
irn = insn->next_insn;
obstack_free(&obst, insn);
}
}
static void handle_constraints(be_raext_env_t *raenv) {
irg_walk_graph(raenv->irg, NULL, handle_constraints_walker, raenv);
irg_block_walk_graph(raenv->irg, NULL, handle_constraints_block, raenv);
}
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment