예제 #1
0
  virtual bool Traverse( AstInterface &fa, const AstNodePtr& s,
                               AstInterface::TraversalVisitType t)
   {
       HasValueMapReplace valrepl( fa, valmap, false);
       if (ValueAnnotation::get_inst()->is_value_restrict_op( fa, s, &append, &valrepl, &astcodegen)) 
             return true;
       AstNodePtr lhs, rhs;
       AstInterface::AstNodeList vars, args;
       HasValueDescriptor desc;
       if (fa.IsAssignment(s, &lhs, &rhs)) {
          if (append.has_value( rhs, &desc) ) {
             append( lhs, desc);
          }
       }
       else if (fa.IsVariableDecl( s, &vars, &args)) {
          AstInterface::AstNodeList::iterator pv = vars.begin();
          AstInterface::AstNodeList::iterator pa = args.begin();
          while (pv != vars.end()) {
            lhs = *pv;
            rhs = *pa;
            if (append.has_value( rhs, &desc) ) {
                append( lhs, desc );
            }
            ++pv;
            ++pa;
          }
       }

       return true;
   } 
예제 #2
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;
}
예제 #3
0
AstNodePtr  SymbolicConst :: CodeGen(AstInterface &fa) const
{
  if (type == "int")
    return fa.CreateConstInt(intval);
  else
    return fa.CreateConstant( type, val);
}
예제 #4
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());
  }
}
예제 #5
0
void PtrAnal::
ProcessMod(AstInterface& fa, const std::string& readname, 
          std::list<std::string>& fields, const AstNodePtr& mod)
{
  std::string modname;
  AstNodePtr p = mod;
  if (fa.IsVarRef(mod) || fa.IsArrayAccess(mod, &p)) {
      modname = Get_VarName(fa,p);
      Stmt stmt_last = fields.size()?
                      field_x_eq_y(modname, fields, readname)
                     : x_eq_y(modname, readname);
      stmts_pushback(stmts,stmt_last);
      namemap[mod.get_ptr()] = VarRef(stmt_last,modname);
  }
  else {
     AstInterface::OperatorEnum op;
     AstNodePtr p2;
     if (fa.IsUnaryOp(mod,&op, &p) && op == AstInterface::UOP_DEREF) {
            std::string lhs = Get_VarName(fa,p); 
            Stmt stmt_last  = deref_x_eq_y(lhs, fields, readname); 
            stmts_pushback(stmts,stmt_last);
            namemap[p.get_ptr()] = VarRef(stmt_last,lhs);
            namemap[mod.get_ptr()] = VarRef(stmt_last, readname);
     }
    else if (fa.IsBinaryOp(mod,&op,&p,&p2)) { 
         if (op==AstInterface::BOP_DOT_ACCESS) {
            std::string field = Local_GetFieldName(fa, p2);
            fields.push_front(field);
            ProcessMod(fa, readname, fields, p);
            Stmt stmt_last = stmts_back(stmts);
            namemap[mod.get_ptr()] = VarRef(stmt_last, readname);
         }
         else if (op==AstInterface::BOP_ARROW_ACCESS) {
            std::string lhs = Get_VarName(fa, p), field = Local_GetFieldName(fa, p2);
            fields.push_front(field);
            Stmt stmt_last  = deref_x_eq_y(lhs,fields,readname);
            stmts_pushback(stmts,stmt_last);
            namemap[p.get_ptr()] = VarRef(stmt_last,lhs);
            namemap[mod.get_ptr()] = VarRef(stmt_last, readname);
         }
         else {
            std::cerr << "can't handle " << AstToString(mod) << "\n";
            assert(false); // other operations? to be handled later  
         }
     }
     else if (fa.IsFunctionCall(mod)) {
         std::string lhs = Get_VarName(fa, mod);
         Stmt stmt_last = deref_x_eq_y(lhs, fields, readname);
         stmts_pushback(stmts,stmt_last);
         namemap[mod.get_ptr()] = VarRef(stmt_last,lhs);
     }
     else {
       std::cerr << "cannot process " << AstToString(mod) << "\n";
       assert(false); // other operations? to be handled later  
    }
  }
}
예제 #6
0
AstNodePtr SymbolicMultiply::
CodeGenOP( AstInterface &fa, const AstNodePtr& a1, const AstNodePtr& a2) const
  { 
    int val = 0;
    if (fa.IsConstInt(a1, &val) && val == -1)
        return fa.CreateUnaryOP(AstInterface::UOP_MINUS, a2);
    else if (fa.IsConstInt(a2, &val) && val == -1)
        return fa.CreateUnaryOP(AstInterface::UOP_MINUS, a1);
    return fa.CreateBinaryOP(AstInterface::BOP_TIMES, a1, a2); 
  }
