void DepCompCopyArrayToBuffer::
ApplyCopyArray( DepCompCopyArrayCollect& collect,
                 const DepCompAstRefGraphCreate& refDep)
{
   const DepCompAstRefAnal& stmtorder = collect.get_stmtref_info();
   for (DepCompCopyArrayCollect::iterator arrays = collect.begin();
        arrays != collect.end(); ++arrays) {
      DepCompCopyArrayCollect::CopyArrayUnit& curarray = *arrays;
      if (DebugCopyConfig())
        std::cerr << IteratorToString2(curarray.refs.begin()) << std::endl;

      const DepCompAstRefGraphNode* initcut = 0, *savecut = 0;
      ComputeCutBoundary(refDep, stmtorder, curarray, initcut, savecut);
      CopyArrayConfig curconfig = 
                 ComputeCopyConfig(stmtorder, curarray, initcut);

      LoopTreeNode* repl = curarray.root;
assert(repl != 0);
      LoopTreeNode* init = initcut->GetInfo().stmt;
      LoopTreeNode* save = savecut->GetInfo().stmt;
      CopyArrayOpt opt = curconfig.get_opt();
      if (init != 0) {
         if (opt & SHIFT_COPY)
            init = curarray.root;
         else for ( ; init->Parent() != curarray.root;
                    init=init->Parent());
      }
      if ( (opt & SHIFT_COPY) && (init != 0 || save != 0)) 
            save = curarray.root->LastChild();
      else if (save != 0)  
            for (; save->Parent()!=curarray.root;                    
              save=save->Parent());
      ApplyXform(curarray, curconfig, repl, init,save);
  }
}
 void write(std::ostream& out) const 
  { out << "slice stmt: \n";
    stmt->write(out);
    out << "slice loop: \n";
    loop->write(out);
    out << "alignment: " << alignInfo.mina << "->" << alignInfo.maxa << "\n";
  }
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;
}
void DependenceHoisting ::
Analyze( LoopTreeDepComp &comp, CompSliceNest& result)
{
  typedef PerfectLoopSlicable<DepInfoEdge,LoopTreeDepGraph> LoopSlicable;
  typedef PerfectLoopReversible<DepInfoEdge,LoopTreeDepGraph> 
          LoopReversible;

  LoopTreeNode *root = comp.GetLoopTreeRoot();
  int rootlevel = root->LoopLevel(), index = rootlevel-1;
  int stmtnum, stmtlevel;
  GetLoopTreeSize(root, stmtnum, stmtlevel);
  if (!stmtnum)
    return;
  result.Reset(stmtlevel - rootlevel );

  LoopTreeDepGraph *dg = comp.GetDepGraph();
  for (LoopTreeNode *n = root;
       n; n = (n->ChildCount() == 1)? n->FirstChild() : 0) { 
     if (!n->IncreaseLoopLevel())
        continue;
     index++;
     if (!LoopSlicable()(dg, index))
        continue;   
     CompSlice *slice = CreateCompSlice( rootlevel );
     bool r = LoopReversible()(dg, index);
     LoopTreeTraverseSelectStmt stmtIter(n);
     for (LoopTreeNode *s; (s = stmtIter.Current()); stmtIter++) 
       slice->SetSliceLoop( s, n, r, 0);
     result.Append(slice);   
  }
}
LoopTreeNode* DepCompCopyArrayCollect:: 
OutmostCopyRoot( CopyArrayUnit& unit, DepCompAstRefGraphCreate& refDep, LoopTreeNode* treeroot)
{
 LoopTreeNode* origroot = unit.root;
 while (unit.root != 0) {
    DepCompCopyArrayCollect::CopyArrayUnit::CrossGraph crossgraph(&refDep, unit);
      GraphEdgeIterator<DepCompCopyArrayCollect::CopyArrayUnit::CrossGraph>
          edges(&crossgraph);
    if (!edges.ReachEnd()) 
       break; 
     DepCompCopyArrayCollect::CopyArrayUnit::InsideGraph insidegraph(&refDep, unit);
     GraphEdgeIterator<DepCompCopyArrayCollect::CopyArrayUnit::InsideGraph> 
          ep(&insidegraph);
     for (  ;  !ep.ReachEnd(); ++ep) {
        if (!(*ep)->GetInfo().is_precise()) {
          break;
        }
     }
     if (!ep.ReachEnd())
        break;
     LoopTreeInterface interface;
     unit.root = GetEnclosingLoop(unit.root, interface);
  }
  LoopTreeNode* res = unit.root;
  if (res == 0)
     res = treeroot; 
  else if (res->LoopLevel() +1 == origroot->LoopLevel() && origroot->Parent()->ChildCount() == 1) {
     res = origroot->Parent();   
  }
  unit.root = origroot;
  return res;
}
Exemple #6
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;
}
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;
}
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); 
       }
    }
