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; }
AstNodePtr SymbolicFunction :: CodeGen( AstInterface &_fa) const { AstNodeList l; for (const_iterator i = args.begin(); i != args.end(); ++i) { SymbolicVal cur = *i; AstNodePtr curast = cur.CodeGen(_fa); l.push_back(curast.get_ptr()); } if (t == AstInterface::OP_NONE) { return _fa.CreateFunctionCall( op, l.begin(), l.end()); } else if (t == AstInterface::OP_ARRAY_ACCESS) { AstNodeList::const_iterator b = l.begin(); AstNodePtr arr = *b; for (++b; b != l.end(); ++b) { arr = _fa.CreateArrayAccess(arr, *b); } return arr; } 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()); } }
PtrAnal::VarRef PtrAnal::translate_exp(const AstNodePtr& exp) const { VarRef cur; NameMap::const_iterator p = namemap.find(exp.get_ptr()); if (p != namemap.end()) { cur = (*p).second; } return cur; }
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 } } }
void HasValueMap:: copy_value( AstInterfaceImpl& fa, const AstNodePtr& orig, const AstNodePtr& copy) { HasValueDescriptor desc; if (has_value( orig, &desc)) { set_val(copy, desc); if (DebugValuePropogate()) { std::cerr << "copying ast: " << AstInterface::AstToString(copy) << copy.get_ptr() << " to have value " << desc.toString() << std::endl; } } }
PtrAnal::StmtRef PtrAnal::translate_stmt(const AstNodePtr& s) const { StmtRef cur; StmtMap::const_iterator p = stmtmap.find(s.get_ptr()); if (p != stmtmap.end()) { std::pair<size_t,size_t> i = (*p).second; for (size_t j = i.first; j <= i.second; ++j) { cur.push_back(stmts[j]); } } return cur; }
void HasValueMap:: set_val( const AstNodePtr& ast, const HasValueDescriptor& val) { std::map<AstNodePtr,HasValueDescriptor>::iterator p = valmap.find(ast); if (p == valmap.end()) valmap[ast] = val; else (*p).second.merge(val); if (DebugValuePropogate()) { std::cerr << "set value for " << ast.get_ptr() << ":" << AstInterface::AstToString(ast) << " : "; valmap[ast].Dump(); std::cerr << std::endl; } }
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); } }
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.get_ptr()); ++size; } assert( size > 1); std::string func = (opt< 0)? "min" : "max"; return fa.CreateFunctionCall(func, list.begin(), list.end()); }
AstNodePtr LoopTransformInterface:: CreateArrayAccess(const std::string& arrname, const std::vector<SymbolicVal>& arrindex) { assert(fa != 0); AstNodePtr res = fa->CreateVarRef(arrname); AstNodeList args; for (std::vector<SymbolicVal>::const_iterator indexp = arrindex.begin(); indexp != arrindex.end(); ++indexp) { AstNodePtr cur = (*indexp).CodeGen(*fa); args.push_back(cur.get_ptr()); } return CreateArrayAccess(res,args); }
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; }
bool PtrAnal:: ProcessTree( AstInterface &fa, const AstNodePtr& s, AstInterface::TraversalVisitType t) { if (t == AstInterface::PreVisit) { AstNodePtr lhs, rhs; AstInterface::AstNodeList vars, args; if (fa.IsStatement(s)) { if (DebugAliasAnal()) std::cerr << "pre visiting " << AstToString(s) << "\n"; stmt_active.push_back(stmts.size()); } if (fa.IsReturn(s,&rhs)) { // size_t stmt_firstIndex = stmts.size(); std::string fname = fdefined.back(); if (rhs != AST_NULL) { std::string rhsname = Get_VarName(fa, rhs); Stmt stmt_last = x_eq_y(func_return_name(fname), rhsname); stmts_pushback(stmts,stmt_last); namemap[rhs.get_ptr()] = VarRef(stmt_last, rhsname); } Stmt stmt_last = funcexit_x(fname); stmts_pushback(stmts,stmt_last); Skip(s); } else if (fa.IsVariableDecl( s, &vars, &args)) { // size_t stmt_firstIndex = stmts.size(); AstInterface::AstNodeList::const_iterator pv = vars.begin(); AstInterface::AstNodeList::const_iterator pa = args.begin(); while (pv != vars.end()) { AstNodePtr v = *pv; AstNodePtr a = *pa; if (a != AST_NULL) { ProcessAssign(fa, v, a); } ++pv; ++pa; } Skip(s); } else if ( (lhs = fa.IsExpression(s)) != AST_NULL) { ProcessExpression(fa, "", lhs); Skip(s); } } else { if (DebugAliasAnal()) std::cerr << "post visiting " << AstToString(s) << "\n"; if (fa.IsStatement(s)) { size_t stmt_firstIndex = stmt_active.back(); stmt_active.pop_back(); if (stmt_firstIndex < stmts.size()) { if (DebugAliasAnal()) std::cerr << "setting stmt mapping \n"; stmtmap[s.get_ptr()] = pair<size_t,size_t>(stmt_firstIndex, stmts.size()-1); } else if (DebugAliasAnal()) std::cerr << "no translation: " << AstToString(s) << "\n"; } } return true; }
void PtrAnal:: ProcessExpression( AstInterface& fa, const std::string& _modname, const AstNodePtr& rhs) { AstInterface::OperatorEnum op; std::string modname = _modname; AstNodePtr p,p1,p2; AstInterface::AstNodeList args, out; if (fa.IsFunctionCall(rhs, &p, &args, &out)) { typedef std::pair<AstNodePtr,std::string> RefRec; std::list<RefRec> refs; std::string fname = Get_VarName(fa,p); refs.push_back(RefRec(p,fname)); std::list<std::string> pargs, pres; for (AstInterface::AstNodeList::const_iterator p = args.begin(); p != args.end(); ++p) { AstNodePtr cur = *p; std::string curname = Get_VarName(fa, cur); pargs.push_back(curname); refs.push_back(RefRec(cur,curname)); } pres.push_back(modname); for (AstInterface::AstNodeList::const_iterator p2 = out.begin(); p2 != out.end(); ++p2) { AstNodePtr cur = *p2; std::string curname = Get_VarName(fa, cur); pres.push_back(curname); refs.push_back(RefRec(cur,curname)); } Stmt stmt = funccall_x(fname, pargs, pres); stmts_pushback(stmts,stmt); for (std::list<RefRec>::const_iterator p3 = refs.begin(); p3 != refs.end(); ++p3) { RefRec cur = *p3; namemap[cur.first.get_ptr()] = PtrAnal::VarRef(stmt,cur.second); } } else if (fa.IsUnaryOp(rhs,&op, &p) ) { std::string readname; if (modname == "") { modname = Local_GetVarName(fa, rhs); } switch (op) { case AstInterface::UOP_ADDR: { readname= Get_VarName(fa, p); Stmt stmt = x_eq_addr_y(modname, readname); stmts_pushback(stmts,stmt); namemap[p.get_ptr()] = VarRef(stmt,readname); namemap[rhs.get_ptr()] = VarRef(stmt,modname); break; } case AstInterface::UOP_DEREF: { readname= Get_VarName(fa, p); Stmt stmt = x_eq_deref_y(modname, "", readname); stmts_pushback(stmts,stmt); namemap[p.get_ptr()] = VarRef(stmt,readname); namemap[rhs.get_ptr()] = VarRef(stmt,modname); break; } case AstInterface::UOP_ALLOCATE: { Stmt stmt = allocate_x(modname) ; stmts_pushback(stmts,stmt); break; } default: { readname = Get_VarName(fa,p); std::list<std::string> opds; opds.push_back(readname); Stmt stmt_last = x_eq_op_y(OTHER,modname, opds); stmts_pushback(stmts,stmt_last); namemap[p.get_ptr()] = VarRef(stmt_last,readname); namemap[rhs.get_ptr()] = VarRef(stmt_last,modname); break; } } } else if (fa.IsBinaryOp(rhs, &op, &p1, &p2)) { std::list<std::string> opds; std::string readname , refname; if (modname == "") { modname = Local_GetVarName(fa, rhs); } Stmt stmt_last=0; switch (op) { case AstInterface::BOP_DOT_ACCESS: { readname = Get_VarName(fa, p1); refname = Local_GetFieldName(fa, p2); stmt_last = x_eq_field_y( modname, refname, readname); stmts_pushback(stmts,stmt_last); break; } case AstInterface::BOP_ARROW_ACCESS: { readname = Get_VarName(fa, p1); refname = Local_GetFieldName(fa, p2); stmt_last = x_eq_deref_y(modname, refname, readname); stmts_pushback(stmts,stmt_last); break; } default: { readname = Get_VarName(fa,p1); refname = Get_VarName(fa,p2); opds.push_back(readname); opds.push_back(refname); OpType opt = OTHER; switch (op) { case AstInterface::BOP_EQ: opt = EQ; break; case AstInterface::BOP_LT: opt = LT; break; case AstInterface::BOP_GT: opt = GT; break; case AstInterface::BOP_LE: opt = LE; break; case AstInterface::BOP_GE: opt = GE; break; case AstInterface::BOP_NE: opt = NE; break; default: break; } stmt_last = x_eq_op_y( opt, modname, opds); stmts_pushback(stmts,stmt_last); } } namemap[p1.get_ptr()] = VarRef(stmt_last,readname); namemap[p2.get_ptr()] = VarRef(stmt_last,refname); namemap[rhs.get_ptr()] = VarRef(stmt_last,modname); } else { std::string cur = Get_VarName(fa, rhs); assert (cur != ""); if (modname != "") { Stmt stmt_last = x_eq_y(modname, cur); stmts_pushback(stmts,stmt_last); namemap[rhs.get_ptr()] = VarRef(stmt_last,cur); } } }