Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions src/solvers/gecode/models/completemodel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -84,16 +84,21 @@ CompleteModel::CompleteModel(Parameters * p_input, ModelOptions * p_options,
v_r = int_var_array(T().size(), -1, input->RA.size() - 1);
v_i = int_var_array(O().size(), 0, input->I.size() - 1);
v_c = int_var_array(O().size(), 0, max_of(input->maxc));
v_ff = int_var_array(O().size(), 0, W * max_of(input->maxc));
if (!P().empty()) {
v_y = int_var_array(P().size(), 0, input->T.size() - 1);
}
v_x = bool_var_array(sum_of(input->n_global_optionals), 0, 1);
v_ry = int_var_array(P().size(), -1, input->RA.size() - 1);
v_a = bool_var_array(O().size(), 0, 1);
v_ls = int_var_array(T().size(), 0, max_of(input->maxc));
v_ls_ff = int_var_array(T().size(), 0, W * max_of(input->maxc));
v_ld = int_var_array(T().size(), 0, max_of(input->maxc));
v_ld_ff = int_var_array(T().size(), 0, W * max_of(input->maxc));
v_le = int_var_array(T().size(), 0,
max_of(input->maxc) + maybe_max_of(0, input->minlive));
v_le_ff = int_var_array(T().size(), 0,
W * (max_of(input->maxc) + maybe_max_of(0, input->minlive)));
v_al = bool_var_array(T().size() * input->RS.size(), 0, 1);
v_u = bool_var_array(input->nu, 0, 1);
v_us = int_var_array(T().size(), 0, O().size());
Expand Down Expand Up @@ -370,6 +375,10 @@ string CompleteModel::solution_to_json() const {
for (operation o : input->O)
cs.push_back(a(o).val() ? c(o).val() : -1);

vector<int> ffs;
for (operation o : input->O)
ffs.push_back(a(o).val() ? ff(o).val() : -1);

vector<temporary> ys;
for (operand p : input->P)
ys.push_back(input->temps[p][y(p).val()]);
Expand All @@ -378,6 +387,7 @@ string CompleteModel::solution_to_json() const {
pOs << "\"registers\":" << to_json(rs) << ",";
pOs << "\"instructions\":" << to_json(is) << ",";
pOs << "\"cycles\":" << to_json(cs) << ",";
pOs << "\"fetches\":" << to_json(ffs) << ",";
pOs << "\"temporaries\":" << to_json(ys);
pOs << "}";

Expand Down
6 changes: 5 additions & 1 deletion src/solvers/gecode/models/globalmodel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -709,6 +709,8 @@ void GlobalModel::post_complete_branchers(unsigned int s) {
branch(*this, v_c, INT_VAR_NONE(), INT_VAL_MIN(),
&schedulable, &print_global_cycle_decision);

branch(*this, v_ff, INT_VAR_NONE(), INT_VAL_MIN());

branch(*this, v_r, INT_VAR_NONE(), INT_VAL_RND(r),
&global_assignable, &print_global_register_decision);

Expand Down Expand Up @@ -786,8 +788,10 @@ void GlobalModel::apply_solution(LocalModel * ls) {
constraint(i(o) == ls->i(o));

for (operation o : input->ops[b])
if (!ls->is_inactive(o))
if (!ls->is_inactive(o)) {
constraint(c(o) == ls->c(o));
constraint(ff(o) == ls->ff(o));
}

for (operand p : input->ope[b])
constraint(y(p) == ls->y(p));
Expand Down
14 changes: 14 additions & 0 deletions src/solvers/gecode/models/localmodel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -86,16 +86,21 @@ LocalModel::LocalModel(Parameters * p_input, ModelOptions * p_options,
v_r = int_var_array(T().size(), -1, input->RA.size() - 1);
v_i = int_var_array(O().size(), 0, input->I.size() - 1);
v_c = int_var_array(O().size(), 0, input->maxc[b]);
v_ff = int_var_array(O().size(), 0, W * input->maxc[b]);
if (!P().empty()) {
v_y = int_var_array(P().size(), 0, input->T.size() - 1);
}
v_x = bool_var_array(input->n_global_optionals[b], 0, 1);
v_ry = int_var_array(P().size(), -1, input->RA.size() - 1);
v_a = bool_var_array(O().size(), 0, 1);
v_ls = int_var_array(T().size(), 0, input->maxc[b]);
v_ls_ff = int_var_array(T().size(), 0, W * input->maxc[b]);
v_ld = int_var_array(T().size(), 0, input->maxc[b]);
v_ld_ff = int_var_array(T().size(), 0, W * input->maxc[b]);
v_le = int_var_array(T().size(), 0,
input->maxc[b] + maybe_max_of(0, input->minlive));
v_le_ff = int_var_array(T().size(), 0,
W * (input->maxc[b] + maybe_max_of(0, input->minlive)));
v_al = bool_var_array(T().size() * input->RS.size(), 0, 1);
v_u = bool_var_array(input->bnu[b], 0, 1);
v_us = int_var_array(T().size(), 0, O().size());
Expand Down Expand Up @@ -291,6 +296,7 @@ void LocalModel::post_aggressive_branchers(void) {
branch(*this, &LocalModel::post_before_scheduling_constraints_in_space);

branch_on_pressure_scheduling(*this, v_c);
branch(*this, v_ff, INT_VAR_NONE(), INT_VAL_MIN());

branch(*this, v_r, INT_VAR_SIZE_MIN(), INT_VAL_MIN(),
&assignable, &print_register_decision);
Expand All @@ -314,6 +320,7 @@ void LocalModel::post_trivial_branchers(void) {

branch(*this, v_c, INT_VAR_MIN_MIN(), INT_VAL_MIN(),
&schedulable, &print_cycle_decision);
branch(*this, v_ff, INT_VAR_NONE(), INT_VAL_MIN());

branch(*this, v_r, INT_VAR_SIZE_MIN(), INT_VAL_MIN(), &assignable,
&print_register_decision);
Expand All @@ -340,6 +347,7 @@ void LocalModel::post_minimum_cost_branchers(void) {

branch(*this, v_c, INT_VAR_MIN_MIN(), INT_VAL_MIN(),
&schedulable, &print_cycle_decision);
branch(*this, v_ff, INT_VAR_NONE(), INT_VAL_MIN());

branch(*this, v_r, INT_VAR_SIZE_MIN(), INT_VAL_MIN(), &assignable,
&print_register_decision);
Expand All @@ -363,6 +371,7 @@ void LocalModel::post_fail_first_branchers(void) {

branch(*this, v_c, INT_VAR_SIZE_MIN(), INT_VAL_MIN(),
&schedulable, &print_cycle_decision);
branch(*this, v_ff, INT_VAR_NONE(), INT_VAL_MIN());

branch(*this, v_r, INT_VAR_SIZE_MIN(), INT_VAL_MIN(), &assignable,
&print_register_decision);
Expand All @@ -376,6 +385,7 @@ void LocalModel::post_conservative_branchers(void) {
branch(*this, &LocalModel::post_before_scheduling_constraints_in_space);

branch_on_pressure_scheduling(*this, v_c);
branch(*this, v_ff, INT_VAR_NONE(), INT_VAL_MIN());

branch(*this, v_r, INT_VAR_SIZE_MIN(), INT_VAL_MIN(), &assignable,
&print_register_decision);
Expand Down Expand Up @@ -451,6 +461,7 @@ void LocalModel::apply_solution(const GlobalModel * gs) {
for (operation o : input->ops[b]) {
copy_domain(*this, gs->i(o), i(o));
copy_domain(*this, gs->c(o), c(o));
copy_domain(*this, gs->ff(o), ff(o));
copy_domain(*this, gs->a(o), a(o));
}

Expand All @@ -468,6 +479,9 @@ void LocalModel::apply_solution(const GlobalModel * gs) {
copy_domain(*this, gs->ls(t), ls(t));
copy_domain(*this, gs->ld(t), ld(t));
copy_domain(*this, gs->le(t), le(t));
copy_domain(*this, gs->ls_ff(t), ls_ff(t));
copy_domain(*this, gs->ld_ff(t), ld_ff(t));
copy_domain(*this, gs->le_ff(t), le_ff(t));
}

for (unsigned int n = 0; n < input->N; n++) {
Expand Down
90 changes: 82 additions & 8 deletions src/solvers/gecode/models/model.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -454,13 +454,17 @@ Model::Model(Model& m) :
v_r.update(*this, m.v_r);
v_i.update(*this, m.v_i);
v_c.update(*this, m.v_c);
v_ff.update(*this, m.v_ff);
v_y.update(*this, m.v_y);
v_x.update(*this, m.v_x);
v_ry.update(*this, m.v_ry);
v_a.update(*this, m.v_a);
v_ls.update(*this, m.v_ls);
v_ld.update(*this, m.v_ld);
v_le.update(*this, m.v_le);
v_ls_ff.update(*this, m.v_ls_ff);
v_ld_ff.update(*this, m.v_ld_ff);
v_le_ff.update(*this, m.v_le_ff);
v_al.update(*this, m.v_al);
v_u.update(*this, m.v_u);
v_us.update(*this, m.v_us);
Expand Down Expand Up @@ -497,19 +501,27 @@ void Model::post_issue_cycle_domains(block b) {
for (operation o : input->ops[b]) {
constraint(c(o) <= bmaxc);
constraint(c(o) <= c(input->out[b]));
constraint(ff(o) <= W * bmaxc);
constraint(ff(o) <= ff(input->out[b]));
}

for (temporary t : input->tmp[b]) {
constraint(ls(t) <= bmaxc);
constraint(le(t) <= (bmaxc + input->minlive[t]));
constraint(le(t) <= bmaxc + input->minlive[t]);

constraint(ls_ff(t) <= W * bmaxc);
constraint(le_ff(t) <= W * (bmaxc + input->minlive[t]));
}

// in-delimiters always start in cycle 0
constraint(c(input->in[b]) == 0);
constraint(ff(input->in[b]) == 0);

// the rest of operations start at least in cycle 1
for (operation o : input->ops[b])
for (operation o : input->ops[b]) {
if (o != input->in[b]) constraint(c(o) >= 1);
if (o != input->in[b]) constraint(ff(o) >= W);
}

}

Expand Down Expand Up @@ -564,8 +576,10 @@ void Model::post_live_start_definition(block b) {

// The live range of a temporary starts at the issue cycle of its definer:

for (temporary t : input->tmp[b])
for (temporary t : input->tmp[b]) {
constraint(ls(t) == c(input->oper[input->definer[t]]));
constraint(ls_ff(t) == ff(input->oper[input->definer[t]]));
}

}

Expand All @@ -574,8 +588,10 @@ void Model::post_live_duration_definition(block b) {
// The live range of a temporary t is as long as the distance between its live
// end and its live start:

for (temporary t : input->tmp[b])
for (temporary t : input->tmp[b]) {
constraint(ld(t) == (le(t) - ls(t)));
constraint(ld_ff(t) == (le_ff(t) - ls_ff(t)));
}

}

Expand All @@ -590,6 +606,12 @@ void Model::post_live_end_definition(block b) {
uc << var(ite(u(p, t), c(input->oper[p]), 0));
uc << var(ls(t) + input->minlive[t]);
constraint(le(t) == max(uc));

IntVarArgs uc_ff;
for (operand p : input->users[t])
uc_ff << var(ite(u(p, t), ff(input->oper[p]), 0));
uc_ff << var(ls_ff(t) + W * input->minlive[t]);
constraint(le_ff(t) == max(uc_ff));
}

}
Expand Down Expand Up @@ -727,6 +749,7 @@ void Model::post_basic_model_constraints(block b) {
post_prescheduling_constraints(b);
post_bypassing_constraints(b);
post_adhoc_constraints(b);
post_fetch_constraints(b);

}

Expand Down Expand Up @@ -813,15 +836,15 @@ void Model::post_disjoint_live_ranges_constraints(block b) {

IntVarArgs bld, bw, bre,
br = temps_to_var_args(v_r, input->tmp[b]),
bls = temps_to_var_args(v_ls, input->tmp[b]),
ble = temps_to_var_args(v_le, input->tmp[b]);
bls = temps_to_var_args(v_ls_ff, input->tmp[b]),
ble = temps_to_var_args(v_le_ff, input->tmp[b]);
BoolVarArgs bm;

for (temporary t : input->tmp[b]) {
bld << ld(t);
bld << ld_ff(t);
bw << var(input->width[t]);
bre << var(r(t) + input->width[t]);
bm << var(l(t) && (ld(t) > 0));
bm << var(l(t) && (ld_ff(t) > 0));
}

nooverlap(*this, br, bw, bre, bls, bld, ble, bm, ipl);
Expand Down Expand Up @@ -1138,6 +1161,51 @@ void Model::post_adhoc_constraints(block b) {

}

void Model::post_fetch_constraints(block b) {
for (operation o : input->ops[b]) {
constraint(a(o) >> (c(o) * W <= ff(o)));
constraint(a(o) >> (ff(o) < (c(o) + 1) * W));
}

BoolVarArgs acts;
IntVarArgs vals;
for(operation o : input->ops[b]) {
acts << a(o);
vals << ff(o);
}
Gecode::distinct(*this, acts, vals, IPL_DOM);

// Branch should be the last operation in bundle
for (operation o : input->ops[b]) {
if (input->type[o] == BRANCH) {
for (operation o2 : input->ops[b]) {
if (o2 == o)
continue;
if (input->type[o2] == OUT)
continue;
// Virtual operations have special constraints and
// may sometimes be scheduled after branches.
// They are not present in generated MIR so won't cause
// verification errors.
if (input->type[o2] == DEFINE || input->type[o2] == KILL)
continue;
constraint(ff(o2) < ff(o));
}
break;
}
}

// Call should be the last operation in bundle
for (operation o : input->ops[b]) {
if (input->type[o] == CALL) {
for (operation o2 : input->ops[b]) {
if (o2 != o)
constraint((c(o2) == c(o)) >> (ff(o2) < ff(o)));
}
}
}
}

void Model::post_improved_model_constraints(block b) {

if (!options->disable_improving()) {
Expand Down Expand Up @@ -2301,6 +2369,11 @@ void Model::print(ostream & pOs, block b) const {

pOs << endl << endl;

for (operation o : os)
pOs << left << "ff" << setw(tColWidth) << ff(o) << " ";

pOs << endl << endl;

for (operand p : ps)
pOs << left << "p" << setw(tColWidth) << p << " ";

Expand Down Expand Up @@ -2341,6 +2414,7 @@ void Model::compare(const Space& sp, std::ostream& pOs) const {
pOs << "r : " << compare<IntVar>("r", "t", temp_index, v_r, m.v_r) << endl;
pOs << "i : " << compare<IntVar>("i", "o", instr_index, v_i, m.v_i) << endl;
pOs << "c : " << compare<IntVar>("c", "o", instr_index, v_c, m.v_c) << endl;
pOs << "ff : " << compare<IntVar>("ff", "o", instr_index, v_ff, m.v_ff) << endl;
pOs << "y : " << compare<IntVar>("y", "p", opr_index, v_y, m.v_y) << endl;

pOs << endl;
Expand Down
17 changes: 17 additions & 0 deletions src/solvers/gecode/models/model.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,10 @@ class Model : public IntLexMinimizeSpace {

public:

// Must be larger than maximum issue size due to pseudo-insns (kill, low, etc.)
// TODO: this should of course come from model.json
static const int W = 8;

Parameters * input;
ModelOptions * options;
IntPropLevel ipl;
Expand All @@ -85,6 +89,7 @@ class Model : public IntLexMinimizeSpace {

// c[o]: issue cycle of operation o relative to the beginning of its block
IntVarArray v_c;
IntVarArray v_ff;

// y[p]: temporary that is connected to operand p
IntVarArray v_y;
Expand All @@ -102,12 +107,15 @@ class Model : public IntLexMinimizeSpace {

// ls[t]: start of live range of temporary t
IntVarArray v_ls;
IntVarArray v_ls_ff;

// ld[t]: duration of live range of temporary t
IntVarArray v_ld;
IntVarArray v_ld_ff;

// le[t]: end of live range of temporary t
IntVarArray v_le;
IntVarArray v_le_ff;

// al[t][rs]: whether temporary t is allocated to register space rs
// (some of the register atoms of t overlap with rs)
Expand Down Expand Up @@ -216,6 +224,8 @@ class Model : public IntLexMinimizeSpace {

IntVar c(operation o) const { return v_c[instr(o)]; }

IntVar ff(operation o) const { return v_ff[instr(o)]; }

IntVar y(operand p) const { return v_y[opr(p)]; }

virtual BoolVar x(operand p) const = 0;
Expand All @@ -232,6 +242,12 @@ class Model : public IntLexMinimizeSpace {

IntVar le(temporary t) const { return v_le[temp(t)]; }

IntVar ls_ff(temporary t) const { return v_ls_ff[temp(t)]; }

IntVar ld_ff(temporary t) const { return v_ld_ff[temp(t)]; }

IntVar le_ff(temporary t) const { return v_le_ff[temp(t)]; }

BoolVar al(register_space rs, temporary t) const {
return v_al[temp(t) * input->RS.size() + rs];
}
Expand Down Expand Up @@ -374,6 +390,7 @@ class Model : public IntLexMinimizeSpace {
void post_prescheduling_constraints(block b);
void post_bypassing_constraints(block b);
void post_adhoc_constraints(block b);
void post_fetch_constraints(block b);

void post_improved_model_constraints(block b);
void post_null_register_constraints(block b);
Expand Down
1 change: 1 addition & 0 deletions src/solvers/gecode/models/simplemodel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -78,4 +78,5 @@ void SimpleModel::post_trivial_branchers(void) {
branch(*this, v_r, INT_VAR_NONE(), INT_VAL_MIN());
// TODO: do not assign cycles to inactive operations
branch(*this, v_c, INT_VAR_NONE(), INT_VAL_MIN());
branch(*this, v_ff, INT_VAR_NONE(), INT_VAL_MIN());
}
Loading