예제 #7
0
  bool operator()( AstInterface& fa, const AstNodePtr& head, AstNodePtr& result)
  {  
#ifdef DEBUG
std::cerr << "LoopTransformationWrap:operator()\n";
#endif
     if (!fa.IsStatement(head))
         return false;
     fa.SetRoot( head);
     return LoopTransformation(head, result);
  }
예제 #8
0
bool ArrayUseAccessFunction::get_modify(AstInterface& fa, const AstNodePtr& fc,
                               CollectObject<AstNodePtr>* collect)
{
  AstInterface::AstNodeList args;
  if (prev1 != 0 && prev1->get_modify(fa, fc, collect))
       return true;
  std::string sig;
  AstNodePtr f;
  if (fa.IsFunctionCall(fc, &f,&args) && fa.IsVarRef(f,0,&sig) && sig == funcname) {
       return true;
  }
  return false;
}
예제 #9
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);
}
예제 #10
0
AstNodePtr SymbolicAstWrap::CodeGen( AstInterface &fa) const
      { 
         if (codegen == 0)
             return fa.CopyAstTree(ast);
         else
             return (*codegen)(&fa, ast);
      }
예제 #11
0
bool BuildAstTreeDepGraph::
ProcessLoop( AstInterface &fa, const AstNodePtr& l, const AstNodePtr& body,
                      AstInterface::TraversalVisitType t)
{
  if (t == AstInterface::PreVisit) {
    GraphAccessInterface::Node *n = graph->CreateNodeImpl(l, GetStmtDomain(l));
    AstNodePtr init,cond,incr;
    if (!fa.IsLoop(l, &init, &cond, &incr))
        assert(false);
    for (StmtStackType::Iterator p(stmtNodes); !p.ReachEnd(); ++p) {
      if (init != AST_NULL)
         ComputeDataDep(*p, StmtNodeInfo(n,init), DEPTYPE_DATA );
      if (cond != AST_NULL)
         ComputeDataDep(*p, StmtNodeInfo(n,cond), DEPTYPE_DATA );
      if (incr != AST_NULL)
         ComputeDataDep(*p, StmtNodeInfo(n,incr), DEPTYPE_DATA );
    }
    for (StmtStackType::Iterator ps(gotoNodes); !ps.ReachEnd(); ++ps) {
        StmtNodeInfo info(n,l);
        ComputeCtrlDep((*ps), info);
    }
    ctrlNodes.PushFirst(StmtNodeInfo(n,l) );
  }
  else {
    ctrlNodes.PopFirst();
  }
  return ProcessAstTree::ProcessLoop(fa, l, body, t);
}
예제 #12
0
static bool 
AliasAnnotAnal(AstInterface& fa, 
               OperatorAnnotCollection <OperatorAliasDescriptor>& aliasInfo,
               const AstNodePtr& fc, const AstNodePtr& result, 
               CollectObject< pair<AstNodePtr, int> >& collectalias)
{
  AstInterface::AstNodeList args;
  OperatorAliasDescriptor desc; 
  if (!aliasInfo.known_operator( fa, fc, &args, &desc, false) )
    return false;
  ReplaceParams paramMap( desc.get_param_decl().get_params(), args);
  paramMap.add("result", result);
  int index = 0;
  for (OperatorAliasDescriptor::const_iterator p1 = desc.begin();
       p1 != desc.end(); ++p1, ++index) {
    const NameGroup& cur = *p1;
    for (NameGroup::const_iterator p2 = cur.begin(); 
         p2 != cur.end(); ++p2) {
      string varname = *p2;
      AstNodePtr arg = paramMap.find(varname).get_ast();
      if (arg != AST_NULL) {
        collectalias( pair<AstNodePtr, int>(arg, index));
      }
      else {
        AstNodePtr var = fa.CreateVarRef(varname);
        collectalias( pair<AstNodePtr, int>(var, index));
      }
    }
  }
  return true;
}
예제 #13
0
bool ArrayUseAccessFunction::
GetArrayBound( AstInterface& fa, const AstNodePtr& array,
                                 int dim, int &lb, int &ub)
{
  if (prev != 0)
     return prev->GetArrayBound(fa, array, dim, lb, ub);
  return fa.GetArrayBound(array, dim, lb, ub);
}
예제 #14
0
bool PtrAnal::
may_alias(AstInterface& fa, const AstNodePtr& _r1, const AstNodePtr& _r2)
{
  AstNodePtr r1 = fa.IsExpression(_r1);
  AstNodePtr r2 = fa.IsExpression(_r2);
  if (r1 == AST_NULL || r2 == AST_NULL)
    assert(false);
  std::string varname1 = Get_VarName(fa, r1), varname2 = Get_VarName(fa, r2);
  return may_alias(varname1, varname2);
}
예제 #15
0
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;
}
예제 #16
0
bool ArrayUseAccessFunction:: 
IsUniqueArray( AstInterface& fa, const AstNodePtr& array)
{
  if (prev != 0 &&  prev->IsUniqueArray(fa, array))
       return true;
  AstNodeType t;
  if (!fa.IsVarRef(array, &t)) assert(0);
  
  return false;
}
예제 #17
0
static std::string 
Local_GetFieldName(AstInterface& fa, const AstNodePtr& field)
{
   std::string name;
   if (fa.IsVarRef(field, 0, &name)) {
       assert(name != "");
       return "d:" + name;
    }
   std::cerr << "Not field name: " << AstToString(field) << "\n";
    assert(false);
}
예제 #18
0
  virtual bool Traverse( AstInterface &fa, const AstNodePtr& _n,
                            AstInterface::TraversalVisitType t) 
 {
      AstNodePtr n = fa.IsExpression(_n); 
      if (n != AST_NULL) {
         PtrAnal::VarRef p = m.translate_exp(n);
         if (p.name != "") {
           std::cout << AstInterface::AstToString(n) << ":" << 
            ((long) p.stmt) << p.name << "\n"; 
         }
     }
     else if (fa.IsStatement(_n)) {
         PtrAnal::StmtRef p = m.translate_stmt(_n);
         if (p.size()) {
           std::cout << AstInterface::AstToString(_n) << ":" << 
            ((long) p.front()) << "->" << ((long)p.back()) << "\n"; 
         }
     }
      return true;
 }
