SymbolicVal ApplyBinOP( SymOpType t, const SymbolicVal &v1,
                               const SymbolicVal &v2)
{
  SymbolicVal r;
  switch (t) {
  case SYMOP_PLUS: 
     {
      PlusApplicator op; 
      r = ApplyBinOP(op, v1, v2);
      if (DebugOp())
         std::cerr << v1.toString() << " + " << v2.toString() << " = " << r.toString() << std::endl;  
      return r;
     }
  case SYMOP_MULTIPLY: 
    {
      MultiplyApplicator op; 
      r = ApplyBinOP(op, v1, v2);
      if (DebugOp())
         std::cerr << v1.toString() << " * " << v2.toString() << " = " << r.toString() << std::endl;  
      return r;
    }
  case SYMOP_MIN: 
      r = Min(v1,v2);
      if (DebugOp())
         std::cerr << "Min( " << v1.toString() << " , " << v2.toString() << ") = " << r.toString() << std::endl;  
      return r;
  case SYMOP_MAX: return Max(v1, v2);
      r = Max(v1,v2);
      if (DebugOp())
         std::cerr << "Max( " << v1.toString() << " , " << v2.toString() << ") = " << r.toString() << std::endl;  
      return r;
  case SYMOP_POW: 
     {
      int val2;
      int vu1, vd1;
      if (!v2.isConstInt(val2))
         assert(false);
      if (v1 == 1 || val2 == 1)
         r =  v1;
      else if (val2 == -1 && v1.isConstInt(vu1, vd1)) 
         r = new SymbolicConst(vd1, vu1);
      else   
         r = new SymbolicPow(v1, val2);
      if (DebugOp())
         std::cerr << "Pow( " << v1.toString() << " , " << v2.toString() << ") = " << r.toString() << std::endl;  
      return r;
     }
  default:
    assert(false);
  }
}
Exemple #2
0
bool ArrayInterface ::
GetArrayBound( AstInterface& _fa, const AstNodePtr& array,
                                 int dim, int &lb, int &ub) 
{ 
  CPPAstInterface& fa = static_cast<CPPAstInterface&>(_fa);
  SymbolicFunctionDeclarationGroup len;
  if (!is_array_exp( fa, array, 0, &len))
    assert(false);

  std::vector<SymbolicVal> pars;
  pars.push_back( SymbolicConst(dim));

  SymbolicVal rval;
  if (!len.get_val( pars, rval)) 
     return false;
  if (!rval.isConstInt(ub))
     return false;
  lb = 0;
  return true;
}
Exemple #3
0
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;
}
Exemple #4
0
bool LoopUnrolling::operator() ( AstInterface& fa, const AstNodePtr& s, AstNodePtr& r)
{
   bool isLoop = false;
   if (enclosingloop == s || (enclosingloop == AST_NULL && (isLoop = fa.IsLoop(s)))) {
       for (enclosingloop = fa.GetParent(s); 
            enclosingloop != AST_NULL && !fa.IsLoop(enclosingloop); 
            enclosingloop = fa.GetParent(enclosingloop));
       if (!isLoop)
          return false;
   }

   AstNodePtr body;
   SymbolicVal stepval, ubval, lbval;
   SymbolicVar ivar;
   if (!SymbolicValGenerator::IsFortranLoop(fa, s, &ivar, &lbval, &ubval, &stepval, &body)) 
      return false; 
    
   if (opt & POET_TUNING) {
     AutoTuningInterface* tune = LoopTransformInterface::getAutoTuningInterface();
     if (tune == 0) {
        std::cerr << "ERROR: AutoTuning Interface not defined!\n";
        assert(0);
     }
     tune->UnrollLoop(fa,s, unrollsize);
   }
   else {
          AstNodePtr r = s;
          SymbolicVal nstepval = stepval * unrollsize;
          SymbolicVal nubval = ubval;

          bool hasleft = true, negativeStep = (stepval < 0);
          std::vector<AstNodePtr> bodylist;
          AstNodePtr leftbody, lefthead;

          int stepnum=0, loopnum = 0;
          SymbolicVal loopval = ubval - lbval + 1;
          if (stepval.isConstInt(stepnum) && loopval.isConstInt(loopnum) 
               && !(loopnum % stepnum)) {
             hasleft = false; 
          }
          else {
             nubval = ubval - SymbolicVal(unrollsize - 1);
             if (opt & COND_LEFTOVER) {
                 leftbody = fa.CreateBlock();
                 lefthead = leftbody;
             }
             else {
                 leftbody = fa.CopyAstTree(body);
                 lefthead = fa.CreateLoop( ivar.CodeGen(fa), 
                                           AstNodePtr(), 
                                           ubval.CodeGen(fa), 
                                           stepval.CodeGen(fa), leftbody,
                                           negativeStep);
             }
          }
          fa.RemoveStmt(body);
          AstNodePtr s1 = fa.CreateLoop(ivar.CodeGen(fa), lbval.CodeGen(fa),
                                          nubval.CodeGen(fa), 
                                          nstepval.CodeGen(fa), body,
                                           negativeStep);
          fa.ReplaceAst( s,s1);
          r = s1; 

          AstNodePtr origbody = fa.CopyAstTree(body);
          std::string nvarname = "";
          SymbolicVal nvar;
          if (opt & USE_NEWVAR) {
               nvarname = fa.NewVar(fa.GetType("int"),"",true,body, ivar.CodeGen(fa)); 
               nvar = SymbolicVar(nvarname,body);
          }
          bodylist.push_back(body);
          for (int i = 1; i < unrollsize; ++i) {
              AstNodePtr bodycopy = fa.CopyAstTree(origbody);
              if (opt & USE_NEWVAR) {
                 AstNodePtr nvarassign = 
                     fa.CreateAssignment(nvar.CodeGen(fa), (nvar+1).CodeGen(fa));
                 fa.BlockAppendStmt( body, nvarassign);
                 AstTreeReplaceVar repl(ivar, nvar);
                 repl( fa, bodycopy);
              }
              else {
                 AstTreeReplaceVar repl(ivar, ivar+i);
                 repl( fa, bodycopy);
              }
              fa.BlockAppendStmt( body, bodycopy);
              bodylist.push_back(bodycopy);
              if (hasleft && (opt & COND_LEFTOVER)) {
                 AstNodePtr cond = 
                      fa.CreateBinaryOP( AstInterface::BOP_LE, ivar.CodeGen(fa), (ubval-(i-1)).CodeGen(fa));
                 AstNodePtr body1 = fa.CopyAstTree(bodylist[i-1]);
                 AstNodePtr ifstmt =  fa.CreateIf( cond, body1);
                 fa.BlockAppendStmt( leftbody, ifstmt);
                 leftbody = body1;
              }
          }
          if (hasleft) {
              fa.InsertStmt( r, lefthead, false, true);
          }
          r  = s;
          return true;
   }
   return false;
}