SymbolicVal Min( const SymbolicVal &v1, const SymbolicVal &v2, MapObject<SymbolicVal, SymbolicBound>* f) { if (v1.IsNIL()) return v2; if (v2.IsNIL()) return v1; switch (CompareVal(v1,v2,f)) { case REL_NONE: case REL_UNKNOWN: case REL_NE: { SelectApplicator minOp(-1); return ApplyBinOP(minOp,v1,v2); } case REL_EQ: case REL_LT: case REL_LE: return v1; case REL_GT: case REL_GE: return v2; default: assert(0); } }
CompareRel CompareVal(const SymbolicVal &v1, const SymbolicVal &v2, MapObject<SymbolicVal,SymbolicBound>* f) { if ( v1.IsNIL() && v2.IsNIL()) return REL_UNKNOWN; if (DebugCompareVal()) std::cerr << "comparing " << v1.toString() << " with " << v2.toString() << " under " << f << std::endl; comparetime = 0; return CompareValHelp(v1,v2,f); }
void Default1( const SymbolicVal &v1, const SymbolicVal &v2) { if (v1.IsSame(v2)) result = REL_EQ; else if (v1.IsNIL() || v2.IsNIL()) result = REL_UNKNOWN; else if (v1 == v2) result = REL_EQ; else result = REL_UNKNOWN; }
virtual SymbolicVal operator()( const SymbolicVal& v) { SymbolicVal r; if (valmap != 0) r = (*valmap)(v); if (r.IsNIL()) { v.Visit(this); } return r; }
SymbolicVal DecomposeAffineExpression( const SymbolicVal& exp, const VarVec& vars, CoeffVec& vec, int size) { // AstInterface& fa = la; SymbolicVal val = exp; // int coeff; for (int i = 0; i < size; ++i) { SymbolicVar ivar = vars[i]; SymbolicBound ivarbound; SymbolicVal coeff = UnwrapVarCond( SymbolicCond( REL_LE, val, 0), ivar, ivarbound); if (coeff.IsNIL()) return SymbolicVal(); if (!(coeff == 0)) { if (!ivarbound.ub.IsNIL()) val = -ivarbound.ub; else { val = ivarbound.lb; coeff = -coeff; } } vec.push_back(coeff); } return val; }
bool AnalyzeEquation(const CoeffVec& vec, const BoundVec& bounds, BoundOp& boundop, Dep& result, const DepRel& rel) { int dim = vec.size()- 1; std::vector<int> signs; for (int index = 0; index < dim; ++index) { if (vec[index]==0) { signs.push_back(0); continue; } SymbolicBound cb = GetValBound(vec[index], boundop); assert(!cb.lb.IsNIL() && !cb.ub.IsNIL()); const SymbolicBound& b = bounds[index]; assert(!b.lb.IsNIL() && !b.ub.IsNIL()); if (b.lb >= 0) { if (cb.lb >= 0) signs.push_back(1); else if (cb.ub <= 0) signs.push_back(-1); else { if (DebugDep()) std::cerr << "unable to decide sign of coeff when lb >=0 for ivar[" << index << "]\n"; //return false; signs.push_back(2); } } else if (b.ub <= 0) { if (cb.lb >= 0) signs.push_back(-1); else if (cb.ub <= 0) signs.push_back(1); else { if (DebugDep()) std::cerr << "unable to decide sign of coeff when ub <=0 for ivar[" << index << "]\n"; //return false; signs.push_back(2); } } else { if (DebugDep()) std::cerr << "unable to decide sign of ivar[" << index << "]\n"; //return false; signs.push_back(2); } } if (vec[dim] == 0) signs.push_back(0); else { SymbolicVal leftval = vec[dim]; if (leftval.IsNIL()) { if (DebugDep()) std::cerr << "unable to decide sign of leftval\n"; return false; } SymbolicBound lb = GetValBound(vec[dim], boundop); if (lb.ub <= 0) signs.push_back(-1); else if (lb.lb >= 0) signs.push_back(1); else { if (DebugDep()) std::cerr << "unable to decide sign of leftval\n"; return false; //signs.push_back(2); } } for (int i = 0; i < dim ; ++i) { if (signs[i] == 0) continue; SymbolicVal coeff = vec[i]; assert(!coeff.IsNIL()); int j = 0; for ( j = i+1; j < dim; ++j) { if (signs[j] == 0 || coeff + vec[j] != 0) continue; int left = 0, k; for (k = 0; k < dim ; ++k) { if (k == i || k == j) continue; if (left == 0) left = signs[k]; else if (signs[k] == 2 || signs[k] * left < 0) break; } if ( k < dim || left == 2 || left * signs[dim] < 0) continue; int diff = 0, c = 1; bool hasdiff = false; if (left == 0 && vec[dim].isConstInt(diff) && (diff == 0 || coeff.isConstInt(c))) { if (diff != 0 && c != 1) { int odiff = diff; diff = diff / c; if (odiff != diff * c) { //DepStats.AddAdhocDV(DepStats.RoseToPlatoDV(DepRel(DEPDIR_NONE))); result[i][j] = DepRel(DEPDIR_NONE); return true; } } hasdiff = true; } if (hasdiff) { //DepStats.AddAdhocDV(DepStats.RoseToPlatoDV(DepRel(DEPDIR_EQ, diff))); result[i][j] = rel * DepRel(DEPDIR_EQ, diff); return true; // precise dependence } else if (signs[i] != 2) { if (signs[dim]* signs[i] > 0) { //DepStats.AddAdhocDV(DepStats.RoseToPlatoDV(DepRel(DEPDIR_GE, diff))); result[i][j] = rel * DepRel(DEPDIR_GE, diff); } else { //DepStats.AddAdhocDV(DepStats.RoseToPlatoDV(DepRel(DEPDIR_LE, diff))); result[i][j] = rel * DepRel(DEPDIR_LE, diff); } } } } return false; }