- Added 2 new blockschedulers, a greedy algorithm and an "optimal" ILP that
[libfirm] / ir / be / bespillloc.c
index c236754..0447f4d 100644 (file)
@@ -1,6 +1,34 @@
+/*     be_spill_loc (ation) -> BY Sven Polk*/
+
+#include "obst.h"
+#include "list.h"
+#include "bitset.h"
+#include "iterator.h"
+
+#include "irmode_t.h"
+#include "irgraph_t.h"
+#include "irprintf_t.h"
+#include "irgwalk.h"
+#include "irdump.h"
+#include "irdom.h"
+#include "debug.h"
+#include "xmalloc.h"
+
+#include "beutil.h"
+#include "besched.h"
+#include "benumb_t.h"
+#include "besched_t.h"
+#include "belive_t.h"
+#include "bechordal_t.h"
+
 #include "obst.h"
+#include "set.h"
+#include "pdeq.h"
 #include "pset.h"
+#include "bitset.h"
+
 #include "irprintf_t.h"
+
 #include "irgraph.h"
 #include "irnode.h"
 #include "irmode.h"
@@ -9,8 +37,7 @@
 #include "ircons_t.h"
 #include "irprintf.h"
 
-#include "obst.h"
-#include "bitset.h"
+
 
 #include "irprog.h"
 #include "irgopt.h"
@@ -37,6 +64,7 @@
 #include "besched_t.h"
 #include "belistsched.h"
 #include "belive_t.h"
+
 #include "bespillbelady.h"
 #include "bera.h"
 #include "beraextern.h"
 #include "beabi.h"
 #include "belower.h"
 #include "bestat.h"
-#include "typewalk.h"
+
 #include "error.h"
 
+#include "irnode_t.h"
+#include "entity_t.h"
+
+#include "irprintf.h"
+
+#include "irphase.h"
+#include "irphase_t.h"
+
+#include "typewalk.h"
+
+//#include "bespillloc_t.h"
+#include "bespillloc.h"
+
+#define LPP_SERVER "i44pc52"
+#define LPP_SOLVER "cplex"
+
+// "cat /proc/cpuinfo" cache size : 512 KB => wahrscheinlich L2
+// arranged into 32-byte cache lines
+
+
+
+#define LINESIZE_BYTES (32)
+
+#define L1SIZE   (64)
+#define L2SIZE   (512)
+
+#define L1SIZE_BYTES   (L1SIZE * 1024)
+#define L2SIZE_BYTES   (L2SIZE * 1024)
+
+#define L1LINECOUNT (L1SIZE_BYTES / LINESIZE_BYTES)
+#define L2LINECOUNT (L2SIZE_BYTES / LINESIZE_BYTES)
+
+#define ASSOCIATIVE   (1)
+#define BLOCKFACTOR   (2)
+#define CONTEMP_RANGE (10)
+
+
 
 
 typedef struct _spilloc_env_t {
+
        struct obstack ob;
+
+       ir_graph                 *irg;
+       const arch_env_t *arch;
+
        pset *ents;
-       int entcnt;
-       ir_graph *irg;
-       pmap *nodents;
+       pset *nodes;
+       pmap *ent_nodes;
+
        pmap *afgraph;
+       pset *afgraph_vs;
+       pset *afgraph_es;
+
+       int   ent_cnt;
+       int   node_cnt;
+
+       int   blk_cnt;
+       int       cli_cnt;
+
+       int       intval_cnt;
+       int       intval[100];
+
+       pmap *Cli_ents;
+       pmap *position;
+       pset *coals;
+
+       pset *chilimbi_Cli_ents;
+
+       //lpp_t *lpp;
+
 } spilloc_env_t;
 
 
+
+typedef struct _cacheline {
+       int   start;
+       int   end;
+       int   nr;               // (1,...,n)
+       pset *ents;
+} cacheline;
+
+
+
 typedef struct _vertex {
-       entity *ent;
-       int node_nr;
-       pset *edges;
+       entity          *ent;
+       int                     offset_bits;
+       int                     offset_bytes;
+
+       pset            *neighbors;             /* The neighboring entities */
+       int         ela;                        /* entity layout affinity */
+    cacheline   *Cli;
+       int         is_coal;            /* singled/doubled position */
 } vertex;
 
 
 
 typedef struct _edge {
-       entity *ent;
-       unsigned int wt_val_interfere;
-       unsigned int wt_con_interfere;
-       struct edge *next;
+       entity *src;
+       entity *tgt;
+       vertex *vtx_src;
+       vertex *vtx_tgt;
+       int     aff;
 } edge;
 
 
-#define STRUCTSIZE sizeof(vertex)
-#define NIL (-1)
-#define ABSENT (-2)
 
