bool LoopTransformInterface::
IsDynamicFusionConfig( const AstNodePtr& n, AstNodePtr* configvar, int* configID,
                       AstInterface::AstNodeList* params)
{ assert(fa != 0);
  AstNodePtr invoc;
  if (!fa->IsAssignment(n, configvar, &invoc))
    return false;
  AstInterface::AstNodeList args;
  std::string sig;
  AstNodePtr f;
  if (!fa->IsFunctionCall(invoc, &f, &args) || !fa->IsVarRef(f, 0, &sig) )
    return false;
  if (sig == "DynamicFusionConfig") {
    if (configID != 0) {
      AstNodePtr idnode = args.front();
      bool isconst = fa->IsConstInt( idnode, configID);
      assert(isconst);
    } 
    if (params != 0) {
      *params = args;
      params->erase(params->begin()); 
      params->erase(params->begin());
    }
   return true;
  }
  return false;
}
AstNodePtr LoopTransformInterface::CreateDynamicFusionEnd( int id)
{ assert(fa != 0);
  AstInterface::AstNodeList args;
  args.push_back( fa->CreateConstInt(id).get_ptr());
  std::string funname = "DynamicFusionEnd";
  return fa->CreateFunctionCall(funname, args.begin(), args.end());
}
Beispiel #3
0
CopyArrayConfig 
ComputeCopyConfig( const DepCompAstRefAnal& stmtorder,
                   const DepCompCopyArrayCollect::CopyArrayUnit& unit,
                   const DepCompAstRefGraphNode* initcut)
{
    assert (unit.refs.size() > 0);

    AstInterface& ai = LoopTransformInterface::getAstInterface();
    const DepCompAstRef& initInfo = initcut->GetInfo();

    AstNodePtr lhs;
    bool is_init = ai.IsAssignment(initInfo.stmt->GetOrigStmt(), &lhs) 
                   && (lhs == initcut->GetInfo().orig);
    AstNodeType inittype;
    if (ai.IsExpression(initInfo.orig, &inittype)==AST_NULL)
      assert(false);
    bool has_write = false;

    AstNodePtr arr;
    std::string arrname, elemtypename;
    ai.GetTypeInfo(inittype, 0, &elemtypename); //QY: strip out ref info &
    AstNodeType elemtype = ai.GetType(elemtypename);

    AstInterface::AstNodeList initIndex;
    if (!LoopTransformInterface::IsArrayAccess(initInfo.orig, &arr, &initIndex) || !ai.IsVarRef(arr,0,&arrname))
       assert(false);

    SelectArray cursel(elemtype, arrname, initIndex.size());
    cursel.select(initInfo.stmt, unit.root, initIndex);

    for (DepCompCopyArrayCollect::CopyArrayUnit::NodeSet::const_iterator p = unit.refs.begin();
          !p.ReachEnd(); ++p)  {
        const DepCompAstRefGraphNode* curref = *p;
        const DepCompAstRef& curinfo = curref->GetInfo();
        if (stmtorder.is_mod_ref(curinfo.orig))
            has_write = true;
        AstInterface::AstNodeList curIndex;
        if (!LoopTransformInterface::IsArrayAccess(curinfo.orig, 0, &curIndex))
           assert(false);
        if (cursel.select(curinfo.stmt, unit.root, curIndex)) 
          is_init = false;
   }
   cursel.set_bufsize(ai);
   LoopTreeNode* shift = 0;
   if (unit.carrybyroot)
       shift = unit.root; 
   int copyopt = 0;
   if (!is_init) 
      copyopt |= INIT_COPY;
   if  (has_write)
      copyopt |= SAVE_COPY;
      
   CopyArrayOpt opt = (CopyArrayOpt)copyopt;
   CopyArrayConfig curconfig(ai, cursel, opt, shift);
   return curconfig;
}
Beispiel #4
0
AstNodePtr LoopTransformInterface:: 
CreateDynamicFusionConfig( const AstNodePtr& groupNum, AstInterface::AstNodeList& args, int &id)
{ assert(fa != 0); 
  std::string name = "DynamicFusionConfig";
  ++configIndex;
  args.push_front( fa->CreateConstInt( args.size() ) );
  args.push_front( fa->CreateConstInt(configIndex) );
  AstNodePtr invoc = fa->CreateFunctionCall( "DynamicFusionConfig",  args); 
  return fa->CreateAssignment ( groupNum, invoc) ;
}
AstNodePtr LoopTransformInterface:: 
CreateDynamicFusionConfig( const AstNodePtr& groupNum, AstInterface::AstNodeList& args, int &id)
{ assert(fa != 0); 
  std::string name = "DynamicFusionConfig";
  ++configIndex;
  args.push_back( fa->CreateConstInt(configIndex).get_ptr() );
  args.push_back( fa->CreateConstInt( args.size() ).get_ptr() );
  std::string funname = "DynamicFusionConfig";
  AstNodePtr invoc = fa->CreateFunctionCall( funname,  args.begin(), args.end()); 
  return fa->CreateAssignment ( groupNum, invoc) ;
}
Beispiel #6
0
AstNodePtr ArrayUseAccessFunction::
CreateArrayAccess( AstInterface& fa, const AstNodePtr& arr,
                                AstInterface::AstNodeList& index)
{
  if (prev != 0)
     return prev->CreateArrayAccess(fa, arr, index);
  if (index.size() > 1) {
     AstInterface::AstNodeList tmp = index;
     tmp.push_front(arr);
     return fa.CreateFunctionCall(funcname, tmp);
  }
  else 
     return fa.CreateArrayAccess(arr, index);
}
Beispiel #7
0
AstNodePtr SymbolicSelect:: CodeGen(  AstInterface &fa ) const
   {
      int size = 0;
      AstInterface::AstNodeList list;
      for (OpdIterator iter = GetOpdIterator(); !iter.ReachEnd(); iter.Advance()) {
           AstNodePtr p = Term2Val(iter.Current()).CodeGen(fa);
           list.push_back(p);
           ++size;
      }
      assert( size > 1);
      std::string func = (opt< 0)? "min" : "max";

      return fa.CreateFunctionCall(func, list);
   }
