virtual void VisitExpr( const SymbolicExpr& v) { SymbolicVal in1, fr1; bool _hasfrac = hasfrac; SymbolicExpr::OpdIterator opds = v.GetOpdIterator(); for ( ; !opds.ReachEnd(); ++opds) { if (operator()(v.Term2Val(*opds), inp, frp)) { _hasfrac = true; break; } } if (opds.ReachEnd()) { if (inp != 0) *inp = v; } else { if (inp == 0 && frp == 0) return; SymbolicExpr* inv = (inp == 0)? 0 : v.DistributeExpr(SYMOP_NIL, SymbolicVal()); SymbolicExpr* frv = (frp == 0)? 0 : v.DistributeExpr(SYMOP_NIL, SymbolicVal()); SymbolicExpr::OpdIterator opd1 = v.GetOpdIterator(); for ( ; opd1 != opds ; ++opd1) { if (inv != 0) inv->AddOpd(*opd1); if (frv != 0) frv->AddOpd(*opd1); } if (inv != 0) inv->ApplyOpd(*inp); if (frv != 0) frv->ApplyOpd(*frp); for (++opd1; !opd1.ReachEnd(); ++opd1) { SymbolicVal cur = v.Term2Val(*opd1); if (operator()(cur, inp, frp)) { if (inv != 0) inv->ApplyOpd(*inp); if (frv != 0) frv->ApplyOpd(*frp); } else { if (inv != 0) inv->AddOpd(*opd1); if (frv != 0) frv->AddOpd(*opd1); } } if (inp != 0) *inp = GetExprVal(inv); if (frp != 0) *frp = GetExprVal(frv); } hasfrac = _hasfrac; }
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; }
bool operator()( HasValueDescriptor& desc) { bool onesucc = false; for (HasValueDescriptor::iterator p = desc.begin(); p != desc.end(); ++p) { SymbolicValDescriptor& r = (*p).second; succ = true; r.replace_val(*this); if (!succ) r = SymbolicVal(); else onesucc = true; } return onesucc; }
SymbolicVal DecomposeAffineExpression( const SymbolicVal& exp, const VarVec& vars, CoeffVec& vec, int size) { // AstInterface& fa = la; SymbolicVal val = exp; // int coeff; for (int i = 0; i < size; ++i) { SymbolicVar ivar = vars[i]; SymbolicBound ivarbound; SymbolicVal coeff = UnwrapVarCond( SymbolicCond( REL_LE, val, 0), ivar, ivarbound); if (coeff.IsNIL()) return SymbolicVal(); if (!(coeff == 0)) { if (!ivarbound.ub.IsNIL()) val = -ivarbound.ub; else { val = ivarbound.lb; coeff = -coeff; } } vec.push_back(coeff); } return val; }
SymbolicVal HasValueMapReplace :: operator() ( const SymbolicVal& v) { repl = SymbolicVal(); v.Visit(this); return repl; }
bool LoopUnrolling::operator() ( AstInterface& fa, const AstNodePtr& s, AstNodePtr& r) { bool isLoop = false; if (enclosingloop == s || (enclosingloop == AST_NULL && (isLoop = fa.IsLoop(s)))) { for (enclosingloop = fa.GetParent(s); enclosingloop != AST_NULL && !fa.IsLoop(enclosingloop); enclosingloop = fa.GetParent(enclosingloop)); if (!isLoop) return false; } AstNodePtr body; SymbolicVal stepval, ubval, lbval; SymbolicVar ivar; if (!SymbolicValGenerator::IsFortranLoop(fa, s, &ivar, &lbval, &ubval, &stepval, &body)) return false; if (opt & POET_TUNING) { AutoTuningInterface* tune = LoopTransformInterface::getAutoTuningInterface(); if (tune == 0) { std::cerr << "ERROR: AutoTuning Interface not defined!\n"; assert(0); } tune->UnrollLoop(fa,s, unrollsize); } else { AstNodePtr r = s; SymbolicVal nstepval = stepval * unrollsize; SymbolicVal nubval = ubval; bool hasleft = true, negativeStep = (stepval < 0); std::vector<AstNodePtr> bodylist; AstNodePtr leftbody, lefthead; int stepnum=0, loopnum = 0; SymbolicVal loopval = ubval - lbval + 1; if (stepval.isConstInt(stepnum) && loopval.isConstInt(loopnum) && !(loopnum % stepnum)) { hasleft = false; } else { nubval = ubval - SymbolicVal(unrollsize - 1); if (opt & COND_LEFTOVER) { leftbody = fa.CreateBlock(); lefthead = leftbody; } else { leftbody = fa.CopyAstTree(body); lefthead = fa.CreateLoop( ivar.CodeGen(fa), AstNodePtr(), ubval.CodeGen(fa), stepval.CodeGen(fa), leftbody, negativeStep); } } fa.RemoveStmt(body); AstNodePtr s1 = fa.CreateLoop(ivar.CodeGen(fa), lbval.CodeGen(fa), nubval.CodeGen(fa), nstepval.CodeGen(fa), body, negativeStep); fa.ReplaceAst( s,s1); r = s1; AstNodePtr origbody = fa.CopyAstTree(body); std::string nvarname = ""; SymbolicVal nvar; if (opt & USE_NEWVAR) { nvarname = fa.NewVar(fa.GetType("int"),"",true,body, ivar.CodeGen(fa)); nvar = SymbolicVar(nvarname,body); } bodylist.push_back(body); for (int i = 1; i < unrollsize; ++i) { AstNodePtr bodycopy = fa.CopyAstTree(origbody); if (opt & USE_NEWVAR) { AstNodePtr nvarassign = fa.CreateAssignment(nvar.CodeGen(fa), (nvar+1).CodeGen(fa)); fa.BlockAppendStmt( body, nvarassign); AstTreeReplaceVar repl(ivar, nvar); repl( fa, bodycopy); } else { AstTreeReplaceVar repl(ivar, ivar+i); repl( fa, bodycopy); } fa.BlockAppendStmt( body, bodycopy); bodylist.push_back(bodycopy); if (hasleft && (opt & COND_LEFTOVER)) { AstNodePtr cond = fa.CreateBinaryOP( AstInterface::BOP_LE, ivar.CodeGen(fa), (ubval-(i-1)).CodeGen(fa)); AstNodePtr body1 = fa.CopyAstTree(bodylist[i-1]); AstNodePtr ifstmt = fa.CreateIf( cond, body1); fa.BlockAppendStmt( leftbody, ifstmt); leftbody = body1; } } if (hasleft) { fa.InsertStmt( r, lefthead, false, true); } r = s; return true; } return false; }