-/**
- * Create ILP pressure constraints, based on dead 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_dead_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);
- lc_timer_t *t_cst = lc_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 */
- for (t = cur_na->asap - 1; t <= cur_na->alap - 1; ++t) {
- int cst, y_idx;
- ir_node *irn;
- int *tmp_idx_1 = NEW_ARR_F(int, 0);
- int *tmp_idx_m1 = NEW_ARR_F(int, 0);
-
- 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 scheduled on unit type k till t
- - subtract all nodes died on unit type k till t
- */
- 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 tn, tmax;
- int tp_idx;
-
- tmax = MIN(t, na->alap - 1);
- tp_idx = is_valid_unit_type_for_node(cur_tp, node);
-
- /* current unit type is not suitable for current node */
- if (tp_idx < 0)
- continue;
-
- for (tn = na->asap - 1; tn <= tmax; ++tn) {
- int idx;
-
- /* node scheduled */
- idx = ILPVAR_IDX(na, tp_idx, tn);
- ARR_APP1(int, tmp_idx_1, na->ilp_vars.x[idx]);
-
- /* node dead */
- idx = ILPVAR_IDX_DEAD(ba, na, tp_idx, tn);
- ARR_APP1(int, tmp_idx_m1, na->ilp_vars.d[idx]);
- }
- }
-
- if (ARR_LEN(tmp_idx_1) > 0)
- lpp_set_factor_fast_bulk(lpp, cst, tmp_idx_1, ARR_LEN(tmp_idx_1), 1.0);
-
- if (ARR_LEN(tmp_idx_m1) > 0)
- lpp_set_factor_fast_bulk(lpp, cst, tmp_idx_m1, ARR_LEN(tmp_idx_m1), -1.0);
-
- /* BEWARE: t is unsigned, so (double)(-t) won't work */
- y_idx = ILPVAR_IDX(cur_na, cur_tp_idx, t);
- lpp_set_factor_fast(lpp, cst, cur_na->ilp_vars.y[y_idx], -1.0);
-
- DEL_ARR_F(tmp_idx_1);
- DEL_ARR_F(tmp_idx_m1);
- }
- }
- }
- ilp_timer_pop();
- DBG((env->dbg, LEVEL_1, "\t%u pressure constraints (%g sec)\n",
- num_cst, ilp_timer_elapsed_usec(t_cst) / 1000000.0));
-}
-