Commit ea6e9be0 authored by Matthias Braun's avatar Matthias Braun
Browse files

remove be_Barrier and lots of hacks for maintaining it

parent 8228e120
......@@ -206,7 +206,6 @@ static void TEMPLATE_register_emitters(void)
set_emitter(op_Phi, emit_nothing);
set_emitter(op_be_Keep, emit_nothing);
set_emitter(op_be_Start, emit_nothing);
set_emitter(op_be_Barrier, emit_nothing);
}
typedef void (*emit_func_ptr) (const ir_node *);
......
......@@ -163,9 +163,6 @@ static ir_node *gen_Const(ir_node *node)
result = new_bd_TEMPLATE_Const(dbgi, new_block, value);
/* make sure the node does not float above the barrier into the prologue */
be_dep_on_frame(result);
return result;
}
......
......@@ -562,7 +562,6 @@ static void amd64_register_emitters(void)
set_emitter(op_be_Start, emit_nothing);
set_emitter(op_be_Keep, emit_nothing);
set_emitter(op_be_Barrier, emit_nothing);
set_emitter(op_Phi, emit_nothing);
}
......
......@@ -91,8 +91,6 @@ static ir_node *gen_Const(ir_node *node) {
ir_node *res = create_const_graph(node, block);
(void) mode;
be_dep_on_frame(res);
return res;
}
......@@ -109,7 +107,6 @@ static ir_node *gen_SymConst(ir_node *node)
ir_node *new_node;
new_node = new_bd_amd64_SymConst(dbgi, block, entity);
be_dep_on_frame(new_node);
return new_node;
}
......@@ -128,7 +125,6 @@ static ir_node *gen_Add(ir_node *node) {
ir_node *new_op2 = be_transform_node(op2);
ir_node *res = new_bd_amd64_Add(dbgi, block, new_op1, new_op2);
be_dep_on_frame (res);
return res;
}
......@@ -147,7 +143,6 @@ static ir_node *gen_Sub(ir_node *node) {
ir_node *new_op2 = be_transform_node(op2);
ir_node *res = new_bd_amd64_Sub(dbgi, block, new_op1, new_op2);
be_dep_on_frame (res);
return res;
}
......@@ -161,7 +156,6 @@ static ir_node *gen_Mul(ir_node *node) {
ir_node *new_op2 = be_transform_node(op2);
ir_node *res = new_bd_amd64_Mul(dbgi, block, new_op1, new_op2);
be_dep_on_frame (res);
return res;
}
......
......@@ -923,7 +923,6 @@ static void arm_register_emitters(void)
set_emitter(op_Phi, emit_nothing);
set_emitter(op_be_Keep, emit_nothing);
set_emitter(op_be_Start, emit_nothing);
set_emitter(op_be_Barrier, emit_nothing);
}
/**
......
......@@ -94,7 +94,6 @@ static ir_node *create_const_graph_value(dbg_info *dbgi, ir_node *block,
if (vn.ops < v.ops) {
/* remove bits */
result = new_bd_arm_Mvn_imm(dbgi, block, vn.values[0], vn.rors[0]);
be_dep_on_frame(result);
for (cnt = 1; cnt < vn.ops; ++cnt) {
result = new_bd_arm_Bic_imm(dbgi, block, result,
......@@ -103,7 +102,6 @@ static ir_node *create_const_graph_value(dbg_info *dbgi, ir_node *block,
} else {
/* add bits */
result = new_bd_arm_Mov_imm(dbgi, block, v.values[0], v.rors[0]);
be_dep_on_frame(result);
for (cnt = 1; cnt < v.ops; ++cnt) {
result = new_bd_arm_Or_imm(dbgi, block, result,
......@@ -1131,7 +1129,6 @@ static ir_node *gen_Const(ir_node *node)
if (USE_FPA(isa)) {
ir_tarval *tv = get_Const_tarval(node);
node = new_bd_arm_fConst(dbg, block, tv);
be_dep_on_frame(node);
return node;
} else if (USE_VFP(isa)) {
assert(mode != mode_E && "IEEE Extended FP not supported");
......@@ -1151,7 +1148,6 @@ static ir_node *gen_SymConst(ir_node *node)
ir_node *new_node;
new_node = new_bd_arm_SymConst(dbgi, block, entity, 0);
be_dep_on_frame(new_node);
return new_node;
}
......@@ -1644,7 +1640,6 @@ static ir_node *gen_Unknown(ir_node *node)
if (mode_is_float(mode)) {
ir_tarval *tv = get_mode_null(mode);
ir_node *node = new_bd_arm_fConst(dbgi, new_block, tv);
be_dep_on_frame(node);
return node;
} else if (mode_needs_gp_reg(mode)) {
return create_const_graph_value(dbgi, new_block, 0);
......@@ -1733,7 +1728,6 @@ static ir_node *gen_Start(ir_node *node)
ir_node *start;
ir_node *incsp;
ir_node *sp;
ir_node *barrier;
size_t i;
/* stackpointer is important at function prolog */
......@@ -1756,9 +1750,8 @@ static ir_node *gen_Start(ir_node *node)
sp = be_prolog_get_reg_value(abihelper, sp_reg);
incsp = be_new_IncSP(sp_reg, new_block, sp, BE_STACK_FRAME_SIZE_EXPAND, 0);
be_prolog_set_reg_value(abihelper, sp_reg, incsp);
barrier = be_prolog_create_barrier(abihelper, new_block);
return barrier;
return start;
}
static ir_node *get_stack_pointer_for(ir_node *node)
......@@ -1826,9 +1819,6 @@ static ir_node *gen_Return(ir_node *node)
be_epilog_add_reg(abihelper, reg, arch_register_req_type_none, value);
}
/* create the barrier before the epilog code */
be_epilog_create_barrier(abihelper, new_block);
/* epilog code: an incsp */
sp_proj = be_epilog_get_reg_value(abihelper, sp_reg);
incsp = be_new_IncSP(sp_reg, new_block, sp_proj,
......
......@@ -1224,76 +1224,14 @@ static void reg_map_to_arr(reg_node_map_t *res, pmap *reg_map)
qsort(res, n, sizeof(res[0]), cmp_regs);
}
/**
* Creates a barrier.
*/
static ir_node *create_barrier(ir_node *bl, ir_node **mem, pmap *regs,
int in_req)
{
int n_regs = pmap_count(regs);
int n;
ir_node *irn;
ir_node **in;
reg_node_map_t *rm;
in = ALLOCAN(ir_node*, n_regs+1);
rm = ALLOCAN(reg_node_map_t, n_regs);
reg_map_to_arr(rm, regs);
for (n = 0; n < n_regs; ++n) {
in[n] = rm[n].irn;
}
if (mem) {
in[n++] = *mem;
}
irn = be_new_Barrier(bl, n, in);
for (n = 0; n < n_regs; ++n) {
ir_node *pred = rm[n].irn;
const arch_register_t *reg = rm[n].reg;
arch_register_req_type_t add_type = arch_register_req_type_none;
ir_node *proj;
const backend_info_t *info;
/* stupid workaround for now... as not all nodes report register
* requirements. */
info = be_get_info(skip_Proj(pred));
if (info != NULL && info->out_infos != NULL) {
const arch_register_req_t *ireq = arch_get_register_req_out(pred);
if (ireq->type & arch_register_req_type_ignore)
add_type |= arch_register_req_type_ignore;
if (ireq->type & arch_register_req_type_produces_sp)
add_type |= arch_register_req_type_produces_sp;
}
proj = new_r_Proj(irn, get_irn_mode(pred), n);
be_node_set_reg_class_in(irn, n, reg->reg_class);
if (in_req) {
be_set_constr_single_reg_in(irn, n, reg,
arch_register_req_type_none);
}
be_set_constr_single_reg_out(irn, n, reg, add_type);
arch_set_irn_register(proj, reg);
pmap_insert(regs, (void *) reg, proj);
}
if (mem) {
*mem = new_r_Proj(irn, mode_M, n);
}
return irn;
}
/**
* Creates a be_Return for a Return node.
*
* @param @env the abi environment
* @param irn the Return node or NULL if there was none
* @param bl the block where the be_Retun should be placed
* @param mem the current memory
* @param n_res number of return results
* @param @env the abi environment
* @param irn the Return node or NULL if there was none
* @param bl the block where the be_Retun should be placed
* @param mem the current memory
* @param n_res number of return results
*/
static ir_node *create_be_return(be_abi_irg_t *env, ir_node *irn, ir_node *bl,
ir_node *mem, int n_res)
......@@ -1345,7 +1283,6 @@ static ir_node *create_be_return(be_abi_irg_t *env, ir_node *irn, ir_node *bl,
be_abi_reg_map_set(reg_map, arch_env->sp, stack);
/* Make the Epilogue node and call the arch's epilogue maker. */
create_barrier(bl, &mem, reg_map, 1);
call->cb->epilogue(env->cb, bl, &mem, reg_map);
/*
......@@ -1392,13 +1329,14 @@ static ir_node *create_be_return(be_abi_irg_t *env, ir_node *irn, ir_node *bl,
/* we have to pop the shadow parameter in in case of struct returns */
pop = call->pop;
ret = be_new_Return(dbgi, irg, bl, n_res, pop, n, in);
arch_irn_add_flags(ret, arch_irn_flags_epilog);
/* Set the register classes of the return's parameter accordingly. */
for (i = 0; i < n; ++i) {
if (regs[i] == NULL)
continue;
be_node_set_reg_class_in(ret, i, regs[i]->reg_class);
be_set_constr_single_reg_in(ret, i, regs[i], arch_register_req_type_none);
}
/* Free the space of the Epilog's in array and the register <-> proj map. */
......@@ -1735,8 +1673,6 @@ static void modify_irg(ir_graph *irg)
DBG((dbg, LEVEL_1, "introducing abi on %+F\n", irg));
/* Must fetch memory here, otherwise the start Barrier gets the wrong
* memory, which leads to loops in the DAG. */
old_mem = get_irg_initial_mem(irg);
irp_reserve_resources(irp, IR_RESOURCE_ENTITY_LINK);
......@@ -1854,6 +1790,7 @@ static void modify_irg(ir_graph *irg)
pmap_insert(env->regs, (void *) arch_env->bp, NULL);
start_bl = get_irg_start_block(irg);
env->start = be_new_Start(NULL, start_bl, pmap_count(env->regs) + 1);
arch_irn_add_flags(env->start, arch_irn_flags_prolog);
set_irg_start(irg, env->start);
/*
......@@ -1895,14 +1832,11 @@ static void modify_irg(ir_graph *irg)
/* Generate the Prologue */
fp_reg = call->cb->prologue(env->cb, &mem, env->regs, &stack_layout->initial_bias);
/* do the stack allocation BEFORE the barrier, or spill code
might be added before it */
env->init_sp = be_abi_reg_map_get(env->regs, sp);
env->init_sp = be_new_IncSP(sp, start_bl, env->init_sp, BE_STACK_FRAME_SIZE_EXPAND, 0);
arch_irn_add_flags(env->init_sp, arch_irn_flags_prolog);
be_abi_reg_map_set(env->regs, sp, env->init_sp);
create_barrier(start_bl, &mem, env->regs, 0);
env->init_sp = be_abi_reg_map_get(env->regs, sp);
arch_set_irn_register(env->init_sp, sp);
......
......@@ -231,47 +231,6 @@ static void rsm_set_reg_value(register_state_mapping_t *rsm,
rsm_set_value(rsm, input_idx, value);
}
/**
* Create a Barrier from the registers stored at a register state map.
*
* @param rsm the register state map
* @param block the block to create the Barrier on
*/
static ir_node *rsm_create_barrier(register_state_mapping_t *rsm,
ir_node *block)
{
size_t n_barrier_outs = ARR_LEN(rsm->regs);
ir_node **in = rsm->value_map;
ir_node *barrier;
size_t o;
assert(ARR_LEN(rsm->value_map) == n_barrier_outs);
barrier = be_new_Barrier(block, n_barrier_outs, in);
for (o = 0; o < n_barrier_outs; ++o) {
const reg_flag_t *regflag = &rsm->regs[o];
const arch_register_t *reg = regflag->reg;
ir_node *proj;
if (reg == NULL) {
arch_set_out_register_req(barrier, o, arch_no_register_req);
proj = new_r_Proj(barrier, mode_M, o);
} else {
be_set_constr_single_reg_in(barrier, o, reg, arch_register_req_type_none);
be_set_constr_single_reg_out(barrier, o, reg, regflag->flags);
proj = new_r_Proj(barrier, reg->reg_class->mode, o);
}
rsm->value_map[o] = proj;
}
rsm->last_barrier = barrier;
return barrier;
}
beabi_helper_env_t *be_abihelper_prepare(ir_graph *irg)
{
......@@ -309,6 +268,8 @@ ir_node *be_prolog_create_start(beabi_helper_env_t *env, dbg_info *dbgi,
ir_node *start = be_new_Start(dbgi, block, n_start_outs);
int o;
arch_irn_add_flags(start, arch_irn_flags_prolog);
assert(env->prolog.value_map == NULL);
env->prolog.value_map = NEW_ARR_F(ir_node*, n_start_outs);
......@@ -329,17 +290,11 @@ ir_node *be_prolog_create_start(beabi_helper_env_t *env, dbg_info *dbgi,
}
/* start node should really be the first thing constructed */
assert(env->prolog.last_barrier == NULL);
env->prolog.last_barrier = start;
return start;
}
ir_node *be_prolog_create_barrier(beabi_helper_env_t *env, ir_node *block)
{
return rsm_create_barrier(&env->prolog, block);
}
ir_node *be_prolog_get_reg_value(beabi_helper_env_t *env,
const arch_register_t *reg)
{
......@@ -401,11 +356,6 @@ ir_node *be_epilog_get_memory(beabi_helper_env_t *env)
return rsm_get_value(&env->epilog, 0);
}
ir_node *be_epilog_create_barrier(beabi_helper_env_t *env, ir_node *block)
{
return rsm_create_barrier(&env->epilog, block);
}
ir_node *be_epilog_create_return(beabi_helper_env_t *env, dbg_info *dbgi,
ir_node *block)
{
......@@ -420,6 +370,7 @@ ir_node *be_epilog_create_return(beabi_helper_env_t *env, dbg_info *dbgi,
ret = be_new_Return(dbgi, get_irn_irg(block), block, n_res, pop,
n_return_in, in);
arch_irn_add_flags(ret, arch_irn_flags_epilog);
for (i = 0; i < n_return_in; ++i) {
const reg_flag_t *regflag = &env->epilog.regs[i];
const arch_register_t *reg = regflag->reg;
......
......@@ -62,15 +62,9 @@ void be_prolog_add_reg(beabi_helper_env_t *env, const arch_register_t *reg,
ir_node *be_prolog_create_start(beabi_helper_env_t *env, dbg_info *dbgi,
ir_node *block);
/**
* Creates a barrier node which lets all registers specified by prolog_add_reg
* pass through
*/
ir_node *be_prolog_create_barrier(beabi_helper_env_t *env, ir_node *block);
/**
* Get "value" of a register.
* This usually creates a Proj node for the start-node or barrier-node.
* This usually creates a Proj node for the start-node.
* Or returns the value set by a abi_helper_set_reg_value call
*/
ir_node *be_prolog_get_reg_value(beabi_helper_env_t *env,
......@@ -107,8 +101,6 @@ ir_node *be_epilog_get_memory(beabi_helper_env_t *env);
void be_epilog_begin(beabi_helper_env_t *env);
ir_node *be_epilog_create_barrier(beabi_helper_env_t *env, ir_node *block);
/**
* Create return node and finishes epilog handling
*/
......
......@@ -348,6 +348,12 @@ void arch_dump_reqs_and_registers(FILE *F, const ir_node *node)
if (flags & arch_irn_flags_modify_flags) {
fprintf(F, " modify_flags");
}
if (flags & arch_irn_flags_prolog) {
fprintf(F, " prolog");
}
if (flags & arch_irn_flags_epilog) {
fprintf(F, " epilog");
}
}
fprintf(F, " (%d)\n", flags);
}
......
......@@ -171,7 +171,7 @@ static void pair_up_operands(const be_chordal_alloc_env_t *alloc_env, be_insn_t
}
static ir_node *handle_constraints(be_chordal_alloc_env_t *alloc_env,
ir_node *irn, int *silent)
ir_node *irn)
{
int n_regs;
bitset_t *bs;
......@@ -188,7 +188,6 @@ static ir_node *handle_constraints(be_chordal_alloc_env_t *alloc_env,
void *base = obstack_base(env->obst);
be_insn_t *insn = chordal_scan_insn(env, irn);
ir_node *res = insn->next_insn;
int be_silent = *silent;
bipartite_t *bp;
if (insn->pre_colored) {
......@@ -197,19 +196,6 @@ static ir_node *handle_constraints(be_chordal_alloc_env_t *alloc_env,
pset_insert_ptr(alloc_env->pre_colored, insn->ops[i].carrier);
}
/*
* If the current node is a barrier toggle the silent flag.
* If we are in the start block, we are ought to be silent at the beginning,
* so the toggling activates the constraint handling but skips the barrier.
* If we are in the end block we handle the in requirements of the barrier
* and set the rest to silent.
*/
if (be_is_Barrier(irn))
*silent = !*silent;
if (be_silent)
goto end;
/*
* Perms inserted before the constraint handling phase are considered to be
* correctly precolored. These Perms arise during the ABI handling phase.
......@@ -407,21 +393,11 @@ end:
*/
static void constraints(ir_node *bl, void *data)
{
/*
* Start silent in the start block.
* The silence remains until the first barrier is seen.
* Each other block is begun loud.
*/
int silent = bl == get_irg_start_block(get_irn_irg(bl));
be_chordal_alloc_env_t *env = (be_chordal_alloc_env_t*)data;
ir_node *irn;
/*
* If the block is the start block search the barrier and
* start handling constraints from there.
*/
for (irn = sched_first(bl); !sched_is_end(irn);) {
irn = handle_constraints(env, irn, &silent);
irn = handle_constraints(env, irn);
}
}
......
......@@ -105,7 +105,6 @@ ir_op *op_be_AddSP;
ir_op *op_be_SubSP;
ir_op *op_be_Start;
ir_op *op_be_FrameAddr;
ir_op *op_be_Barrier;
/**
* Compare the attributes of two be_FrameAddr nodes.
......@@ -735,35 +734,6 @@ void be_set_CopyKeep_op(ir_node *cpy, ir_node *op)
set_irn_n(cpy, be_pos_CopyKeep_op, op);
}
ir_node *be_new_Barrier(ir_node *bl, int n, ir_node *in[])
{
ir_node *res;
int i;
ir_graph *irg = get_Block_irg(bl);
res = new_ir_node(NULL, irg, bl, op_be_Barrier, mode_T, -1, NULL);
init_node_attr(res, -1, -1);
for (i = 0; i < n; ++i) {
add_irn_n(res, in[i]);
add_register_req_in(res);
add_register_req_out(res);
}
return res;
}
ir_node *be_Barrier_append_node(ir_node *barrier, ir_node *node)
{
ir_mode *mode = get_irn_mode(node);
int n = add_irn_n(barrier, node);
ir_node *proj = new_r_Proj(barrier, mode, n);
add_register_req_in(barrier);
add_register_req_out(barrier);
return proj;
}
static bool be_has_frame_entity(const ir_node *irn)
{
switch (get_irn_opcode(irn)) {
......@@ -1266,7 +1236,7 @@ static void copy_attr(ir_graph *irg, const ir_node *old_node, ir_node *new_node)
if (old_info->out_infos != NULL) {
unsigned n_outs = ARR_LEN(old_info->out_infos);
/* need dyanmic out infos? */
if (be_is_Barrier(new_node) || be_is_Perm(new_node)) {
if (be_is_Perm(new_node)) {
new_info->out_infos = NEW_ARR_F(reg_out_info_t, n_outs);
} else {
new_info->out_infos = NEW_ARR_D(reg_out_info_t, obst, n_outs);
......@@ -1337,7 +1307,6 @@ void be_init_op(void)
op_be_IncSP = new_ir_op(beo_IncSP, "be_IncSP", op_pin_state_pinned, irop_flag_none, oparity_unary, 0, sizeof(be_incsp_attr_t), &be_node_op_ops);
op_be_Start = new_ir_op(beo_Start, "be_Start", op_pin_state_pinned, irop_flag_none, oparity_zero, 0, 0, &be_node_op_ops);
op_be_FrameAddr = new_ir_op(beo_FrameAddr, "be_FrameAddr", op_pin_state_floats, irop_flag_none, oparity_unary, 0, sizeof(be_frame_attr_t), &be_node_op_ops);
op_be_Barrier = new_ir_op(beo_Barrier, "be_Barrier", op_pin_state_pinned, irop_flag_none, oparity_dynamic, 0, 0, &be_node_op_ops);
op_be_Spill->ops.node_cmp_attr = FrameAddr_cmp_attr;
op_be_Reload->ops.node_cmp_attr = FrameAddr_cmp_attr;
......@@ -1353,7 +1322,6 @@ void be_init_op(void)
op_be_IncSP->ops.node_cmp_attr = IncSP_cmp_attr;
op_be_Start->ops.node_cmp_attr = be_nodes_equal;
op_be_FrameAddr->ops.node_cmp_attr = FrameAddr_cmp_attr;
op_be_Barrier->ops.node_cmp_attr = be_nodes_equal;
/* attach out dummy_ops to middle end nodes */
for (opc = iro_First; opc <= iro_Last; ++opc) {
......
......@@ -53,7 +53,6 @@ extern ir_op *op_be_AddSP;
extern ir_op *op_be_SubSP;
extern ir_op *op_be_Start;
extern ir_op *op_be_FrameAddr;
extern ir_op *op_be_Barrier;
/**
* A "symbolic constant" for the size of the stack frame to use with IncSP nodes.
......@@ -371,13 +370,6 @@ int be_Return_append_node(ir_node *ret, ir_node *node);
ir_node *be_new_Start(dbg_info *dbgi, ir_node *block, int n_out);
ir_node *be_new_Barrier(ir_node *block, int n, ir_node *in[]);
/**
* Appends a node to a barrier, returns the result proj of the node
*/
ir_node *be_Barrier_append_node(ir_node *barrier, ir_node *node);
/**
* Make a spill node.
*
......@@ -513,6 +505,5 @@ static inline int be_is_AddSP (const ir_node *irn) { return get_irn_opcode(ir
static inline int be_is_SubSP (const ir_node *irn) { return get_irn_opcode(irn) == beo_SubSP ; }
static inline int be_is_Start (const ir_node *irn) { return get_irn_opcode(irn) == beo_Start; }
static inline int be_is_FrameAddr(const ir_node *irn) { return get_irn_opcode(irn) == beo_FrameAddr; }
static inline int be_is_Barrier (const ir_node *irn) { return get_irn_opcode(irn) == beo_Barrier ; }
#endif
......@@ -599,13 +599,7 @@ static void create_pbqp_coloring_instance(ir_node *block, void *data)
static void insert_perms(ir_node *block, void *data)
{
/*
* Start silent in the start block.
* The silence remains until the first barrier is seen.
* Each other block is begun loud.
*/
be_chordal_env_t *env = (be_chordal_env_t*)data;
int silent = block == get_irg_start_block(get_irn_irg(block));
ir_node *irn;
/*
......@@ -613,16 +607,9 @@ static void insert_perms(ir_node *block, void *data)
* start handling constraints from there.
*/
for (irn = sched_first(block); !sched_is_end(irn);) {
int silent_old = silent; /* store old silent value */
if (be_is_Barrier(irn))
silent = !silent; /* toggle silent flag */
be_insn_t *insn = chordal_scan_insn(env, irn);
irn = insn->next_insn;
if (silent_old)
continue;
if (!insn->has_constraints)
continue;
......
......@@ -234,165 +234,6 @@ static void process_block(ir_node *block, void *data)
}
}
static void kill_node_and_preds(ir_node *node)
{
ir_graph *irg = get_irn_irg(node);
int arity, i;
arity = get_irn_arity(node);
for (i = 0; i < arity; ++i) {
ir_node *pred = get_irn_n(node, i);
set_irn_n(node, i, new_r_Bad(irg));
if (get_irn_n_edges(pred) != 0)
continue;