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); ...@@ -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_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); 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); 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)) #define be_abi_reg_map_get(map, reg) pmap_get((map), (void *) (reg))
......
...@@ -46,6 +46,7 @@ ...@@ -46,6 +46,7 @@
#include "bearch.h" #include "bearch.h"
#include "beirgmod.h" #include "beirgmod.h"
#include "beifg.h" #include "beifg.h"
#include "beinsn_t.h"
#include "bechordal_t.h" #include "bechordal_t.h"
#include "bechordal_draw.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 * ...@@ -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); return bitset_next_clear(tmp, 0);
} }
typedef struct _operand_t operand_t; static bitset_t *get_decisive_partner_regs(bitset_t *bs, const be_operand_t *o1, const be_operand_t *o2)
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)
{ {
bitset_t *res = bs; bitset_t *res = bs;
...@@ -320,12 +208,23 @@ static bitset_t *get_decisive_partner_regs(bitset_t *bs, const operand_t *o1, co ...@@ -320,12 +208,23 @@ static bitset_t *get_decisive_partner_regs(bitset_t *bs, const operand_t *o1, co
return res; 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; const be_chordal_env_t *env = alloc_env->chordal_env;
int n_uses = insn_n_uses(insn); int n_uses = be_insn_n_uses(insn);
int n_defs = insn_n_defs(insn); int n_defs = be_insn_n_defs(insn);
bitset_t *bs = bitset_alloca(env->cls->n_regs); bitset_t *bs = bitset_alloca(env->cls->n_regs);
bipartite_t *bp = bipartite_new(n_defs, n_uses); bipartite_t *bp = bipartite_new(n_defs, n_uses);
int *pairing = alloca(MAX(n_defs, n_uses) * sizeof(pairing[0])); 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 ...@@ -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. same register as the out operand.
*/ */
for(j = 0; j < insn->use_start; ++j) { 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 ... */ /* Try to find an in operand which has ... */
for(i = insn->use_start; i < insn->n_ops; ++i) { 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 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 ...@@ -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; be_chordal_env_t *env = alloc_env->chordal_env;
const arch_env_t *aenv = env->birg->main_env->arch_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 *bl = get_nodes_block(insn->irn);
ir_node *copy = NULL; ir_node *copy = NULL;
ir_node *perm = NULL; ir_node *perm = NULL;
...@@ -398,7 +297,7 @@ static ir_node *pre_process_constraints(be_chordal_alloc_env_t *alloc_env, insn_ ...@@ -398,7 +297,7 @@ static ir_node *pre_process_constraints(be_chordal_alloc_env_t *alloc_env, insn_
be copied. be copied.
*/ */
for(i = 0; i < insn->use_start; ++i) { 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) if(op->has_constraints)
bitset_or(out_constr, op->regs); bitset_or(out_constr, op->regs);
} }
...@@ -408,7 +307,7 @@ static ir_node *pre_process_constraints(be_chordal_alloc_env_t *alloc_env, insn_ ...@@ -408,7 +307,7 @@ static ir_node *pre_process_constraints(be_chordal_alloc_env_t *alloc_env, insn_
constraints which are also output constraints. constraints which are also output constraints.
*/ */
for(i = insn->use_start; i < insn->n_ops; ++i) { 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))) { if(op->has_constraints && (values_interfere(op->carrier, insn->irn) || arch_irn_is(aenv, op->carrier, ignore))) {
bitset_copy(bs, op->regs); bitset_copy(bs, op->regs);
bitset_and(bs, out_constr); bitset_and(bs, out_constr);
...@@ -449,14 +348,14 @@ static ir_node *pre_process_constraints(be_chordal_alloc_env_t *alloc_env, insn_ ...@@ -449,14 +348,14 @@ static ir_node *pre_process_constraints(be_chordal_alloc_env_t *alloc_env, insn_
*/ */
be_liveness(env->irg); be_liveness(env->irg);
obstack_free(&env->obst, insn); 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 Copy the input constraints of the insn to the Perm as output
constraints. Succeeding phases (coalescing will need that). constraints. Succeeding phases (coalescing will need that).
*/ */
for(i = insn->use_start; i < insn->n_ops; ++i) { 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; ir_node *proj = op->carrier;
/* /*
Note that the predecessor must not be a Proj of the Perm, 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 ...@@ -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; be_chordal_env_t *env = alloc_env->chordal_env;
void *base = obstack_base(&env->obst); 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; ir_node *res = insn->next_insn;
int be_silent = *silent; int be_silent = *silent;
...@@ -532,7 +431,7 @@ static ir_node *handle_constraints(be_chordal_alloc_env_t *alloc_env, ir_node *i ...@@ -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). to a bipartite graph (left: nodes with partners, right: admissible colors).
*/ */
for(i = 0, n_alloc = 0; i < insn->n_ops; ++i) { 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 If the operand has no partner or the partner has not been marked
......
...@@ -94,6 +94,7 @@ alloc ::= node-nr reg-nr . ...@@ -94,6 +94,7 @@ alloc ::= node-nr reg-nr .
#include "besched_t.h" #include "besched_t.h"
#include "beutil.h" #include "beutil.h"
#include "belive_t.h" #include "belive_t.h"
#include "beinsn_t.h"
#define DBG_LEVEL 2 #define DBG_LEVEL 2
...@@ -193,14 +194,17 @@ static int get_loop_weight(ir_node *irn) { ...@@ -193,14 +194,17 @@ static int get_loop_weight(ir_node *irn) {
|_| |_|
*****************************************************************************/ *****************************************************************************/
static void handle_constraints_walker(ir_node *irn, void *env) { #if 0
be_raext_env_t *raenv = env; static void handle_constraints_insn(be_raext_env_t *raenv, be_insn_t *insn)
{
arch_register_req_t req; arch_register_req_t req;
int pos, max; int pos, max;
/* handle output constraints /* handle output constraints
* user -> irn becomes user -> cpy -> irn * user -> irn becomes user -> cpy -> irn
*/ */
if(get_irn_mode(irn) == mode_T) {
}
arch_get_register_req(raenv->aenv, &req, irn, -1); arch_get_register_req(raenv->aenv, &req, irn, -1);
if (arch_register_req_is(&req, limited)) { if (arch_register_req_is(&req, limited)) {
ir_node *cpy = be_new_Copy(req.cls, raenv->irg, get_nodes_block(irn), irn); 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) { ...@@ -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) { 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