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 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()); } }
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 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); }
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)); 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)); l.push_back(size.CodeGen(fa)); AstNodePtr init = fa.CreateFunctionCall("getTuningValue", l); return SymbolicVar(fa.NewVar(fa.GetType("int"), "",true,AST_NULL, init),AST_NULL); } }
AstNodePtr LoopTransformInterface:: CreateArrayAccess(const std::string& arrname, const std::vector<SymbolicVal>& arrindex) { assert(fa != 0); AstInterface::AstNodeList indexlist; for (std::vector<SymbolicVal>::const_iterator indexp = arrindex.begin(); indexp != arrindex.end(); ++indexp) { AstNodePtr cur = (*indexp).CodeGen(*fa); if (cur == AST_NULL) { std::cerr << "Empty AST from Symbolic Val: " << (*indexp).toString() << "\n"; assert(0); } indexlist.push_back(cur); } AstNodePtr res = CreateArrayAccess(fa->CreateVarRef(arrname),indexlist); return res; }
LoopTreeNode* DynamicSlicing:: Transform( LoopTreeDepComp& c, const CompSlice *_slice, LoopTreeNode *root) { AstInterface& fa = LoopTransformInterface::getAstInterface(); const DynamicCompSlice* slice = static_cast<const DynamicCompSlice*>(_slice); int num = slice->QuerySliceGroupNumber(); LoopTreeNode *nr = root; if (num > 1) { std::string groupVar = fa.NewVar(fa.GetType("int")), groupVarN = groupVar + "N"; fa.NewVar( fa.GetType("int"), groupVarN); LoopTreeCreate *tc = c.GetLoopTreeCreate(); nr = tc->CreateLoopNode( SymbolicVar(groupVar, AST_NULL), 1, SymbolicVar(groupVarN, AST_NULL), 1); LoopTreeTransform().InsertLoop( nr, root, -1); AstInterface::AstNodeList args; char buf[11]; for (int i = 1; i <= num; ++i) { sprintf(buf, "%1d", i); std::string name = groupVar + buf; fa.NewVar(fa.GetType("int"), name); args.push_back( fa.CreateVarRef( name) ); } int id; AstNodePtr config = LoopTransformInterface::CreateDynamicFusionConfig( fa.CreateVarRef(groupVarN), args, id); LoopTreeNode *configNode = tc->CreateStmtNode(config); configNode->Link( nr, LoopTreeNode::AsPrevSibling); AstNodePtr configEnd = LoopTransformInterface::CreateDynamicFusionEnd( id); LoopTreeNode *endNode = tc->CreateStmtNode(configEnd); endNode->Link( nr, LoopTreeNode::AsNextSibling); for (CompSlice::ConstStmtIterator p = slice->GetConstStmtIterator(); !p.ReachEnd(); ++p) { LoopTreeNode* stmt = p.Current(); sprintf(buf, "%1d", slice->QuerySliceStmtGroupIndex(stmt)); LoopTreeEmbedStmt()( nr, stmt, SymbolicVar(groupVar + buf, AST_NULL) ); } DependenceHoisting::Transform(c, slice, root); } else nr = DependenceHoisting::Transform(c, slice, root); return nr; }
AstNodePtr LoopTransformInterface::CreateDynamicFusionEnd( int id) { assert(fa != 0); AstInterface::AstNodeList args; args.push_back( fa->CreateConstInt(id)); return fa->CreateFunctionCall("DynamicFusionEnd", args); }