+ for (unsigned r = 0; r < n_regs; ++r) {
+ if (!rbitset_is_set(normal_regs, r))
+ continue;
+ if (rbitset_is_set(forbidden_edges, l*n_regs + r))
+ continue;
+ /* livethrough values may not use constrained output registers */
+ if (rbitset_is_set(live_through_regs, l)
+ && rbitset_is_set(forbidden_regs, r))
+ continue;
+
+ char name[15];
+ snprintf(name, sizeof(name), "%u_to_%u", l, r);
+
+ double costs = l==r ? 9 : 8;
+ lpp_vars[l*n_regs+r]
+ = lpp_add_var(lpp, name, lpp_binary, costs);
+ assert(lpp_vars[l*n_regs+r] > 0);
+ }
+ }
+ /* add constraints */
+ for (unsigned l = 0; l < n_regs; ++l) {
+ /* only 1 destination per register */
+ int constraint = -1;
+ for (unsigned r = 0; r < n_regs; ++r) {
+ int var = lpp_vars[l*n_regs+r];
+ if (var == 0)
+ continue;
+ if (constraint < 0) {
+ char name[64];
+ snprintf(name, sizeof(name), "%u_to_dest", l);
+ constraint = lpp_add_cst(lpp, name, lpp_equal, 1);
+ }
+ lpp_set_factor_fast(lpp, constraint, var, 1);
+ }
+ /* each destination used by at most 1 value */
+ constraint = -1;
+ for (unsigned r = 0; r < n_regs; ++r) {
+ int var = lpp_vars[r*n_regs+l];
+ if (var == 0)
+ continue;
+ if (constraint < 0) {
+ char name[64];
+ snprintf(name, sizeof(name), "one_to_%u", l);
+ constraint = lpp_add_cst(lpp, name, lpp_less_equal, 1);
+ }
+ lpp_set_factor_fast(lpp, constraint, var, 1);