ReplaceParams:: 
ReplaceParams ( const ParamDescriptor& decl, AstInterface::AstNodeList& args,
                Map2Object<AstInterface*,AstNodePtr,AstNodePtr>* codegen)
{
  assert(decl.size() == args.size());
  int index = 0;
  for (AstInterface::AstNodeList::iterator p1 = args.begin();
       p1 != args.end(); ++p1, ++index) {
    AstNodePtr curAst = *p1;
    string curpar = decl[index];
    SymbolicAstWrap curarg(curAst, codegen);
    parmap[curpar] = curarg;
  }
}
Beispiel #9
0
AstNodePtr ArrayInterface::
impl_access_array_elem (CPPAstInterface& fa, const AstNodePtr& array,
                           const AstInterface::AstNodeList& ivarAst)
{
  SymbolicFunctionDeclarationGroup elem;

  ArrayOptDescriptor desc;
  if (get_array_opt(fa, array, desc)) 
  {
    elem = desc.get_elem();
  }
  else 
  {
    ArrayDefineDescriptor desc1;
    if (!ArrayAnnotation::get_inst()->known_array( fa, array, &desc1))
      assert(false);
    elem = desc1.get_elem();
  }
  elem.replace_var("this", SymbolicAstWrap(array));
  elem.replace_var( "dimension", ivarAst.size());
  AstNodePtr r;
  if (! elem.get_val(fa, ivarAst, r))
     assert(false);
  return r;
}
Beispiel #10
0
AstNodePtr LoopTransformInterface::
CreateArrayAccess(const std::string& arrname, 
                            const std::vector<SymbolicVal>& arrindex) 
  {
     assert(fa != 0);
     AstInterface::AstNodeList indexlist;
     for (std::vector<SymbolicVal>::const_iterator indexp = arrindex.begin();
          indexp != arrindex.end(); ++indexp) {
         AstNodePtr cur = (*indexp).CodeGen(*fa);
         if (cur == AST_NULL) {
            std::cerr << "Empty AST from Symbolic Val: " << (*indexp).toString() << "\n";
            assert(0);
         }
         indexlist.push_back(cur);
     }
     AstNodePtr res = CreateArrayAccess(fa->CreateVarRef(arrname),indexlist);
     return res;
   }
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;
}
bool ArrayUseAccessFunction::get_read(AstInterface& fa, const AstNodePtr& fc,
                               CollectObject<AstNodePtr>* collect)
{
  AstInterface::AstNodeList args;
  if (prev1 != 0 && prev1->get_read(fa, fc, collect))
       return true;
  std::string sig;
  AstNodePtr f;
  if (fa.IsFunctionCall(fc, &f,&args) && fa.IsVarRef(f,0,&sig) && sig == funcname) {
       if (collect != 0)  {
           AstInterface::AstNodeList::const_iterator argp = args.begin();
           for ( ++argp; argp != args.end(); ++argp) {
              (*collect)(*argp);
           }
       }
       return true;
  }
  return false;
}
bool ArrayUseAccessFunction::
IsArrayAccess( AstInterface& fa, const AstNodePtr& s, AstNodePtr* array, 
                                 AstInterface::AstNodeList* index) 
{
  AstInterface::AstNodeList args;
  if (prev != 0 &&  prev->IsArrayAccess(fa, s, array, index))
       return true;
  std::string sig;
  AstNodePtr f;
  if (fa.IsFunctionCall(s, &f,&args) && fa.IsVarRef(f,0,&sig) && sig == funcname) {
      AstInterface::AstNodeList::const_iterator p = args.begin();
      if (array != 0)
        *array = *p;
      if (index != 0) {
         for (++p; p != args.end(); ++p) {
            index->push_back(*p);
         }
      }
      return true;
  }
  return false;
}
Beispiel #14
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); 
       }
    }