bool ParameterizeCopyArray::
CanBeBlocked( 
     DepCompCopyArrayCollect::CopyArrayUnit& unit, int copydim)
{
   if (copydim == 0) return false;
   
   int k = 0; /* number of sweeping loop dimensions */
   for (int i = 0; i < copydim; ++i) {
      bool sweeping = false; /*QY: any sweeping loops*/
      for (DepCompCopyArrayCollect::CopyArrayUnit::NodeSet::const_iterator 
              p = unit.refs.begin(); !p.ReachEnd(); ++p) {
          int j = 0; /*number of sweeping loop dimensions per array dimension*/
          for (LoopTreeNode* loop = (*p)->GetInfo().stmt->EnclosingLoop(); 
               loop!=0 && loop != unit.root; loop = loop->EnclosingLoop()) {
            AstNodePtr ref = (*p)->GetInfo().orig;
            if (!ReferenceDimension(ref, loop->GetLoopInfo()->GetVar().GetVarName(),i)) { ++j; sweeping=true; break; }
          }
          if (j > 1) return false; /*QY: multiple loops sweeping a dimension*/
      }
      if (sweeping) ++k;
   }
   if (k == 0) return false; /* QY: no sweeping dimensions*/
   return true;
}
LoopTreeNode* DependenceHoisting::
Transform ( LoopTreeDepComp &comp, 
            const CompSlice *slice, LoopTreeNode *h1)
{
  bool alreadySliced = true;
  for (CompSlice::ConstLoopIterator iter = slice->GetConstLoopIterator();
        iter.Current() != 0; iter.Advance()) {
      if (iter.Current() != h1) { alreadySliced = false; break; }
  }
  if (alreadySliced) return h1;

  SymbolicVar ivar = SliceLoopIvar( LoopTransformInterface::getAstInterface(), slice);
  SymbolicVal step = SliceLoopStep( slice).step;
  SymbolicBound bound = SliceLoopRange( slice, h1);
  LoopTreeNode *h2 = (step > 0)? comp.GetLoopTreeCreate()->CreateLoopNode(ivar,bound.lb,bound.ub,step)
                               : comp.GetLoopTreeCreate()->CreateLoopNode(ivar,bound.ub,bound.lb,step);
  LoopTreeTransform().InsertLoop(h2, h1, -1);

  CompSlice::ConstStmtIterator stmtIter=slice->GetConstStmtIterator();
  for (LoopTreeNode *stmt; (stmt = stmtIter.Current()); stmtIter++) {
      CompSlice::SliceStmtInfo info = stmtIter.CurrentInfo();
      LoopTreeMergeStmtLoop()( h2, info.loop, stmt, info.align);
  }

  CompSlice::UpdateLoopIterator loopIter= slice->GetUpdateLoopIterator();
  LoopTreeNode* loop;
  while ((loop = loopIter.Current())) {
     loopIter++;
     DepCompDistributeLoop()(comp,loop);
  }
  for (loopIter.Reset(); (loop = loopIter.Current()); loopIter++) {
    if (loopIter.CurrentInfo().stmtcount < CountEnclosedStmts(loop)){
      CompSlice::SliceLoopInfo info = loopIter.CurrentInfo();
      LoopTreeTraverseSelectStmt inStmts(loop);
      for (LoopTreeNode *s; (s = inStmts.Current()); ) {
        inStmts.Advance();
        CompSlice::SliceStmtInfo info1(slice->QuerySliceStmtInfo(s));
        if (info1.loop != loop)  {
          DepRel r ( DEPDIR_LE, info1.align - info.minalign);
          DepRel r1 = comp.GetDomain(s).Entry(info1.loop->LoopLevel(), loop->LoopLevel());
          DepRel r2 = r & r1;
          if (r2 != r1 && !r2.IsTop())
              LoopTreeSplitStmt()( s, info1.loop, loop, r);
        }
      }
      DepCompDistributeLoop()(comp, loop);
      loop = loopIter.Current();
      while (loopIter.CurrentInfo().stmtcount < CountEnclosedStmts(loop)) {
        while (loop->ChildCount() == 1) {
          LoopTreeNode* child = loop->FirstChild();
          LoopTreeSwapNodePos()( loop, child);
          if (child->IncreaseLoopLevel())
            break;
        }
        DepCompDistributeLoop()( comp, loop );
      }
    }
  }
  OptimizeLoopTree(h2);
  return h2;
}
void DependenceHoisting ::
Analyze( LoopTreeDepComp &comp, LoopTreeTransDepGraphCreate *tg, 
         CompSliceNest& result)
{
  LoopTreeInterface interface;
  LoopTreeNode *root = comp.GetLoopTreeRoot();
  int rootlevel = root->LoopLevel();
  int size, slicesize;
  GetLoopTreeSize(root, slicesize, size);
  size -= rootlevel;
  size *= slicesize;
 
  result.Reset(size);
  TransSlicingAnal* tmpSlices = new TransSlicingAnal[size];
  LoopAlignInfo* buf1 = new LoopAlignInfo[slicesize], *buf2 = new LoopAlignInfo[slicesize];
  for (int i = 0; i < size; ++i)
    tmpSlices[i].Reset(slicesize); 

  /* QY: 6/2009: create a tmporary slice for each individual slicable loop;
     i.e. for each loop that can be placed at the outermost position */
  LoopTreeTraverseSelectStmt stmtIter(root);
  LoopTreeNode *stmt = stmtIter.Current();
  if (stmt == 0) return;
  size = 0;
  int index = stmt->LoopLevel()-1;
  for (LoopTreeNode *loop = GetEnclosingLoop(stmt, interface); 
       index >= rootlevel; loop = GetEnclosingLoop(loop, interface)) {
    SliceInfo curloop(stmt, loop, index--);
    TransSlicingAnal anal;
    if (anal.LoopSlicible( comp, tg, curloop, buf1)) {
       tmpSlices[size++].CommitSliceInfo(curloop, buf1);
    }
  }

  /*QY:6/2009: try to expand each tmpSlice to include all statements */
  for (int sliceindex = 0; sliceindex < size; ++sliceindex) {
    TransSlicingAnal &anal = tmpSlices[sliceindex];
    stmtIter.Current() = anal.LastSliceStmt();
    /* QY:for each stmt, find a surrounding slicing loop to go with
       the loops already in the current slice (stored in anal) */
    for ( stmtIter++; (stmt= stmtIter.Current()); stmtIter++) {
      SliceInfo curloop(stmt);
      index = stmt->LoopLevel()-1;
      LoopTreeNode *loop = GetEnclosingLoop(stmt, interface);
      for ( ; index >= rootlevel; loop = GetEnclosingLoop(loop, interface)) {
        curloop.SetLoop(loop, index--);
        if (anal.LoopSlicible( comp, tg, curloop, buf1)) 
           break;
      } 
      if (loop == 0) /* QY: no slicable loop has been found for stmt */ 
         { break; }
      else {
         for (loop = GetEnclosingLoop(loop, interface);
              index >= rootlevel; loop = GetEnclosingLoop(loop, interface)) {
           SliceInfo curloop1(stmt, loop,index--);
           if (anal.LoopSlicible( comp, tg, curloop1, buf2) ) {
              tmpSlices[size++] = anal;
              tmpSlices[size-1].CommitSliceInfo( curloop1, buf2);
           }
         }
         /* commit the current loop/stmt as part of the current slice */
         anal.CommitSliceInfo(curloop, buf1);
      }
    }
    if (int(anal.NumberOfSliceStmts()) == slicesize) {
       /* QY: a slice is found that includes all statements */
      CompSlice *slice = CreateCompSlice(rootlevel);
      for (int i = 0; i < slicesize; ++i) {
        SliceInfo& info = anal.SliceLoop(i);
        slice->SetSliceLoop(info.stmt, info.loop, info.reversible,
                            info.alignInfo.mina); 
      }
      result.Append( slice ); 
    }
  }
  delete[] tmpSlices;
  delete[] buf1;
  delete[] buf2;
}
void CopyArrayUnderSizeLimit::
ModifyCopyArrayCollect( DepCompCopyArrayCollect& collect, DepCompAstRefGraphCreate& refDep)
{
   LoopTreeInterface interface;
   if (DebugCopyRoot()) 
      std::cerr << "copydim = " << copydim << std::endl;
   for (DepCompCopyArrayCollect::iterator arrays = collect.begin();
        arrays != collect.end(); ) {
       DepCompCopyArrayCollect::CopyArrayUnit& unit = *arrays;
       LoopTreeNode* origroot = unit.root;
       if (DebugCopySplit() || DebugCopyRoot()) 
         std::cerr << " modifying copy unit: " << IteratorToString2(unit.refs.begin()) << " with root = " << ((unit.root == 0)? "null" : unit.root->toString()) << std::endl;
       unit.root = collect.OutmostCopyRoot(unit, refDep, collect.get_tree_root());
       int curdim = -1;
       while (true) {
          DepCompCopyArrayCollect::CopyArrayUnit::NodeSet cuts;
          curdim = EnforceCopyDimension(unit, refDep, copydim, &cuts); 
          if (cuts.size() == 0)
               break;
          if (cuts.size() == unit.refs.size()) {
             assert(origroot != unit.root);
             LoopTreeNode* n = origroot, *p = GetEnclosingLoop(n,interface);
             LoopTreeNode* rootloop = (unit.root->GetLoopInfo() == 0)? 0 : unit.root;
             while (n != rootloop && p != rootloop) {
                 n = p;
                 p = GetEnclosingLoop(p, interface); 
             }
             if (DebugCopyRoot()) 
               std::cerr << "resetting copy root to be " << n->toString() << std::endl;
             unit.root = n;
             unit.carrybyroot = true;
             continue;
          }
          if (DebugCopySplit())
             std::cerr << "Enforce copy dimension by removing " << IteratorToString2(cuts.begin()) << std::endl;
          collect.AddCopyArray() = 
                DepCompCopyArrayCollect::CopyArrayUnit(cuts, collect.ComputeCommonRoot(cuts));
          unit.refs -= cuts;
          unit.root = origroot = collect.ComputeCommonRoot(unit.refs);
          unit.root = collect.OutmostCopyRoot(unit, refDep, collect.get_tree_root());
       }
       DepCompCopyArrayCollect::CopyArrayUnit::NodeSet cuts;
       if (SplitDisconnectedUnit(collect, unit, refDep,cuts))  {
          origroot = collect.ComputeCommonRoot(cuts);
          DepCompCopyArrayCollect::CopyArrayUnit::NodeSet left = unit.refs;
          if (DebugCopySplit() || DebugCopyRoot()) 
             std::cerr << " Spliting disconnected refs: removing " << IteratorToString2(cuts.begin()) << std::endl;
          left -= cuts;
          collect.AddCopyArray() = DepCompCopyArrayCollect::CopyArrayUnit(left,collect.ComputeCommonRoot(left));
          unit.refs = cuts;
          curdim = EnforceCopyDimension(unit, refDep, copydim); 
          assert(curdim <= (int)copydim);
       }    
       if (origroot != 0 && unit.root != origroot) {
           int reuselevel = OutmostReuseLevel( unit, refDep);
           int copylevel = unit.copylevel();
           if (reuselevel > copylevel) {
              LoopTreeNode *cur = origroot;  
              for (int curlevel = origroot->LoopLevel(); reuselevel  <= curlevel; 
                   cur = GetEnclosingLoop(cur, interface), --curlevel);
              if (DebugCopyRoot()) 
                  std::cerr << "After reuse anal, resetting copy root to be " << cur->toString() << std::endl;
              unit.root = cur;
              curdim -= (reuselevel - copylevel+1);
           }
           else if (DebugCopyRoot()) 
                std::cerr << "do not reset copy root because copylevel = " << copylevel << " and copy root = " << unit.root->toString() << std::endl;
       }
       DepCompCopyArrayCollect::iterator tmp = arrays;
       ++arrays;
       if (IsRedundantCopy( unit, curdim)) {
         if (DebugCopyRemove()) {
             std::cerr << "remove redundant copy " <<  IteratorToString2(unit.refs.begin()) << " with root = " << unit.root->toString() << std::endl;
         }
         collect.RemoveCopyArray(tmp);
       }
   }   
}