+/******************************************************************************
+ _ _____ _ _
+ /\ | | | __ \ | | |
+ / \ _ __ _ __ | |_ _ | |__) |___ ___ _ _| | |_
+ / /\ \ | '_ \| '_ \| | | | | | _ // _ \/ __| | | | | __|
+ / ____ \| |_) | |_) | | |_| | | | \ \ __/\__ \ |_| | | |_
+ /_/ \_\ .__/| .__/|_|\__, | |_| \_\___||___/\__,_|_|\__|
+ | | | | __/ |
+ |_| |_| |___/
+ *****************************************************************************/
+
+/**
+ * Spill a variable and add reloads before all uses.
+ */
+static INLINE void var_add_spills_and_reloads(be_raext_env_t *raenv, int var_nr) {
+ var_info_t *vi = var_find(raenv->vars, var_nr);
+ ir_node *spill=NULL, *ctx, *irn;
+ ir_mode *mode;
+ const ir_edge_t *edge, *ne;
+ pset *spills = pset_new_ptr(4); /* the spills of this variable */
+ pset *reloads = pset_new_ptr(4); /* the reloads of this variable */
+ int new_size, n_spills, n_reloads;
+
+ assert(vi && "Variable nr does not exist!");
+ assert(pset_count(vi->values) && "There are no values associated to this variable");
+
+ /* the spill context is set to an arbitrary node of the phi-class,
+ * or the node itself if it is not member of a phi class
+ */
+ if (pset_count(vi->values) == 1)
+ ctx = get_first_non_phi(vi->values);
+ else
+ ctx = get_first_phi(vi->values);
+
+ DBG((raenv->dbg, LEVEL_2, "Spill context: %+F\n", ctx));
+
+ /* for each value of this variable insert the spills */
+ pset_foreach(vi->values, irn) {
+ if (is_Phi(irn)) {
+ sched_remove(irn);
+ continue;
+ }
+
+ /* all ordinary nodes must be spilled */
+ DBG((raenv->dbg, LEVEL_2, " spilling %+F\n", irn));
+ spill = be_spill(raenv->aenv, irn, ctx);
+
+ /* remember the spill */
+ pset_insert_ptr(spills, spill);
+ }
+
+ assert(spill && "There must be at least one non-phi-node");
+
+ mode = get_irn_mode(get_irn_n(spill, be_pos_Spill_val));
+
+ /* insert reloads and wire them arbitrary*/
+ pset_foreach(vi->values, irn)
+ foreach_out_edge_safe(irn, edge, ne) {
+ ir_node *reload, *src = edge->src;
+ if (is_Phi(src) || be_is_Spill(src))
+ continue;
+
+ /* all real uses must be reloaded */
+ DBG((raenv->dbg, LEVEL_2, " reloading before %+F\n", src));
+ reload = be_reload(raenv->aenv, raenv->cls, edge->src, mode, spill);
+ set_irn_n(edge->src, edge->pos, reload);
+
+ /* remember the reload */
+ pset_insert_ptr(reloads, reload);
+ }
+
+ /* correct the reload->spill pointers... */
+ be_ssa_constr_set(raenv->dom_info, spills);
+
+
+ /****** correct the variable <--> values mapping: ******
+ *
+ * - if we had a phi class it gets split into several new variables
+ * - all reloads are new variables
+ */
+ n_spills = pset_count(spills);
+ n_reloads = pset_count(reloads);
+
+ /* first make room for new pointers in the cls_var array */
+ new_size = raenv->n_cls_vars + n_reloads + ((n_spills>1) ? n_spills : 0);
+ raenv->cls_vars = realloc(raenv->cls_vars, (new_size) * sizeof(*raenv->cls_vars));
+ assert(raenv->cls_vars && "Out of mem!?");
+
+ /* if we had a real phi-class, we must... */
+ if (pset_count(spills) > 1) {
+ /* ...remove the old variable corresponding to the phi class */
+ vi->var_nr = SET_REMOVED;
+
+ /* ...add new vars for each non-phi-member */
+ pset_foreach(spills, irn) {
+ ir_node *spilled = get_irn_n(irn, be_pos_Spill_val);
+ raenv->cls_vars[raenv->n_cls_vars++] = var_add_value(raenv, get_irn_node_nr(spilled), spilled);
+ }
+ }
+
+ /* add new variables for all reloads */
+ pset_foreach(reloads, irn) {
+ assert(get_irn_node_nr(irn) != 1089);
+ raenv->cls_vars[raenv->n_cls_vars++] = var_add_value(raenv, get_irn_node_nr(irn), irn);
+ }
+
+ del_pset(spills);
+ del_pset(reloads);
+}
+
+#define INVALID_FILE_FORMAT assert(0 && "Invalid file format.")
+#define BUFLEN 32
+#define BUFCONV " %32s "