예제 #19
0
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;
}
예제 #20
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);
   }
예제 #21
0
AstNodePtr SymbolicPlus::
CodeGenOP( AstInterface &fa, const AstNodePtr& a1, const AstNodePtr& a2) const
 { 
    AstNodePtr opd;
    AstInterface::OperatorEnum opr;
    if (fa.IsUnaryOp(a2, &opr, &opd) && opr == AstInterface::UOP_MINUS) {
      return fa.CreateBinaryOP(AstInterface::BOP_MINUS,a1, fa.CopyAstTree(opd));
    }
    else if (fa.IsUnaryOp(a1, &opr, &opd) && opr == AstInterface::UOP_MINUS) {
      return fa.CreateBinaryOP(AstInterface::BOP_MINUS,a2, fa.CopyAstTree(opd));
    }
    return fa.CreateBinaryOP(AstInterface::BOP_PLUS, a1, a2); 
 }
예제 #22
0
//! Get a unique string name for a type, similar to qualified names in C++
string OperatorDeclaration:: 
get_signiture( AstInterface& fa, const std::string& fname,
                                    const AstInterface::AstTypeList& plist)
{
  std::string r = fname;
  if (!unique)
    for ( AstInterface::AstTypeList::const_iterator p = plist.begin();
          p != plist.end();  ++p) {
      AstNodeType t = *p;
      string name;
      fa.GetTypeInfo( t, &name); 
      r = r + "_" + name;
    }
  return r;
}
예제 #23
0
AstNodePtr ArrayUseAccessFunction::
CreateArrayAccess( AstInterface& fa, const AstNodePtr& arr,
                                const AstNodeList& index)
{
  AstNodePtr r;
  if (prev != 0)
     r =  prev->CreateArrayAccess(fa, arr, index);
  if (r == AST_NULL) {
    AstNodeList nindex;
    nindex.push_back(arr.get_ptr());
    for (AstNodeList::const_iterator p = index.begin(); p != index.end(); ++p) 
       nindex.push_back(*p);
    r = fa.CreateFunctionCall(funcname,nindex.begin(), nindex.end()) ;
  }
  return r;
}
예제 #24
0
void DefUseChain<Node>::
build( AstInterface& fa, AstNodePtr root, AliasAnalysisInterface* alias, 
       FunctionSideEffectInterface *f)
{
   StmtVarAliasCollect defaultAlias;

   ReachingDefinitionAnalysis reachingDef;
   reachingDef(fa, root);
   if (alias == 0) {
      alias = &defaultAlias;
      AstNodePtr defn = fa.GetFunctionDefinition(root); 
      assert(defn != AST_NULL);    
      defaultAlias(fa, defn);
   }
   build(fa, reachingDef,*alias, f);
}
예제 #25
0
void OperatorSideEffectDescriptor::
get_side_effect( AstInterface& fa,
                 AstInterface::AstNodeList& args, CollectObject< AstNodePtr >& collect)
{
  ReplaceParams paramMap( get_param_decl().get_params(), args);
  for (OperatorSideEffectDescriptor::const_iterator p = begin(); p != end(); ++p) {
      string varname = *p;
      AstNodePtr arg = paramMap.find(varname).get_ast();
      if (arg != AST_NULL) {
        collect( arg);
      }
      else {
        AstNodePtr var = fa.CreateVarRef(varname);
        collect( var);
      }
  }
}
예제 #26
0
void ReachingDefinitionBase::
collect_refs ( AstInterface& fa, const AstNodePtr& h, FunctionSideEffectInterface* a,
               AstInterface::AstNodeList* in)
{ 

  for (AstInterface::AstNodeList::iterator p = in->begin();
       p != in->end(); ++p) {
     AstNodePtr cur = *p;
     std::string varname;
     AstNodePtr scope;
     if (fa.IsVarRef( cur, 0, &varname, &scope))
        add_ref(varname, scope, std::pair<AstNodePtr, AstNodePtr>(cur, AST_NULL) ); 
  }
  ConstructReachingDefinitionBase collect(fa, *this);
  StmtSideEffectCollect op(a);
  op(fa, h, &collect);
}
예제 #27
0
void ReachingDefinitionAnalysis:: FinalizeCFG( AstInterface& fa)
{
  ReachingDefinitions in = g->get_empty_set();
  for (AstInterface::AstNodeList::iterator p = pars.begin();
       p != pars.end(); ++p) {
      AstNodePtr cur = *p;
      std::string name;
      AstNodePtr scope;
      if (fa.IsVarRef(cur, 0, &name, &scope))
         g->add_def( in, name, scope, std::pair<AstNodePtr,AstNodePtr>(cur,AST_NULL));
  } 
  NodeIterator p = GetNodeIterator();
  (*p)->finalize( fa, *g, a, &in);
  for ( ++p;!p.ReachEnd(); ++p) {
    (*p)->finalize(fa, *g, a);
  }
}
예제 #28
0
std::string PtrAnal:: 
Get_VarName(AstInterface& fa, const AstNodePtr& rhs)
{
  NameMap::const_iterator p = namemap.find(rhs.get_ptr());
  if (p != namemap.end()) {
     VarRef cur = (*p).second;
     return cur.name;
  }

   std::string readname, res;
   AstNodePtr readscope; 
   AstNodePtr lhs1, rhs1;
   bool readlhs;

   if (fa.IsVarRef(rhs, 0, &readname, &readscope))  {
       assert(readname != "");
       res = Local_GetVarName(fa, readscope, readname); 
    }
   else if (fa.IsConstant(rhs,&res,&readname)) {
      if (res == "string") {
         readname =  Local_GetVarName(fa, rhs);
         Stmt stmt = allocate_x(readname);
         stmts_pushback(stmts,stmt);
         res= readname;
      }
      else
         res = Local_GetConstName(fa, readname);
   }
   else if (fa.IsUnaryOp(rhs) || fa.IsBinaryOp(rhs) || fa.IsFunctionCall(rhs)) {
        readname = Local_GetVarName(fa, rhs);
        ProcessExpression(fa, readname, rhs);
        res = readname;
   }
   else if (fa.IsAssignment(rhs,&lhs1,&rhs1,&readlhs)) {
        ProcessAssign(fa, lhs1, rhs1, readlhs);
        VarRef cur = namemap[lhs1.get_ptr()];
        if (cur.name == "") {
           std::cerr << "does not have map for " << AstToString(lhs1) << " in " << AstToString(rhs) << "\n";
           assert(0);
        }
        namemap[rhs.get_ptr()] = cur;
        res = cur.name;
   }
   else  {
      std::cerr << "No name found for " << AstToString(rhs) << "\n";
      assert(false);
   }
   if (res == "") {
      std::cerr << "No name found for " << AstToString(rhs) << "\n";
      assert(false);
   }
   return res;
}
예제 #29
0
void ReachingDefinitionAnalysis:: 
operator()( AstInterface& fa, const AstNodePtr& h,  FunctionSideEffectInterface* anal)
{
  assert( g == 0 && pars.size() == 0);

  AstNodePtr body = h;
  if (!fa.IsFunctionDefinition( h, 0, &pars, 0, &body))
     ;//assert(false);

  ReachingDefinitionBase base;
  base.collect_refs( fa, body, anal, &pars);
  base.finalize();
  g = new ReachingDefinitionGenerator( base);
 
  a = anal;

  if (DebugReachingDef())
     std::cerr << "start building reaching definitions \n";
  DataFlowAnalysis<ReachingDefNode, ReachingDefinitions>::operator()( fa, h);
  if (DebugReachingDef()) 
     std::cerr << "finished building reaching definitions \n" << GraphToString(*this);
}
예제 #30
0
void PtrAnal:: operator()( AstInterface& fa, const AstNodePtr& funcdef)
{
  AstNodePtr  body;
  AstInterface::AstNodeList params, outpars;
  std::string fname;
  if (!fa.IsFunctionDefinition(funcdef, &fname, &params, &outpars, &body)) {
     std::cerr << "Error: analysis requires function definition as input instead of " << AstToString(funcdef) << std::endl;
     assert(false);
  }
  typedef std::pair<AstNodePtr,std::string>  RefRec;
  std::list<RefRec>  refs;

  fname = Local_GetVarName(fa, AST_NULL, fname);
  fdefined.push_back(fname);

  std::list<std::string> pnames, pres;
  for (AstInterface::AstNodeList::const_iterator p = params.begin(); p != params.end(); ++p) {
       std::string curname = Get_VarName(fa, *p);
       pnames.push_back(curname);
       refs.push_back(RefRec(*p, curname));
  }
  pres.push_back( func_return_name(fname));
  for (AstInterface::AstNodeList::const_iterator p2 = outpars.begin(); 
        p2 != outpars.end(); ++p2) {
       std::string curname = Get_VarName(fa, *p2);
       pres.push_back(curname);
       refs.push_back(RefRec(*p2, curname));
  }
  Stmt stmt_last = funcdef_x(fname, pnames, pres);
  stmts_pushback(stmts,stmt_last);
  for (std::list<RefRec>::const_iterator p3 = refs.begin();
        p3 != refs.end(); ++p3) {
      RefRec cur = *p3;
      namemap[cur.first.get_ptr()] = PtrAnal::VarRef(stmt_last,cur.second);
  }
  ProcessAstTreeBase::operator()(fa, body);
  ControlFlowAnalysis(fa, body, stmt_last);
}