+
+
+#define HASH_VAR_NR(var_nr) var_nr
+
+
+
+static int compare_var_infos(const void *e1, const void *e2, size_t size) {
+ const var_info_t *v1 = e1;
+ const var_info_t *v2 = e2;
+
+ return v1->var_nr != v2->var_nr;
+}
+
+static INLINE var_info_t *var_find(set *vars, int var_nr) {
+ var_info_t vi;
+ vi.var_nr = var_nr;
+
+ return set_find(vars, &vi, sizeof(vi), HASH_VAR_NR(var_nr));
+}
+
+static INLINE var_info_t *var_find_or_insert(set *vars, int var_nr) {
+ var_info_t vi, *found;
+ memset(&vi, 0, sizeof(vi));
+ vi.var_nr = var_nr;
+
+ found = set_insert(vars, &vi, sizeof(vi), HASH_VAR_NR(var_nr));
+
+ if (!found->values) {
+ found->values = pset_new_ptr(1);
+ found->spills = pset_new_ptr(1);
+ found->reloads = pset_new_ptr(1);
+ }
+
+ return found;
+}
+
+/**
+ * Adds a value to a variable. Sets all pointers accordingly.
+ */
+static INLINE var_info_t *var_add_value(be_raext_env_t *raenv, int var_nr, ir_node *irn) {
+ var_info_t *vi = var_find_or_insert(raenv->vars, var_nr);
+
+ /* var 2 value mapping */
+ pset_insert_ptr(vi->values, irn);
+
+ /* value 2 var mapping */
+ set_var_info(irn, vi);
+
+ return vi;
+}
+
+/**
+ * Adds a spill to a variable. Sets all pointers accordingly.
+ */
+static INLINE var_info_t *var_add_spill(be_raext_env_t *raenv, int var_to_spill, ir_node *before) {
+ var_info_t *vi = var_find_or_insert(raenv->vars, var_to_spill);
+ ir_node *blk, *tospill, *spill;
+
+ assert(pset_count(vi->values) && "There are no values associated to this variable (yet?)");
+ assert(!vi->reload_phase && "I have already seen a reload for this variable, so you cant spill anymore!");
+
+ /* add spill to graph and schedule */
+ blk = get_nodes_block(before);
+ tospill = dom_up_search(vi->values, before); /* which value gets spilled */
+ spill = be_new_Spill(raenv->cls, raenv->irg, blk, tospill, tospill); /* the corresponding spill node */
+
+ sched_add_before(before, spill);
+
+ /* the spill also points to the var_info of the spilled node */
+ set_var_info(spill, vi);
+
+ /* remember the spill */
+ pset_insert_ptr(vi->spills, spill);
+
+ return vi;
+}
+
+/**
+ * Adds a reload to a variable. Sets all pointers accordingly.
+ */
+static INLINE var_info_t *var_add_reload(be_raext_env_t *raenv, int var_to_reload, int var_nr_for_reload, ir_node *before) {
+ var_info_t *vi = var_find_or_insert(raenv->vars, var_to_reload);
+ ir_node *blk, *spill, *reload;
+
+ assert(pset_count(vi->spills) && "There are no spills associated to this variable (yet?)");
+ /* now we enter the reload phase, so no more spills are allowed */
+ vi->reload_phase = 1;
+
+ /* add reload to graph and schedule */
+ blk = get_nodes_block(before);
+ spill = pset_first(vi->spills); /* For now use an arbitrary spill node. This is corrected later in fix_reloads */
+ pset_break(vi->spills);
+ reload = be_new_Reload(raenv->cls, raenv->irg, blk, get_irn_mode(get_irn_n(spill, 0)), spill);
+
+ sched_add_before(before, reload);
+
+ /* create a new variable for the result of the reload */
+ assert(!var_find(raenv->vars, var_nr_for_reload) && "Each reload must define a new variable");
+ var_add_value(raenv, var_nr_for_reload, reload);
+
+ /* remember the reload */
+ pset_insert_ptr(vi->reloads, reload);
+
+ return vi;
+}
+
+static INLINE pset *get_var_values(be_raext_env_t *raenv, int var_nr) {
+ var_info_t *vi = var_find(raenv->vars, var_nr);
+ assert(vi && "Variable does not (yet?) exist");
+ return vi->values;
+}
+
+static INLINE pset *get_var_spills(be_raext_env_t *raenv, int var_nr) {
+ var_info_t *vi = var_find(raenv->vars, var_nr);
+ assert(vi && "Variable does not (yet?) exist");
+ return vi->spills;
+}
+
+static INLINE pset *get_var_reloads(be_raext_env_t *raenv, int var_nr) {
+ var_info_t *vi = var_find(raenv->vars, var_nr);
+ assert(vi && "Variable does not (yet?) exist");
+ return vi->reloads;
+}