X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ir%2Fbe%2Fbespillslots.c;h=8ed95ebbf68d5ae4b39ff40d55b828ed7bf4ef49;hb=d0e160eb88f354c822352444042329ca8514bc7d;hp=46e4ca3c4ad7bc4faea2592eb9788cd23ea953b1;hpb=aa44a311d7a861b1eb0a326cd6b66714883b3077;p=libfirm diff --git a/ir/be/bespillslots.c b/ir/be/bespillslots.c index 46e4ca3c4..8ed95ebbf 100644 --- a/ir/be/bespillslots.c +++ b/ir/be/bespillslots.c @@ -21,6 +21,7 @@ #include "irdump_t.h" #include "benode_t.h" +#include "besched.h" #include "bespillslots.h" #include "bechordal_t.h" #include "bejavacoal.h" @@ -505,6 +506,10 @@ static entity* create_stack_entity(ss_env_t *env, spill_slot_t *slot) { ir_type* frame = get_irg_frame_type(env->chordal_env->irg); entity* res = frame_alloc_area(frame, slot->size, slot->align, 0); + // adjust size of the entity type... + ir_type *enttype = get_entity_type(res); + set_type_size_bytes(enttype, slot->size); + slot->entity = res; return res; @@ -584,12 +589,14 @@ static void assign_spillslots(ss_env_t *env) { be_set_frame_entity(node, slot->entity); } else { int i, arity; + ir_node *block = get_nodes_block(node); // should be a PhiM assert(is_Phi(node)); for(i = 0, arity = get_irn_arity(node); i < arity; ++i) { ir_node *arg = get_irn_n(node, i); + ir_node *predblock = get_Block_cfgpred_block(block, i); spill_t *argspill; int argslotid; @@ -605,7 +612,7 @@ static void assign_spillslots(ss_env_t *env) { create_stack_entity(env, argslot); } - memperm = get_memperm(env, get_nodes_block(arg)); + memperm = get_memperm(env, predblock); entry = obstack_alloc(&env->obst, sizeof(entry[0])); entry->node = node; @@ -632,12 +639,36 @@ static void assign_spillslots(ss_env_t *env) { } } +/** + * Returns the last node in a block which is no control flow changing node + */ +static ir_node *get_end_of_block_insertion_point(ir_node* block) +{ + ir_node* ins = sched_last(block); + while(is_Proj(ins) && get_irn_mode(ins) == mode_X) { + ins = sched_prev(ins); + assert(ins != NULL); + } + + if(is_cfop(ins)) { + while(1) { + ir_node *prev = sched_prev(ins); + if(!is_cfop(prev)) + break; + ins = prev; + } + } + + return ins; +} + static void create_memperms(ss_env_t *env) { memperm_t *memperm; for(memperm = set_first(env->memperms); memperm != NULL; memperm = set_next(env->memperms)) { int i; memperm_entry_t *entry; + ir_node *blockend; ir_node** nodes = alloca(memperm->entrycount * sizeof(nodes[0])); ir_node* mempermnode; @@ -651,16 +682,22 @@ static void create_memperms(ss_env_t *env) { mempermnode = be_new_MemPerm(env->chordal_env->birg->main_env->arch_env, env->chordal_env->irg, memperm->block, memperm->entrycount, nodes); + // insert node into schedule + blockend = get_end_of_block_insertion_point(memperm->block); + sched_add_before(blockend, mempermnode); + for(entry = memperm->entries, i = 0; entry != NULL; entry = entry->next, ++i) { ir_node *proj; ir_node* arg = get_irn_n(entry->node, entry->pos); be_set_MemPerm_in_entity(mempermnode, i, entry->in); be_set_MemPerm_out_entity(mempermnode, i, entry->out); + set_irg_current_block(env->chordal_env->irg, memperm->block); proj = new_Proj(mempermnode, get_irn_mode(arg), i); + sched_add_before(blockend, proj); + set_irn_n(entry->node, entry->pos, proj); } - ir_printf("Memperm created in block %+F\n", memperm->block); } }