diff options
author | Tuowen Zhao <ztuowen@gmail.com> | 2016-09-17 03:22:53 +0000 |
---|---|---|
committer | Tuowen Zhao <ztuowen@gmail.com> | 2016-09-17 03:22:53 +0000 |
commit | 75ff98e4d65862ff5b36b533b4f6e3ea71ede1d5 (patch) | |
tree | 498ac06b4cf78568b807fafd2619856afff69c28 /omegatools.cc | |
parent | 29efa7b1a0d089e02a70f73f348f11878955287c (diff) | |
download | chill-75ff98e4d65862ff5b36b533b4f6e3ea71ede1d5.tar.gz chill-75ff98e4d65862ff5b36b533b4f6e3ea71ede1d5.tar.bz2 chill-75ff98e4d65862ff5b36b533b4f6e3ea71ede1d5.zip |
cmake build
Diffstat (limited to 'omegatools.cc')
-rw-r--r-- | omegatools.cc | 2312 |
1 files changed, 0 insertions, 2312 deletions
diff --git a/omegatools.cc b/omegatools.cc deleted file mode 100644 index d88fd2a..0000000 --- a/omegatools.cc +++ /dev/null @@ -1,2312 +0,0 @@ -/***************************************************************************** - Copyright (C) 2008 University of Southern California - Copyright (C) 2009-2010 University of Utah - All Rights Reserved. - - Purpose: - Useful tools involving Omega manipulation. - - Notes: - - History: - 01/2006 Created by Chun Chen. - 03/2009 Upgrade Omega's interaction with compiler to IR_Code, by Chun Chen. -*****************************************************************************/ - -#include <codegen.h> -// #include <code_gen/output_repr.h> -#include "omegatools.hh" -#include "ir_code.hh" -#include "chill_error.hh" - -using namespace omega; - -namespace { - struct DependenceLevel { - Relation r; - int level; - int dir; // direction upto current level: - // -1:negative, 0: undetermined, 1: postive - std::vector<coef_t> lbounds; - std::vector<coef_t> ubounds; - DependenceLevel(const Relation &_r, int _dims): - r(_r), level(0), dir(0), lbounds(_dims), ubounds(_dims) {} - }; -} - - - - -std::string tmp_e() { - static int counter = 1; - return std::string("e")+to_string(counter++); -} - - - -//----------------------------------------------------------------------------- -// Convert expression tree to omega relation. "destroy" means shallow -// deallocation of "repr", not freeing the actual code inside. -// ----------------------------------------------------------------------------- -void exp2formula(IR_Code *ir, Relation &r, F_And *f_root, std::vector<Free_Var_Decl*> &freevars, - CG_outputRepr *repr, Variable_ID lhs, char side, IR_CONDITION_TYPE rel, bool destroy) { - -// void exp2formula(IR_Code *ir, Relation &r, F_And *f_root, std::vector<Free_Var_Decl*> &freevars, -// CG_outputRepr *repr, Variable_ID lhs, char side, char rel, bool destroy) { - - switch (ir->QueryExpOperation(repr)) { - case IR_OP_CONSTANT: - { - std::vector<CG_outputRepr *> v = ir->QueryExpOperand(repr); - IR_ConstantRef *ref = static_cast<IR_ConstantRef *>(ir->Repr2Ref(v[0])); - if (!ref->is_integer()) - throw ir_exp_error("non-integer constant coefficient"); - - coef_t c = ref->integer(); - if (rel == IR_COND_GE || rel == IR_COND_GT) { - GEQ_Handle h = f_root->add_GEQ(); - h.update_coef(lhs, 1); - if (rel == IR_COND_GE) - h.update_const(-c); - else - h.update_const(-c-1); - } - else if (rel == IR_COND_LE || rel == IR_COND_LT) { - GEQ_Handle h = f_root->add_GEQ(); - h.update_coef(lhs, -1); - if (rel == IR_COND_LE) - h.update_const(c); - else - h.update_const(c-1); - } - else if (rel == IR_COND_EQ) { - EQ_Handle h = f_root->add_EQ(); - h.update_coef(lhs, 1); - h.update_const(-c); - } - else - throw std::invalid_argument("unsupported condition type"); - - delete v[0]; - delete ref; - if (destroy) - delete repr; - break; - } - case IR_OP_VARIABLE: - { - std::vector<CG_outputRepr *> v = ir->QueryExpOperand(repr); - IR_ScalarRef *ref = static_cast<IR_ScalarRef *>(ir->Repr2Ref(v[0])); - - std::string s = ref->name(); - Variable_ID e = find_index(r, s, side); - - if (e == NULL) { // must be free variable - Free_Var_Decl *t = NULL; - for (unsigned i = 0; i < freevars.size(); i++) { - std::string ss = freevars[i]->base_name(); - if (s == ss) { - t = freevars[i]; - break; - } - } - - if (t == NULL) { - t = new Free_Var_Decl(s); - freevars.insert(freevars.end(), t); - } - - e = r.get_local(t); - } - - if (rel == IR_COND_GE || rel == IR_COND_GT) { - GEQ_Handle h = f_root->add_GEQ(); - h.update_coef(lhs, 1); - h.update_coef(e, -1); - if (rel == IR_COND_GT) - h.update_const(-1); - } - else if (rel == IR_COND_LE || rel == IR_COND_LT) { - GEQ_Handle h = f_root->add_GEQ(); - h.update_coef(lhs, -1); - h.update_coef(e, 1); - if (rel == IR_COND_LT) - h.update_const(-1); - } - else if (rel == IR_COND_EQ) { - EQ_Handle h = f_root->add_EQ(); - h.update_coef(lhs, 1); - h.update_coef(e, -1); - } - else - throw std::invalid_argument("unsupported condition type"); - - // delete v[0]; - delete ref; - if (destroy) - delete repr; - break; - } - case IR_OP_ASSIGNMENT: - { - std::vector<CG_outputRepr *> v = ir->QueryExpOperand(repr); - exp2formula(ir, r, f_root, freevars, v[0], lhs, side, rel, true); - if (destroy) - delete repr; - break; - } - case IR_OP_PLUS: - { - F_Exists *f_exists = f_root->add_exists(); - Variable_ID e1 = f_exists->declare(tmp_e()); - Variable_ID e2 = f_exists->declare(tmp_e()); - F_And *f_and = f_exists->add_and(); - - if (rel == IR_COND_GE || rel == IR_COND_GT) { - GEQ_Handle h = f_and->add_GEQ(); - h.update_coef(lhs, 1); - h.update_coef(e1, -1); - h.update_coef(e2, -1); - if (rel == IR_COND_GT) - h.update_const(-1); - } - else if (rel == IR_COND_LE || rel == IR_COND_LT) { - GEQ_Handle h = f_and->add_GEQ(); - h.update_coef(lhs, -1); - h.update_coef(e1, 1); - h.update_coef(e2, 1); - if (rel == IR_COND_LT) - h.update_const(-1); - } - else if (rel == IR_COND_EQ) { - EQ_Handle h = f_and->add_EQ(); - h.update_coef(lhs, 1); - h.update_coef(e1, -1); - h.update_coef(e2, -1); - } - else - throw std::invalid_argument("unsupported condition type"); - - std::vector<CG_outputRepr *> v = ir->QueryExpOperand(repr); - exp2formula(ir, r, f_and, freevars, v[0], e1, side, IR_COND_EQ, true); - exp2formula(ir, r, f_and, freevars, v[1], e2, side, IR_COND_EQ, true); - if (destroy) - delete repr; - break; - } - case IR_OP_MINUS: - { - F_Exists *f_exists = f_root->add_exists(); - Variable_ID e1 = f_exists->declare(tmp_e()); - Variable_ID e2 = f_exists->declare(tmp_e()); - F_And *f_and = f_exists->add_and(); - - if (rel == IR_COND_GE || rel == IR_COND_GT) { - GEQ_Handle h = f_and->add_GEQ(); - h.update_coef(lhs, 1); - h.update_coef(e1, -1); - h.update_coef(e2, 1); - if (rel == IR_COND_GT) - h.update_const(-1); - } - else if (rel == IR_COND_LE || rel == IR_COND_LT) { - GEQ_Handle h = f_and->add_GEQ(); - h.update_coef(lhs, -1); - h.update_coef(e1, 1); - h.update_coef(e2, -1); - if (rel == IR_COND_LT) - h.update_const(-1); - } - else if (rel == IR_COND_EQ) { - EQ_Handle h = f_and->add_EQ(); - h.update_coef(lhs, 1); - h.update_coef(e1, -1); - h.update_coef(e2, 1); - } - else - throw std::invalid_argument("unsupported condition type"); - - std::vector<CG_outputRepr *> v = ir->QueryExpOperand(repr); - exp2formula(ir, r, f_and, freevars, v[0], e1, side, IR_COND_EQ, true); - exp2formula(ir, r, f_and, freevars, v[1], e2, side, IR_COND_EQ, true); - if (destroy) - delete repr; - break; - } - case IR_OP_MULTIPLY: - { - std::vector<CG_outputRepr *> v = ir->QueryExpOperand(repr); - - coef_t coef; - CG_outputRepr *term; - if (ir->QueryExpOperation(v[0]) == IR_OP_CONSTANT) { - IR_ConstantRef *ref = static_cast<IR_ConstantRef *>(ir->Repr2Ref(v[0])); - coef = ref->integer(); - delete v[0]; - delete ref; - term = v[1]; - } - else if (ir->QueryExpOperation(v[1]) == IR_OP_CONSTANT) { - IR_ConstantRef *ref = static_cast<IR_ConstantRef *>(ir->Repr2Ref(v[1])); - coef = ref->integer(); - delete v[1]; - delete ref; - term = v[0]; - } - else - throw ir_exp_error("not presburger expression"); - - F_Exists *f_exists = f_root->add_exists(); - Variable_ID e = f_exists->declare(tmp_e()); - F_And *f_and = f_exists->add_and(); - - if (rel == IR_COND_GE || rel == IR_COND_GT) { - GEQ_Handle h = f_and->add_GEQ(); - h.update_coef(lhs, 1); - h.update_coef(e, -coef); - if (rel == IR_COND_GT) - h.update_const(-1); - } - else if (rel == IR_COND_LE || rel == IR_COND_LT) { - GEQ_Handle h = f_and->add_GEQ(); - h.update_coef(lhs, -1); - h.update_coef(e, coef); - if (rel == IR_COND_LT) - h.update_const(-1); - } - else if (rel == IR_COND_EQ) { - EQ_Handle h = f_and->add_EQ(); - h.update_coef(lhs, 1); - h.update_coef(e, -coef); - } - else - throw std::invalid_argument("unsupported condition type"); - - exp2formula(ir, r, f_and, freevars, term, e, side, IR_COND_EQ, true); - if (destroy) - delete repr; - break; - } - case IR_OP_DIVIDE: - { - std::vector<CG_outputRepr *> v = ir->QueryExpOperand(repr); - - assert(ir->QueryExpOperation(v[1]) == IR_OP_CONSTANT); - IR_ConstantRef *ref = static_cast<IR_ConstantRef *>(ir->Repr2Ref(v[1])); - coef_t coef = ref->integer(); - delete v[1]; - delete ref; - - F_Exists *f_exists = f_root->add_exists(); - Variable_ID e = f_exists->declare(tmp_e()); - F_And *f_and = f_exists->add_and(); - - if (rel == IR_COND_GE || rel == IR_COND_GT) { - GEQ_Handle h = f_and->add_GEQ(); - h.update_coef(lhs, coef); - h.update_coef(e, -1); - if (rel == IR_COND_GT) - h.update_const(-1); - } - else if (rel == IR_COND_LE || rel == IR_COND_LT) { - GEQ_Handle h = f_and->add_GEQ(); - h.update_coef(lhs, -coef); - h.update_coef(e, 1); - if (rel == IR_COND_LT) - h.update_const(-1); - } - else if (rel == IR_COND_EQ) { - EQ_Handle h = f_and->add_EQ(); - h.update_coef(lhs, coef); - h.update_coef(e, -1); - } - else - throw std::invalid_argument("unsupported condition type"); - - exp2formula(ir, r, f_and, freevars, v[0], e, side, IR_COND_EQ, true); - if (destroy) - delete repr; - break; - } - case IR_OP_POSITIVE: - { - std::vector<CG_outputRepr *> v = ir->QueryExpOperand(repr); - - exp2formula(ir, r, f_root, freevars, v[0], lhs, side, rel, true); - if (destroy) - delete repr; - break; - } - case IR_OP_NEGATIVE: - { - std::vector<CG_outputRepr *> v = ir->QueryExpOperand(repr); - - F_Exists *f_exists = f_root->add_exists(); - Variable_ID e = f_exists->declare(tmp_e()); - F_And *f_and = f_exists->add_and(); - - if (rel == IR_COND_GE || rel == IR_COND_GT) { - GEQ_Handle h = f_and->add_GEQ(); - h.update_coef(lhs, 1); - h.update_coef(e, 1); - if (rel == IR_COND_GT) - h.update_const(-1); - } - else if (rel == IR_COND_LE || rel == IR_COND_LT) { - GEQ_Handle h = f_and->add_GEQ(); - h.update_coef(lhs, -1); - h.update_coef(e, -1); - if (rel == IR_COND_LT) - h.update_const(-1); - } - else if (rel == IR_COND_EQ) { - EQ_Handle h = f_and->add_EQ(); - h.update_coef(lhs, 1); - h.update_coef(e, 1); - } - else - throw std::invalid_argument("unsupported condition type"); - - exp2formula(ir, r, f_and, freevars, v[0], e, side, IR_COND_EQ, true); - if (destroy) - delete repr; - break; - } - case IR_OP_MIN: - { - std::vector<CG_outputRepr *> v = ir->QueryExpOperand(repr); - - F_Exists *f_exists = f_root->add_exists(); - - if (rel == IR_COND_GE || rel == IR_COND_GT) { - F_Or *f_or = f_exists->add_and()->add_or(); - for (int i = 0; i < v.size(); i++) { - Variable_ID e = f_exists->declare(tmp_e()); - F_And *f_and = f_or->add_and(); - GEQ_Handle h = f_and->add_GEQ(); - h.update_coef(lhs, 1); - h.update_coef(e, -1); - if (rel == IR_COND_GT) - h.update_const(-1); - - exp2formula(ir, r, f_and, freevars, v[i], e, side, IR_COND_EQ, true); - } - } - else if (rel == IR_COND_LE || rel == IR_COND_LT) { - F_And *f_and = f_exists->add_and(); - for (int i = 0; i < v.size(); i++) { - Variable_ID e = f_exists->declare(tmp_e()); - GEQ_Handle h = f_and->add_GEQ(); - h.update_coef(lhs, -1); - h.update_coef(e, 1); - if (rel == IR_COND_LT) - h.update_const(-1); - - exp2formula(ir, r, f_and, freevars, v[i], e, side, IR_COND_EQ, true); - } - } - else if (rel == IR_COND_EQ) { - F_Or *f_or = f_exists->add_and()->add_or(); - for (int i = 0; i < v.size(); i++) { - Variable_ID e = f_exists->declare(tmp_e()); - F_And *f_and = f_or->add_and(); - - EQ_Handle h = f_and->add_EQ(); - h.update_coef(lhs, 1); - h.update_coef(e, -1); - - exp2formula(ir, r, f_and, freevars, v[i], e, side, IR_COND_EQ, false); - - for (int j = 0; j < v.size(); j++) - if (j != i) { - Variable_ID e2 = f_exists->declare(tmp_e()); - GEQ_Handle h2 = f_and->add_GEQ(); - h2.update_coef(e, -1); - h2.update_coef(e2, 1); - - exp2formula(ir, r, f_and, freevars, v[j], e2, side, IR_COND_EQ, false); - } - } - - for (int i = 0; i < v.size(); i++) - delete v[i]; - } - else - throw std::invalid_argument("unsupported condition type"); - - if (destroy) - delete repr; - } - case IR_OP_MAX: - { - std::vector<CG_outputRepr *> v = ir->QueryExpOperand(repr); - - F_Exists *f_exists = f_root->add_exists(); - - if (rel == IR_COND_LE || rel == IR_COND_LT) { - F_Or *f_or = f_exists->add_and()->add_or(); - for (int i = 0; i < v.size(); i++) { - Variable_ID e = f_exists->declare(tmp_e()); - F_And *f_and = f_or->add_and(); - GEQ_Handle h = f_and->add_GEQ(); - h.update_coef(lhs, -1); - h.update_coef(e, 1); - if (rel == IR_COND_LT) - h.update_const(-1); - - exp2formula(ir, r, f_and, freevars, v[i], e, side, IR_COND_EQ, true); - } - } - else if (rel == IR_COND_GE || rel == IR_COND_GT) { - F_And *f_and = f_exists->add_and(); - for (int i = 0; i < v.size(); i++) { - Variable_ID e = f_exists->declare(tmp_e()); - GEQ_Handle h = f_and->add_GEQ(); - h.update_coef(lhs, 1); - h.update_coef(e, -1); - if (rel == IR_COND_GT) - h.update_const(-1); - - exp2formula(ir, r, f_and, freevars, v[i], e, side, IR_COND_EQ, true); - } - } - else if (rel == IR_COND_EQ) { - F_Or *f_or = f_exists->add_and()->add_or(); - for (int i = 0; i < v.size(); i++) { - Variable_ID e = f_exists->declare(tmp_e()); - F_And *f_and = f_or->add_and(); - - EQ_Handle h = f_and->add_EQ(); - h.update_coef(lhs, 1); - h.update_coef(e, -1); - - exp2formula(ir, r, f_and, freevars, v[i], e, side, IR_COND_EQ, false); - - for (int j = 0; j < v.size(); j++) - if (j != i) { - Variable_ID e2 = f_exists->declare(tmp_e()); - GEQ_Handle h2 = f_and->add_GEQ(); - h2.update_coef(e, 1); - h2.update_coef(e2, -1); - - exp2formula(ir, r, f_and, freevars, v[j], e2, side, IR_COND_EQ, false); - } - } - - for (int i = 0; i < v.size(); i++) - delete v[i]; - } - else - throw std::invalid_argument("unsupported condition type"); - - if (destroy) - delete repr; - } - case IR_OP_NULL: - break; - default: - throw ir_exp_error("unsupported operand type"); - } -} - - -//----------------------------------------------------------------------------- -// Build dependence relation for two array references. -// ----------------------------------------------------------------------------- -Relation arrays2relation(IR_Code *ir, std::vector<Free_Var_Decl*> &freevars, - const IR_ArrayRef *ref_src, const Relation &IS_w, - const IR_ArrayRef *ref_dst, const Relation &IS_r) { - Relation &IS1 = const_cast<Relation &>(IS_w); - Relation &IS2 = const_cast<Relation &>(IS_r); - - Relation r(IS1.n_set(), IS2.n_set()); - - for (int i = 1; i <= IS1.n_set(); i++) - r.name_input_var(i, IS1.set_var(i)->name()); - - for (int i = 1; i <= IS2.n_set(); i++) - r.name_output_var(i, IS2.set_var(i)->name()+"'"); - - IR_Symbol *sym_src = ref_src->symbol(); - IR_Symbol *sym_dst = ref_dst->symbol(); - if (*sym_src != *sym_dst) { - r.add_or(); // False Relation - delete sym_src; - delete sym_dst; - return r; - } - else { - delete sym_src; - delete sym_dst; - } - - F_And *f_root = r.add_and(); - - for (int i = 0; i < ref_src->n_dim(); i++) { - F_Exists *f_exists = f_root->add_exists(); - Variable_ID e1 = f_exists->declare(tmp_e()); - Variable_ID e2 = f_exists->declare(tmp_e()); - F_And *f_and = f_exists->add_and(); - - CG_outputRepr *repr_src = ref_src->index(i); - CG_outputRepr *repr_dst = ref_dst->index(i); - - bool has_complex_formula = false; - try { - exp2formula(ir, r, f_and, freevars, repr_src, e1, 'w', IR_COND_EQ, false); - exp2formula(ir, r, f_and, freevars, repr_dst, e2, 'r', IR_COND_EQ, false); - } - catch (const ir_exp_error &e) { - has_complex_formula = true; - } - - if (!has_complex_formula) { - EQ_Handle h = f_and->add_EQ(); - h.update_coef(e1, 1); - h.update_coef(e2, -1); - } - - repr_src->clear(); - repr_dst->clear(); - delete repr_src; - delete repr_dst; - } - - // add iteration space restriction - r = Restrict_Domain(r, copy(IS1)); - r = Restrict_Range(r, copy(IS2)); - - // reset the output variable names lost in restriction - for (int i = 1; i <= IS2.n_set(); i++) - r.name_output_var(i, IS2.set_var(i)->name()+"'"); - - return r; -} - - -//----------------------------------------------------------------------------- -// Convert array dependence relation into set of dependence vectors, assuming -// ref_w is lexicographically before ref_r in the source code. -// ----------------------------------------------------------------------------- -std::pair<std::vector<DependenceVector>, std::vector<DependenceVector> > relation2dependences (const IR_ArrayRef *ref_src, const IR_ArrayRef *ref_dst, const Relation &r) { - assert(r.n_inp() == r.n_out()); - - std::vector<DependenceVector> dependences1, dependences2; - std::stack<DependenceLevel> working; - working.push(DependenceLevel(r, r.n_inp())); - - while (!working.empty()) { - DependenceLevel dep = working.top(); - working.pop(); - - // No dependence exists, move on. - if (!dep.r.is_satisfiable()) - continue; - - if (dep.level == r.n_inp()) { - DependenceVector dv; - - // for loop independent dependence, use lexical order to - // determine the correct source and destination - if (dep.dir == 0) { - if (*ref_src == *ref_dst) - continue; // trivial self zero-dependence - - if (ref_src->is_write()) { - if (ref_dst->is_write()) - dv.type = DEP_W2W; - else - dv.type = DEP_W2R; - } - else { - if (ref_dst->is_write()) - dv.type = DEP_R2W; - else - dv.type = DEP_R2R; - } - - } - else if (dep.dir == 1) { - if (ref_src->is_write()) { - if (ref_dst->is_write()) - dv.type = DEP_W2W; - else - dv.type = DEP_W2R; - } - else { - if (ref_dst->is_write()) - dv.type = DEP_R2W; - else - dv.type = DEP_R2R; - } - } - else { // dep.dir == -1 - if (ref_dst->is_write()) { - if (ref_src->is_write()) - dv.type = DEP_W2W; - else - dv.type = DEP_W2R; - } - else { - if (ref_src->is_write()) - dv.type = DEP_R2W; - else - dv.type = DEP_R2R; - } - } - - dv.lbounds = dep.lbounds; - dv.ubounds = dep.ubounds; - dv.sym = ref_src->symbol(); - - if (dep.dir == 0 || dep.dir == 1) - dependences1.push_back(dv); - else - dependences2.push_back(dv); - } - else { - // now work on the next dimension level - int level = ++dep.level; - - coef_t lbound, ubound; - Relation delta = Deltas(copy(dep.r)); - delta.query_variable_bounds(delta.set_var(level), lbound, ubound); - - if (dep.dir == 0) { - if (lbound > 0) { - dep.dir = 1; - dep.lbounds[level-1] = lbound; - dep.ubounds[level-1] = ubound; - - working.push(dep); - } - else if (ubound < 0) { - dep.dir = -1; - dep.lbounds[level-1] = -ubound; - dep.ubounds[level-1] = -lbound; - - working.push(dep); - } - else { - // split the dependence vector into flow- and anti-dependence - // for the first non-zero distance, also separate zero distance - // at this level. - { - DependenceLevel dep2 = dep; - - dep2.lbounds[level-1] = 0; - dep2.ubounds[level-1] = 0; - - F_And *f_root = dep2.r.and_with_and(); - EQ_Handle h = f_root->add_EQ(); - h.update_coef(dep2.r.input_var(level), 1); - h.update_coef(dep2.r.output_var(level), -1); - - working.push(dep2); - } - - if (lbound < 0 && *ref_src != *ref_dst) { - DependenceLevel dep2 = dep; - - F_And *f_root = dep2.r.and_with_and(); - GEQ_Handle h = f_root->add_GEQ(); - h.update_coef(dep2.r.input_var(level), 1); - h.update_coef(dep2.r.output_var(level), -1); - h.update_const(-1); - - // get tighter bounds under new constraints - coef_t lbound, ubound; - delta = Deltas(copy(dep2.r)); - delta.query_variable_bounds(delta.set_var(level), - lbound, ubound); - - dep2.dir = -1; - dep2.lbounds[level-1] = max(-ubound,static_cast<coef_t>(1)); // use max() to avoid Omega retardness - dep2.ubounds[level-1] = -lbound; - - working.push(dep2); - } - - if (ubound > 0) { - DependenceLevel dep2 = dep; - - F_And *f_root = dep2.r.and_with_and(); - GEQ_Handle h = f_root->add_GEQ(); - h.update_coef(dep2.r.input_var(level), -1); - h.update_coef(dep2.r.output_var(level), 1); - h.update_const(-1); - - // get tighter bonds under new constraints - coef_t lbound, ubound; - delta = Deltas(copy(dep2.r)); - delta.query_variable_bounds(delta.set_var(level), - lbound, ubound); - dep2.dir = 1; - dep2.lbounds[level-1] = max(lbound,static_cast<coef_t>(1)); // use max() to avoid Omega retardness - dep2.ubounds[level-1] = ubound; - - working.push(dep2); - } - } - } - // now deal with dependence vector with known direction - // determined at previous levels - else { - // For messy bounds, further test to see if the dependence distance - // can be reduced to positive/negative. This is an omega hack. - if (lbound == negInfinity && ubound == posInfinity) { - { - Relation t = dep.r; - F_And *f_root = t.and_with_and(); - GEQ_Handle h = f_root->add_GEQ(); - h.update_coef(t.input_var(level), 1); - h.update_coef(t.output_var(level), -1); - h.update_const(-1); - - if (!t.is_satisfiable()) { - lbound = 0; - } - } - { - Relation t = dep.r; - F_And *f_root = t.and_with_and(); - GEQ_Handle h = f_root->add_GEQ(); - h.update_coef(t.input_var(level), -1); - h.update_coef(t.output_var(level), 1); - h.update_const(-1); - - if (!t.is_satisfiable()) { - ubound = 0; - } - } - } - - // Same thing as above, test to see if zero dependence - // distance possible. - if (lbound == 0 || ubound == 0) { - Relation t = dep.r; - F_And *f_root = t.and_with_and(); - EQ_Handle h = f_root->add_EQ(); - h.update_coef(t.input_var(level), 1); - h.update_coef(t.output_var(level), -1); - - if (!t.is_satisfiable()) { - if (lbound == 0) - lbound = 1; - if (ubound == 0) - ubound = -1; - } - } - - if (dep.dir == -1) { - dep.lbounds[level-1] = -ubound; - dep.ubounds[level-1] = -lbound; - } - else { // dep.dir == 1 - dep.lbounds[level-1] = lbound; - dep.ubounds[level-1] = ubound; - } - - working.push(dep); - } - } - } - - return std::make_pair(dependences1, dependences2); -} - - -//----------------------------------------------------------------------------- -// Convert a boolean expression to omega relation. "destroy" means shallow -// deallocation of "repr", not freeing the actual code inside. -//----------------------------------------------------------------------------- -void exp2constraint(IR_Code *ir, Relation &r, F_And *f_root, - std::vector<Free_Var_Decl *> &freevars, - CG_outputRepr *repr, bool destroy) { - IR_CONDITION_TYPE cond = ir->QueryBooleanExpOperation(repr); - switch (cond) { - case IR_COND_LT: - case IR_COND_LE: - case IR_COND_EQ: - case IR_COND_GT: - case IR_COND_GE: { - F_Exists *f_exist = f_root->add_exists(); - Variable_ID e = f_exist->declare(); - F_And *f_and = f_exist->add_and(); - std::vector<omega::CG_outputRepr *> op = ir->QueryExpOperand(repr); - exp2formula(ir, r, f_and, freevars, op[0], e, 's', IR_COND_EQ, true); - exp2formula(ir, r, f_and, freevars, op[1], e, 's', cond, true); - if (destroy) - delete repr; - break; - } - case IR_COND_NE: { - F_Exists *f_exist = f_root->add_exists(); - Variable_ID e = f_exist->declare(); - F_Or *f_or = f_exist->add_or(); - F_And *f_and = f_or->add_and(); - std::vector<omega::CG_outputRepr *> op = ir->QueryExpOperand(repr); - exp2formula(ir, r, f_and, freevars, op[0], e, 's', IR_COND_EQ, false); - exp2formula(ir, r, f_and, freevars, op[1], e, 's', IR_COND_GT, false); - - f_and = f_or->add_and(); - exp2formula(ir, r, f_and, freevars, op[0], e, 's', IR_COND_EQ, true); - exp2formula(ir, r, f_and, freevars, op[1], e, 's', IR_COND_LT, true); - - if (destroy) - delete repr; - break; - } - default: - throw ir_exp_error("unrecognized conditional expression"); - } -} - - - - - -// inline void exp2formula(IR_Code *ir, Relation &r, F_And *f_root, -// std::vector<Free_Var_Decl*> &freevars, -// const CG_outputRepr *repr, Variable_ID lhs, char side, char rel) { -// exp2formula(ir, r, f_root, freevars, const_cast<CG_outputRepr *>(repr), lhs, side, rel, false); -// } - - - - - - - -//----------------------------------------------------------------------------- -// Convert suif expression tree to omega relation. -//----------------------------------------------------------------------------- - -// void suif2formula(Relation &r, F_And *f_root, -// std::vector<Free_Var_Decl*> &freevars, -// operand op, Variable_ID lhs, -// char side, char rel) { -// if (op.is_immed()) { -// immed im = op.immediate(); - -// if (im.is_integer()) { -// int c = im.integer(); - -// if (rel == '>') { -// GEQ_Handle h = f_root->add_GEQ(); -// h.update_coef(lhs, 1); -// h.update_const(-1*c); -// } -// else if (rel == '<') { -// GEQ_Handle h = f_root->add_GEQ(); -// h.update_coef(lhs, -1); -// h.update_const(c); -// } -// else { // '=' -// EQ_Handle h = f_root->add_EQ(); -// h.update_coef(lhs, 1); -// h.update_const(-1*c); -// } -// } -// else { -// return; //add Function in the future -// } -// } -// else if (op.is_symbol()) { -// String s = op.symbol()->name(); -// Variable_ID e = find_index(r, s, side); - -// if (e == NULL) { // must be free variable -// Free_Var_Decl *t = NULL; -// for (unsigned i = 0; i < freevars.size(); i++) { -// String ss = freevars[i]->base_name(); -// if (s == ss) { -// t = freevars[i]; -// break; -// } -// } - -// if (t == NULL) { -// t = new Free_Var_Decl(s); -// freevars.insert(freevars.end(), t); -// } - -// e = r.get_local(t); -// } - -// if (rel == '>') { -// GEQ_Handle h = f_root->add_GEQ(); -// h.update_coef(lhs, 1); -// h.update_coef(e, -1); -// } -// else if (rel == '<') { -// GEQ_Handle h = f_root->add_GEQ(); -// h.update_coef(lhs, -1); -// h.update_coef(e, 1); -// } -// else { // '=' -// EQ_Handle h = f_root->add_EQ(); -// h.update_coef(lhs, 1); -// h.update_coef(e, -1); -// } -// } -// else if (op.is_instr()) -// suif2formula(r, f_root, freevars, op.instr(), lhs, side, rel); -// } - - -// void suif2formula(Relation &r, F_And *f_root, -// std::vector<Free_Var_Decl*> &freevars, -// instruction *ins, Variable_ID lhs, -// char side, char rel) { -// if (ins->opcode() == io_cpy) { -// suif2formula(r, f_root, freevars, ins->src_op(0), lhs, side, rel); -// } -// else if (ins->opcode() == io_add || ins->opcode() == io_sub) { -// F_Exists *f_exists = f_root->add_exists(); -// Variable_ID e1 = f_exists->declare(tmp_e()); -// Variable_ID e2 = f_exists->declare(tmp_e()); -// F_And *f_and = f_exists->add_and(); - -// int add_or_sub = ins->opcode() == io_add ? 1 : -1; -// if (rel == '>') { -// GEQ_Handle h = f_and->add_GEQ(); -// h.update_coef(lhs, 1); -// h.update_coef(e1, -1); -// h.update_coef(e2, -1 * add_or_sub); -// } -// else if (rel == '<') { -// GEQ_Handle h = f_and->add_GEQ(); -// h.update_coef(lhs, -1); -// h.update_coef(e1, 1); -// h.update_coef(e2, 1 * add_or_sub); -// } -// else { // '=' -// EQ_Handle h = f_and->add_EQ(); -// h.update_coef(lhs, 1); -// h.update_coef(e1, -1); -// h.update_coef(e2, -1 * add_or_sub); -// } - -// suif2formula(r, f_and, freevars, ins->src_op(0), e1, side, '='); -// suif2formula(r, f_and, freevars, ins->src_op(1), e2, side, '='); -// } -// else if (ins->opcode() == io_mul) { -// operand op1 = ins->src_op(0); -// operand op2 = ins->src_op(1); - -// if (!op1.is_immed() && !op2.is_immed()) -// return; // add Function in the future -// else { -// operand op; -// immed im; -// if (op1.is_immed()) { -// im = op1.immediate(); -// op = op2; -// } -// else { -// im = op2.immediate(); -// op = op1; -// } - -// if (!im.is_integer()) -// return; //add Function in the future -// else { -// int c = im.integer(); - -// F_Exists *f_exists = f_root->add_exists(); -// Variable_ID e = f_exists->declare(tmp_e()); -// F_And *f_and = f_exists->add_and(); - -// if (rel == '>') { -// GEQ_Handle h = f_and->add_GEQ(); -// h.update_coef(lhs, 1); -// h.update_coef(e, -c); -// } -// else if (rel == '<') { -// GEQ_Handle h = f_and->add_GEQ(); -// h.update_coef(lhs, -1); -// h.update_coef(e, c); -// } -// else { -// EQ_Handle h = f_and->add_EQ(); -// h.update_coef(lhs, 1); -// h.update_coef(e, -c); -// } - -// suif2formula(r, f_and, freevars, op, e, side, '='); -// } -// } -// } -// else if (ins->opcode() == io_div) { -// operand op1 = ins->src_op(0); -// operand op2 = ins->src_op(1); - -// if (!op2.is_immed()) -// return; //add Function in the future -// else { -// immed im = op2.immediate(); - -// if (!im.is_integer()) -// return; //add Function in the future -// else { -// int c = im.integer(); - -// F_Exists *f_exists = f_root->add_exists(); -// Variable_ID e = f_exists->declare(tmp_e()); -// F_And *f_and = f_exists->add_and(); - -// if (rel == '>') { -// GEQ_Handle h = f_and->add_GEQ(); -// h.update_coef(lhs, c); -// h.update_coef(e, -1); -// } -// else if (rel == '<') { -// GEQ_Handle h = f_and->add_GEQ(); -// h.update_coef(lhs, -c); -// h.update_coef(e, 1); -// } -// else { -// EQ_Handle h = f_and->add_EQ(); -// h.update_coef(lhs, c); -// h.update_coef(e, -1); -// } - -// suif2formula(r, f_and, freevars, op1, e, side, '='); -// } -// } -// } -// else if (ins->opcode() == io_neg) { -// F_Exists *f_exists = f_root->add_exists(); -// Variable_ID e = f_exists->declare(tmp_e()); -// F_And *f_and = f_exists->add_and(); - -// if (rel == '>') { -// GEQ_Handle h = f_and->add_GEQ(); -// h.update_coef(lhs, 1); -// h.update_coef(e, 1); -// } -// else if (rel == '<') { -// GEQ_Handle h = f_and->add_GEQ(); -// h.update_coef(lhs, -1); -// h.update_coef(e, -1); -// } -// else { -// EQ_Handle h = f_and->add_EQ(); -// h.update_coef(lhs, 1); -// h.update_coef(e, 1); -// } - -// suif2formula(r, f_and, freevars, ins->src_op(0), e, side, '='); -// } -// else if (ins->opcode() == io_min) { -// operand op1 = ins->src_op(0); -// operand op2 = ins->src_op(1); - -// F_Exists *f_exists = f_root->add_exists(); -// Variable_ID e1 = f_exists->declare(tmp_e()); -// Variable_ID e2 = f_exists->declare(tmp_e()); -// F_And *f_and = f_exists->add_and(); - -// if (rel == '>') { -// F_Or *f_or = f_and->add_or(); -// F_And *f_and1 = f_or->add_and(); -// GEQ_Handle h1 = f_and1->add_GEQ(); -// h1.update_coef(lhs, 1); -// h1.update_coef(e1, -1); -// F_And *f_and2 = f_or->add_and(); -// GEQ_Handle h2 = f_and2->add_GEQ(); -// h2.update_coef(lhs, 1); -// h2.update_coef(e2, -1); -// } -// else if (rel == '<') { -// GEQ_Handle h1 = f_and->add_GEQ(); -// h1.update_coef(lhs, -1); -// h1.update_coef(e1, 1); -// GEQ_Handle h2 = f_and->add_GEQ(); -// h2.update_coef(lhs, -1); -// h2.update_coef(e2, 1); -// } -// else { -// F_Or *f_or = f_and->add_or(); -// F_And *f_and1 = f_or->add_and(); -// EQ_Handle h1 = f_and1->add_EQ(); -// h1.update_coef(lhs, 1); -// h1.update_coef(e1, -1); -// GEQ_Handle h2 = f_and1->add_GEQ(); -// h2.update_coef(e1, -1); -// h2.update_coef(e2, 1); -// F_And *f_and2 = f_or->add_and(); -// EQ_Handle h3 = f_and2->add_EQ(); -// h3.update_coef(lhs, 1); -// h3.update_coef(e2, -1); -// GEQ_Handle h4 = f_and2->add_GEQ(); -// h4.update_coef(e1, 1); -// h4.update_coef(e2, -1); -// } - -// suif2formula(r, f_and, freevars, op1, e1, side, '='); -// suif2formula(r, f_and, freevars, op2, e2, side, '='); -// } -// else if (ins->opcode() == io_max) { -// operand op1 = ins->src_op(0); -// operand op2 = ins->src_op(1); - -// F_Exists *f_exists = f_root->add_exists(); -// Variable_ID e1 = f_exists->declare(tmp_e()); -// Variable_ID e2 = f_exists->declare(tmp_e()); -// F_And *f_and = f_exists->add_and(); - -// if (rel == '>') { -// GEQ_Handle h1 = f_and->add_GEQ(); -// h1.update_coef(lhs, 1); -// h1.update_coef(e1, -1); -// GEQ_Handle h2 = f_and->add_GEQ(); -// h2.update_coef(lhs, 1); -// h2.update_coef(e2, -1); -// } -// else if (rel == '<') { -// F_Or *f_or = f_and->add_or(); -// F_And *f_and1 = f_or->add_and(); -// GEQ_Handle h1 = f_and1->add_GEQ(); -// h1.update_coef(lhs, -1); -// h1.update_coef(e1, 1); -// F_And *f_and2 = f_or->add_and(); -// GEQ_Handle h2 = f_and2->add_GEQ(); -// h2.update_coef(lhs, -1); -// h2.update_coef(e2, 1); -// } -// else { -// F_Or *f_or = f_and->add_or(); -// F_And *f_and1 = f_or->add_and(); -// EQ_Handle h1 = f_and1->add_EQ(); -// h1.update_coef(lhs, 1); -// h1.update_coef(e1, -1); -// GEQ_Handle h2 = f_and1->add_GEQ(); -// h2.update_coef(e1, 1); -// h2.update_coef(e2, -1); -// F_And *f_and2 = f_or->add_and(); -// EQ_Handle h3 = f_and2->add_EQ(); -// h3.update_coef(lhs, 1); -// h3.update_coef(e2, -1); -// GEQ_Handle h4 = f_and2->add_GEQ(); -// h4.update_coef(e1, -1); -// h4.update_coef(e2, 1); -// } - -// suif2formula(r, f_and, freevars, op1, e1, side, '='); -// suif2formula(r, f_and, freevars, op2, e2, side, '='); -// } -// } - -//----------------------------------------------------------------------------- -// Generate iteration space constraints -//----------------------------------------------------------------------------- - -// void add_loop_stride_constraints(Relation &r, F_And *f_root, -// std::vector<Free_Var_Decl*> &freevars, -// tree_for *tnf, char side) { - -// std::string name(tnf->index()->name()); -// int dim = 0; -// for (;dim < r.n_set(); dim++) -// if (r.set_var(dim+1)->name() == name) -// break; - -// Relation bound = get_loop_bound(r, dim); - -// operand op = tnf->step_op(); -// if (!op.is_null()) { -// if (op.is_immed()) { -// immed im = op.immediate(); -// if (im.is_integer()) { -// int c = im.integer(); - -// if (c != 1 && c != -1) -// add_loop_stride(r, bound, dim, c); -// } -// else -// assert(0); // messy stride -// } -// else -// assert(0); // messy stride -// } -// } - -// void add_loop_bound_constraints(IR_Code *ir, Relation &r, F_And *f_root, -// std::vector<Free_Var_Decl*> &freevars, -// tree_for *tnf, -// char upper_or_lower, char side, IR_CONDITION_TYPE rel) { -// Variable_ID v = find_index(r, tnf->index()->name(), side); - -// tree_node_list *tnl; - -// if (upper_or_lower == 'u') -// tnl = tnf->ub_list(); -// else -// tnl = tnf->lb_list(); - -// tree_node_list_iter iter(tnl); -// while (!iter.is_empty()) { -// tree_node *tn = iter.step(); -// if (tn->kind() != TREE_INSTR) -// break; // messy bounds - -// instruction *ins = static_cast<tree_instr *>(tn)->instr(); - - -// if (upper_or_lower == 'u' && (tnf->test() == FOR_SLT || tnf->test() == FOR_ULT)) { -// operand op1(ins->clone()); -// operand op2(new in_ldc(type_s32, operand(), immed(1))); -// instruction *t = new in_rrr(io_sub, op1.type(), operand(), op1, op2); - -// CG_suifRepr *repr = new CG_suifRepr(operand(t)); -// exp2formula(ir, r, f_root, freevars, repr, v, side, rel, true); -// delete t; -// } -// else if (tnf->test() == FOR_SLT || tnf->test() == FOR_SLTE || tnf->test() == FOR_ULT || tnf->test() == FOR_ULTE) { -// CG_suifRepr *repr = new CG_suifRepr(operand(ins)); -// exp2formula(ir, r, f_root, freevars, repr, v, side, rel, true); -// } -// else -// assert(0); -// } -// } - - -// Relation loop_iteration_space(std::vector<Free_Var_Decl*> &freevars, -// tree_node *tn, std::vector<tree_for*> &loops) { -// Relation r(loops.size()); -// for (unsigned i = 0; i < loops.size(); i++) { -// String s = loops[i]->index()->name(); -// r.name_set_var(i+1, s); -// } - -// F_And *f_root = r.add_and(); - -// std::vector<tree_for *> outer = find_outer_loops(tn); -// std::vector<LexicalOrderType> loops_lex(loops.size(), LEX_UNKNOWN); - -// for (unsigned i = 0; i < outer.size(); i++) { -// unsigned j; - -// for (j = 0; j < loops.size(); j++) { -// if (outer[i] == loops[j]) { -// loops_lex[j] = LEX_MATCH; -// break; -// } else if (outer[i]->index() == loops[j]->index()) { -// loops_lex[j] = lexical_order(outer[i],loops[j]); -// break; -// } -// } - -// if (j != loops.size()) { -// add_loop_bound_constraints(r, f_root, freevars, outer[i], 'l', 's', '>'); -// add_loop_bound_constraints(r, f_root, freevars, outer[i], 'u', 's', '<'); -// add_loop_stride_constraints(r,f_root, freevars, outer[i], 's'); -// } -// } - -// // Add degenerated constraints for non-enclosing loops for this -// // statement. We treat low-dim space as part of whole -// // iteration space. -// LexicalOrderType lex = LEX_MATCH; -// for (unsigned i = 0; i < loops.size(); i++) { -// if (loops_lex[i] != 0) { -// if (lex == LEX_MATCH) -// lex = loops_lex[i]; -// continue; -// } - -// if (lex == LEX_MATCH) { -// for (unsigned j = i+1; j < loops.size(); j++) { -// if (loops_lex[j] == LEX_BEFORE || loops_lex[j] == LEX_AFTER) { -// lex = loops_lex[j]; -// break; -// } -// } -// } - -// if (lex == LEX_MATCH) -// lex = lexical_order(tn, loops[i]); - -// if (lex == LEX_BEFORE) -// add_loop_bound_constraints(r, f_root, freevars, loops[i], 'l', 's', '='); -// else -// add_loop_bound_constraints(r, f_root, freevars, loops[i], 'u', 's', '='); -// } - -// return r; -// } - -// Relation arrays2relation(std::vector<Free_Var_Decl*> &freevars, -// in_array *ia_w, const Relation &IS1_, -// in_array *ia_r, const Relation &IS2_) { -// Relation &IS1 = const_cast<Relation &>(IS1_); -// Relation &IS2 = const_cast<Relation &>(IS2_); - -// Relation r(IS1.n_set(), IS2.n_set()); - -// for (int i = 1; i <= IS1.n_set(); i++) -// r.name_input_var(i, IS1.set_var(i)->name()); - -// for (int i = 1; i <= IS2.n_set(); i++) -// r.name_output_var(i, IS2.set_var(i)->name()+"'"); - -// if (get_sym_of_array(ia_w) != get_sym_of_array(ia_r)) { -// r.add_or(); // False Relation -// return r; -// } - -// F_And *f_root = r.add_and(); - -// for (unsigned i = 0; i < ia_w->dims(); i++) { -// F_Exists *f_exists = f_root->add_exists(); -// Variable_ID e = f_exists->declare(tmp_e()); -// F_And *f_and = f_exists->add_and(); - -// suif2formula(r, f_and, freevars, ia_w->index(i), e, 'w', '='); -// suif2formula(r, f_and, freevars, ia_r->index(i), e, 'r', '='); -// } - -// // add iteration space restriction -// r = Restrict_Domain(r, copy(IS1)); -// r = Restrict_Range(r, copy(IS2)); - -// // reset the output variable names lost in restriction -// for (int i = 1; i <= IS2.n_set(); i++) -// r.name_output_var(i, IS2.set_var(i)->name()+"'"); - -// return r; -// } - - -// std::vector<DependenceVector> relation2dependences (IR_Code *ir, in_array *ia_w, in_array *ia_r, const Relation &r) { -// assert(r.n_inp() == r.n_out()); - -// std::vector<DependenceVector> dependences; - -// std::stack<DependenceLevel> working; -// working.push(DependenceLevel(r, r.n_inp())); - -// while (!working.empty()) { -// DependenceLevel dep = working.top(); -// working.pop(); - -// // No dependence exists, move on. -// if (!dep.r.is_satisfiable()) -// continue; - -// if (dep.level == r.n_inp()) { -// DependenceVector dv; - -// // for loop independent dependence, use lexical order to -// // determine the correct source and destination -// if (dep.dir == 0) { -// LexicalOrderType order = lexical_order(ia_w->parent(), ia_r->parent()); - -// if (order == LEX_MATCH) -// continue; //trivial self zero-dependence -// else if (order == LEX_AFTER) { -// dv.src = new IR_suifArrayRef(ir, ia_r); -// dv.dst = new IR_suifArrayRef(ir, ia_w); -// } -// else { -// dv.src = new IR_suifArrayRef(ir, ia_w); -// dv.dst = new IR_suifArrayRef(ir,ia_r); -// } -// } -// else if (dep.dir == 1) { -// dv.src = new IR_suifArrayRef(ir, ia_w); -// dv.dst = new IR_suifArrayRef(ir, ia_r); -// } -// else { // dep.dir == -1 -// dv.src = new IR_suifArrayRef(ir, ia_r); -// dv.dst = new IR_suifArrayRef(ir, ia_w); -// } - -// dv.lbounds = dep.lbounds; -// dv.ubounds = dep.ubounds; - -// // // set the dependence type -// // if (is_lhs(dv.source) && is_lhs(dv.dest)) -// // dv.type = 'o'; -// // else if (!is_lhs(dv.source) && ! is_lhs(dv.dest)) -// // dv.type = 'i'; -// // else if (is_lhs(dv.source)) -// // dv.type = 'f'; -// // else -// // dv.type = 'a'; - -// dependences.push_back(dv); -// } -// else { -// // now work on the next dimension level -// int level = ++dep.level; - -// coef_t lbound, ubound; -// Relation delta = Deltas(copy(dep.r)); -// delta.query_variable_bounds(delta.set_var(level), lbound, ubound); - -// if (dep.dir == 0) { -// if (lbound > 0) { -// dep.dir = 1; -// dep.lbounds[level-1] = lbound; -// dep.ubounds[level-1] = ubound; - -// working.push(dep); -// } -// else if (ubound < 0) { -// dep.dir = -1; -// dep.lbounds[level-1] = -ubound; -// dep.ubounds[level-1] = -lbound; - -// working.push(dep); -// } -// else { -// // split the dependence vector into flow- and anti-dependence -// // for the first non-zero distance, also separate zero distance -// // at this level. -// { -// DependenceLevel dep2 = dep; - -// dep2.lbounds[level-1] = 0; -// dep2.ubounds[level-1] = 0; - -// F_And *f_root = dep2.r.and_with_and(); -// EQ_Handle h = f_root->add_EQ(); -// h.update_coef(dep2.r.input_var(level), 1); -// h.update_coef(dep2.r.output_var(level), -1); - -// working.push(dep2); -// } - -// if (lbound < 0 && ia_w != ia_r) { -// DependenceLevel dep2 = dep; - -// F_And *f_root = dep2.r.and_with_and(); -// GEQ_Handle h = f_root->add_GEQ(); -// h.update_coef(dep2.r.input_var(level), 1); -// h.update_coef(dep2.r.output_var(level), -1); -// h.update_const(-1); - -// // get tighter bounds under new constraints -// coef_t lbound, ubound; -// delta = Deltas(copy(dep2.r)); -// delta.query_variable_bounds(delta.set_var(level), -// lbound, ubound); - -// dep2.dir = -1; -// dep2.lbounds[level-1] = max(-ubound,static_cast<coef_t>(1)); // use max() to avoid Omega retardness -// dep2.ubounds[level-1] = -lbound; - -// working.push(dep2); -// } - -// if (ubound > 0) { -// DependenceLevel dep2 = dep; - -// F_And *f_root = dep2.r.and_with_and(); -// GEQ_Handle h = f_root->add_GEQ(); -// h.update_coef(dep2.r.input_var(level), -1); -// h.update_coef(dep2.r.output_var(level), 1); -// h.update_const(-1); - -// // get tighter bonds under new constraints -// coef_t lbound, ubound; -// delta = Deltas(copy(dep2.r)); -// delta.query_variable_bounds(delta.set_var(level), -// lbound, ubound); -// dep2.dir = 1; -// dep2.lbounds[level-1] = max(lbound,static_cast<coef_t>(1)); // use max() to avoid Omega retardness -// dep2.ubounds[level-1] = ubound; - -// working.push(dep2); -// } -// } -// } -// // now deal with dependence vector with known direction -// // determined at previous levels -// else { -// // For messy bounds, further test to see if the dependence distance -// // can be reduced to positive/negative. This is an omega hack. -// if (lbound == negInfinity && ubound == posInfinity) { -// { -// Relation t = dep.r; -// F_And *f_root = t.and_with_and(); -// GEQ_Handle h = f_root->add_GEQ(); -// h.update_coef(t.input_var(level), 1); -// h.update_coef(t.output_var(level), -1); -// h.update_const(-1); - -// if (!t.is_satisfiable()) { -// lbound = 0; -// } -// } -// { -// Relation t = dep.r; -// F_And *f_root = t.and_with_and(); -// GEQ_Handle h = f_root->add_GEQ(); -// h.update_coef(t.input_var(level), -1); -// h.update_coef(t.output_var(level), 1); -// h.update_const(-1); - -// if (!t.is_satisfiable()) { -// ubound = 0; -// } -// } -// } - -// // Same thing as above, test to see if zero dependence -// // distance possible. -// if (lbound == 0 || ubound == 0) { -// Relation t = dep.r; -// F_And *f_root = t.and_with_and(); -// EQ_Handle h = f_root->add_EQ(); -// h.update_coef(t.input_var(level), 1); -// h.update_coef(t.output_var(level), -1); - -// if (!t.is_satisfiable()) { -// if (lbound == 0) -// lbound = 1; -// if (ubound == 0) -// ubound = -1; -// } -// } - -// if (dep.dir == -1) { -// dep.lbounds[level-1] = -ubound; -// dep.ubounds[level-1] = -lbound; -// } -// else { // dep.dir == 1 -// dep.lbounds[level-1] = lbound; -// dep.ubounds[level-1] = ubound; -// } - -// working.push(dep); -// } -// } -// } - -// return dependences; -// } - -//----------------------------------------------------------------------------- -// Determine whether the loop (starting from 0) in the iteration space -// has only one iteration. -//----------------------------------------------------------------------------- -bool is_single_loop_iteration(const Relation &r, int level, const Relation &known) { - int n = r.n_set(); - Relation r1 = Intersection(copy(r), Extend_Set(copy(known), n-known.n_set())); - - Relation mapping(n, n); - F_And *f_root = mapping.add_and(); - for (int i = 1; i <= level; i++) { - EQ_Handle h = f_root->add_EQ(); - h.update_coef(mapping.input_var(i), 1); - h.update_coef(mapping.output_var(i), -1); - } - r1 = Range(Restrict_Domain(mapping, r1)); - r1.simplify(); - - Variable_ID v = r1.set_var(level); - for (DNF_Iterator di(r1.query_DNF()); di; di++) { - bool is_single = false; - for (EQ_Iterator ei((*di)->EQs()); ei; ei++) - if ((*ei).get_coef(v) != 0 && !(*ei).has_wildcards()) { - is_single = true; - break; - } - - if (!is_single) - return false; - } - - return true; -} - - - - -bool is_single_iteration(const Relation &r, int dim) { - assert(r.is_set()); - const int n = r.n_set(); - - if (dim >= n) - return true; - - Relation bound = get_loop_bound(r, dim); - -// if (!bound.has_single_conjunct()) -// return false; - -// Conjunct *c = bound.query_DNF()->single_conjunct(); - - for (DNF_Iterator di(bound.query_DNF()); di; di++) { - bool is_single = false; - for (EQ_Iterator ei((*di)->EQs()); ei; ei++) - if (!(*ei).has_wildcards()) { - is_single = true; - break; - } - - if (!is_single) - return false; - } - - return true; - - - - -// Relation r = copy(r_); -// const int n = r.n_set(); - -// if (dim >= n) -// return true; - -// Relation bound = get_loop_bound(r, dim); -// bound = Approximate(bound); -// Conjunct *c = bound.query_DNF()->single_conjunct(); - -// return c->n_GEQs() == 0; - - - - - -// Relation r = copy(r_); -// r.simplify(); -// const int n = r.n_set(); - -// if (dim >= n) -// return true; - -// for (DNF_Iterator i(r.query_DNF()); i; i++) { -// std::vector<bool> is_single(n); -// for (int j = 0; j < dim; j++) -// is_single[j] = true; -// for (int j = dim; j < n; j++) -// is_single[j] = false; - -// bool found_new_single = true; -// while (found_new_single) { -// found_new_single = false; - -// for (EQ_Iterator j = (*i)->EQs(); j; j++) { -// int saved_pos = -1; -// for (Constr_Vars_Iter k(*j); k; k++) -// if ((*k).var->kind() == Set_Var || (*k).var->kind() == Input_Var) { -// int pos = (*k).var->get_position() - 1; -// if (!is_single[pos]) -// if (saved_pos == -1) -// saved_pos = pos; -// else { -// saved_pos = -1; -// break; -// } -// } - -// if (saved_pos != -1) { -// is_single[saved_pos] = true; -// found_new_single = true; -// } -// } - -// if (is_single[dim]) -// break; -// } - -// if (!is_single[dim]) -// return false; -// } - -// return true; -} - -//----------------------------------------------------------------------------- -// Set/get the value of a variable which is know to be constant. -//----------------------------------------------------------------------------- -void assign_const(Relation &r, int dim, int val) { - const int n = r.n_out(); - - Relation mapping(n, n); - F_And *f_root = mapping.add_and(); - - for (int i = 1; i <= n; i++) { - if (i != dim+1) { - EQ_Handle h = f_root->add_EQ(); - h.update_coef(mapping.output_var(i), 1); - h.update_coef(mapping.input_var(i), -1); - } - else { - EQ_Handle h = f_root->add_EQ(); - h.update_coef(mapping.output_var(i), 1); - h.update_const(-val); - } - } - - r = Composition(mapping, r); -} - - -int get_const(const Relation &r, int dim, Var_Kind type) { -// Relation rr = copy(r); - Relation &rr = const_cast<Relation &>(r); - - Variable_ID v; - switch (type) { - // case Set_Var: - // v = rr.set_var(dim+1); - // break; - case Input_Var: - v = rr.input_var(dim+1); - break; - case Output_Var: - v = rr.output_var(dim+1); - break; - default: - throw std::invalid_argument("unsupported variable type"); - } - - for (DNF_Iterator di(rr.query_DNF()); di; di++) - for (EQ_Iterator ei = (*di)->EQs(); ei; ei++) - if ((*ei).is_const(v)) - return (*ei).get_const(); - - throw std::runtime_error("cannot get variable's constant value"); -} - - - - - - -//--------------------------------------------------------------------------- -// Get the bound for a specific loop. -//--------------------------------------------------------------------------- -Relation get_loop_bound(const Relation &r, int dim) { - assert(r.is_set()); - const int n = r.n_set(); - -// Relation r1 = project_onto_levels(copy(r), dim+1, true); - Relation mapping(n,n); - F_And *f_root = mapping.add_and(); - for (int i = 1; i <= dim+1; i++) { - EQ_Handle h = f_root->add_EQ(); - h.update_coef(mapping.input_var(i), 1); - h.update_coef(mapping.output_var(i), -1); - } - Relation r1 = Range(Restrict_Domain(mapping, copy(r))); - for (int i = 1; i <= n; i++) - r1.name_set_var(i, const_cast<Relation &>(r).set_var(i)->name()); - r1.setup_names(); - Relation r2 = Project(copy(r1), dim+1, Set_Var); - - return Gist(r1, r2, 1); -} - -Relation get_loop_bound(const Relation &r, int level, const Relation &known) { - int n = r.n_set(); - Relation r1 = Intersection(copy(r), Extend_Set(copy(known), n-known.n_set())); - - Relation mapping(n, n); - F_And *f_root = mapping.add_and(); - for (int i = 1; i <= level; i++) { - EQ_Handle h = f_root->add_EQ(); - h.update_coef(mapping.input_var(i), 1); - h.update_coef(mapping.output_var(i), -1); - } - r1 = Range(Restrict_Domain(mapping, r1)); - Relation r2 = Project(copy(r1), level, Set_Var); - r1 = Gist(r1, r2, 1); - - for (int i = 1; i <= n; i++) - r1.name_set_var(i, const_cast<Relation &>(r).set_var(i)->name()); - r1.setup_names(); - - return r1; -} - - - -Relation get_max_loop_bound(const std::vector<Relation> &r, int dim) { - if (r.size() == 0) - return Relation::Null(); - - const int n = r[0].n_set(); - Relation res(Relation::False(n)); - for (int i = 0; i < r.size(); i++) { - Relation &t = const_cast<Relation &>(r[i]); - if (t.is_satisfiable()) - res = Union(get_loop_bound(t, dim), res); - } - - res.simplify(); - - return res; -} - -Relation get_min_loop_bound(const std::vector<Relation> &r, int dim) { - if (r.size() == 0) - return Relation::Null(); - - const int n = r[0].n_set(); - Relation res(Relation::True(n)); - for (int i = 0; i < r.size(); i++) { - Relation &t = const_cast<Relation &>(r[i]); - if (t.is_satisfiable()) - res = Intersection(get_loop_bound(t, dim), res); - } - - res.simplify(); - - return res; -} - -//----------------------------------------------------------------------------- -// Add strident to a loop. -// Issues: -// - Don't work with relations with multiple disjuncts. -// - Omega's dealing with max lower bound is awkward. -//----------------------------------------------------------------------------- -void add_loop_stride(Relation &r, const Relation &bound_, int dim, int stride) { - F_And *f_root = r.and_with_and(); - Relation &bound = const_cast<Relation &>(bound_); - for (DNF_Iterator di(bound.query_DNF()); di; di++) { - F_Exists *f_exists = f_root->add_exists(); - Variable_ID e1 = f_exists->declare(tmp_e()); - Variable_ID e2 = f_exists->declare(tmp_e()); - F_And *f_and = f_exists->add_and(); - EQ_Handle stride_eq = f_and->add_EQ(); - stride_eq.update_coef(e1, 1); - stride_eq.update_coef(e2, stride); - if (!r.is_set()) - stride_eq.update_coef(r.output_var(dim+1), -1); - else - stride_eq.update_coef(r.set_var(dim+1), -1); - F_Or *f_or = f_and->add_or(); - - for (GEQ_Iterator gi = (*di)->GEQs(); gi; gi++) { - if ((*gi).get_coef(bound.set_var(dim+1)) > 0) { - // copy the lower bound constraint - EQ_Handle h1 = f_or->add_and()->add_EQ(); - GEQ_Handle h2 = f_and->add_GEQ(); - for (Constr_Vars_Iter ci(*gi); ci; ci++) { - switch ((*ci).var->kind()) { - // case Set_Var: - case Input_Var: { - int pos = (*ci).var->get_position(); - if (pos == dim + 1) { - h1.update_coef(e1, (*ci).coef); - h2.update_coef(e1, (*ci).coef); - } - else { - if (!r.is_set()) { - h1.update_coef(r.output_var(pos), (*ci).coef); - h2.update_coef(r.output_var(pos), (*ci).coef); - } - else { - h1.update_coef(r.set_var(pos), (*ci).coef); - h2.update_coef(r.set_var(pos), (*ci).coef); - } - } - break; - } - case Global_Var: { - Global_Var_ID g = (*ci).var->get_global_var(); - h1.update_coef(r.get_local(g, (*ci).var->function_of()), (*ci).coef); - h2.update_coef(r.get_local(g, (*ci).var->function_of()), (*ci).coef); - break; - } - default: - break; - } - } - h1.update_const((*gi).get_const()); - h2.update_const((*gi).get_const()); - } - } - } -} - - -bool is_inner_loop_depend_on_level(const Relation &r, int level, const Relation &known) { - Relation r1 = Intersection(copy(r), Extend_Set(copy(known), r.n_set()-known.n_set())); - Relation r2 = copy(r1); - for (int i = level+1; i <= r2.n_set(); i++) - r2 = Project(r2, r2.set_var(i)); - r2.simplify(2, 4); - Relation r3 = Gist(r1, r2); - - Variable_ID v = r3.set_var(level); - for (DNF_Iterator di(r3.query_DNF()); di; di++) { - for (EQ_Iterator ei = (*di)->EQs(); ei; ei++) - if ((*ei).get_coef(v) != 0) - return true; - - for (GEQ_Iterator gi = (*di)->GEQs(); gi; gi++) - if ((*gi).get_coef(v) != 0) - return true; - } - - return false; -} - - -//----------------------------------------------------------------------------- -// Suppose loop dim is i. Replace i with i+adjustment in loop bounds. -// e.g. do i = 1, n -// do j = i, n -// after call with dim = 0 and adjustment = 1: -// do i = 1, n -// do j = i+1, n -// ----------------------------------------------------------------------------- -Relation adjust_loop_bound(const Relation &r, int level, int adjustment) { - if (adjustment == 0) - return copy(r); - - const int n = r.n_set(); - Relation r1 = copy(r); - for (int i = level+1; i <= r1.n_set(); i++) - r1 = Project(r1, r1.set_var(i)); - r1.simplify(2, 4); - Relation r2 = Gist(copy(r), copy(r1)); - - Relation mapping(n, n); - F_And *f_root = mapping.add_and(); - for (int i = 1; i <= n; i++) - if (i == level) { - EQ_Handle h = f_root->add_EQ(); - h.update_coef(mapping.input_var(level), -1); - h.update_coef(mapping.output_var(level), 1); - h.update_const(static_cast<coef_t>(adjustment)); - } - else { - EQ_Handle h = f_root->add_EQ(); - h.update_coef(mapping.input_var(i), -1); - h.update_coef(mapping.output_var(i), 1); - } - - r2 = Range(Restrict_Domain(mapping, r2)); - r1 = Intersection(r1, r2); - r1.simplify(); - - for (int i = 1; i <= n; i++) - r1.name_set_var(i, const_cast<Relation &>(r).set_var(i)->name()); - r1.setup_names(); - return r1; -} - - -// commented out on 07/14/2010 -// void adjust_loop_bound(Relation &r, int dim, int adjustment, std::vector<Free_Var_Decl *> globals) { -// assert(r.is_set()); - -// if (adjustment == 0) -// return; - -// const int n = r.n_set(); -// Tuple<std::string> name(n); -// for (int i = 1; i <= n; i++) -// name[i] = r.set_var(i)->name(); - -// Relation r1 = project_onto_levels(copy(r), dim+1, true); -// Relation r2 = Gist(copy(r), copy(r1)); - -// // remove old bogus global variable conditions since we are going to -// // update the value. -// if (globals.size() > 0) -// r1 = Gist(r1, project_onto_levels(copy(r), 0, true)); - -// Relation r4 = Relation::True(n); - -// for (DNF_Iterator di(r2.query_DNF()); di; di++) { -// for (EQ_Iterator ei = (*di)->EQs(); ei; ei++) { -// EQ_Handle h = r4.and_with_EQ(*ei); - -// Variable_ID v = r2.set_var(dim+1); -// coef_t c = (*ei).get_coef(v); -// if (c != 0) -// h.update_const(c*adjustment); - -// for (int i = 0; i < globals.size(); i++) { -// Variable_ID v = r2.get_local(globals[i]); -// coef_t c = (*ei).get_coef(v); -// if (c != 0) -// h.update_const(c*adjustment); -// } -// } - -// for (GEQ_Iterator gi = (*di)->GEQs(); gi; gi++) { -// GEQ_Handle h = r4.and_with_GEQ(*gi); - -// Variable_ID v = r2.set_var(dim+1); -// coef_t c = (*gi).get_coef(v); -// if (c != 0) -// h.update_const(c*adjustment); - -// for (int i = 0; i < globals.size(); i++) { -// Variable_ID v = r2.get_local(globals[i]); -// coef_t c = (*gi).get_coef(v); -// if (c != 0) -// h.update_const(c*adjustment); -// } -// } -// } -// r = Intersection(r1, r4); -// // } -// // else -// // r = Intersection(r1, r2); - -// for (int i = 1; i <= n; i++) -// r.name_set_var(i, name[i]); -// r.setup_names(); -// } - - -// void adjust_loop_bound(Relation &r, int dim, int adjustment) { -// assert(r.is_set()); -// const int n = r.n_set(); -// Tuple<String> name(n); -// for (int i = 1; i <= n; i++) -// name[i] = r.set_var(i)->name(); - -// Relation r1 = project_onto_levels(copy(r), dim+1, true); -// Relation r2 = Gist(r, copy(r1)); - -// Relation r3(n, n); -// F_And *f_root = r3.add_and(); -// for (int i = 0; i < n; i++) { -// EQ_Handle h = f_root->add_EQ(); -// h.update_coef(r3.output_var(i+1), 1); -// h.update_coef(r3.input_var(i+1), -1); -// if (i == dim) -// h.update_const(adjustment); -// } - -// r2 = Range(Restrict_Domain(r3, r2)); -// r = Intersection(r1, r2); - -// for (int i = 1; i <= n; i++) -// r.name_set_var(i, name[i]); -// r.setup_names(); -// } - -// void adjust_loop_bound(Relation &r, int dim, Free_Var_Decl *global_var, int adjustment) { -// assert(r.is_set()); -// const int n = r.n_set(); -// Tuple<String> name(n); -// for (int i = 1; i <= n; i++) -// name[i] = r.set_var(i)->name(); - -// Relation r1 = project_onto_levels(copy(r), dim+1, true); -// Relation r2 = Gist(r, copy(r1)); - -// Relation r3(n); -// Variable_ID v = r2.get_local(global_var); - -// for (DNF_Iterator di(r2.query_DNF()); di; di++) { -// for (EQ_Iterator ei = (*di)->EQs(); ei; ei++) { -// coef_t c = (*ei).get_coef(v); -// EQ_Handle h = r3.and_with_EQ(*ei); -// if (c != 0) -// h.update_const(c*adjustment); -// } -// for (GEQ_Iterator gi = (*di)->GEQs(); gi; gi++) { -// coef_t c = (*gi).get_coef(v); -// GEQ_Handle h = r3.and_with_GEQ(*gi); -// if (c != 0) -// h.update_const(c*adjustment); -// } -// } - -// r = Intersection(r1, r3); -// for (int i = 1; i <= n; i++) -// r.name_set_var(i, name[i]); -// r.setup_names(); -// } - - - -//------------------------------------------------------------------------------ -// If the dimension has value posInfinity, the statement should be privatized -// at this dimension. -//------------------------------------------------------------------------------ -// boolean is_private_statement(const Relation &r, int dim) { -// int n; -// if (r.is_set()) -// n = r.n_set(); -// else -// n = r.n_out(); - -// if (dim >= n) -// return false; - -// try { -// coef_t c; -// if (r.is_set()) -// c = get_const(r, dim, Set_Var); -// else -// c = get_const(r, dim, Output_Var); -// if (c == posInfinity) -// return true; -// else -// return false; -// } -// catch (loop_error e){ -// } - -// return false; -// } - - - -// // ---------------------------------------------------------------------------- -// // Calculate v mod dividend based on equations inside relation r. -// // Return posInfinity if it is not a constant. -// // ---------------------------------------------------------------------------- -// static coef_t mod_(const Relation &r_, Variable_ID v, int dividend, std::set<Variable_ID> &working_on) { -// assert(dividend > 0); -// if (v->kind() == Forall_Var || v->kind() == Exists_Var || v->kind() == Wildcard_Var) -// return posInfinity; - -// working_on.insert(v); - -// Relation &r = const_cast<Relation &>(r_); -// Conjunct *c = r.query_DNF()->single_conjunct(); - -// for (EQ_Iterator ei(c->EQs()); ei; ei++) { -// int coef = mod((*ei).get_coef(v), dividend); -// if (coef != 1 && coef != dividend - 1 ) -// continue; - -// coef_t result = 0; -// for (Constr_Vars_Iter cvi(*ei); cvi; cvi++) -// if ((*cvi).var != v) { -// int p = mod((*cvi).coef, dividend); - -// if (p == 0) -// continue; - -// if (working_on.find((*cvi).var) != working_on.end()) { -// result = posInfinity; -// break; -// } - -// coef_t q = mod_(r, (*cvi).var, dividend, working_on); -// if (q == posInfinity) { -// result = posInfinity; -// break; -// } -// result += p * q; -// } - -// if (result != posInfinity) { -// result += (*ei).get_const(); -// if (coef == 1) -// result = -result; -// working_on.erase(v); - -// return mod(result, dividend); -// } -// } - -// working_on.erase(v); -// return posInfinity; -// } - - -// coef_t mod(const Relation &r, Variable_ID v, int dividend) { -// std::set<Variable_ID> working_on = std::set<Variable_ID>(); - -// return mod_(r, v, dividend, working_on); -// } - - - -//----------------------------------------------------------------------------- -// Generate mapping relation for permuation. -//----------------------------------------------------------------------------- -Relation permute_relation(const std::vector<int> &pi) { - const int n = pi.size(); - - Relation r(n, n); - F_And *f_root = r.add_and(); - - for (int i = 0; i < n; i++) { - EQ_Handle h = f_root->add_EQ(); - h.update_coef(r.output_var(i+1), 1); - h.update_coef(r.input_var(pi[i]+1), -1); - } - - return r; -} - - - -//--------------------------------------------------------------------------- -// Find the position index variable in a Relation by name. -//--------------------------------------------------------------------------- -Variable_ID find_index(Relation &r, const std::string &s, char side) { - // Omega quirks: assure the names are propagated inside the relation - r.setup_names(); - - if (r.is_set()) { // side == 's' - for (int i = 1; i <= r.n_set(); i++) { - std::string ss = r.set_var(i)->name(); - if (s == ss) { - return r.set_var(i); - } - } - } - else if (side == 'w') { - for (int i = 1; i <= r.n_inp(); i++) { - std::string ss = r.input_var(i)->name(); - if (s == ss) { - return r.input_var(i); - } - } - } - else { // side == 'r' - for (int i = 1; i <= r.n_out(); i++) { - std::string ss = r.output_var(i)->name(); - if (s+"'" == ss) { - return r.output_var(i); - } - } - } - - return NULL; -} - -// EQ_Handle get_eq(const Relation &r, int dim, Var_Kind type) { -// Variable_ID v; -// switch (type) { -// case Set_Var: -// v = r.set_var(dim+1); -// break; -// case Input_Var: -// v = r.input_var(dim+1); -// break; -// case Output_Var: -// v = r.output_var(dim+1); -// break; -// default: -// return NULL; -// } -// for (DNF_iterator di(r.query_DNF()); di; di++) -// for (EQ_Iterator ei = (*di)->EQs(); ei; ei++) -// if ((*ei).get_coef(v) != 0) -// return (*ei); - -// return NULL; -// } - - -// std::Pair<Relation, Relation> split_loop(const Relation &r, const Relation &cond) { -// Relation r1 = Intersection(copy(r), copy(cond)); -// Relation r2 = Intersection(copy(r), Complement(copy(cond))); - -// return std::Pair<Relation, Relation>(r1, r2); -// } |