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()); }
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) ; }
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()); }
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; } }
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; }
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).get_ptr()); 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).get_ptr()); l.push_back(size.CodeGen(fa).get_ptr()); std::string funname = "getTuningValue"; AstNodePtr init = fa.CreateFunctionCall(funname, l.begin(), l.end()); return SymbolicVar(fa.NewVar(fa.GetType("int"), "",true,true,AST_NULL, init),AST_NULL); } }
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); }
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; }