-static void add_ent(entity *ent, void *env) {
+typedef struct _Node { /*Prototype Row of Graph-Matrix*/
+       vertex *vtx;
+       pset   *edges;  /*The outgoin' edges of vtx*/
+       int     status;
+} Node;
+
+
+
+
+
+
+
+
+
+
+
+typedef struct _ent_position {
+       int                     is_set;
+       int                     offset;
+       cacheline       *Cli;
+       int                     nr;
+       entity          *ent;
+} ent_position;
+
+
+
+
+
+
+
+
+typedef struct _Coalesce {
+       entity *ent_1;
+       entity *ent_2;
+} Coalesce;
+
+
+
+
+
+
+
+static void _ents(entity*, void*);
+static void _ent_nodes(ir_node*, void*);
+
+static void create_Vertex(void*);
+static void create_Edge(entity*, entity*, void*);
+
+int            values_contemp(ir_node*, ir_node*);
+int            count_Edge_Affinity(pset*, pset*);
+
+static void    Cli_ents(int, int, int, void*);
+static cacheline *create_Cli_ent(struct obstack*);
+
+int            wt(entity*, entity*);
+int            get_edge_affinity(entity*, entity*, void*);
+int            compute_Entity_Cache_Affinity(entity*, pset*, void*);
+
+void   ir_printf_ent_nodes(void*);
+void   ir_printf_ent_nodes_aff(void*) ;
+
+int            Entity_values_interfere(entity*, entity*, void*);
+int            Ents_Coalesce (entity*, entity*, void*);
+void    Check_Coalesce(void*);
+
+int            delta_configuration_locality(entity*, cacheline*, void*);
+
+int            check_offset(void*);
+int            is_filled(pset*, pset*);
+
+entity *min_configuration_locality(cacheline*, void*);
+entity *max_configuration_locality(cacheline*, void*);
+void   bbcache_REORDER (void*);
+
+int            is_pasteable(entity*, pset*);
+entity *MAX_affinity_ents(pset*, pset*, void*);
+int            bbcache_CHILIMBI (void*);
+
+
+
+
+
+static void _ents(entity *_entity, void *env) {
+       /* GET all ents from stack-frame of the current irg*/
+
        spilloc_env_t *spi = env;
-       entity *e = obstack_alloc(&spi->ob, sizeof(*e));
+       entity *ent = obstack_alloc(&spi->ob, sizeof(*ent));
 
-       e = ent;
-       pset_insert_ptr(spi->ents, e);
-       spi->entcnt++;
+       ent = _entity;
+       pset_insert_ptr(spi->ents, ent);
+       spi->ent_cnt++;
 }
 
-static void data_init(spilloc_env_t *env) {
-       pset *ps = pset_new_ptr_default();
-       entity *e;
+static void _ent_nodes(ir_node *irn, void *env) {
+       /* GET ir_node(s) for each found entity */
+
+       spilloc_env_t *spi = env;
+       entity *ir_ent, *ent;
+       ir_node *node;
+       pset *nodes;
+
+       ir_ent = arch_get_frame_entity(spi->arch, irn);
+       if (ir_ent)
+       {
+               foreach_pset(spi->ents, ent)
+               {
+                       if(ir_ent == ent)
+                       {
+                               if(!pmap_find(spi->ent_nodes, ent)) {
+                                       nodes = pset_new_ptr_default();
+                                       pmap_insert(spi->ent_nodes, ent, nodes);
+
+                               }
+                               nodes = pmap_get(spi->ent_nodes, ent);
+                               node = obstack_alloc(&spi->ob, sizeof(*node));
+                               node = irn;
 
-       foreach_pset(env->ents, e) {
-               pmap_insert(env->nodents, e, ps);
+                               pset_insert_ptr(nodes, node);           /* entity and their ir_node(set)*/
+
+                               pset_insert_ptr(spi->nodes, node);      /* 'only' all ir_node(s)*/
+
+                               spi->node_cnt++;
+                       }
+               }
        }
 }
 
-static void get_entity_nodes(ir_node *irn, void *env) {
-       entity *e, *ent;
+static void create_Vertex(void *env) {
+
        spilloc_env_t *spi = env;
+       entity *ent;
+       Node *node;
 
-       e = get_irn_entity_attr(irn);
-       //get_entity_additional_properties();
-       if (e)
+
+       foreach_pset(spi->ents, ent)
        {
-               foreach_pset(spi->ents, ent) {
+               /* alloc */
 
-                       if ((ent->nr == e->nr) && (ent->ld_name == e->ld_name) )
-                       {
-                               pset *ps = pmap_get(spi->nodents, ent);
-                               if (ps && (!pset_find_ptr(pmap_get(spi->nodents, ent),irn))) {
-                                       pset_insert_ptr(pmap_get(spi->nodents, ent), irn);
-                               }
-                       }
+               node   = obstack_alloc(&spi->ob, sizeof(*node));
+               node->vtx = obstack_alloc(&spi->ob, sizeof(*(node->vtx)));
+               node->edges = pset_new_ptr_default();
+
+               /* init */
+               node->vtx->ent                  = ent;
+               node->vtx->offset_bits  = 0;
+               node->vtx->offset_bytes = 0;
+               node->vtx->ela                  = 0;
+               node->vtx->neighbors    = pset_new_ptr_default();
+               /*
+               node->vtx->Cli->end     = 0;
+               node->vtx->Cli->start   = 0;
+               node->vtx->Cli->nr              = 0;
+               node->vtx->Cli->ents   = pset_new_ptr_default();
+               */
+               node->status                    = 0;
+
+               /* write */
+               pmap_insert(spi->afgraph, ent, node);
+               pset_insert_ptr(spi->afgraph_vs, node);
+       }
+}
+
+int values_contemp(ir_node *a, ir_node *b) {
+
+       /* check, if 2 nodes lying within range */
+
+       int i;
+       ir_node *irn = a;
+       ir_node *prev;
+       ir_node *next;
+       int range = CONTEMP_RANGE;
+
+       // backward (until block-border)
+       for(i = 0; i < range; i++) {
+               if(sched_has_prev(irn)) {
+                       prev = sched_prev(irn);
+                       if(prev == b) return -1;
+                       irn = prev;
+               }
+       }
+
+       // forward (until block-border)
+       for(i = 0, irn = a; i < range; i++) {
+               if(sched_has_next(irn)) {
+
+                       next = sched_next(irn);
+                       if(next == b) return 1;
+                       irn = next;
+               }
+       }
+       return 0;
+}
+
+int count_Edge_Affinity(pset *a, pset *b) {
+
+       /* count entity *a and entity *b */
+
+       ir_node *a_node, *cpy;
+       pset *copy = pset_new_ptr(pset_count(b));
+       int cnt=0;
+
+       foreach_pset(b, cpy) {pset_insert_ptr(copy, cpy);}
+       foreach_pset(a, a_node) {
+               foreach_pset(copy, cpy) {
+                        if (values_contemp(a_node, cpy) != 0)
+                                cnt++;
                }
        }
+       del_pset(copy);
+       return cnt;
+
 }
 
-pset *get_entity_irn(entity *ent, void *env) {
+static void create_Edge(entity *a, entity *b, void *env) {
+
+       /* create a node in afgraph */
+
        spilloc_env_t *spi = env;
 
-       pset *pirn = pmap_get(spi->nodents, ent);
-       if (pirn)
+       pset *nodes_a,*nodes_b;
+       int aff;
+       Node *node;
+       edge *edg;
+
+       nodes_a = ((pset *)pmap_get(spi->ent_nodes, a));
+       nodes_b = ((pset *)pmap_get(spi->ent_nodes, b));
+       aff = 0;
+       if(nodes_a && nodes_b)aff = count_Edge_Affinity(nodes_a, nodes_b);
+
+       if(aff != 0)
        {
-               return pirn;
+               // alloc
+               edg = obstack_alloc(&spi->ob, sizeof(*edg));
+
+               // init
+               edg->src = a;
+               node = (Node *)pmap_get(spi->afgraph, a);
+               edg->vtx_src = node->vtx;
+               edg->tgt = b;
+               node = (Node *)pmap_get(spi->afgraph, b);
+               edg->vtx_tgt = node->vtx;
+               edg->aff = aff;
+
+               // write
+               node = pmap_get(spi->afgraph, a);
+               pset_insert_ptr(node->edges, b);
+               node = pmap_get(spi->afgraph, b);
+               pset_insert_ptr(node->edges, a);
+               pset_insert_ptr(spi->afgraph_es, edg);
        }
-       return NULL;
 }
 
-int entities_interfere(entity *e1, entity *e2, void *env) {
+static void Cli_ents(int start, int end, int nr, void *env) {
+
        spilloc_env_t *spi = env;
-       ir_node *n1, *n2;
+       pset *surrounder = pset_new_ptr_default();
+       entity *ent;
+
+       cacheline *cli;
+
+       foreach_pset(spi->ents, ent)
+       {
+                       if((start < get_entity_offset_bytes(ent)) && (get_entity_offset_bytes(ent) < end)) {
+                               pset_insert_ptr(surrounder, ent);
+                       }
+       }
+
+       cli = obstack_alloc(&spi->ob, sizeof(*cli));
+
+       cli->start      = start;
+       cli->end        = end;
+       cli->nr         = nr;
+       cli->ents       = pset_new_ptr_default();
+
+       foreach_pset(surrounder, ent) {pset_insert_ptr(cli->ents,ent);}
+       pmap_insert(spi->Cli_ents, (void *)nr, cli);
+       del_pset(surrounder);
+}
+
+static cacheline *create_Cli_ent(struct obstack *ob) {
+
+       cacheline *cli;
+
+       cli = obstack_alloc(ob, sizeof(*cli));
 
-       pset *pe1 = pmap_get(spi->nodents, e1);
-       pset *pe2 = pmap_get(spi->nodents, e2);
+       cli->start      = 0;
+       cli->end        = 0;
+       cli->nr         = 0;
+       cli->ents       = pset_new_ptr_default();
 
-       foreach_pset(pe1, n1) {
-               foreach_pset(pe2, n2) {
-                       if (values_interfere(n1, n2)) return 1;
+       return cli;
+}
+
+
+
+
+
+
+int wt(entity *ent1, entity *ent2) {
+       /*Relative Distance of 2 Ents == from start to start*/
+
+       int o1, o2, cache_blk_size, dist, wt;
+
+       o1 = get_entity_offset_bytes(ent1);
+       o2 = get_entity_offset_bytes(ent2);
+
+       if (o1 < o2) {
+               ent1->type->size;
+               dist = (o2 - o1);
+       }
+       if (o1 > o2) dist = (o1 - o2);
+
+       cache_blk_size = LINESIZE_BYTES;
+       wt = ((cache_blk_size - dist) / cache_blk_size);
+       if(wt != 0) return wt;
+
+       // default
+       return 0;
+}
+
+int get_edge_affinity(entity *a, entity *b, pmap *graph) {
+
+       Node *node;
+       edge *edg;
+
+       if((pmap_find(graph,a))) {
+               node = pmap_get(graph, a);
+               foreach_pset(node->edges, edg) {
+                       if(edg->src == a && edg->tgt == b) {
+                               return edg->aff;
+                       }
                }
        }
        return 0;
 }
 
-static void set_aff_graph(void *env) {
+int compute_Entity_Cache_Affinity(entity *ent, pset *surrs, void *env) {
+
+       spilloc_env_t *spi = env;
+       entity *sur;
+       int ela = 0;
+       int aff = 0;
+
+       if(pset_count(surrs) != 0) {
+               foreach_pset(surrs, sur)
+               {
+                       aff = get_edge_affinity(ent, sur, spi->afgraph);
+                       ela += (wt(ent, sur) * aff);
+               }
+       }
+       return ela;
+}
+
+
+void ir_printf_ent_nodes(void *env) {
+
+       spilloc_env_t *spi = env;
+
+       entity *ent;
+       pset *nodes;
+       ir_node *node;
+
+       printf("\n\n\n");
+       // printf("%c", get_irg_dump_name(spi->irg));
+
+       nodes = pset_new_ptr_default();
+       foreach_pset(spi->ents, ent) {
+               printf("\n <%d>",ent->nr);
+               nodes = pmap_get(spi->ent_nodes, ent);
+               if(nodes) {foreach_pset(nodes, node) {printf(" %d, ", node->node_nr);}}
+       }
+}
+
+
+void ir_printf_ent_nodes_aff(void *env) {
+
        spilloc_env_t *spi = env;
-       entity *e, *cmp;
-       vertex *v;
-       int i = 1;
+       edge *edg;
+       entity *ent;
+       pset *nodes;
+       ir_node *node;
+
+       printf("\n\n\n");
 
-       foreach_pset(spi->ents, e) {
-               vertex *ver = obstack_alloc(&spi->ob, sizeof(*ver));
-               ver->edges = pset_new_ptr_default();
-               ver->ent = e;
-               ver->node_nr = i;
-               pmap_insert(spi->afgraph, e, ver);
+       nodes = pset_new_ptr_default();
+       foreach_pset(spi->afgraph_es, edg) {
+               printf("\n <%d-%d> :",edg->src->nr, edg->tgt->nr);
+               printf(" %d \n", edg->aff);
+       }
+}
+
+void ir_printf_chilimbi_cachelines(spilloc_env_t env) {
+
+       spilloc_env_t spi = env;
+       cacheline *cline;
+       entity *ent;
+       int i=0;
+
+       printf("<< ");
+       foreach_pset(spi.chilimbi_Cli_ents, cline) {
+               printf("%d", i);
+               foreach_pset(cline->ents, ent)
+               {
+                       printf("%d,", ent->nr);
+               }
                i++;
        }
+       printf(" >>\n");
+}
 
-       foreach_pset(spi->ents, e) {
-               foreach_pset(spi->ents, cmp) {
-                       if (entities_interfere(e, cmp, &spi) == 1) {
-                               v = pmap_get(spi->afgraph, e);
-                               pset_insert_ptr(v->edges, cmp);
+
+
+
+
+
+
+
+
+
+
+
+int Entity_values_interfere(entity *ent_A, entity *ent_B, void *env) {
+
+       spilloc_env_t *spi = env;
+
+       ir_node *node_A, *node_B;
+       pset *nodes_A = pmap_get(spi->ent_nodes, ent_A);
+       pset *nodes_B = pmap_get(spi->ent_nodes, ent_B);
+
+       foreach_pset(nodes_A, node_A) {
+               foreach_pset(nodes_B, node_B) {
+                       if(values_interfere(node_A, node_B)) {
+                               return 0;
                        }
                }
        }
+       return 1;
 }
 
-void be_spill_loc(const be_chordal_env_t *chordal_env) {
+int Ents_Coalesce (entity *a, entity *b, void *env) {
 
-       spilloc_env_t spi;
+       spilloc_env_t *spi = env;
+       edge *edg;
+       Node *aNode,*bNode;
 
-       // create initial graph representing data structure
-       obstack_init(&spi.ob);
-       spi.ents = pset_new_ptr_default();
-       spi.entcnt = 0;
-       spi.irg = chordal_env->irg;
-       spi.nodents = pmap_create();
-       spi.afgraph = pmap_create();
+                       /* check  (ent,ent)-interfere */
 
+       if(Entity_values_interfere(a,b,&spi) == 1) {
 
-       /* Walks over all entities in the type */
-       walk_types_entities(get_irg_frame_type(chordal_env->irg), add_ent, &spi);
+               aNode = pmap_get(spi->afgraph, a);
+               bNode = pmap_get(spi->afgraph, b);
 
-       data_init(&spi);
-       irg_walk_blkwise_graph(chordal_env->irg, NULL, get_entity_nodes, &spi);
+               if(pset_find_ptr(aNode->edges,b) && pset_find_ptr(bNode->edges,a))
+               {
 
+                       // find THE EDGE(a,b) - if exists
+
+                       pmap_foreach(spi->afgraph_es, edg) {
+                               if((edg->src == a || edg->tgt == b) || (edg->src == b || edg->tgt == a)) pmap_break(spi->afgraph_es);
+                       }
+                       // (a,b) are coalescable
+
+                       if ((edg != NULL) && (edg->aff > 0))
+                       {
+                               return 1;
+                       }
+               }
+       }
+                       // (a,b) not coalescable
+
+       return 0;
+
+}
+
+
+void Check_Coalesce(void *env) {
+
+       /* return a subset of (ptr_set) = all potential coalescing pairs */
+
+       spilloc_env_t *spi = env;
+       pset *these = pset_new_ptr_default();
+       pset *those = pset_new_ptr_default();
+
+       entity *cpy, *ea, *eb;
+       Coalesce *coal;
+
+       foreach_pset(spi->ents, cpy) {
+               pset_insert_ptr(these, cpy);
+               pset_insert_ptr(those, cpy);
+       }
+
+       foreach_pset(these, ea) {               /* (ena,enb) */
+               foreach_pset(those, eb) {
+
+                       if(Ents_Coalesce(ea, eb, &spi) == 1)
+                       {
+                               /* markieren */
+
+
+                               /* alloc and set new information*/
+                               coal = obstack_alloc(&spi->ob, sizeof(*coal));
+                               coal->ent_1 = ea;
+                               coal->ent_2 = eb;
+
+                               /* sammeln */
+                               pset_insert_ptr(spi->coals, coal);
+                       }
+               }
+       }
+}
+
+
+
+
+
+
+
+ir_node *find_phi_ent() {
+       return NULL;
+}
+
+ir_node *looptroop() {
+       return NULL;
+}
+
+
+
+
+
+
+
+
+
+int delta_configuration_locality(entity *ent, cacheline *cli_env, void *env) {
+
+       spilloc_env_t *spi = env;
+       cacheline *cli;
+       Node *node;
+
+       cli->ents = pset_new_ptr_default();
+
+       // teste ent in allen cachelines ...
+       pmap_foreach(spi->Cli_ents, cli) {
+
+               /* ausser der gegebenen cacheline(ent)*/
+               if(cli != cli_env) {
+                       node = pmap_get(spi->afgraph, ent);
+                       //node->vtx->ela = compute_Entity_Cache_Affinity(ent,rel,&spi);
+                       node->vtx->ela = compute_Entity_Cache_Affinity(ent,(cli->ents),&spi);
+               }
+       }
+
+       return 0;
+}
+
+
+
+int is_pasteable(entity *ent, pset *co) {
+
+       /*      RETURNs 1, IF ent could be moved to CACHELine co
+       */
+
+       int align;
+       int size;
+       int step,curr_pos,curr_end, etc_pos, etc_end;
+       entity *etc;
+
+       ir_type *stype = get_entity_type(ent);
+
+       align = get_type_alignment_bytes(stype);
+       size  = get_type_size_bytes(stype);
+
+       // check all possible alignment-constrainted positions
+       for(step=0; (step*align) >= LINESIZE_BYTES; step++) {
+               curr_pos = (step*align);
+               curr_end = curr_pos + size;
+
+               // collision with prev and/or next neighbor
+               foreach_pset(co, etc) {
+                       etc_pos = get_entity_offset_bytes(get_entity_type(etc));
+                       etc_end = (get_entity_offset_bytes(get_entity_type(etc)) + get_type_size_bytes(get_entity_type(etc)));
+
+                       if((etc_end < curr_pos) || (curr_end < etc_pos)) { /* (etc,ent) is OK  */ }
+                       else if((etc_pos < curr_pos) && (curr_pos < etc_end) && (etc_end < curr_end)) {return 0;}
+                       else if((curr_pos < etc_pos) && (etc_end < curr_end)) {return 0;}
+                       else if((etc_pos < curr_pos) && (curr_end < etc_end)) {return 0;}
+                       else if((curr_pos < etc_pos) && (etc_pos < curr_end) && (etc_end > curr_end)) {return 0;}
+               }
+
+               // overlapping to next LINE
+               if(get_entity_offset_bytes(ent)+get_type_size_bytes(ent) > LINESIZE_BYTES) {return 0;}
+       }
+       return 1;
+}
+
+
+
+
+
+
+
+
+
+
+entity *min_configuration_locality(cacheline *cli_env, void *env) {
+
+       spilloc_env_t *spi = env;
+
+       cacheline *cli = cli_env;
+       entity *ent,*ret;
+       Node *node;
+       float min = 9999;
+
+       if(cli->ents == NULL) return NULL;
+
+       foreach_pset(cli->ents, ent) {
+               node = pmap_get(spi->afgraph, ent);
+               if(node->vtx->ela < min) {min = (float)node->vtx->ela; ret = node->vtx->ent;}
+       }
+
+       return ret;
+}
+
+void bbcache_REORDER (void *env) {
+
+       spilloc_env_t *spi = env;
+       int  curr_ela, line_nr;
+       Node *node;
+       entity *ent,*cpy;
+       pset *Cli_ents;
+       pset *ws = pset_new_ptr_default();
+       pset *copy;
+       cacheline *cli, *mv2cli;
+
+       do{     /* first, find 'some' (= 1 ?) bad for each CACHELINE */
+               pmap_foreach(spi->Cli_ents, cli) {
+
+                       /* ents(cacheline) holen - jeweils kleinste insert(ws) und remove(cacheline(i) = cli(i)) */
+
+                       if(min_configuration_locality(&cli, &spi) != NULL) {
+
+                               ent = min_configuration_locality(&cli, &spi);
+                               pset_insert_ptr(ws, ent);                                                               // insert(ws,ent)
+                               //pset_remove_ptr(Cli_ents,ent);                                                        // cacheline_remove(i,ent)
+
+                       }
+               }
+
+
+
+               /* second, PASTE them AGAIN hopefully elsewhere*/
+               copy=pset_new_ptr(pset_count(ws));
+               foreach_pset(ws, ent) {pset_insert_ptr(copy,ent);}
+
+               foreach_pset(copy,cpy){
+
+                       node = pmap_get(spi->afgraph,cpy);
+                       curr_ela = node->vtx->ela;
+                       mv2cli = NULL;
+                       line_nr = -1;
+
+                       pmap_foreach(spi->Cli_ents, cli) {                                                                      /* for each CACHELINE */
+                               if(delta_configuration_locality(cpy, &cli, &spi) > curr_ela){       // condition 1
+                                       if((is_pasteable(cpy,&cli) != 0)) {                                                         // condition 2
+
+                                               mv2cli = cli;
+                                               line_nr = cli->nr;
+
+                                       }
+                               }
+                       }
+
+                       if((mv2cli != NULL) && (line_nr > 0)) {
+
+                               cli = pmap_get(spi->Cli_ents, line_nr);
+                               pset_insert_ptr(cli->ents,cpy);
+                               pset_remove_ptr(ws,cpy);
+
+                       }
+               }
+
+               del_pset(copy);
+
+       } while(pset_count(ws) > 0);
+}
+
+entity *MAX_affinity_ents(pset *ws, pset *layout_set, spilloc_env_t *env) {
+
+       //spilloc_env_t *spi = env;
+       //pset *layout = pset_new_ptr_default();
+       entity *ent, *max;
+       int x = 0;
+       int y;
+
+       //foreach_pset() {layout}
+
+       foreach_pset(ws, ent) {
+
+               y = compute_Entity_Cache_Affinity(ent, layout_set, env);
+
+               if(x <= y) {
+                       max = ent;
+                       x = y;
+               }
+       }
+
+       return max;
+
+}
+
+entity *max_configuration_locality(cacheline *cli_env, void *env) {
+
+       spilloc_env_t *spi = env;
+       cacheline *cli = cli_env;
+       entity *ent;
+       Node *node;
+       float min;
+       entity *ret;
+/*
+       min = 9999;
+       if(cli->ents == NULL) return NULL;
+
+       foreach_pset(cli->ents, ent) {
+               node = pmap_get(spi->afgraph, ent);
+               if(node->vtx->ela < min) {min = (float)node->vtx->ela; ret = node->vtx->ent;}
+       }
+*/
+       return ret;
+}
+
+int check_offset(void *env) {
+
+       spilloc_env_t *spi = env;
+       pset *cli_ent_set;
+       entity *ent;
+       int m,n;
+
+       cli_ent_set = pset_new_ptr_default();
+       if(is_pasteable(ent, cli_ent_set)) return ;
+
+       return -1;
+}
+
+int is_filled(pset *cli, pset *ws) {
+
+       int re = 1;
+       entity *ent;
+
+       foreach_pset(ws, ent) {
+               if (is_pasteable(ent, cli)) re = 0;
+       }
+
+       return re;
+}
+
+int bbcache_CHILIMBI (void *env) {
+
+       spilloc_env_t *spi = env;
+
+       entity *ent;
+       cacheline *cline;
+       pset *ws;
+       edge *edg, *max_edge;
+       entity *max, *last_max;
+
+       int o,p,q, x,y,z, i,j,k;
+
+
+
+               /* get workset: ws == (spi->ents) */
+       o = pset_count(spi->ents);
+       ws = pset_new_ptr(o);
+       foreach_pset(spi->ents,ent) {pset_insert_ptr(ws,ent);}
+
+
+       do {
+
+               cline = create_Cli_ent(&spi->ob);
+
+               cline->start = 0;
+               cline->end   = 0;
+               cline->nr    = 0;
+
+               p = 0;
+
+               /*
+                  (1) start BY: adding the pair of ents
+                      connected by
+                          the maxinmum affinity edge
+               */
+
+
+                       /* MAX affinity-edge */
+               foreach_pset(spi->afgraph_es, edg)
+               {
+
+                       if((edg->aff > p) && (pset_find_ptr(ws, edg->src)) && (pset_find_ptr(ws, edg->tgt)))
+                       {
+                               p = edg->aff;
+                               max_edge = edg;
+                       }
+               }
+
+               o = pset_count(spi->afgraph_es);
+               if(o == 0) return -1;
+
+               if(is_pasteable(max_edge->src, cline->ents)) {
+                       pset_insert_ptr(cline->ents, max_edge->src);
+                       pset_remove_ptr(ws, max_edge->src);
+               }
+
+               if(is_pasteable(max_edge->tgt, cline->ents)) {
+                       pset_insert_ptr(cline->ents, max_edge->tgt);
+                       pset_remove_ptr(ws, max_edge->tgt);
+               }
+
+
+               /* (2) A single entity
+                          is appended to the existing layout,
+                          the one
+                          that increases configuration locality
+                          by the largest amount
+               */
+               o = pset_count(ws);
+               if(o == 0) return -2;
+
+               o = pset_count(cline->ents);
+               if(o != 0)
+                       max = MAX_affinity_ents(ws, (cline->ents), spi);
+
+
+               if((o != 0) && (max != NULL) ) { // && (max->value != NULL)
+
+                       do {
+
+                               last_max = max;
+
+                                       // paste to layout set
+                               if(is_pasteable(max, cline->ents)) {
+                                       pset_insert_ptr(cline->ents, max);
+                                       pset_remove_ptr(ws, max);
+                                       last_max = NULL;
+                               }
+
+                                       // get the best-fit'in entity
+                               o = pset_count(cline->ents);
+                               p = pset_count(ws);
+                               if(o != 0 && p != 0)
+                                       max = MAX_affinity_ents(ws, (cline->ents), spi);
+
+                       } while( ((max != last_max) || (last_max != NULL) || (max == NULL)) && (p != 0));
+
+               }
+
+                       /* insert one "filled" cacheline */
+               pset_insert_ptr(spi->chilimbi_Cli_ents, cline);
+
+       } while(ws != NULL && pset_count(ws) > 0);
+
+       del_pset(ws);
+       return 0;
+}
+
+void frame_information (spilloc_env_t spi) {
+
+       int frame_align;
+       ir_type *frame;
+
+       frame = get_irg_frame_type(spi.irg);
+       frame_align = get_type_alignment_bytes(frame);
+
+}
+
+void be_spill_loc(const be_chordal_env_t *chordal_env) {
+
+       spilloc_env_t spi;
+       pset *copy;
+       entity *ent,*cpy;
+       int max_off, i, start, end;
+       Node *node;
+       ent_position *pos;
+
+               /* Init */
+       obstack_init(&spi.ob);
+
+       spi.irg   = chordal_env->irg;
+       spi.arch          = chordal_env->birg->main_env->arch_env;
+
+       spi.ents            = pset_new_ptr_default();
+       spi.nodes           = pset_new_ptr_default();
+       spi.ent_nodes   = pmap_create();
+
+       spi.ent_cnt     = 0;
+       spi.node_cnt    = 0;
+       spi.blk_cnt     = 0;
+       spi.cli_cnt         = 0;
+
+       spi.intval_cnt  = 0;
+
+       spi.afgraph         = pmap_create();
+       spi.afgraph_es  = pset_new_ptr_default();
+       spi.afgraph_vs  = pset_new_ptr_default();
+
+       spi.Cli_ents    = pmap_create();
+       spi.position    = pmap_create();
+       spi.coals       = pset_new_ptr_default();
+
+       spi.chilimbi_Cli_ents = pset_new_ptr_default();
+
+
+
+               /* irg -> {ent}  */
+       walk_types_entities(get_irg_frame_type(chordal_env->irg), _ents, &spi);
+       if(spi.ent_cnt != pset_count(spi.ents))
+               spi.ent_cnt = pset_count(spi.ents);
+
+
+
+               /* ent -> {irn} */
+       irg_walk_blkwise_graph(chordal_env->irg, NULL, _ent_nodes, &spi);
+       if(spi.node_cnt != pset_count(spi.nodes))
+               spi.ent_cnt = pset_count(spi.ents);
+
+
+               /* ent -> Node */
+       create_Vertex(&spi);
+
+
+
+               /* (ent,ent) -> edge */
+       copy = pset_new_ptr(spi.ent_cnt);
+       foreach_pset(spi.ents, ent)     {pset_insert_ptr(copy,ent);}
+       foreach_pset(copy, cpy) {
+               foreach_pset(spi.ents, ent) {
+                       if(ent != cpy)
+                               create_Edge(ent,cpy,&spi);
+               }
+       }
+       del_pset(copy);
+
+
+
+       /* ======================================================================================================*/
+       /* ======================================================================================================*/
+       /* ======================================================================================================*/
+       /* ======================================================================================================*/
+
+                                                                               /* use the dumb offset */
+
+       /* ======================================================================================================*/
+       /* ======================================================================================================*/
+       /* ======================================================================================================*/
+       /* ======================================================================================================*/
+
+
+               /* {ent} -> max_off */
+       max_off = 0;
+       foreach_pset(spi.ents, ent) {
+               if(get_entity_offset_bytes(ent) > max_off) {max_off = get_entity_offset_bytes(ent);}
+       }
+
+
+
+                       /* max_off -> max_cli */
+       i=1;
+       while((i * LINESIZE_BYTES) < max_off){
+               i++;
+       }
+       spi.cli_cnt = i;
+
+
+
+
+               /* {ent} -> {({ent},int), ({ent},int), ({ent},int),...,({ent},int)} */
+       for(i = 0; i < spi.cli_cnt; i++) {
+               start = (i * LINESIZE_BYTES);
+               end   = start + LINESIZE_BYTES;
+               Cli_ents(start, end, (i + 1), &spi);
+       }
+
+
+
+               /* (ent,{ent}) -> int */
+
+       for(i = 1; i <= spi.cli_cnt; i++) {
+
+               cacheline *cline;
+
+               cline = pmap_get(spi.Cli_ents, i);
+               if(!cline) break;
+
+               foreach_pset(spi.ents, ent) {
+                       node = pmap_get(spi.afgraph, ent);
+                       //node->vtx->ela = compute_Entity_Cache_Affinity(ent,rel,&spi);
+                       node->vtx->ela = compute_Entity_Cache_Affinity(ent,(cline->ents),&spi);
+               }
+       }
+
+
+       /* ======================================================================================================*/
+
+
+                       /* {ent} -> {ent_position} (INIT) */
+
+       foreach_pset(spi.ents, ent) {
+
+               ent_position *epos;
+
+               epos = obstack_alloc(&spi.ob, sizeof(*epos));
+               epos->Cli                       = NULL;
+               epos->is_set            = 0;
+               epos->offset            = 0;
+               epos->nr                        = 0;
+               epos->ent                       = ent;
+               pmap_insert(spi.position,ent,epos);
+       }
+
+                       /* {ent_position->offset} -> {ent_position} (SET) */
+
+       foreach_pset(spi.ents, ent) {
+               pos = pmap_get(spi.position, ent);
+               pos->offset = get_entity_offset_bytes(pos->ent);
+       }
+
+
+
+
+
+       /* ======================================================================================================*/
+       /* ======================================================================================================*/
+       /* ======================================================================================================*/
+       /* ======================================================================================================*/
+
+                                                                               /* use the initial offset */
+
+       /* ======================================================================================================*/
+       /* ======================================================================================================*/
+       /* ======================================================================================================*/
+       /* ======================================================================================================*/
+
+
+
+
+
+
+
+
+                       /* PRINT INFO's */
+       /*
+       ir_printf_ent_nodes(&spi);              // <ent->nr>: ir_node->node_nr, ir_node->node_nr ....
+       ir_printf_ent_nodes_aff(&spi);  // <ent->nr,ent->nr>: affinity
+       */
+
+               // CHILIMBI => BBCache - algorithm
+
+       bbcache_CHILIMBI(&spi);
+
+
+                       /* PRINT INFO's */
+
+       ir_printf_chilimbi_cachelines(spi);
+
+
+               // HIGH affinity  &&  NO values_interfere
+
+       //Check_Coalesce(&spi);
+
+
+
+
+
+
+
+
+
+                       /* CLEAN */
+
+       del_pset(spi.ents);
+       del_pset(spi.nodes);
+       pmap_destroy(spi.ent_nodes);
+
+       pmap_destroy(spi.afgraph);
+       del_pset(spi.afgraph_es);
+       del_pset(spi.afgraph_vs);
+
+       pmap_destroy(spi.Cli_ents);
+       pmap_destroy(spi.position);
+
+       del_pset(spi.coals);
+
+       del_pset(spi.chilimbi_Cli_ents);
+
+       obstack_free(&spi.ob, NULL);
 
-       /*clean*/
-       del_pset(spi.ents);
-       pmap_destroy(spi.nodents);
-       pmap_destroy(spi.afgraph);
-       obstack_free(&spi.ob, NULL);
 }