summaryrefslogtreecommitdiff
path: root/src/omegatools.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/omegatools.cc')
-rw-r--r--src/omegatools.cc3007
1 files changed, 2543 insertions, 464 deletions
diff --git a/src/omegatools.cc b/src/omegatools.cc
index 3aac404..0322182 100644
--- a/src/omegatools.cc
+++ b/src/omegatools.cc
@@ -14,10 +14,15 @@
*****************************************************************************/
#include <code_gen/codegen.h>
+
#include "omegatools.hh"
#include "ir_code.hh"
#include "chill_error.hh"
+#include "chill_ast.hh"
+#include "code_gen/CG_chillRepr.h"
+#include <code_gen/CG_utils.h>
+
using namespace omega;
namespace {
@@ -41,471 +46,855 @@ std::string tmp_e() {
return std::string("e")+to_string(counter++);
}
-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) {
+
+
+//-----------------------------------------------------------------------------
+// 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,
+ std::map<std::string, std::vector<omega::CG_outputRepr *> > &uninterpreted_symbols,
+ std::map<std::string, std::vector<omega::CG_outputRepr *> > &uninterpreted_symbols_stringrepr
+ ) {
- 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");
+ fprintf(stderr, "\n*** exp2formula()\n");
+ //repr->dump(); /* printf("\n"); */fflush(stdout);
+ fprintf(stderr, "repr "); r.print(); printf("\n"); fflush(stdout);
+
+
+ IR_OPERATION_TYPE optype = ir->QueryExpOperation(repr);
+
+ switch (optype) {
- 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)
+
+
+
+ case IR_OP_CONSTANT:
+ {
+ fprintf(stderr, "IR_OP_CONSTANT\n");
+ 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
- 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);
+ throw std::invalid_argument("unsupported condition type");
+
+ delete v[0];
+ delete ref;
+ if (destroy)
+ delete repr;
+
+ break;
}
- 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;
+ {
+ fprintf(stderr, "IR_OP_VARIABLE\n");
+ //fprintf(stderr, "repr "); repr->dump(); fflush(stdout);
+ std::vector<CG_outputRepr *> v = ir->QueryExpOperand(repr);
+ //fprintf(stderr, "v "); v[0]->dump(); fflush(stdout);
+ IR_ScalarRef *ref = static_cast<IR_ScalarRef *>(ir->Repr2Ref(v[0]));
+
+ //fprintf(stderr, "omegatools.cc calling ref->name()\n");
+ std::string s = ref->name();
+ Variable_ID e = find_index(r, s, side);
+ //fprintf(stderr, "s %s\n", s.c_str());
+
+
+ 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 (t == NULL) {
- t = new Free_Var_Decl(s);
- freevars.insert(freevars.end(), 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");
- 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);
+ // delete v[0];
+ delete ref;
+ if (destroy)
+ delete repr;
+ break;
}
- else if (rel == IR_COND_EQ) {
- EQ_Handle h = f_root->add_EQ();
- h.update_coef(lhs, 1);
- h.update_coef(e, -1);
+
+ case IR_OP_ASSIGNMENT:
+ {
+ fprintf(stderr, "IR_OP_ASSIGNMENT\n");
+ std::vector<CG_outputRepr *> v = ir->QueryExpOperand(repr);
+ exp2formula(ir, r, f_root, freevars, v[0], lhs, side, rel, true,
+ uninterpreted_symbols, uninterpreted_symbols_stringrepr);
+ if (destroy)
+ delete repr;
+ break;
}
- 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);
+ {
+ fprintf(stderr, "IR_OP_PLUS\n");
+ 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,
+ uninterpreted_symbols, uninterpreted_symbols_stringrepr);
+ exp2formula(ir, r, f_and, freevars, v[1], e2, side, IR_COND_EQ, true,
+ uninterpreted_symbols, uninterpreted_symbols_stringrepr);
+ if (destroy)
+ delete repr;
+ break;
}
- 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);
+ {
+ fprintf(stderr, "IR_OP_MINUS\n");
+ 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);
+ fprintf(stderr, "IR_OP_MINUS v has %d parts\n", (int)v.size());
+ fprintf(stderr, "IR_OP_MINUS recursing 1\n");
+ exp2formula(ir, r, f_and, freevars, v[0], e1, side, IR_COND_EQ, true,
+ uninterpreted_symbols, uninterpreted_symbols_stringrepr);
+
+ if (v.size() > 1) {
+ fprintf(stderr, "IR_OP_MINUS recursing 2\n"); // dies here because it's unary minus?
+ exp2formula(ir, r, f_and, freevars, v[1], e2, side, IR_COND_EQ, true,
+ uninterpreted_symbols, uninterpreted_symbols_stringrepr);
+ }
+
+
+ if (destroy)
+ delete repr;
+ break;
}
- 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];
+ {
+ fprintf(stderr, "IR_OP_MULTIPLY\n");
+ 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,
+ uninterpreted_symbols, uninterpreted_symbols_stringrepr);
+ if (destroy)
+ delete repr;
+ break;
}
- else if (ir->QueryExpOperation(v[1]) == IR_OP_CONSTANT) {
+
+ case IR_OP_DIVIDE:
+ {
+ fprintf(stderr, "IR_OP_DIVIDE\n");
+ 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 = ref->integer();
+ coef_t 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();
+
+ 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(lhs, coef);
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());
+ 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(lhs, -coef);
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) {
+ 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,
+ uninterpreted_symbols, uninterpreted_symbols_stringrepr);
+ if (destroy)
+ delete repr;
+ break;
}
- 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();
+
+ case IR_OP_MOD:
+ {
+ fprintf(stderr, "IR_OP_MOD\n");
+ /* the left hand of a mod can be a var but the right must be a const */
+ 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());
+ Variable_ID b = f_exists->declare(tmp_e());
+ F_And *f_and = f_exists->add_and();
+
+
+ if (rel == IR_COND_EQ)
+ {
+ EQ_Handle h = f_and->add_EQ();
+ h.update_coef(lhs, 1);
+ h.update_coef(b, coef);
+ h.update_coef(e, -1);
+ }
+
+ else if (rel == IR_COND_GE || rel == IR_COND_GT) {
+ //i = CONST alpha + beta && beta >= const ( handled higher up ) && beta < CONST
+ EQ_Handle h = f_and->add_EQ();
+ h.update_coef(lhs, 1);
+ h.update_coef(b, coef);
+ h.update_coef(e, -1);
+ GEQ_Handle k = f_and->add_GEQ();
+ k.update_coef(lhs, -1 );
+ k.update_const(coef-1);
+
+ }
+
+ else if (rel == IR_COND_LE || rel == IR_COND_LT) {
+ //i = CONST alpha + beta && beta <= const ( handled higher up ) && beta >= 0
EQ_Handle h = f_and->add_EQ();
h.update_coef(lhs, 1);
+ h.update_coef(b, coef);
h.update_coef(e, -1);
- exp2formula(ir, r, f_and, freevars, v[i], e, side, IR_COND_EQ, false);
+ GEQ_Handle k = f_and->add_GEQ();
+ k.update_coef(lhs, 1 );
- 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];
+ exp2formula(ir, r, f_and, freevars, v[0], e, side, IR_COND_EQ, true,
+ uninterpreted_symbols, uninterpreted_symbols_stringrepr);
+ if (destroy)
+ delete repr;
+
+ break;
}
- 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();
+ case IR_OP_POSITIVE:
+ {
+ fprintf(stderr, "IR_OP_POSITIVE\n");
+ std::vector<CG_outputRepr *> v = ir->QueryExpOperand(repr);
+
+ exp2formula(ir, r, f_root, freevars, v[0], lhs, side, rel, true,
+ uninterpreted_symbols, uninterpreted_symbols_stringrepr);
+
+ if (destroy)
+ delete repr;
+ break;
+ }
+
- 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();
+ case IR_OP_NEGATIVE:
+ {
+ fprintf(stderr, "IR_OP_NEGATIVE\n");
+ 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(lhs, 1);
h.update_coef(e, 1);
- if (rel == IR_COND_LT)
+ 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_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());
+ 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(lhs, -1);
h.update_coef(e, -1);
- if (rel == IR_COND_GT)
+ 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();
-
+ else if (rel == IR_COND_EQ) {
EQ_Handle h = f_and->add_EQ();
h.update_coef(lhs, 1);
- h.update_coef(e, -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,
+ uninterpreted_symbols, uninterpreted_symbols_stringrepr);
+ if (destroy)
+ delete repr;
+ break;
+ }
+
+
+ case IR_OP_MIN:
+ {
+ fprintf(stderr, "IR_OP_MIN\n");
+ 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,
+ uninterpreted_symbols, uninterpreted_symbols_stringrepr);
+ }
+ }
+ 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,
+ uninterpreted_symbols, uninterpreted_symbols_stringrepr);
+ }
+ }
+ 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,
+ uninterpreted_symbols, uninterpreted_symbols_stringrepr);
+
+ 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,
+ uninterpreted_symbols, uninterpreted_symbols_stringrepr);
+ }
+ }
- exp2formula(ir, r, f_and, freevars, v[i], e, 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;
+ break;
+ }
+
+ case IR_OP_MAX:
+ {
+ fprintf(stderr, "IR_OP_MAX\n");
+ 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,
+ uninterpreted_symbols, uninterpreted_symbols_stringrepr);
+ }
+ }
+ 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,
+ uninterpreted_symbols, uninterpreted_symbols_stringrepr);
+
+ }
+ }
+ 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,
+ uninterpreted_symbols, uninterpreted_symbols_stringrepr);
+
+ 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,
+ uninterpreted_symbols, uninterpreted_symbols_stringrepr);
+ }
+ }
- 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");
- for (int i = 0; i < v.size(); i++)
- delete v[i];
+ if (destroy)
+ delete repr;
+ break;
}
- else
- throw std::invalid_argument("unsupported condition type");
- if (destroy)
- delete repr;
+ case IR_OP_ARRAY_VARIABLE: { // *****
+ fprintf(stderr, "\nomegatools.cc IR_OP_ARRAY_VARIABLE ARRAY! \n");
+
+ // temp for printing
+ //CG_chillRepr *CR = (CG_chillRepr *)repr;
+ //fprintf(stderr, "repr "); CR->dump(); fflush(stdout);
+
+ //fprintf(stderr, "repr "); repr->dump(); /* printf("\n"); */fflush(stdout);
+
+ std::vector<CG_outputRepr *> v = ir->QueryExpOperand(repr);
+ IR_Ref *ref = static_cast<IR_ScalarRef *>(ir->Repr2Ref(v[0]));
+
+
+ CG_chillRepr *CR = (CG_chillRepr *)v[0]; // cheat for now. we should not know this is a chillRepr
+ //fprintf(stderr, "v "); CR->dump(); fflush(stdout);
+ //fprintf(stderr, "v "); v[0]->dump(); /* printf("\n"); */ fflush(stdout);
+ chillAST_node* node = CR->GetCode();
+
+
+ //fprintf(stderr, "\n**** walking parents!\n");
+ //std::vector<chillAST_VarDecl*> loopvars;
+ //node->gatherLoopIndeces( loopvars );
+ //fprintf(stderr, "in omegatools, %d loop vars\n", (int)loopvars.size());
+
+
+ std::string s = ref->name();
+ //fprintf(stderr, "array variable s is %s\n", s.c_str());
+
+ int max_dim = 0;
+ bool need_new_fsymbol = false;
+ std::set<std::string> vars;
+ //fprintf(stderr, "ref->n_dim %d\n", ref->n_dim());
+ for (int i = 0; i < ref->n_dim(); i++) {
+ //fprintf(stderr, "dimension %d\n", i);
+ Relation temp(r.n_inp());
+
+ // r is enclosing relation, we build another that will include this
+ r.setup_names();
+ if (r.is_set())
+ for (int j = 1; j <= r.n_set(); j++) {
+ temp.name_set_var(j, r.set_var(j)->name());
+ }
+ else
+ for (int j = 1; j <= r.n_inp(); j++) {
+ temp.name_input_var(j, r.input_var(j)->name());
+ }
+
+ F_And *temp_root = temp.add_and();
+
+ CG_outputRepr* repr;
+ if(dynamic_cast<IR_PointerArrayRef *>(ref) != NULL)
+ repr = dynamic_cast<IR_PointerArrayRef *>(ref)->index(i); // i or i+1
+ else if(dynamic_cast<IR_ArrayRef *>(ref) != NULL)
+ repr = dynamic_cast<IR_ArrayRef *>(ref)->index(i);
+
+ std::vector<Free_Var_Decl*> freevars;
+ Free_Var_Decl *t = new Free_Var_Decl(s);
+ Variable_ID e = temp.get_local(t);
+ freevars.insert(freevars.end(), t);
+
+ fprintf(stderr, "exp2formula recursing? \n");
+ exp2formula(ir, temp, temp_root, freevars, repr, e, side,
+ IR_COND_EQ, false, uninterpreted_symbols,
+ uninterpreted_symbols_stringrepr);
+ fprintf(stderr, "BACK FROM exp2formula recursing? \n");
+
+ // temp is relation for the index of the array ??
+ for (DNF_Iterator di(temp.query_DNF()); di; di++) {
+ for (EQ_Iterator ei = (*di)->EQs(); ei; ei++) {
+
+ if ((*ei).get_const() != 0)
+ need_new_fsymbol = true;
+ for (Constr_Vars_Iter cvi(*ei); cvi; cvi++)
+ if ((*cvi).var->kind() == Input_Var) {
+ if ((*cvi).var->get_position() > max_dim)
+ max_dim = (*cvi).var->get_position();
+ vars.insert(
+ r.input_var((*cvi).var->get_position())->name());
+
+ }
+ }
+
+ }
+
+ if (max_dim != ref->n_dim())
+ need_new_fsymbol = true;
+ }
+
+ //fprintf(stderr, "%d vars: ", (int)vars.size());
+ //for (int i=0; i<vars.size(); i++) fprintf(stderr, "%s", vars[i].c_str());
+ //for (std::set<std::string>::iterator it = vars.begin(); it != vars.end(); it++) {
+ // fprintf(stderr, "%s ", (*it).c_str());
+ //}
+ //fprintf(stderr, "\n");
+
+ // r is enclosing relation, we build another that will include
+ Variable_ID e = find_index(r, s, side); // s is the array named "index"
+
+ std::vector<chillAST_node*> internals = ((CG_chillRepr *)v[0])->getChillCode();
+ int numnodes = internals.size(); // always 1?
+ std::vector<chillAST_DeclRefExpr *>dres;
+ std::vector<chillAST_VarDecl*> decls;
+ std::vector<chillAST_VarDecl*> sdecls;
+ for (int i=0; i<numnodes; i++) {
+ internals[i]->gatherScalarVarDecls(sdecls); // vardecls for scalars
+ }
+
+ //fprintf(stderr, "%d scalar var decls()\n", sdecls.size());
+ //for (int i=0; i<sdecls.size(); i++) {
+ // fprintf(stderr, "vardecl %2d: ", i);
+ // sdecls[i]->print(); printf("\n"); fflush(stdout);
+ //}
+
+
+ //fprintf(stderr, "omegatools.cc, exp2formula() NOW WHAT\n");
+ //exit(0);
+
+ if (e == NULL) { // s must be a free variable
+ //fprintf(stderr, "'%s' must be free variable\n\n", s.c_str());
+ //fprintf(stderr, "SO WE WILL CREATE A MACRO ???\n");
+
+ Free_Var_Decl *t = NULL;
+
+ // keep adding underscores until we have created a unique name based on the original
+ do {
+ s += "_";
+ t = NULL;
+ for (unsigned i = 0; i < freevars.size(); i++) {
+ std::string ss = freevars[i]->base_name();
+
+ if (s == ss) {
+ t = freevars[i];
+ break;
+ }
+ }
+ } while (t != NULL);
+
+ if (!need_new_fsymbol)
+ t = new Free_Var_Decl(s, ref->n_dim());
+ else
+ t = new Free_Var_Decl(s, max_dim);
+ freevars.insert(freevars.end(), t); // add index_____ to freevars
+
+
+ std::vector< std::string > Vargs; // vector of args
+ std::string args;
+ std::vector<omega::CG_outputRepr *> reprs;
+ std::vector<omega::CG_outputRepr *> reprs2;
+ for (std::set<std::string>::iterator it = vars.begin();
+ it != vars.end(); it++) {
+ if (it == vars.begin())
+ args += "(";
+ else
+ args += ",";
+ args += *it;
+ //fprintf(stderr, "an argument to the macro: %s\n", it->c_str());
+ Vargs.push_back( (*it) );
+ reprs.push_back(ir->builder()->CreateIdent(*it));
+ reprs2.push_back(ir->builder()->CreateIdent(*it));
+ }
+ args += ")";
+
+ //fprintf(stderr, "args '%s'\n", args.c_str());
+ //fprintf(stderr, "Vargs ");
+ //for (int i=0; i<Vargs.size(); i++) fprintf(stderr, "%s ",Vargs[i].c_str());
+ //fprintf(stderr, "\n");
+
+ //fprintf(stderr, "omegatools.cc ir->CreateDefineMacro( s (%s), args(%s), repr)\n", s.c_str(), args.c_str());
+
+ // TODO repr, the rhs of the macro, needs to NOT refer to an actual variable ???
+
+
+ ir->CreateDefineMacro(s, Vargs, repr);
+
+
+
+ // index_(i) uses i outputrepr
+ //fprintf(stderr,"omegatools.cc making uninterpreted symbol %s\n",s.c_str());
+ uninterpreted_symbols.insert( // adding to uninterpreted_symbols
+ std::pair<std::string, std::vector<omega::CG_outputRepr *> >(
+ s, reprs));
+ uninterpreted_symbols_stringrepr.insert( // adding to uninterpreted_symbols_stringrepr
+ std::pair<std::string, std::vector<omega::CG_outputRepr *> >(s, reprs2));
+
+
+ e = r.get_local(t, Input_Tuple);
+
+ 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;
+
+ //fprintf(stderr, "FINALLY DONE with IR_OP_ARRAY_VARIABLE\n\n");
+ break;
}
- case IR_OP_NULL:
+
+
+ case IR_OP_NULL:
+ fprintf(stderr, "IR_OP_NULL\n");
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) {
+ const IR_ArrayRef *ref_dst, const Relation &IS_r,
+ std::map<std::string, std::vector<omega::CG_outputRepr *> > &uninterpreted_symbols,
+ std::map<std::string, std::vector<omega::CG_outputRepr *> > &uninterpreted_symbols_stringrepr) {
+
+ //fprintf(stderr, "arrays2relation()\n");
+ //fprintf(stderr, "%d freevars\n", freevars.size());
+ //for (int i=0; i<freevars.size(); i++) fprintf(stderr, "freevar %d %s\n", i, (const char *)(freevars[i]->base_name()));
+
+
Relation &IS1 = const_cast<Relation &>(IS_w);
Relation &IS2 = const_cast<Relation &>(IS_r);
+ //Relation *helper;
+ //helper = new Relation(IS1); fprintf(stderr, "IS1 "); helper->print(); fflush(stdout);
+ //helper = new Relation(IS2); fprintf(stderr, "IS2 "); helper->print(); fflush(stdout);
+
Relation r(IS1.n_set(), IS2.n_set());
+ //helper = new Relation(r); fprintf(stderr, "r "); helper->print(); fflush(stdout);
for (int i = 1; i <= IS1.n_set(); i++)
r.name_input_var(i, IS1.set_var(i)->name());
@@ -513,9 +902,25 @@ Relation arrays2relation(IR_Code *ir, std::vector<Free_Var_Decl*> &freevars,
for (int i = 1; i <= IS2.n_set(); i++)
r.name_output_var(i, IS2.set_var(i)->name()+"'");
+ //fprintf(stderr, "omegatools.cc sym_src\n");
IR_Symbol *sym_src = ref_src->symbol();
IR_Symbol *sym_dst = ref_dst->symbol();
+ //fprintf(stderr, "omegatools.cc going to do IR_Symbol operator==\n");
+ //fprintf(stderr, "omegatools.cc comparing symbol 0x%x to symbol 0x%x\n", sym_src, sym_dst);
+
+ //if (!(*sym_src == *sym_dst)) fprintf(stderr, "!(*sym_src == *sym_dst)\n");
+
+ //fprintf(stderr, "calling !=\n");
+ //if (*sym_src != *sym_dst) fprintf(stderr, "omegatools.cc (*sym_src != *sym_dst) TRUE\n");
+ //else fprintf(stderr, "omegatools.cc (*sym_src != *sym_dst) FALSE\n");
+
+ //fprintf(stderr, "calling ==\n");
+ //if ((*sym_src == *sym_dst)) fprintf(stderr, "(*sym_src == *sym_dst)) TRUE \n");
+ //else fprintf(stderr, "(*sym_src == *sym_dst) FALSE \n");
+
if (*sym_src != *sym_dst) {
+ //if (!(*sym_src == *sym_dst)) {
+ //fprintf(stderr, "False Relation\n");
r.add_or(); // False Relation
delete sym_src;
delete sym_dst;
@@ -526,9 +931,13 @@ Relation arrays2relation(IR_Code *ir, std::vector<Free_Var_Decl*> &freevars,
delete sym_dst;
}
+ //fprintf(stderr, "f_root\n");
F_And *f_root = r.add_and();
+ //fprintf(stderr, "omegatools.cc ref_src->n_dim() %d\n", ref_src->n_dim());
for (int i = 0; i < ref_src->n_dim(); i++) {
+ //fprintf(stderr, "arrays2 i %d\n", 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());
@@ -538,20 +947,29 @@ Relation arrays2relation(IR_Code *ir, std::vector<Free_Var_Decl*> &freevars,
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) {
+
+ if (ir->QueryExpOperation(repr_src) == IR_OP_ARRAY_VARIABLE
+ || ir->QueryExpOperation(repr_dst) == IR_OP_ARRAY_VARIABLE)
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);
+
+ try {
+ exp2formula(ir, r, f_and, freevars, repr_src, e1, 'w', IR_COND_EQ, false,
+ uninterpreted_symbols, uninterpreted_symbols_stringrepr);
+ exp2formula(ir, r, f_and, freevars, repr_dst, e2, 'r', IR_COND_EQ, false,
+ uninterpreted_symbols, uninterpreted_symbols_stringrepr);
+ }
+ 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;
@@ -566,32 +984,61 @@ Relation arrays2relation(IR_Code *ir, std::vector<Free_Var_Decl*> &freevars,
for (int i = 1; i <= IS2.n_set(); i++)
r.name_output_var(i, IS2.set_var(i)->name()+"'");
+ //helper = new Relation(r); fprintf(stderr, "r "); helper->print(); fflush(stdout);
+ //fprintf(stderr, "leaving arrays2relation\n");
return r;
}
-std::pair<std::vector<DependenceVector>, std::vector<DependenceVector> > relation2dependences (const IR_ArrayRef *ref_src, const IR_ArrayRef *ref_dst, const Relation &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) {
+ //fprintf(stderr, "relation2dependences()\n");
assert(r.n_inp() == r.n_out());
std::vector<DependenceVector> dependences1, dependences2;
+ //std::vector<DependenceVector*> dep1, dep2;
std::stack<DependenceLevel> working;
working.push(DependenceLevel(r, r.n_inp()));
while (!working.empty()) {
+ //fprintf(stderr, "!empty size %d\n", working.size());
+
DependenceLevel dep = working.top();
working.pop();
+ //if (!dep.r.is_satisfiable()) fprintf(stderr, "NOT dep.r.is_satisfiable()\n");
+ //else fprintf(stderr, " dep.r.is_satisfiable()\n");
+
// No dependence exists, move on.
- if (!dep.r.is_satisfiable())
+ if (!dep.r.is_satisfiable()) {
+ //fprintf(stderr, "No dependence exists, move on.\n");
continue;
+ }
+ //fprintf(stderr, "satisfiable\n");
+ //fprintf(stderr, "dep.level %d r.n_inp() %d\n", dep.level, r.n_inp());
if (dep.level == r.n_inp()) {
+ //fprintf(stderr, "dep.level == r.n_inp()\n");
DependenceVector dv;
+ //fprintf(stderr, "\ndv created in if ***\n");
+ //DependenceVector *dv2 = new DependenceVector;
+
+ //fprintf(stderr, "for loop independent dependence dep.dir %d\n", dep.dir);
// for loop independent dependence, use lexical order to
// determine the correct source and destination
if (dep.dir == 0) {
- if (*ref_src == *ref_dst)
+ //fprintf(stderr, "dep.dir == 0\n");
+ if (*ref_src == *ref_dst) { // c == c
+ //fprintf(stderr, "trivial\n");
continue; // trivial self zero-dependence
+ }
if (ref_src->is_write()) {
if (ref_dst->is_write())
@@ -608,6 +1055,7 @@ std::pair<std::vector<DependenceVector>, std::vector<DependenceVector> > relatio
}
else if (dep.dir == 1) {
+ //fprintf(stderr, "dep.dir == 1\n");
if (ref_src->is_write()) {
if (ref_dst->is_write())
dv.type = DEP_W2W;
@@ -622,6 +1070,7 @@ std::pair<std::vector<DependenceVector>, std::vector<DependenceVector> > relatio
}
}
else { // dep.dir == -1
+ //fprintf(stderr, "dep.dir == -1\n");
if (ref_dst->is_write()) {
if (ref_src->is_write())
dv.type = DEP_W2W;
@@ -638,27 +1087,74 @@ std::pair<std::vector<DependenceVector>, std::vector<DependenceVector> > relatio
dv.lbounds = dep.lbounds;
dv.ubounds = dep.ubounds;
+
+ //fprintf(stderr, "omegatools.cc calling ref_src->symbol();\n");
dv.sym = ref_src->symbol();
+ //fprintf(stderr, "dv.sym = %p\n", dv.sym);
+
+ //fprintf(stderr, "symbol %s ADDING A DEPENDENCE OF TYPE ", dv.sym->name().c_str());
+ //switch (dv.type) {
+ //case DEP_W2W: fprintf(stderr, "DEP_W2W to "); break;
+ //case DEP_W2R: fprintf(stderr, "DEP_W2R to "); break;
+ //case DEP_R2W: fprintf(stderr, "DEP_R2W to "); break;
+ //case DEP_R2R: fprintf(stderr, "DEP_R2R to "); break;
+ //default: fprintf(stderr, "DEP_UNKNOWN to "); break;
+ //}
+ //if (dep.dir == 0 || dep.dir == 1) fprintf(stderr, "dependences1\n");
+ //else fprintf(stderr, "dependences2\n");
- if (dep.dir == 0 || dep.dir == 1)
+ if (dep.dir == 0 || dep.dir == 1) {
+ //fprintf(stderr, "pushing dv\n");
dependences1.push_back(dv);
- else
+ //fprintf(stderr, "DONE pushing dv\n");
+
+ //fprintf(stderr, "now %d dependences1\n", dependences1.size() );
+ //for (int i=0; i<dependences1.size(); i++) {
+ // fprintf(stderr, "dependences1[%d]: ", i );
+ // //fprintf(stderr, "symbol %p ", dependences1[i].sym);
+ // fprintf(stderr, "symbol ");
+ // fprintf(stderr, "%s\n", dependences1[i].sym->name().c_str());
+ //}
+ //fprintf(stderr, "\n");
+ }
+ else {
+ //fprintf(stderr, "pushing dv\n");
dependences2.push_back(dv);
+ //fprintf(stderr, "DONE pushing dv\n");
+
+ //fprintf(stderr, "now %d dependences2\n", dependences2.size() );
+ //for (int i=0; i<dependences2.size(); i++) {
+ // fprintf(stderr, "dependences2[%d]: ", i);
+ // //fprintf(stderr, "symbol %p ", dependences2[i].sym);
+ // fprintf(stderr, "symbol ");
+ // fprintf(stderr, "%s\n", dependences2[i].sym->name().c_str());
+ //}
+ //fprintf(stderr, "\n");
+ }
+
+ //fprintf(stderr, "dv goes out of scope ***\n");
}
else {
+ //fprintf(stderr, "now work on the next dimension level\n");
// now work on the next dimension level
int level = ++dep.level;
+ //fprintf(stderr, "level %d\n", level);
coef_t lbound, ubound;
Relation delta = Deltas(copy(dep.r));
+ //delta.print(); fflush(stdout);
delta.query_variable_bounds(delta.set_var(level), lbound, ubound);
+ //fprintf(stderr, "delta lb " coef_fmt " 0x%llx ub " coef_fmt " 0x%llx\n", lbound,lbound,ubound,ubound);
+
if (dep.dir == 0) {
+ //fprintf(stderr, "dep.dir == 0\n");
if (lbound > 0) {
dep.dir = 1;
dep.lbounds[level-1] = lbound;
dep.ubounds[level-1] = ubound;
+ //fprintf(stderr, "push 1\n");
working.push(dep);
}
else if (ubound < 0) {
@@ -666,6 +1162,7 @@ std::pair<std::vector<DependenceVector>, std::vector<DependenceVector> > relatio
dep.lbounds[level-1] = -ubound;
dep.ubounds[level-1] = -lbound;
+ //fprintf(stderr, "push 2\n");
working.push(dep);
}
else {
@@ -683,10 +1180,16 @@ std::pair<std::vector<DependenceVector>, std::vector<DependenceVector> > relatio
h.update_coef(dep2.r.input_var(level), 1);
h.update_coef(dep2.r.output_var(level), -1);
+ //fprintf(stderr, "push 3\n");
working.push(dep2);
}
- if (lbound < 0 && *ref_src != *ref_dst) {
+ //fprintf(stderr, "lbound %lld 0x%llx\n", lbound, lbound);
+ //if (lbound < 0LL) fprintf(stderr, "lbound < 0LL\n");
+ //if (*ref_src != *ref_dst) fprintf(stderr, "(*ref_src != *ref_dst)\n");
+ //else fprintf(stderr, "(*ref_src EQUAL *ref_dst)\n");
+
+ if (lbound < 0LL && (*ref_src != *ref_dst)) { // c == c
DependenceLevel dep2 = dep;
F_And *f_root = dep2.r.and_with_and();
@@ -702,12 +1205,14 @@ std::pair<std::vector<DependenceVector>, std::vector<DependenceVector> > relatio
lbound, ubound);
dep2.dir = -1;
- dep2.lbounds[level-1] = max(-ubound,static_cast<coef_t>(1)); // use max() to avoid Omega retardness
+ dep2.lbounds[level-1] = std::max(-ubound,static_cast<coef_t>(1)); // use max() to avoid Omega retardedness
dep2.ubounds[level-1] = -lbound;
+ //fprintf(stderr, "push 4\n");
working.push(dep2);
}
+ //fprintf(stderr, "ubound %d\n", ubound);
if (ubound > 0) {
DependenceLevel dep2 = dep;
@@ -723,9 +1228,10 @@ std::pair<std::vector<DependenceVector>, std::vector<DependenceVector> > relatio
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.lbounds[level-1] = std::max(lbound,static_cast<coef_t>(1)); // use max() to avoid Omega retardness
dep2.ubounds[level-1] = ubound;
+ //fprintf(stderr, "push 5\n");
working.push(dep2);
}
}
@@ -733,6 +1239,7 @@ std::pair<std::vector<DependenceVector>, std::vector<DependenceVector> > relatio
// now deal with dependence vector with known direction
// determined at previous levels
else {
+ //fprintf(stderr, "else messy\n");
// 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) {
@@ -788,59 +1295,167 @@ std::pair<std::vector<DependenceVector>, std::vector<DependenceVector> > relatio
dep.ubounds[level-1] = ubound;
}
+ //fprintf(stderr, "push 6\n");
working.push(dep);
}
}
+ //fprintf(stderr, "at bottom, size %d\n", working.size());
+
}
+ //fprintf(stderr, "leaving relation2dependences, %d and %d dependences\n", dependences1.size(), dependences2.size());
+
+
+ //for (int i=0; i<dependences1.size(); i++) {
+ //fprintf(stderr, "dependences1[%d]: ", i);
+ //fprintf(stderr, "symbol %s\n", dependences1[i].sym->name().c_str());
+
+ //fprintf(stderr, "symbol %s HAS A left DEPENDENCE OF TYPE ", dependences1[i].sym->name().c_str());
+ //switch (dependences1[i].type) {
+ //case DEP_W2W: fprintf(stderr, "DEP_W2W\n"); break;
+ //case DEP_W2R: fprintf(stderr, "DEP_W2R\n"); break;
+ //case DEP_R2W: fprintf(stderr, "DEP_R2W\n"); break;
+ //case DEP_R2R: fprintf(stderr, "DEP_R2R\n"); break;
+ //default: fprintf(stderr, "DEP_UNKNOWN\n"); break;
+ //}
+ //}
+
+
+ //for (int i=0; i<dependences2.size(); i++) {
+
+ //fprintf(stderr, "symbol %s HAS A right DEPENDENCE OF TYPE ", dependences2[i].sym->name().c_str());
+ //switch (dependences2[i].type) {
+ //case DEP_W2W: fprintf(stderr, "DEP_W2W\n"); break;
+ //case DEP_W2R: fprintf(stderr, "DEP_W2R\n"); break;
+ //case DEP_R2W: fprintf(stderr, "DEP_R2W\n"); break;
+ //case DEP_R2R: fprintf(stderr, "DEP_R2R\n"); break;
+ //default: fprintf(stderr, "DEP_UNKNOWN\n"); break;
+ //}
+ //}
+
+
+
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) {
+ CG_outputRepr *repr,
+ bool destroy,
+ std::map<std::string, std::vector<omega::CG_outputRepr *> > &uninterpreted_symbols,
+ std::map<std::string, std::vector<omega::CG_outputRepr *> > &uninterpreted_symbols_stringrepr)
+{
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;
- }
+ 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,
+ uninterpreted_symbols, uninterpreted_symbols_stringrepr);
+ exp2formula(ir, r, f_and, freevars, op[1], e, 's', cond, true,
+ uninterpreted_symbols, uninterpreted_symbols_stringrepr);
+
+ 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,
+ uninterpreted_symbols, uninterpreted_symbols_stringrepr);
+ exp2formula(ir, r, f_and, freevars, op[1], e, 's', IR_COND_GT, false,
+ uninterpreted_symbols, uninterpreted_symbols_stringrepr);
+
+ f_and = f_or->add_and();
+ exp2formula(ir, r, f_and, freevars, op[0], e, 's', IR_COND_EQ, true,
+ uninterpreted_symbols, uninterpreted_symbols_stringrepr);
+ exp2formula(ir, r, f_and, freevars, op[1], e, 's', IR_COND_LT, true,
+ uninterpreted_symbols, uninterpreted_symbols_stringrepr);
+
+ if (destroy)
+ delete repr;
+ break;
+ }
default:
throw ir_exp_error("unrecognized conditional expression");
}
}
-bool is_single_loop_iteration(const Relation &r, int level, const Relation &known) {
+
+
+
+
+//-----------------------------------------------------------------------------
+// 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
+// }
+// }
+
+
+
+
+//-----------------------------------------------------------------------------
+// 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 r1;
+ if(n > known.n_set()) {
+ r1 = Intersection(copy(r), Extend_Set(copy(known), n - known.n_set()));
+ }
+ else{
+ r1 = Intersection(copy(known), Extend_Set(copy(r), known.n_set() - n));
+ n = known.n_set();
+ }
+
Relation mapping(n, n);
F_And *f_root = mapping.add_and();
@@ -869,6 +1484,8 @@ bool is_single_loop_iteration(const Relation &r, int level, const Relation &know
}
+
+
bool is_single_iteration(const Relation &r, int dim) {
assert(r.is_set());
const int n = r.n_set();
@@ -878,6 +1495,11 @@ bool is_single_iteration(const Relation &r, int dim) {
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++)
@@ -891,8 +1513,78 @@ bool is_single_iteration(const Relation &r, int dim) {
}
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();
@@ -917,10 +1609,14 @@ void assign_const(Relation &r, int dim, int val) {
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;
@@ -939,10 +1635,19 @@ int get_const(const Relation &r, int dim, Var_Kind type) {
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++) {
@@ -959,9 +1664,20 @@ Relation get_loop_bound(const Relation &r, int dim) {
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()));
+ int n1 = r.n_set();
+ int n = n1;
+ Relation r1;
+ if(n > known.n_set())
+ r1 = Intersection(copy(r),
+ Extend_Set(copy(known), n - known.n_set()));
+ else{
+ r1 = Intersection(copy(known),
+ Extend_Set(copy(r), known.n_set() - n));
+ n = known.n_set();
+ }
Relation mapping(n, n);
F_And *f_root = mapping.add_and();
@@ -974,7 +1690,7 @@ Relation get_loop_bound(const Relation &r, int level, const Relation &known) {
Relation r2 = Project(copy(r1), level, Set_Var);
r1 = Gist(r1, r2, 1);
- for (int i = 1; i <= n; i++)
+ for (int i = 1; i <= n1; i++)
r1.name_set_var(i, const_cast<Relation &>(r).set_var(i)->name());
r1.setup_names();
@@ -1017,6 +1733,12 @@ Relation get_min_loop_bound(const std::vector<Relation> &r, int dim) {
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_);
@@ -1042,30 +1764,32 @@ void add_loop_stride(Relation &r, const Relation &bound_, int dim, int stride) {
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);
+ 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 {
- h1.update_coef(r.set_var(pos), (*ci).coef);
- h2.update_coef(r.set_var(pos), (*ci).coef);
- }
+ 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;
}
- 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;
}
@@ -1078,8 +1802,18 @@ void add_loop_stride(Relation &r, const Relation &bound_, int dim, int stride) {
}
-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()));
+bool is_inner_loop_depend_on_level(const Relation &r,
+ int level,
+ const Relation &known) {
+
+ Relation r1;
+ if(r.n_set() > known.n_set())
+ r1 = Intersection(copy(r),
+ Extend_Set(copy(known), r.n_set() - known.n_set()));
+ else
+ r1 = Intersection(copy(known),
+ Extend_Set(copy(r), known.n_set() - r.n_set()));
+
Relation r2 = copy(r1);
for (int i = level+1; i <= r2.n_set(); i++)
r2 = Project(r2, r2.set_var(i));
@@ -1100,6 +1834,15 @@ bool is_inner_loop_depend_on_level(const Relation &r, int level, const Relation
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);
@@ -1136,6 +1879,236 @@ Relation adjust_loop_bound(const Relation &r, int level, int adjustment) {
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();
@@ -1151,6 +2124,11 @@ Relation permute_relation(const std::vector<int> &pi) {
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();
@@ -1183,3 +2161,1104 @@ Variable_ID find_index(Relation &r, const std::string &s, char side) {
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);
+// }
+
+
+
+//----------------------------------------------------------------------------
+//check if loop is normalized to zero
+//----------------------------------------------------------------------------
+bool lowerBoundIsZero(const omega::Relation &bound, int dim) {
+ Relation &IS = const_cast<Relation &>(bound);
+ Variable_ID v = IS.input_var(dim);
+ bool found = false;
+ for (DNF_Iterator di(IS.query_DNF()); di; di++) {
+ bool is_single = false;
+ for (GEQ_Iterator gi((*di)->GEQs()); gi; gi++)
+ if ((*gi).get_coef(v) >= 0 && !(*gi).is_const(v)
+ && (*gi).get_const() != 0) {
+ return false;
+ }
+ else if ((*gi).get_coef(v) >= 0 && (*gi).is_const(v)
+ && (*gi).get_const() == 0)
+ found = true;
+ }
+
+ return found;
+}
+
+
+
+Relation replicate_IS_and_add_bound(const omega::Relation &R, int level,
+ omega::Relation &bound) {
+
+ if (!R.is_set())
+ throw std::invalid_argument("Input R has to be a set not a relation!");
+
+ Relation r(R.n_set());
+
+ for (int i = 1; i <= R.n_set(); i++) {
+ r.name_set_var(i + 1, const_cast<Relation &>(R).set_var(i)->name());
+ }
+
+ std::string new_var = bound.set_var(1)->name();
+
+ r.name_set_var(level, new_var);
+
+ F_Exists *f_exists = r.add_and()->add_exists();
+ F_And *f_root = f_exists->add_and();
+ std::map<Variable_ID, Variable_ID> exists_mapping;
+
+ for (DNF_Iterator di(const_cast<Relation &>(R).query_DNF()); di; di++) {
+ for (GEQ_Iterator gi((*di)->GEQs()); gi; gi++) {
+ GEQ_Handle h = f_root->add_GEQ();
+
+ for (Constr_Vars_Iter cvi(*gi); cvi; cvi++) {
+ Variable_ID v = cvi.curr_var();
+ switch (v->kind()) {
+ case Input_Var:
+
+ h.update_coef(r.input_var(v->get_position()),
+ cvi.curr_coef());
+
+ break;
+ case Wildcard_Var:
+ {
+ Variable_ID v2 = replicate_floor_definition(R, v, r,
+ f_exists, f_root, exists_mapping);
+ h.update_coef(v2, cvi.curr_coef());
+ break;
+ }
+ case Global_Var:
+ {
+ Global_Var_ID g = v->get_global_var();
+ Variable_ID v2;
+ if (g->arity() == 0)
+ v2 = r.get_local(g);
+ else
+ v2 = r.get_local(g, v->function_of());
+ h.update_coef(v2, cvi.curr_coef());
+ break;
+ }
+ default:
+ assert(false);
+ }
+ }
+ h.update_const((*gi).get_const());
+ }
+ }
+
+ for (DNF_Iterator di(const_cast<Relation &>(R).query_DNF()); di; di++) {
+ for (EQ_Iterator gi((*di)->EQs()); gi; gi++) {
+ EQ_Handle h1 = f_root->add_EQ();
+
+ for (Constr_Vars_Iter cvi(*gi); cvi; cvi++) {
+ Variable_ID v = cvi.curr_var();
+ switch (v->kind()) {
+ case Input_Var:
+
+ h1.update_coef(r.input_var(v->get_position()),
+ cvi.curr_coef());
+
+ break;
+ case Wildcard_Var:
+ {
+ Variable_ID v2 = replicate_floor_definition(R, v, r,
+ f_exists, f_root, exists_mapping);
+ h1.update_coef(v2, cvi.curr_coef());
+ break;
+ }
+ case Global_Var:
+ {
+ Global_Var_ID g = v->get_global_var();
+ Variable_ID v2;
+ if (g->arity() == 0)
+ v2 = r.get_local(g);
+ else
+ v2 = r.get_local(g, v->function_of());
+ h1.update_coef(v2, cvi.curr_coef());
+ break;
+ }
+ default:
+ assert(false);
+ }
+ }
+ h1.update_const((*gi).get_const());
+ }
+ }
+
+ for (DNF_Iterator di(bound.query_DNF()); di; di++) {
+ for (GEQ_Iterator gi((*di)->GEQs()); gi; gi++) {
+ GEQ_Handle h = f_root->add_GEQ();
+ for (Constr_Vars_Iter cvi(*gi); cvi; cvi++) {
+ Variable_ID v = cvi.curr_var();
+ switch (v->kind()) {
+ case Input_Var:
+
+ h.update_coef(r.input_var(level), cvi.curr_coef());
+
+ break;
+ case Wildcard_Var:
+ {
+ Variable_ID v2 = replicate_floor_definition(R, v, r,
+ f_exists, f_root, exists_mapping);
+ h.update_coef(v2, cvi.curr_coef());
+ break;
+ }
+ case Global_Var:
+ {
+ Global_Var_ID g = v->get_global_var();
+ Variable_ID v2;
+ if (g->arity() == 0)
+ v2 = r.get_local(g);
+ else
+ v2 = r.get_local(g, v->function_of());
+ h.update_coef(v2, cvi.curr_coef());
+ break;
+ }
+ default:
+ assert(false);
+ }
+ }
+ h.update_const((*gi).get_const());
+ }
+ }
+
+ for (DNF_Iterator di(bound.query_DNF()); di; di++) {
+ for (EQ_Iterator gi((*di)->EQs()); gi; gi++) {
+ EQ_Handle h = f_root->add_EQ();
+ for (Constr_Vars_Iter cvi(*gi); cvi; cvi++) {
+ Variable_ID v = cvi.curr_var();
+ switch (v->kind()) {
+ case Input_Var:
+ h.update_coef(r.input_var(level), cvi.curr_coef());
+
+ break;
+ case Wildcard_Var:
+ {
+ Variable_ID v2 = replicate_floor_definition(R, v, r,
+ f_exists, f_root, exists_mapping);
+ h.update_coef(v2, cvi.curr_coef());
+ break;
+ }
+ case Global_Var:
+ {
+ Global_Var_ID g = v->get_global_var();
+ Variable_ID v2;
+ if (g->arity() == 0)
+ v2 = r.get_local(g);
+ else
+ v2 = r.get_local(g, v->function_of());
+ h.update_coef(v2, cvi.curr_coef());
+ break;
+ }
+ default:
+ assert(false);
+ }
+ }
+ h.update_const((*gi).get_const());
+ }
+ }
+ r.simplify();
+ r.setup_names();
+ return r;
+}
+
+
+
+
+// Replicates old_relation's bounds for set var at old_pos int o new_relation at new_pos, but position's bounds must involve constants
+// only supports GEQs
+//
+Relation replace_set_var_as_another_set_var(const omega::Relation &new_relation,
+ const omega::Relation &old_relation, int new_pos, int old_pos) {
+
+ Relation r = copy(new_relation);
+ r.copy_names(new_relation);
+ r.setup_names();
+
+ F_Exists *f_exists = r.and_with_and()->add_exists();
+ F_And *f_root = f_exists->add_and();
+ std::map<Variable_ID, Variable_ID> exists_mapping;
+
+ for (DNF_Iterator di(const_cast<Relation &>(old_relation).query_DNF()); di;
+ di++)
+ for (GEQ_Iterator gi((*di)->GEQs()); gi; gi++) {
+ GEQ_Handle h = f_root->add_GEQ();
+ if (((*gi).get_coef(
+ const_cast<Relation &>(old_relation).set_var(old_pos)) != 0)
+ && (*gi).is_const_except_for_global(
+ const_cast<Relation &>(old_relation).set_var(
+ old_pos))) {
+ for (Constr_Vars_Iter cvi(*gi); cvi; cvi++) {
+ Variable_ID v = cvi.curr_var();
+ switch (v->kind()) {
+ case Input_Var:
+ {
+
+ if (v->get_position() == old_pos)
+ h.update_coef(r.input_var(new_pos),
+ cvi.curr_coef());
+ else
+ throw omega_error(
+ "relation contains set vars other than that to be replicated!");
+ break;
+
+ }
+ case Wildcard_Var:
+ {
+ Variable_ID v2 = replicate_floor_definition(
+ old_relation, v, r, f_exists, f_root,
+ exists_mapping);
+ h.update_coef(v2, cvi.curr_coef());
+ break;
+ }
+ case Global_Var:
+ {
+ Global_Var_ID g = v->get_global_var();
+ Variable_ID v2;
+ if (g->arity() == 0)
+ v2 = r.get_local(g);
+ else
+ v2 = r.get_local(g, v->function_of());
+ h.update_coef(v2, cvi.curr_coef());
+ break;
+ }
+ default:
+ assert(false);
+ }
+ }
+ h.update_const((*gi).get_const());
+ }
+ }
+ return r;
+
+}
+
+
+
+
+
+//-----------------------------------------------------------------------------
+// Copy all relations from r and add new bound at position indicated by level.
+// -----------------------------------------------------------------------------
+
+Relation replicate_IS_and_add_at_pos(const omega::Relation &R, int level,
+ omega::Relation &bound) {
+
+ if (!R.is_set())
+ throw std::invalid_argument("Input R has to be a set not a relation!");
+
+ Relation r(R.n_set() + 1);
+
+ for (int i = 1; i <= R.n_set(); i++) {
+ if (i < level)
+ r.name_set_var(i, const_cast<Relation &>(R).set_var(i)->name());
+ else
+ r.name_set_var(i + 1, const_cast<Relation &>(R).set_var(i)->name());
+
+ }
+
+ std::string new_var = bound.set_var(1)->name();
+
+ r.name_set_var(level, new_var);
+
+ F_Exists *f_exists = r.add_and()->add_exists();
+ F_And *f_root = f_exists->add_and();
+ std::map<Variable_ID, Variable_ID> exists_mapping;
+
+ for (int i = 1; i <= R.n_set(); i++)
+ for (DNF_Iterator di(const_cast<Relation &>(R).query_DNF()); di; di++) {
+ for (GEQ_Iterator gi((*di)->GEQs()); gi; gi++) {
+ GEQ_Handle h = f_root->add_GEQ();
+ if ((*gi).get_coef(const_cast<Relation &>(R).set_var(i)) != 0) {
+ for (Constr_Vars_Iter cvi(*gi); cvi; cvi++) {
+ Variable_ID v = cvi.curr_var();
+ switch (v->kind()) {
+ case Input_Var:
+ {
+ if (i < level)
+ h.update_coef(r.input_var(v->get_position()),
+ cvi.curr_coef());
+ else
+ h.update_coef(
+ r.input_var(v->get_position() + 1),
+ cvi.curr_coef());
+ break;
+ }
+ case Wildcard_Var:
+ {
+ Variable_ID v2 = replicate_floor_definition(R, v, r,
+ f_exists, f_root, exists_mapping);
+ h.update_coef(v2, cvi.curr_coef());
+ break;
+ }
+ case Global_Var:
+ {
+ Global_Var_ID g = v->get_global_var();
+ Variable_ID v2;
+ if (g->arity() == 0)
+ v2 = r.get_local(g);
+ else
+ v2 = r.get_local(g, v->function_of());
+ h.update_coef(v2, cvi.curr_coef());
+ break;
+ }
+ default:
+ assert(false);
+ }
+
+ }
+ h.update_const((*gi).get_const());
+ }
+ }
+ }
+
+ for (int i = 1; i <= R.n_set(); i++)
+ for (DNF_Iterator di(const_cast<Relation &>(R).query_DNF()); di; di++) {
+ for (EQ_Iterator gi((*di)->EQs()); gi; gi++) {
+ EQ_Handle h1 = f_root->add_EQ();
+ if ((*gi).get_coef(const_cast<Relation &>(R).set_var(i)) != 0) {
+ for (Constr_Vars_Iter cvi(*gi); cvi; cvi++) {
+ Variable_ID v = cvi.curr_var();
+ switch (v->kind()) {
+ case Input_Var:
+ {
+ if (i < level)
+ h1.update_coef(r.input_var(v->get_position()),
+ cvi.curr_coef());
+ else
+ h1.update_coef(
+ r.input_var(v->get_position() + 1),
+ cvi.curr_coef());
+ break;
+ }
+ case Wildcard_Var:
+ {
+ Variable_ID v2 = replicate_floor_definition(R, v, r,
+ f_exists, f_root, exists_mapping);
+ h1.update_coef(v2, cvi.curr_coef());
+ break;
+ }
+ case Global_Var:
+ {
+ Global_Var_ID g = v->get_global_var();
+ Variable_ID v2;
+ if (g->arity() == 0)
+ v2 = r.get_local(g);
+ else
+ v2 = r.get_local(g, v->function_of());
+ h1.update_coef(v2, cvi.curr_coef());
+ break;
+ }
+ default:
+ assert(false);
+ }
+ }
+ h1.update_const((*gi).get_const());
+ }
+ }
+ }
+
+ for (DNF_Iterator di(bound.query_DNF()); di; di++) {
+ for (GEQ_Iterator gi((*di)->GEQs()); gi; gi++) {
+ GEQ_Handle h = f_root->add_GEQ();
+ for (Constr_Vars_Iter cvi(*gi); cvi; cvi++) {
+ Variable_ID v = cvi.curr_var();
+ switch (v->kind()) {
+ case Input_Var:
+ {
+ if (cvi.curr_var()->get_position() < level)
+ h.update_coef(r.input_var(level), cvi.curr_coef());
+ else
+ h.update_coef(r.input_var(level), cvi.curr_coef());
+ break;
+ }
+ case Wildcard_Var:
+ {
+ Variable_ID v2 = replicate_floor_definition(R, v, r,
+ f_exists, f_root, exists_mapping);
+ h.update_coef(v2, cvi.curr_coef());
+ break;
+ }
+ case Global_Var:
+ {
+ Global_Var_ID g = v->get_global_var();
+ Variable_ID v2;
+ if (g->arity() == 0)
+ v2 = r.get_local(g);
+ else
+ v2 = r.get_local(g, v->function_of());
+ h.update_coef(v2, cvi.curr_coef());
+ break;
+ }
+ default:
+ assert(false);
+ }
+ h.update_const((*gi).get_const());
+ }
+ }
+ }
+
+ for (DNF_Iterator di(bound.query_DNF()); di; di++) {
+ for (EQ_Iterator gi((*di)->EQs()); gi; gi++) {
+ EQ_Handle h = f_root->add_EQ();
+ for (Constr_Vars_Iter cvi(*gi); cvi; cvi++) {
+ Variable_ID v = cvi.curr_var();
+ switch (v->kind()) {
+ case Input_Var:
+ {
+ if (cvi.curr_var()->get_position() < level)
+ h.update_coef(r.input_var(level), cvi.curr_coef());
+ else
+ h.update_coef(r.input_var(level), cvi.curr_coef());
+ break;
+ }
+ case Wildcard_Var:
+ {
+ Variable_ID v2 = replicate_floor_definition(R, v, r,
+ f_exists, f_root, exists_mapping);
+ h.update_coef(v2, cvi.curr_coef());
+ break;
+ }
+ case Global_Var:
+ {
+ Global_Var_ID g = v->get_global_var();
+ Variable_ID v2;
+ if (g->arity() == 0)
+ v2 = r.get_local(g);
+ else
+ v2 = r.get_local(g, v->function_of());
+ h.update_coef(v2, cvi.curr_coef());
+ break;
+ }
+ default:
+ assert(false);
+ }
+ }
+ h.update_const((*gi).get_const());
+ }
+ }
+ r.simplify();
+ r.setup_names();
+ return r;
+}
+
+
+
+
+omega::Relation replace_set_var_as_Global(const omega::Relation &R, int pos,
+ std::vector<omega::Relation> &bound) {
+
+ if (!R.is_set())
+ throw std::invalid_argument("Input R has to be a set not a relation!");
+
+ Relation r(R.n_set());
+ F_Exists *f_exists = r.add_and()->add_exists();
+ F_And *f_root = f_exists->add_and();
+ std::map<Variable_ID, Variable_ID> exists_mapping;
+ int count = 1;
+ for (int i = 1; i <= R.n_set(); i++) {
+
+ if (i != pos) {
+ r.name_set_var(i, const_cast<Relation &>(R).set_var(i)->name());
+
+ }
+ else
+ r.name_set_var(i, "void");
+ }
+
+ Free_Var_Decl *repl = new Free_Var_Decl(
+ const_cast<Relation &>(R).set_var(pos)->name());
+
+ Variable_ID v3 = r.get_local(repl);
+
+ for (DNF_Iterator di(const_cast<Relation &>(R).query_DNF()); di; di++) {
+ for (EQ_Iterator gi((*di)->EQs()); gi; gi++) {
+ EQ_Handle h1 = f_root->add_EQ();
+ for (Constr_Vars_Iter cvi(*gi); cvi; cvi++) {
+ Variable_ID v = cvi.curr_var();
+ switch (v->kind()) {
+ case Input_Var:
+ {
+ if (v->get_position() != pos)
+ h1.update_coef(r.input_var(v->get_position()),
+ cvi.curr_coef());
+ else
+
+ h1.update_coef(v3, cvi.curr_coef());
+ break;
+ }
+ case Wildcard_Var:
+ {
+ Variable_ID v2 = replicate_floor_definition(R, v, r,
+ f_exists, f_root, exists_mapping);
+ h1.update_coef(v2, cvi.curr_coef());
+ break;
+ }
+ case Global_Var:
+ {
+ Global_Var_ID g = v->get_global_var();
+ Variable_ID v2;
+ if (g->arity() == 0)
+ v2 = r.get_local(g);
+ else
+ v2 = r.get_local(g, v->function_of());
+ h1.update_coef(v2, cvi.curr_coef());
+ break;
+ }
+ default:
+ assert(false);
+ }
+ }
+ h1.update_const((*gi).get_const());
+ }
+ }
+
+ for (int i = 0; i < bound.size(); i++)
+ for (DNF_Iterator di(bound[i].query_DNF()); di; di++) {
+ for (GEQ_Iterator gi((*di)->GEQs()); gi; gi++) {
+ GEQ_Handle h = f_root->add_GEQ();
+ if ((*gi).get_coef(bound[i].set_var(pos)) == 0) {
+ for (Constr_Vars_Iter cvi(*gi); cvi; cvi++) {
+ Variable_ID v = cvi.curr_var();
+ switch (v->kind()) {
+ case Input_Var:
+ {
+ //if (i < level)
+ if (v->get_position() != pos)
+ h.update_coef(r.input_var(v->get_position()),
+ cvi.curr_coef());
+ else
+
+ h.update_coef(v3, cvi.curr_coef());
+ break;
+
+ //else
+ // h.update_coef(
+ // r.input_var(v->get_position() + 1),
+ // cvi.curr_coef());
+ break;
+ }
+ case Wildcard_Var:
+ {
+ Variable_ID v2 = replicate_floor_definition(R, v, r,
+ f_exists, f_root, exists_mapping);
+ h.update_coef(v2, cvi.curr_coef());
+ break;
+ }
+ case Global_Var:
+ {
+ Global_Var_ID g = v->get_global_var();
+ Variable_ID v2;
+ if (g->arity() == 0)
+ v2 = r.get_local(g);
+ else
+ v2 = r.get_local(g, v->function_of());
+ h.update_coef(v2, cvi.curr_coef());
+ break;
+ }
+ default:
+ assert(false);
+ }
+
+ }
+ h.update_const((*gi).get_const());
+ }
+ }
+ }
+ return r;
+}
+
+
+
+
+
+//-----------------------------------------------------------------------------
+// Replace an input variable's constraints as an existential in order
+// to simplify other constraints in Relation
+// -----------------------------------------------------------------------------
+std::pair<Relation, bool> replace_set_var_as_existential(
+ const omega::Relation &R, int pos,
+ std::vector<omega::Relation> &bound) {
+
+ if (!R.is_set())
+ throw std::invalid_argument("Input R has to be a set not a relation!");
+
+ Relation r(R.n_set());
+ for (int i = 1; i <= R.n_set(); i++)
+ r.name_set_var(i, const_cast<Relation &>(R).set_var(i)->name());
+
+ F_Exists *f_exists = r.add_and()->add_exists();
+ F_And *f_root = f_exists->add_and();
+ std::map<Variable_ID, Variable_ID> exists_mapping;
+ int coef_in_equality = 0;
+ for (DNF_Iterator di(const_cast<Relation &>(R).query_DNF()); di; di++)
+ for (EQ_Iterator gi((*di)->EQs()); gi; gi++)
+ if (((*gi).get_coef(const_cast<Relation &>(R).set_var(pos)) != 0)
+ && (!(*gi).has_wildcards()))
+ if (coef_in_equality == 0)
+ coef_in_equality = (*gi).get_coef(
+ const_cast<Relation &>(R).set_var(pos));
+ else
+ return std::pair<Relation, bool>(copy(R), false);
+
+ if (coef_in_equality < 0)
+ coef_in_equality = -coef_in_equality;
+
+ std::pair<EQ_Handle, Variable_ID> result = find_simplest_stride(
+ const_cast<Relation &>(R), const_cast<Relation &>(R).set_var(pos));
+
+ if (result.second == NULL && coef_in_equality != 1)
+ return std::pair<Relation, bool>(copy(R), false);
+
+ if (result.second != NULL) {
+ if (result.first.get_coef(const_cast<Relation &>(R).set_var(pos)) != 1)
+ return std::pair<Relation, bool>(copy(R), false);
+
+ if (result.first.get_coef(result.second) != coef_in_equality)
+ return std::pair<Relation, bool>(copy(R), false);
+ }
+ Variable_ID v3 = f_exists->declare();
+
+ for (DNF_Iterator di(const_cast<Relation &>(R).query_DNF()); di; di++) {
+ for (EQ_Iterator gi((*di)->EQs()); gi; gi++) {
+ EQ_Handle h1 = f_root->add_EQ();
+ if ((*gi).get_coef(const_cast<Relation &>(R).set_var(pos)) == 0
+ || !(*gi).has_wildcards()) {
+ for (Constr_Vars_Iter cvi(*gi); cvi; cvi++) {
+ Variable_ID v = cvi.curr_var();
+ switch (v->kind()) {
+ case Input_Var:
+ {
+ if (v->get_position() != pos)
+ h1.update_coef(r.input_var(v->get_position()),
+ cvi.curr_coef());
+ else
+
+ h1.update_coef(v3, cvi.curr_coef());
+ break;
+ }
+ case Wildcard_Var:
+ {
+ Variable_ID v2 = replicate_floor_definition(R, v, r,
+ f_exists, f_root, exists_mapping);
+ h1.update_coef(v2, cvi.curr_coef());
+ break;
+ }
+ case Global_Var:
+ {
+ Global_Var_ID g = v->get_global_var();
+ Variable_ID v2;
+ if (g->arity() == 0)
+ v2 = r.get_local(g);
+ else
+ v2 = r.get_local(g, v->function_of());
+ h1.update_coef(v2, cvi.curr_coef());
+ break;
+ }
+ default:
+ assert(false);
+ }
+ }
+ h1.update_const((*gi).get_const());
+ }
+ }
+ }
+
+ for (int i = 0; i < bound.size(); i++)
+ for (DNF_Iterator di(bound[i].query_DNF()); di; di++) {
+ for (GEQ_Iterator gi((*di)->GEQs()); gi; gi++) {
+ GEQ_Handle h = f_root->add_GEQ();
+ //if ((*gi).get_coef(const_cast<Relation &>(R).set_var(i)) != 0) {
+ for (Constr_Vars_Iter cvi(*gi); cvi; cvi++) {
+ Variable_ID v = cvi.curr_var();
+ switch (v->kind()) {
+ case Input_Var:
+ {
+ //if (i < level)
+ if (v->get_position() != pos)
+
+ h.update_coef(r.set_var(v->get_position()),
+ cvi.curr_coef());
+ else
+
+ h.update_coef(v3, cvi.curr_coef());
+
+ //else
+ // h.update_coef(
+ // r.input_var(v->get_position() + 1),
+ // cvi.curr_coef());
+ break;
+ }
+ case Wildcard_Var:
+ {
+ Variable_ID v2 = replicate_floor_definition(R, v, r,
+ f_exists, f_root, exists_mapping);
+ h.update_coef(v2, cvi.curr_coef());
+ break;
+ }
+ case Global_Var:
+ {
+ Global_Var_ID g = v->get_global_var();
+ Variable_ID v2;
+ if (g->arity() == 0)
+ v2 = r.get_local(g);
+ else
+ v2 = r.get_local(g, v->function_of());
+ h.update_coef(v2, cvi.curr_coef());
+ break;
+ }
+ default:
+ assert(false);
+ }
+
+ }
+ h.update_const((*gi).get_const());
+ //}
+ }
+ }
+
+ //for (int i = 1; i <= R.n_set(); i++)
+ return std::pair<Relation, bool>(r, true);
+}
+
+
+
+
+
+//-----------------------------------------------------------------------------
+// Copy all relations from r except those for set var v.
+// And with GEQ given by g
+// NOTE: This function only removes the relations involving v if they are simple relations
+// involving only v but not complex relations that have v in other variables' constraints
+// -----------------------------------------------------------------------------
+Relation and_with_relation_and_replace_var(const Relation &R, Variable_ID v1,
+ Relation &g) {
+ if (!R.is_set())
+ throw std::invalid_argument("Input R has to be a set not a relation!");
+
+ Relation r(R.n_set());
+
+ F_Exists *f_exists = r.add_and()->add_exists();
+ F_And *f_root = f_exists->add_and();
+ std::map<Variable_ID, Variable_ID> exists_mapping;
+ EQ_Handle h = f_root->add_EQ();
+ for (DNF_Iterator di(const_cast<Relation &>(R).query_DNF()); di; di++) {
+ for (EQ_Iterator gi((*di)->EQs()); gi; gi++) {
+ EQ_Handle h = f_root->add_EQ();
+ if (!(*gi).is_const(v1) && !(*gi).is_const_except_for_global(v1)) {
+ for (Constr_Vars_Iter cvi(*gi); cvi; cvi++) {
+ Variable_ID v = cvi.curr_var();
+ switch (v->kind()) {
+ case Input_Var:
+ {
+ h.update_coef(r.input_var(v->get_position()),
+ cvi.curr_coef());
+ break;
+ }
+ case Wildcard_Var:
+ {
+ Variable_ID v2 = replicate_floor_definition(R, v, r,
+ f_exists, f_root, exists_mapping);
+ h.update_coef(v2, cvi.curr_coef());
+ break;
+ }
+ case Global_Var:
+ {
+ Global_Var_ID g = v->get_global_var();
+ Variable_ID v2;
+ if (g->arity() == 0)
+ v2 = r.get_local(g);
+ else
+ v2 = r.get_local(g, v->function_of());
+ h.update_coef(v2, cvi.curr_coef());
+ break;
+ }
+ default:
+ assert(false);
+ }
+ }
+
+ h.update_const((*gi).get_const());
+ }
+ }
+
+ for (GEQ_Iterator gi((*di)->GEQs()); gi; gi++) {
+ GEQ_Handle h = f_root->add_GEQ();
+ if ((*gi).get_coef(v1) == 0) {
+ for (Constr_Vars_Iter cvi(*gi); cvi; cvi++) {
+ Variable_ID v = cvi.curr_var();
+ switch (v->kind()) {
+ case Input_Var:
+ {
+ h.update_coef(r.input_var(v->get_position()),
+ cvi.curr_coef());
+ break;
+ }
+ case Wildcard_Var:
+ {
+ Variable_ID v2 = replicate_floor_definition(R, v, r,
+ f_exists, f_root, exists_mapping);
+ h.update_coef(v2, cvi.curr_coef());
+ break;
+ }
+ case Global_Var:
+ {
+ Global_Var_ID g = v->get_global_var();
+ Variable_ID v2;
+ if (g->arity() == 0)
+ v2 = r.get_local(g);
+ else
+ v2 = r.get_local(g, v->function_of());
+ h.update_coef(v2, cvi.curr_coef());
+ break;
+ }
+ default:
+ assert(false);
+ }
+ }
+ h.update_const((*gi).get_const());
+ }
+ }
+ }
+ for (DNF_Iterator di(const_cast<Relation &>(g).query_DNF()); di; di++)
+ for (GEQ_Iterator gi((*di)->GEQs()); gi; gi++)
+ r.and_with_GEQ(*gi);
+
+ for (DNF_Iterator di(const_cast<Relation &>(g).query_DNF()); di; di++)
+ for (EQ_Iterator gi((*di)->EQs()); gi; gi++)
+ r.and_with_EQ(*gi);
+
+ r.simplify();
+ r.copy_names(R);
+ r.setup_names();
+ return r;
+}
+
+
+
+
+
+omega::Relation extract_upper_bound(const Relation &R, Variable_ID v1) {
+ if (!R.is_set())
+ throw std::invalid_argument("Input R has to be a set not a relation!");
+
+ Relation r(R.n_set());
+
+ F_Exists *f_exists = r.add_and()->add_exists();
+ F_And *f_root = f_exists->add_and();
+ std::map<Variable_ID, Variable_ID> exists_mapping;
+ GEQ_Handle h = f_root->add_GEQ();
+ for (DNF_Iterator di(const_cast<Relation &>(R).query_DNF()); di; di++)
+ for (GEQ_Iterator gi((*di)->GEQs()); gi; gi++)
+ if ((*gi).get_coef(v1) < 0) {
+
+ for (Constr_Vars_Iter cvi(*gi); cvi; cvi++) {
+ Variable_ID v = cvi.curr_var();
+ switch (v->kind()) {
+ case Input_Var:
+ h.update_coef(r.input_var(v->get_position()),
+ cvi.curr_coef());
+ break;
+ case Wildcard_Var:
+ {
+ Variable_ID v2 = replicate_floor_definition(R, v, r,
+ f_exists, f_root, exists_mapping);
+ h.update_coef(v2, cvi.curr_coef());
+ break;
+ }
+ case Global_Var:
+ {
+ Global_Var_ID g = v->get_global_var();
+ Variable_ID v2;
+ if (g->arity() == 0)
+ v2 = r.get_local(g);
+ else
+ v2 = r.get_local(g, v->function_of());
+ h.update_coef(v2, cvi.curr_coef());
+ break;
+ }
+ default:
+ assert(false);
+ }
+ }
+ h.update_const((*gi).get_const());
+ }
+
+ r.simplify();
+
+ return r;
+
+}
+
+/*CG_outputRepr * modified_output_subs_repr(CG_outputBuilder * ocg, const Relation &R, const EQ_Handle &h, Variable_ID v,const std::vector<std::pair<CG_outputRepr *, int> > &assigned_on_the_fly,
+ std::map<std::string, std::vector<CG_outputRepr *> > unin){
+
+
+
+
+ }
+*/
+
+
+
+
+
+CG_outputRepr * construct_int_floor(CG_outputBuilder * ocg, const Relation &R,
+ const GEQ_Handle &h, Variable_ID v,
+ const std::vector<std::pair<CG_outputRepr *, int> > &assigned_on_the_fly,
+ std::map<std::string, std::vector<CG_outputRepr *> > unin) {
+
+ std::set<Variable_ID> excluded_floor_vars;
+ const_cast<Relation &>(R).setup_names(); // hack
+ assert(v->kind() == Set_Var);
+
+ int a = h.get_coef(v);
+
+ CG_outputRepr *lhs = ocg->CreateIdent(v->name());
+ excluded_floor_vars.insert(v);
+ std::vector<std::pair<bool, GEQ_Handle> > result2;
+ CG_outputRepr *repr = NULL;
+ for (Constr_Vars_Iter cvi(h); cvi; cvi++)
+ if (cvi.curr_var() != v) {
+ CG_outputRepr *t;
+ if (cvi.curr_var()->kind() == Wildcard_Var) {
+ std::pair<bool, GEQ_Handle> result = find_floor_definition(R,
+ cvi.curr_var(), excluded_floor_vars);
+ if (!result.first) {
+ coef_t coef_ = cvi.curr_coef();
+ result2 = find_floor_definition_temp(R, cvi.curr_var(),
+ excluded_floor_vars);
+
+ for (Constr_Vars_Iter cvi_(
+ result2[result2.size() - 1].second); cvi_; cvi_++) {
+ if (cvi_.curr_var()->kind() != Wildcard_Var
+ && cvi_.curr_var()->kind() != Set_Var) {
+ t = output_ident(ocg, R, cvi_.curr_var(),
+ assigned_on_the_fly, unin);
+ coef_t coef2 = cvi_.curr_coef();
+ assert(cvi_.curr_coef() == -1 && a == 1);
+ repr = ocg->CreateIntegerFloor(t,
+ ocg->CreateInt(-coef_));
+ repr = ocg->CreateTimes(ocg->CreateInt(-coef_),
+ repr);
+
+ return repr;
+
+ }
+
+ }
+
+ };
+ if (!result.first) {
+ delete repr;
+ throw omega_error(
+ "Can't generate bound expression with wildcard not involved in floor definition");
+ }
+
+ try {
+ t = output_inequality_repr(ocg, result.second,
+ cvi.curr_var(), R, assigned_on_the_fly, unin,
+ excluded_floor_vars);
+ } catch (const std::exception &e) {
+ delete repr;
+ throw e;
+ }
+ }
+ else
+ t = output_ident(ocg, R, cvi.curr_var(), assigned_on_the_fly,
+ unin);
+
+ coef_t coef = cvi.curr_coef();
+ if (a > 0) {
+ if (coef > 0) {
+ if (coef == 1)
+ repr = ocg->CreateMinus(repr, t);
+ else
+ repr = ocg->CreateMinus(repr,
+ ocg->CreateTimes(ocg->CreateInt(coef), t));
+ }
+ else {
+ if (coef == -1)
+ repr = ocg->CreatePlus(repr, t);
+ else
+ repr = ocg->CreatePlus(repr,
+ ocg->CreateTimes(ocg->CreateInt(-coef), t));
+ }
+ }
+ else {
+ if (coef > 0) {
+ if (coef == 1)
+ repr = ocg->CreatePlus(repr, t);
+ else
+ repr = ocg->CreatePlus(repr,
+ ocg->CreateTimes(ocg->CreateInt(coef), t));
+ }
+ else {
+ if (coef == -1)
+ repr = ocg->CreateMinus(repr, t);
+ else
+ repr = ocg->CreateMinus(repr,
+ ocg->CreateTimes(ocg->CreateInt(-coef), t));
+ }
+ }
+ }
+ coef_t c = h.get_const();
+ if (c > 0) {
+ if (a > 0)
+ repr = ocg->CreateMinus(repr, ocg->CreateInt(c));
+ else
+ repr = ocg->CreatePlus(repr, ocg->CreateInt(c));
+ }
+ else if (c < 0) {
+ if (a > 0)
+ repr = ocg->CreatePlus(repr, ocg->CreateInt(-c));
+ else
+ repr = ocg->CreateMinus(repr, ocg->CreateInt(-c));
+ }
+
+ if (abs(a) == 1)
+ ocg->CreateAssignment(0, lhs, repr);
+ else if (a > 0)
+ return ocg->CreateAssignment(0, lhs,
+ ocg->CreateIntegerCeil(repr, ocg->CreateInt(a)));
+ else
+ // a < 0
+ return ocg->CreateAssignment(0, lhs,
+ ocg->CreateIntegerFloor(repr, ocg->CreateInt(-a)));
+
+}
+
+
+
+