+ assert(max_alap > 0);
+ return max_alap;
+}
+
+/**
+ * Create the following variables:
+ * - x_{nt}^k binary weigthed with: t
+ * node n is scheduled at time step t to unit type k
+ * ==>> These variables represent the schedule
+ *
+ * - a_{nt}^k binary weighted with num_nodes
+ * node n is alive at time step t on unit type k
+ *
+ * - y_{nt}^k continuous weighted with: num_nodes^2
+ * register pressure over limit for unit type k
+ * ==>> These variables represent the register pressure
+ *
+ */
+static void create_variables(be_ilpsched_env_t *env, lpp_t *lpp, be_ilpsched_irn_t *block_node, struct obstack *var_obst) {
+ char buf[1024];
+ ir_node *irn;
+ unsigned num_block_var, num_nodes;
+ ilp_livein_node_t *livein;
+ ilpsched_block_attr_t *ba = get_ilpsched_block_attr(block_node);
+ unsigned weigth_y = ba->n_interesting_nodes * ba->n_interesting_nodes;
+ ir_timer_t *t_var = ir_timer_register("beilpsched_var", "create ilp variables");
+
+ ilp_timer_push(t_var);
+ num_block_var = num_nodes = 0;
+ foreach_linked_irns(ba->head_ilp_nodes, irn) {
+ be_ilpsched_irn_t *node;
+ ilpsched_node_attr_t *na;
+ unsigned n_unit_types, tp_idx, n_var, cur_unit;
+ unsigned cur_var_ad, cur_var_x, cur_var_y, num_ad;
+ int i;
+
+ node = get_ilpsched_irn(env, irn);
+ na = get_ilpsched_node_attr(node);
+ n_unit_types = be_ilpsched_set_type_info(env, irn, var_obst);
+
+ /* allocate space for ilp variables */
+ na->ilp_vars.x = NEW_ARR_D(int, var_obst, n_unit_types * VALID_SCHED_INTERVAL(na));
+ memset(na->ilp_vars.x, -1, ARR_LEN(na->ilp_vars.x) * sizeof(na->ilp_vars.x[0]));
+
+ /* we need these variables only for "real" nodes */
+ if (! na->is_dummy_node) {
+ na->ilp_vars.y = NEW_ARR_D(int, var_obst, n_unit_types * VALID_SCHED_INTERVAL(na));
+ memset(na->ilp_vars.y, -1, ARR_LEN(na->ilp_vars.y) * sizeof(na->ilp_vars.y[0]));
+
+ num_ad = ba->max_steps - na->asap + 1;
+ na->ilp_vars.a = NEW_ARR_D(int, var_obst, n_unit_types * num_ad);
+ memset(na->ilp_vars.a, -1, ARR_LEN(na->ilp_vars.a) * sizeof(na->ilp_vars.a[0]));
+ }
+
+ DBG((env->dbg, LEVEL_3, "\thandling %+F (asap %u, alap %u, unit types %u):\n",
+ irn, na->asap, na->alap, na->n_unit_types));
+
+ cur_var_x = cur_var_ad = cur_var_y = cur_unit = n_var = 0;
+ /* create variables */
+ for (tp_idx = 0; tp_idx < n_unit_types; ++tp_idx) {
+ unsigned t;
+
+ for (t = na->asap - 1; t <= na->alap - 1; ++t) {
+ /* x_{nt}^k variables */
+ snprintf(buf, sizeof(buf), "x_n%u_%s_%u",
+ get_irn_idx(irn), na->type_info[tp_idx].tp->name, t);
+ na->ilp_vars.x[cur_var_x++] = lpp_add_var(lpp, buf, lpp_binary, (double)(t + 1));
+ DBG((env->dbg, LEVEL_4, "\t\tcreated ILP variable %s\n", buf));
+ /* variable counter */
+ n_var++;
+ num_block_var++;
+
+ if (! na->is_dummy_node) {
+ /* y_{nt}^k variables */
+ snprintf(buf, sizeof(buf), "y_n%u_%s_%u",
+ get_irn_idx(irn), na->type_info[tp_idx].tp->name, t);
+ na->ilp_vars.y[cur_var_y++] = lpp_add_var(lpp, buf, lpp_continous, (double)(weigth_y));
+ DBG((env->dbg, LEVEL_4, "\t\tcreated ILP variable %s\n", buf));
+
+ /* variable counter */
+ n_var++;
+ num_block_var++;
+ }
+ }
+
+ /* a node can die at any step t: asap(n) <= t <= U */
+ if (! na->is_dummy_node) {
+ for (t = na->asap - 1; t <= ba->max_steps; ++t) {
+
+ /* a_{nt}^k variables */
+ snprintf(buf, sizeof(buf), "a_n%u_%s_%u",
+ get_irn_idx(irn), na->type_info[tp_idx].tp->name, t);
+ na->ilp_vars.a[cur_var_ad++] = lpp_add_var(lpp, buf, lpp_binary, (double)(ba->n_interesting_nodes));
+ DBG((env->dbg, LEVEL_4, "\t\tcreated ILP variable %s\n", buf));
+
+ /* variable counter */
+ n_var++;
+ num_block_var++;
+ }
+ }
+
+ /* collect live-in nodes */
+ for (i = get_irn_arity(irn) - 1; i >= 0; --i) {
+ ir_node *pred = get_irn_n(irn, i);
+
+ if (get_nodes_block(pred) != block_node->irn && consider_for_sched(env->arch_env, pred)) {
+ be_ilpsched_set_type_info(env, pred, var_obst);
+ if (! na->is_dummy_node) {
+ ilp_livein_node_t *entry = obstack_alloc(var_obst, sizeof(*entry));
+ entry->irn = pred;
+ entry->a = NULL;
+ pset_insert(ba->livein_nodes, entry, (unsigned)get_irn_idx(pred));
+ }
+ }
+ }
+ }
+
+ DB((env->dbg, LEVEL_3, "%u variables created\n", n_var));
+ num_nodes++;
+ }
+
+ /* create alive variables a_{nt}^k for live-ins */
+ foreach_pset(ba->livein_nodes, livein) {
+ be_ilpsched_irn_t *node;
+ ilpsched_node_attr_t *na;
+ unsigned tp_idx, var_idx;
+ ir_node *irn;
+
+ irn = livein->irn;
+ node = get_ilpsched_irn(env, irn);
+ na = get_ilpsched_node_attr(node);
+
+ livein->max_alive_steps = be_ilpsched_get_max_alap_user(env, irn, block_node->irn);
+
+ livein->a = NEW_ARR_D(int, var_obst, na->n_unit_types * livein->max_alive_steps);
+ var_idx = 0;
+
+ /* create variables */
+ for (tp_idx = 0; tp_idx < na->n_unit_types; ++tp_idx) {
+ unsigned t;
+
+ for (t = 0; t < livein->max_alive_steps; ++t) {
+ /* a_{nt}^k variables */
+ snprintf(buf, sizeof(buf), "al_n%u_%s_%u",
+ get_irn_idx(irn), na->type_info[tp_idx].tp->name, t);
+ livein->a[var_idx++] = lpp_add_var(lpp, buf, lpp_binary, (double)(ba->n_interesting_nodes));
+ DBG((env->dbg, LEVEL_4, "\t\tcreated ILP variable %s\n", buf));
+ num_block_var++;
+ }
+ }
+ }
+
+ ilp_timer_pop();
+ DBG((env->dbg, LEVEL_1, "... %u variables for %u nodes created (%g sec)\n",
+ num_block_var, num_nodes, ilp_timer_elapsed_usec(t_var) / 1000000.0));
+}
+
+/*******************************************************
+ * _ _ _
+ * | | (_) | |
+ * ___ ___ _ __ ___| |_ _ __ __ _ _ _ __ | |_ ___
+ * / __/ _ \| '_ \/ __| __| '__/ _` | | '_ \| __/ __|
+ * | (_| (_) | | | \__ \ |_| | | (_| | | | | | |_\__ \
+ * \___\___/|_| |_|___/\__|_| \__,_|_|_| |_|\__|___/
+ *
+ *******************************************************/
+
+/**
+ * Collect all operands and nodes @p irn depends on.
+ * If there is a Proj within the dependencies, all other Projs of the parent node are added as well.
+ */
+static void sta_collect_in_deps(ir_node *irn, ir_nodeset_t *deps) {
+ int i;
+
+ for (i = get_irn_ins_or_deps(irn) - 1; i >= 0; --i) {
+ ir_node *p = get_irn_in_or_dep(irn, i);
+
+ if (is_Proj(p)) {
+ const ir_edge_t *edge;
+
+ p = get_Proj_pred(p);
+ foreach_out_edge(p, edge) {
+ ir_node *src = get_edge_src_irn(edge);
+ ir_nodeset_insert(deps, src);
+ }
+ }
+ else {
+ ir_nodeset_insert(deps, p);
+ }
+ }
+}
+
+/**
+ * Create following ILP constraints:
+ * - the assignment constraints:
+ * assure each node is executed once by exactly one (allowed) execution unit
+ * - the dead node assignment constraints:
+ * assure a node can only die at most once
+ * - the precedence constraints:
+ * assure that no data dependencies are violated
+ */
+static void create_assignment_and_precedence_constraints(be_ilpsched_env_t *env, lpp_t *lpp, be_ilpsched_irn_t *block_node) {
+ unsigned num_cst_assign, num_cst_prec, num_cst_dead;
+ char buf[1024];
+ ir_node *irn;
+ ilpsched_block_attr_t *ba = get_ilpsched_block_attr(block_node);
+ bitset_t *bs_block_irns = bitset_alloca(ba->block_last_idx);
+ ir_timer_t *t_cst_assign = ir_timer_register("beilpsched_cst_assign", "create assignment constraints");
+ ir_timer_t *t_cst_prec = ir_timer_register("beilpsched_cst_prec", "create precedence constraints");
+
+ num_cst_assign = num_cst_prec = num_cst_dead = 0;
+ foreach_linked_irns(ba->head_ilp_nodes, irn) {
+ int cst, tp_idx;
+ unsigned cur_var;
+ be_ilpsched_irn_t *node;
+ ilpsched_node_attr_t *na;
+ ir_node *pred;
+ ir_nodeset_t deps;
+ ir_nodeset_iterator_t iter;
+
+ ir_nodeset_init(&deps);
+
+ node = get_ilpsched_irn(env, irn);
+ na = get_ilpsched_node_attr(node);
+ cur_var = 0;
+
+ /* the assignment constraint */
+ ilp_timer_push(t_cst_assign);
+ snprintf(buf, sizeof(buf), "assignment_cst_n%u", get_irn_idx(irn));
+ cst = lpp_add_cst_uniq(lpp, buf, lpp_equal, 1.0);
+ DBG((env->dbg, LEVEL_2, "added constraint %s\n", buf));
+ num_cst_assign++;
+
+ lpp_set_factor_fast_bulk(lpp, cst, na->ilp_vars.x, ARR_LEN(na->ilp_vars.x), 1.0);
+ ilp_timer_pop();
+
+ /* We have separate constraints for Projs and Keeps */
+ // ILP becomes infeasible ?!?
+// if (is_Proj(irn) || be_is_Keep(irn))
+// continue;
+
+ /* the precedence constraints */
+ ilp_timer_push(t_cst_prec);
+ bs_block_irns = bitset_clear_all(bs_block_irns);
+
+ sta_collect_in_deps(irn, &deps);
+ foreach_ir_nodeset(&deps, pred, iter) {
+ unsigned t_low, t_high, t;
+ be_ilpsched_irn_t *pred_node;
+ ilpsched_node_attr_t *pna;
+ unsigned delay;
+
+ pred = skip_normal_Proj(env->arch_env, pred);
+ if (is_Phi(pred) || block_node->irn != get_nodes_block(pred) || is_NoMem(pred))
+ continue;
+
+ pred_node = get_ilpsched_irn(env, pred);
+ pna = get_ilpsched_node_attr(pred_node);
+
+ assert(pna->asap > 0 && pna->alap >= pna->asap && "Invalid scheduling interval.");
+
+ if (! bitset_is_set(bs_block_irns, pna->block_idx))
+ bitset_set(bs_block_irns, pna->block_idx);
+ else
+ continue;
+
+ /* irn = n, pred = m */
+ delay = fixed_latency(env->sel, pred, env->block_env);
+ t_low = MAX(na->asap, pna->asap + delay - 1);
+ t_high = MIN(na->alap, pna->alap + delay - 1);
+ for (t = t_low - 1; t <= t_high - 1; ++t) {
+ unsigned tn, tm;
+ int *tmp_var_idx = NEW_ARR_F(int, 0);
+
+ snprintf(buf, sizeof(buf), "precedence_n%u_n%u_%u", get_irn_idx(pred), get_irn_idx(irn), t);
+ cst = lpp_add_cst_uniq(lpp, buf, lpp_less, 1.0);
+ DBG((env->dbg, LEVEL_2, "added constraint %s\n", buf));
+ num_cst_prec++;
+
+ /* lpp_set_factor_fast_bulk needs variables sorted ascending by index */
+ if (na->ilp_vars.x[0] < pna->ilp_vars.x[0]) {
+ /* node variables have smaller index than pred variables */
+ for (tp_idx = na->n_unit_types - 1; tp_idx >= 0; --tp_idx) {
+ for (tn = na->asap - 1; tn <= t; ++tn) {
+ unsigned idx = ILPVAR_IDX(na, tp_idx, tn);
+ ARR_APP1(int, tmp_var_idx, na->ilp_vars.x[idx]);
+ }
+ }
+
+ for (tp_idx = pna->n_unit_types - 1; tp_idx >= 0; --tp_idx) {
+ for (tm = t - delay + 1; tm < pna->alap; ++tm) {
+ unsigned idx = ILPVAR_IDX(pna, tp_idx, tm);
+ ARR_APP1(int, tmp_var_idx, pna->ilp_vars.x[idx]);
+ }
+ }
+ }
+ else {
+ /* pred variables have smaller index than node variables */
+ for (tp_idx = pna->n_unit_types - 1; tp_idx >= 0; --tp_idx) {
+ for (tm = t - delay + 1; tm < pna->alap; ++tm) {
+ unsigned idx = ILPVAR_IDX(pna, tp_idx, tm);
+ ARR_APP1(int, tmp_var_idx, pna->ilp_vars.x[idx]);
+ }
+ }
+
+ for (tp_idx = na->n_unit_types - 1; tp_idx >= 0; --tp_idx) {
+ for (tn = na->asap - 1; tn <= t; ++tn) {
+ unsigned idx = ILPVAR_IDX(na, tp_idx, tn);
+ ARR_APP1(int, tmp_var_idx, na->ilp_vars.x[idx]);
+ }
+ }
+ }
+
+ if (ARR_LEN(tmp_var_idx) > 0)
+ lpp_set_factor_fast_bulk(lpp, cst, tmp_var_idx, ARR_LEN(tmp_var_idx), 1.0);
+
+ DEL_ARR_F(tmp_var_idx);
+ }
+ }
+ ir_nodeset_destroy(&deps);
+ ilp_timer_pop();
+ }
+ DBG((env->dbg, LEVEL_1, "\t%u assignement constraints (%g sec)\n",
+ num_cst_assign, ilp_timer_elapsed_usec(t_cst_assign) / 1000000.0));
+ DBG((env->dbg, LEVEL_1, "\t%u precedence constraints (%g sec)\n",
+ num_cst_prec, ilp_timer_elapsed_usec(t_cst_prec) / 1000000.0));
+}
+
+/**
+ * Create ILP resource constraints:
+ * - assure that for each time step not more instructions are scheduled
+ * to the same unit types as units of this type are available
+ */
+static void create_ressource_constraints(be_ilpsched_env_t *env, lpp_t *lpp, be_ilpsched_irn_t *block_node) {
+ int glob_type_idx;
+ char buf[1024];
+ unsigned num_cst_resrc = 0;
+ ilpsched_block_attr_t *ba = get_ilpsched_block_attr(block_node);
+ ir_timer_t *t_cst_rsrc = ir_timer_register("beilpsched_cst_rsrc", "create resource constraints");
+
+ ilp_timer_push(t_cst_rsrc);
+ for (glob_type_idx = env->cpu->n_unit_types - 1; glob_type_idx >= 0; --glob_type_idx) {
+ unsigned t;
+ be_execution_unit_type_t *cur_tp = &env->cpu->unit_types[glob_type_idx];
+
+ /* BEWARE: the DUMMY unit type is not in CPU, so it's skipped automatically */
+
+ /* check each time step */
+ for (t = 0; t < ba->max_steps; ++t) {
+ ir_node *irn;
+ int cst;
+ int *tmp_var_idx = NEW_ARR_F(int, 0);
+
+ snprintf(buf, sizeof(buf), "resource_cst_%s_%u", cur_tp->name, t);
+ cst = lpp_add_cst_uniq(lpp, buf, lpp_less, (double)cur_tp->n_units);
+ DBG((env->dbg, LEVEL_2, "added constraint %s\n", buf));
+ num_cst_resrc++;
+
+ foreach_linked_irns(ba->head_ilp_nodes, irn) {
+ be_ilpsched_irn_t *node = get_ilpsched_irn(env, irn);
+ ilpsched_node_attr_t *na = get_ilpsched_node_attr(node);
+ int tp_idx;
+
+ tp_idx = is_valid_unit_type_for_node(cur_tp, node);
+
+ if (tp_idx >= 0 && t >= na->asap - 1 && t <= na->alap - 1) {
+ int cur_var = ILPVAR_IDX(na, tp_idx, t);
+ ARR_APP1(int, tmp_var_idx, na->ilp_vars.x[cur_var]);
+ }
+ }
+
+ /* set constraints if we have some */
+ if (ARR_LEN(tmp_var_idx) > 0)
+ lpp_set_factor_fast_bulk(lpp, cst, tmp_var_idx, ARR_LEN(tmp_var_idx), 1.0);
+
+ DEL_ARR_F(tmp_var_idx);
+ }
+ }
+ ilp_timer_pop();
+ DBG((env->dbg, LEVEL_1, "\t%u resource constraints (%g sec)\n",
+ num_cst_resrc, ilp_timer_elapsed_usec(t_cst_rsrc) / 1000000.0));
+}
+
+/**
+ * Create ILP bundle constraints:
+ * - assure, at most bundle_size * bundles_per_cycle instructions
+ * can be started at a certain point.
+ */
+static void create_bundle_constraints(be_ilpsched_env_t *env, lpp_t *lpp, be_ilpsched_irn_t *block_node) {
+ char buf[1024];
+ unsigned t;
+ unsigned num_cst_bundle = 0;
+ unsigned n_instr_max = env->cpu->bundle_size * env->cpu->bundels_per_cycle;
+ ilpsched_block_attr_t *ba = get_ilpsched_block_attr(block_node);
+ ir_timer_t *t_cst_bundle = ir_timer_register("beilpsched_cst_bundle", "create bundle constraints");
+
+ ilp_timer_push(t_cst_bundle);
+ for (t = 0; t < ba->max_steps; ++t) {
+ ir_node *irn;
+ int cst;
+ int *tmp_var_idx = NEW_ARR_F(int, 0);
+
+ snprintf(buf, sizeof(buf), "bundle_cst_%u", t);
+ cst = lpp_add_cst_uniq(lpp, buf, lpp_less, (double)n_instr_max);
+ DBG((env->dbg, LEVEL_2, "added constraint %s\n", buf));
+ num_cst_bundle++;
+
+ foreach_linked_irns(ba->head_ilp_nodes, irn) {
+ be_ilpsched_irn_t *node;
+ ilpsched_node_attr_t *na;
+ int tp_idx;
+
+ /* Projs and Keeps do not contribute to bundle size */
+ if (is_Proj(irn) || be_is_Keep(irn))
+ continue;
+
+ node = get_ilpsched_irn(env, irn);
+ na = get_ilpsched_node_attr(node);
+
+ /* nodes assigned to DUMMY unit do not contribute to bundle size */
+ if (na->is_dummy_node)
+ continue;
+
+ if (t >= na->asap - 1 && t <= na->alap - 1) {
+ for (tp_idx = na->n_unit_types - 1; tp_idx >= 0; --tp_idx) {
+ int idx = ILPVAR_IDX(na, tp_idx, t);
+ ARR_APP1(int, tmp_var_idx, na->ilp_vars.x[idx]);
+ }
+ }
+ }
+
+ if (ARR_LEN(tmp_var_idx) > 0)
+ lpp_set_factor_fast_bulk(lpp, cst, tmp_var_idx, ARR_LEN(tmp_var_idx), 1.0);
+
+ DEL_ARR_F(tmp_var_idx);
+ }
+ ilp_timer_pop();
+ DBG((env->dbg, LEVEL_1, "\t%u bundle constraints (%g sec)\n",
+ num_cst_bundle, ilp_timer_elapsed_usec(t_cst_bundle) / 1000000.0));
+}
+
+/**
+ * Create ILP alive nodes constraints:
+ * - set variable a_{nt}^k to 1 if nodes n is alive at step t on unit k
+ */
+static void create_alive_nodes_constraint(be_ilpsched_env_t *env, lpp_t *lpp, be_ilpsched_irn_t *block_node) {
+ char buf[1024];
+ ir_node *irn;
+ unsigned num_cst = 0;
+ ilpsched_block_attr_t *ba = get_ilpsched_block_attr(block_node);
+ ir_timer_t *t_cst = ir_timer_register("beilpsched_cst_alive_nodes", "create alive nodes constraints");
+
+ ilp_timer_push(t_cst);
+ /* for each node */
+ foreach_linked_irns(ba->head_ilp_nodes, irn) {
+ be_ilpsched_irn_t *node = get_ilpsched_irn(env, irn);
+ ilpsched_node_attr_t *na = get_ilpsched_node_attr(node);
+ unsigned t;
+
+ /* we ignore nodes assigned to dummy unit here */
+ if (na->is_dummy_node)
+ continue;
+
+ /* check check all time steps: asap(n) <= t <= U */
+ for (t = na->asap - 1; t < ba->max_steps; ++t) {
+ int node_tp_idx;
+
+ /* for all unit types available for this node */
+ for (node_tp_idx = na->n_unit_types - 1; node_tp_idx >= 0; --node_tp_idx) {
+ unsigned tn, tn_max, idx;
+ int cst, i;
+ int *tmp_var_idx_n = NEW_ARR_F(int, 0);
+ int *tmp_var_idx_m = NEW_ARR_F(int, 0);
+
+ snprintf(buf, sizeof(buf), "alive_node_cst_%u_n%u_%s",
+ t, get_irn_idx(irn), na->type_info[node_tp_idx].tp->name);
+ cst = lpp_add_cst_uniq(lpp, buf, lpp_less, 0.0);
+ DBG((env->dbg, LEVEL_2, "added constraint %s\n", buf));
+ num_cst++;
+
+ tn_max = MIN(na->alap - 1, t);
+ /* check if the node has been scheduled so far */
+ for (tn = na->asap - 1; tn <= tn_max; ++tn) {
+ int idx = ILPVAR_IDX(na, node_tp_idx, tn);
+ ARR_APP1(int, tmp_var_idx_n, na->ilp_vars.x[idx]);
+ }
+
+ if (ARR_LEN(tmp_var_idx_n) > 0)
+ lpp_set_factor_fast_bulk(lpp, cst, tmp_var_idx_n, ARR_LEN(tmp_var_idx_n), (double)(na->n_consumer));
+ DEL_ARR_F(tmp_var_idx_n);
+
+ /* subtract the number of consumer scheduled so far */
+ for (i = ARR_LEN(na->block_consumer) - 1; i >= 0; --i) {
+ be_ilpsched_irn_t *cons = get_ilpsched_irn(env, na->block_consumer[i]);
+ ilpsched_node_attr_t *ca = get_ilpsched_node_attr(cons);
+ int tp_idx;
+ unsigned tm, tm_max;
+
+ tm_max = MIN(ca->alap - 1, t);
+ for (tp_idx = ca->n_unit_types - 1; tp_idx >= 0; --tp_idx) {
+ for (tm = ca->asap - 1; tm <= tm_max; ++tm) {
+ int idx = ILPVAR_IDX(ca, tp_idx, tm);
+ ARR_APP1(int, tmp_var_idx_m, ca->ilp_vars.x[idx]);
+ }
+ }
+ }
+
+ if (ARR_LEN(tmp_var_idx_m) > 0)
+ lpp_set_factor_fast_bulk(lpp, cst, tmp_var_idx_m, ARR_LEN(tmp_var_idx_m), -1.0);
+ DEL_ARR_F(tmp_var_idx_m);
+
+ /* -c * a_{nt}^k */
+ idx = ILPVAR_IDX_DEAD(ba, na, node_tp_idx, t);
+ lpp_set_factor_fast(lpp, cst, na->ilp_vars.a[idx], 0.0 - (double)(na->n_consumer));
+
+ }
+ }
+ }
+ ilp_timer_pop();
+ DBG((env->dbg, LEVEL_1, "\t%u alive nodes constraints (%g sec)\n",
+ num_cst, ilp_timer_elapsed_usec(t_cst) / 1000000.0));
+}
+
+/**
+ * Create ILP alive nodes constraints for live-in nodes:
+ * - set variable a_{nt}^k to 1 if nodes n is alive at step t on unit k
+ */
+static void create_alive_livein_nodes_constraint(be_ilpsched_env_t *env, lpp_t *lpp, be_ilpsched_irn_t *block_node) {
+ char buf[1024];
+ ilp_livein_node_t *livein;
+ unsigned num_cst = 0;
+ ilpsched_block_attr_t *ba = get_ilpsched_block_attr(block_node);
+ ir_timer_t *t_cst = ir_timer_register("beilpsched_cst_alive_livein_nodes", "create alive livein nodes constraints");
+
+ ilp_timer_push(t_cst);
+ /* for each node */
+ foreach_pset(ba->livein_nodes, livein) {
+ ir_node *irn = livein->irn;
+ be_ilpsched_irn_t *node = get_ilpsched_irn(env, irn);