fixed remat flag for load nodes
[libfirm] / ir / be / bespillslots.c
index 46e4ca3..8ed95eb 100644 (file)
@@ -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);
        }
 }