+ /* sum(scheduled users) */
+ 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 = node_tp_idx * livein->max_alive_steps + t;
+ lpp_set_factor_fast(lpp, cst, livein->a[idx], (double)(num_block_user));
+ }
+ }
+ }
+ ilp_timer_pop();
+ DBG((env->dbg, LEVEL_1, "\t%u alive livein nodes constraints (%g sec)\n",
+ num_cst, ilp_timer_elapsed_usec(t_cst) / 1000000.0));
+}
+
+/**
+ * Create ILP pressure constraints, based on alive nodes:
+ * - add additional costs to objective function if a node is scheduled
+ * on a unit although all units of this type are currently occupied
+ */
+static void create_pressure_alive_constraint(be_ilpsched_env_t *env, lpp_t *lpp, be_ilpsched_irn_t *block_node) {
+ char buf[1024];
+ ir_node *cur_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_pressure", "create pressure constraints");
+
+ ilp_timer_push(t_cst);
+ /* y_{nt}^k is set for each node and timestep and unit type */
+ foreach_linked_irns(ba->head_ilp_nodes, cur_irn) {
+ unsigned cur_idx = get_irn_idx(cur_irn);
+ be_ilpsched_irn_t *cur_node = get_ilpsched_irn(env, cur_irn);
+ ilpsched_node_attr_t *cur_na = get_ilpsched_node_attr(cur_node);
+ int glob_type_idx;
+
+ /* we ignore nodes assigned to DUMMY unit here */
+ if (cur_na->is_dummy_node)
+ continue;
+
+ /* for all types */
+ for (glob_type_idx = env->cpu->n_unit_types - 1; glob_type_idx >= 0; --glob_type_idx) {
+ be_execution_unit_type_t *cur_tp = &env->cpu->unit_types[glob_type_idx];
+ int cur_tp_idx;
+ unsigned t;
+
+ /* BEWARE: the DUMMY unit types is not in CPU, so it's skipped automatically */
+
+ /* check if node can be executed on this unit type */
+ cur_tp_idx = is_valid_unit_type_for_node(cur_tp, cur_node);
+ if (cur_tp_idx < 0)
+ continue;
+
+ /* check all time_steps at which the current node can be scheduled */
+ for (t = cur_na->asap - 1; t <= cur_na->alap - 1; ++t) {
+ int cst, y_idx;
+ ir_node *irn;
+ int *tmp_var_idx = NEW_ARR_F(int, 0);
+ ilp_livein_node_t *livein;
+
+ snprintf(buf, sizeof(buf), "pressure_cst_n%u_%u_%s", cur_idx, t, cur_tp->name);
+ cst = lpp_add_cst_uniq(lpp, buf, lpp_less, (double)(cur_tp->n_units - 1));
+ DBG((env->dbg, LEVEL_2, "added constraint %s\n", buf));
+ num_cst++;
+
+ /* - accumulate all nodes alive at point t on unit type k */
+ 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 a_idx, tp_idx;
+
+ /* check if node can be alive here */
+ if (t < na->asap - 1)
+ continue;
+
+ tp_idx = is_valid_unit_type_for_node(cur_tp, node);
+
+ /* current type is not suitable */
+ if (tp_idx < 0)
+ continue;
+
+ a_idx = ILPVAR_IDX_DEAD(ba, na, tp_idx, t);
+ ARR_APP1(int, tmp_var_idx, na->ilp_vars.a[a_idx]);
+ }
+ /* do the same for livein nodes */
+ foreach_pset(ba->livein_nodes, livein) {
+ ir_node *irn = livein->irn;
+ be_ilpsched_irn_t *node = get_ilpsched_irn(env, irn);
+ int a_idx, tp_idx;
+
+ /* check if node can be alive here */
+ if (t >= livein->max_alive_steps)
+ continue;
+
+ tp_idx = is_valid_unit_type_for_node(cur_tp, node);