Beispiel #15
0
AstNodePtr ArrayInterface::
impl_reshape_array( CPPAstInterface& fa, 
                    const AstNodePtr& array,
                    AstInterface::AstNodeList& ivarAst)
{
  ArrayDefineDescriptor desc;
  if (!ArrayAnnotation::get_inst()->known_array( fa, array, &desc))
    return AST_NULL;

  SymbolicFunctionDeclarationGroup reshape = desc.get_reshape();
  reshape.replace_var( "this", SymbolicAstWrap(array));
  reshape.replace_var( "dimension", ivarAst.size());

  AstNodePtr r;
  if (!reshape.get_val( fa, ivarAst, r)) {
     std::cerr << "Error: cannot extract value from reshape spec: \n";
     reshape.write(std::cerr);
     std::cerr << std::endl;
     assert(false);
  }
  return r;
}
Beispiel #16
0
SymbolicVal SymbolicValGenerator ::
GetSymbolicVal( AstInterface &fa, const AstNodePtr& exp)
{
  std::string name;
  AstNodePtr scope;
  int val = 0;
  AstNodePtr s1, s2;
  AstInterface::AstNodeList l;
  AstInterface::OperatorEnum opr = (AstInterface::OperatorEnum)0;
  if (fa.IsVarRef(exp, 0, &name, &scope)) {
     return new SymbolicVar( name, scope );
  }
  else if (fa.IsConstInt(exp, &val)) {
     return new SymbolicConst( val );
  }
  else if (fa.IsBinaryOp(exp, &opr, &s1, &s2)) {
     SymbolicVal v1 = GetSymbolicVal( fa, s1 ), v2 = GetSymbolicVal(fa, s2);
     switch (opr) {
     case AstInterface::BOP_TIMES: return v1 * v2;
     case AstInterface::BOP_PLUS: return v1 + v2;
     case AstInterface::BOP_MINUS: return v1 - v2;
     case AstInterface::BOP_DOT_ACCESS:
     case AstInterface::BOP_ARROW_ACCESS: 
     case AstInterface::BOP_DIVIDE:
        return new SymbolicFunction( opr, "/", v1,v2);
     case AstInterface::BOP_EQ: 
        return new SymbolicFunction( opr, "==", v1,v2);
     case AstInterface::BOP_LE: 
        return new SymbolicFunction( opr, "<=", v1,v2);
     case AstInterface::BOP_LT: 
        return new SymbolicFunction( opr, "<", v1,v2);
     case AstInterface::BOP_NE: 
        return new SymbolicFunction( opr, "!=", v1,v2);
     case AstInterface::BOP_GT: 
        return new SymbolicFunction( opr, ">", v1,v2);
     case AstInterface::BOP_GE: 
        return new SymbolicFunction( opr, ">=", v1,v2);
     case AstInterface::BOP_AND: 
        return new SymbolicFunction( opr, "&&", v1,v2);
     case AstInterface::BOP_OR:
        return new SymbolicFunction( opr, "||", v1,v2);
     default:
        assert(false);
     }
  }
  else if (fa.IsUnaryOp(exp, &opr, &s1)) {
    SymbolicVal v = GetSymbolicVal( fa, s1);
    switch (opr) {
    case AstInterface::UOP_MINUS: 
        return (-1) * v; 
    case AstInterface::UOP_ADDR:
        return new SymbolicFunction( opr, "&", v);
    case AstInterface::UOP_DEREF: 
        return new SymbolicFunction( opr, "*", v);
    case AstInterface::UOP_ALLOCATE:
        return new SymbolicFunction( opr, "new", v);
    case AstInterface::UOP_NOT:
        return new SymbolicFunction( opr, "!", v);
    case AstInterface::UOP_CAST:
        return new SymbolicFunction( opr, "cast", v);
    case AstInterface::UOP_DECR1:
        return new SymbolicFunction( opr, "--", v);
    case AstInterface::UOP_INCR1:
        return new SymbolicFunction( opr, "++", v);
    default:
       std::cerr << "Cannot handle " << AstToString(exp) << ":" << opr << "\n";
       assert(false);
     }
  }
  else if (fa.IsFunctionCall(exp, &s1, &l)) { 
     bool ismin = fa.IsMin(s1), ismax = fa.IsMax(s1);
     AstInterface::AstNodeList::const_iterator p = l.begin();
     if (ismin || ismax) {
       AstNodePtr s = *p;
       SymbolicVal v = GetSymbolicVal( fa, s );  
       for ( ++p; p != l.end(); ++p ) {
           s = *p;
           v = (ismin)? Min(v, GetSymbolicVal(fa, s)) 
                        : Max(v, GetSymbolicVal(fa, s));
       }
       return v;
     }
     if (fa.IsVarRef(exp, 0, &name)) {    
        SymbolicFunction::Arguments args;
        for ( ; p != l.end(); ++p) { 
           SymbolicVal cur = GetSymbolicVal(fa, *p);
           args.push_back( cur );
        }
        return new SymbolicFunction( AstInterface::OP_NONE, name, args);
     }
  } 
  return new SymbolicAstWrap(exp);
}
Beispiel #17
0
AstNodePtr SymbolicFunction :: CodeGen( AstInterface &_fa) const
{
  AstInterface::AstNodeList l;
  for (const_iterator i = args.begin(); i != args.end(); ++i) {
     SymbolicVal cur = *i;
     AstNodePtr curast = cur.CodeGen(_fa); 
     l.push_back(curast);
  }
  if (t == AstInterface::OP_NONE) {
     return _fa.CreateFunctionCall( op, l);
  }
  else if (t == AstInterface::OP_ARRAY_ACCESS) {
        AstNodePtr arr = l.front();
        l.pop_front();
        return _fa.CreateArrayAccess(arr, l);
     }
  else if (t == AstInterface::OP_ASSIGN && l.size() == 2) {
        return _fa.CreateAssignment(l.front(), l.back());
     }
  else if (l.size() == 2) 
      return _fa.CreateBinaryOP( t, l.front(), l.back());
  else {
      assert(l.size() == 1);
      return _fa.CreateUnaryOP( t, l.front());
  }
}
Beispiel #18
0
bool ArrayInterface ::
may_alias(AstInterface& _fa, const AstNodePtr& r1, const AstNodePtr& r2)
{
  CPPAstInterface& fa = static_cast<CPPAstInterface&>(_fa);
  AstNodePtr array1, array2;
  ArrayAnnotation* annot = ArrayAnnotation::get_inst();
  bool elem1 = annot->is_access_array_elem( fa, r1, &array1) ;
  bool len1 = annot->is_access_array_length( fa, r1, &array1);
  bool elem2 = annot->is_access_array_elem( fa, r2, &array2);
  bool len2 = annot->is_access_array_length( fa, r2, &array2);

  if ( (elem1 && len2) || (len1 && elem2))  {
     return false;
  } 
  else if ( (elem1 && elem2)  || (len1 && len2)) {
     if (may_alias(fa, array1, array2)) {
        if (DebugAliasAnal())
            std::cerr << "has alias between " << AstInterface::AstToString(r1) << " and " << AstInterface::AstToString(r2) << std::endl;
        return true;
     }
  }
  else if (elem1 || len1) {
     if (may_alias(fa, array1, r2)) {
        if (DebugAliasAnal())
            std::cerr << "has alias between " << AstInterface::AstToString(r1) << " and " << AstInterface::AstToString(r2) << std::endl;
        return true;
     }
  }
  else if (elem2 || len2) {
     if (may_alias(fa, r1, array2)) {
        if (DebugAliasAnal())
            std::cerr << "has alias between " << AstInterface::AstToString(r1) << " and " << AstInterface::AstToString(r2) << std::endl;
        return true;
     }
  }
  else {
     AstInterface::AstNodeList args;
     if (annot->is_array_construct_op( fa, r1, &args)) {
        for (AstInterface::AstNodeList::iterator p = args.begin();
             p != args.end(); ++p) {
          AstNodePtr cur = *p;
          if (may_alias( fa, cur, r2)) {
            if (DebugAliasAnal())
               std::cerr << "has alias between " << AstInterface::AstToString(r1) << " and " << AstInterface::AstToString(r2) << std::endl;
             return true;
          }
        }
        return false;    
     }
     else if (annot->is_array_construct_op( fa, r2, &args)) {
        for (AstInterface::AstNodeList::iterator p = args.begin();
             p != args.end(); ++p) {
          AstNodePtr cur = *p;
          if (may_alias( fa, cur, r1)) {
            if (DebugAliasAnal())
               std::cerr << "has alias between " << AstInterface::AstToString(r1) << " and " << AstInterface::AstToString(r2) << std::endl;
             return true;
          }
        }
        return false;
     }
     return aliasCollect.may_alias( fa, r1, r2);
  }
  return false;
}
Beispiel #19
0
AstNodePtr LoopTransformInterface::CreateDynamicFusionEnd( int id)
{ assert(fa != 0);
  AstInterface::AstNodeList args;
  args.push_back( fa->CreateConstInt(id));
  return fa->CreateFunctionCall("DynamicFusionEnd", args);
}