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; }
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 } } }
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; }
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); }
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; }
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; }
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); }
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); } }
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; }
void PtrAnal:: ProcessAssign( AstInterface& fa, const AstNodePtr& mod, const AstNodePtr& rhs, bool readlhs) { std::string modname, readname; AstNodePtr modscope, readscope; readname = Get_VarName(fa, rhs); if (!fa.IsVarRef(mod, 0, &modname, &modscope) ) { if (readlhs) { modname = Get_VarName(fa,mod); std::list<std::string> opds; opds.push_back(modname); opds.push_back(readname); Stmt stmt_last = x_eq_op_y(OTHER, readname, opds); stmts_pushback(stmts,stmt_last); } std::list<std::string> fields; ProcessMod(fa, readname, fields, mod); Stmt stmt_last = stmts_back(stmts); namemap[rhs.get_ptr()] = VarRef(stmt_last,readname); } else if (!readlhs) { assert (rhs != 0) ; modname = Local_GetVarName(fa, modscope, modname); ProcessExpression(fa, modname, rhs); Stmt stmt_last = stmts_back(stmts); namemap[mod.get_ptr()] = VarRef(stmt_last,modname); } else { modname = Local_GetVarName(fa, modscope, modname); std::list<std::string> opds; opds.push_back(modname); opds.push_back(readname); Stmt stmt_last = x_eq_op_y(OTHER, modname, opds); stmts_pushback(stmts,stmt_last); namemap[mod.get_ptr()] = VarRef(stmt_last, modname); } }
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); }