Example #1
0
bool SymbolicValGenerator::
IsFortranLoop(AstInterface& fa, const AstNodePtr& s, SymbolicVar* ivar ,
        SymbolicVal* lb , SymbolicVal* ub, SymbolicVal* step, AstNodePtr* body)
{
  AstNodePtr ivarast, lbast, ubast, stepast, ivarscope;
  if (!fa.IsFortranLoop(s, &ivarast, &lbast, &ubast, &stepast, body))
      return false;
  std::string varname;
  if (! fa.IsVarRef(ivarast, 0, &varname, &ivarscope)) {
         return false;
  }
  if (ivar != 0)
     *ivar = SymbolicVar(varname, ivarscope);
  if (lb != 0)
     *lb = SymbolicValGenerator::GetSymbolicVal(fa,lbast);
  if (ub != 0)
     *ub = SymbolicValGenerator::GetSymbolicVal(fa,ubast);
  if (step != 0) {
     if (stepast != AST_NULL)
       *step = SymbolicValGenerator::GetSymbolicVal(fa,stepast);
     else
       *step = SymbolicVal(1);
  }
  return true;
}
Example #2
0
AstNodePtr ArrayInterface::
impl_access_array_length( CPPAstInterface& fa, const AstNodePtr& array,
                         int dim, int plus)
{
  SymbolicVal rval;
  ArrayOptDescriptor desc;
  if (get_array_opt(fa, array, desc)) 
  {
    if (!desc.get_length(dim, rval))
      assert(false);
    
  }
  else 
  {
    ArrayDefineDescriptor desc1;
    if (!ArrayAnnotation::get_inst()->known_array( fa, array, &desc1))
      return AST_NULL;
    if (! desc1.get_length(dim, rval))
      assert(false);
  }
  ReplaceVal(rval, SymbolicVar("this",AST_NULL), SymbolicAstWrap(array));
  if (plus != 0)
     rval = rval + plus;
  return rval.CodeGen(fa);
}
Example #3
0
bool ArrayInterface::
get_array_opt(CPPAstInterface& fa, const AstNodePtr& array, ArrayOptDescriptor& r)
{
  std::string name;
  if (!fa.IsVarRef(array, 0, &name))
    return false;
  
  std::map <std::string, ArrayOptDescriptor>::const_iterator p = optmap.find(name);
  if (p != optmap.end()) 
  {
    r = (*p).second;
    return true;
  }
  ArrayOptDescriptor desc;
  if (!ArrayAnnotation::get_inst()->has_array_opt( fa, array, &desc))
    return false;
  
  for (ArrayOptDescriptor::InitVarIterator p = desc.init_var_begin();
       p != desc.init_var_end(); ++p) {
    DefineVariableDescriptor& cur = *p;
    ExtendibleParamDescriptor &par = cur.get_var();
    std::string parname = par.get_param_name();
    par.get_param() = SymbolicVar( name + parname, AST_NULL);
    SymbolicVal newpar = new SymbolicVar(name + parname, AST_NULL);
    desc.replace_var(parname, newpar);
  }
  optmap[name] = desc;
  r = desc;
  return true;
}
LoopTreeNode* DynamicSlicing:: 
Transform( LoopTreeDepComp& c, const CompSlice *_slice, LoopTreeNode *root)
{
  AstInterface& fa = LoopTransformInterface::getAstInterface();
  const DynamicCompSlice* slice = static_cast<const DynamicCompSlice*>(_slice);
  int num = slice->QuerySliceGroupNumber();
  LoopTreeNode *nr = root;
  if (num > 1) {
    std::string groupVar = fa.NewVar(fa.GetType("int")), groupVarN = groupVar + "N";
    fa.NewVar( fa.GetType("int"), groupVarN);
    LoopTreeCreate *tc = c.GetLoopTreeCreate();
    nr = tc->CreateLoopNode( SymbolicVar(groupVar, AST_NULL), 1, SymbolicVar(groupVarN, AST_NULL), 1);
    LoopTreeTransform().InsertLoop( nr, root, -1);

    AstInterface::AstNodeList args;
    char buf[11];
    for (int i = 1; i <= num; ++i) {
       sprintf(buf, "%1d", i);
       std::string name = groupVar + buf;
       fa.NewVar(fa.GetType("int"), name);
       args.push_back( fa.CreateVarRef( name) );
    }
    int id;
    AstNodePtr config = LoopTransformInterface::CreateDynamicFusionConfig( fa.CreateVarRef(groupVarN), args, id); 
    LoopTreeNode *configNode = tc->CreateStmtNode(config);
    configNode->Link( nr, LoopTreeNode::AsPrevSibling);
    AstNodePtr configEnd = LoopTransformInterface::CreateDynamicFusionEnd( id);
    LoopTreeNode *endNode = tc->CreateStmtNode(configEnd);
    endNode->Link( nr, LoopTreeNode::AsNextSibling);
     
    for (CompSlice::ConstStmtIterator p = slice->GetConstStmtIterator();
         !p.ReachEnd(); ++p) {
        LoopTreeNode* stmt = p.Current();
        sprintf(buf, "%1d", slice->QuerySliceStmtGroupIndex(stmt));
        LoopTreeEmbedStmt()( nr, stmt, SymbolicVar(groupVar + buf, AST_NULL) ); 
    }   
    DependenceHoisting::Transform(c, slice, root);
  }
  else
    nr = DependenceHoisting::Transform(c, slice, root);
  
  return nr;
}
Example #5
0
LoopTreeNode* LoopBlocking::
ApplyBlocking( const CompSliceDepGraphNode::FullNestInfo& nestInfo, 
              LoopTreeDepComp& comp, DependenceHoisting &op, LoopTreeNode *&top)
{
  const CompSliceNest& slices = *nestInfo.GetNest();
  if (DebugLoop()) {
     std::cerr << "\n Blocking slices: " << slices.toString() << "\n";
  }
  LoopTreeNode *head = 0;
  AstInterface& fa = LoopTransformInterface::getAstInterface();
  for (int j = FirstIndex(); j >= 0; j = NextIndex(j))  {
     top = op.Transform( comp, slices[j], top);
     SymbolicVal b = BlockSize(j);
     if (DebugLoop()) {
        std::cerr << "\n after slice " << j << " : \n";
        //top->DumpTree();
        comp.DumpTree();
        comp.DumpDep();
        std::cerr << "\n blocking size for this loop is " << b.toString() << "\n";
     }
      
     if (!(b == 1)) {
         LoopTreeNode *n = LoopTreeBlockLoop()( top, SymbolicVar(fa.NewVar(fa.GetType("int")), AST_NULL), b);
         if (DebugLoop()) {
            std::cerr << "\n after tiling loop with size " << b.toString() << " : \n";
            //top->DumpTree();
            comp.DumpTree();
            comp.DumpDep();
         }
         if (head == 0)
             head = n;
         else {
           while (n->FirstChild() != head)
              LoopTreeSwapNodePos()( n->Parent(), n);
         }
       }
   }
  return head;
}
Example #6
0
LoopTreeNode* LoopBlocking::
ApplyBlocking( const CompSliceDepGraphNode::FullNestInfo& nestInfo, 
              LoopTreeDepComp& comp, DependenceHoisting &op, LoopTreeNode *&top)
{
  const CompSliceNest& slices = *nestInfo.GetNest();
  LoopTreeNode *head = 0;
  AstInterface& fa = LoopTransformInterface::getAstInterface();
  for (int j = FirstIndex(); j >= 0; j = NextIndex(j))  {
     top = op.Transform( comp, slices[j], top);
     SymbolicVal b = BlockSize(j);
     if (!(b == 1)) {
         LoopTreeNode *n = LoopTreeBlockLoop()( top, SymbolicVar(fa.NewVar(fa.GetType("int")), AST_NULL), b);
         if (head == 0)
             head = n;
         else {
           while (n->FirstChild() != head)
              LoopTreeSwapNodePos()( n->Parent(), n);
         }
       }
   }
  return head;
}
Example #7
0
static SymbolicVal GetDefaultBlockSize(const CompSlice* slice) 
    {
       AstInterface& fa = LoopTransformInterface::getAstInterface();
       LoopTransformOptions* opt = LoopTransformOptions::GetInstance();
       if (!opt->DoDynamicTuning()) {
            return opt->GetDefaultBlockSize();
       }
       else {
           int dt = opt->GetDynamicTuningIndex();
           AstInterface::AstNodeList l;
           l.push_back(fa.CreateConstInt(dt));

           CompSlice::ConstLoopIterator iter = slice->GetConstLoopIterator();
           LoopTreeNode *loop = iter.Current();
           SymbolicBound b = loop->GetLoopInfo()->GetBound();
           SymbolicVal size = b.ub - b.lb + 1;
 
           l.push_back(fa.CreateConstInt(1));
           l.push_back(size.CodeGen(fa));
           AstNodePtr init = fa.CreateFunctionCall("getTuningValue", l);
           return SymbolicVar(fa.NewVar(fa.GetType("int"), "",true,AST_NULL, init),AST_NULL); 
       }
    }
Example #8
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;
}