void DepCompCopyArrayToBuffer:: ApplyCopyArray( DepCompCopyArrayCollect& collect, const DepCompAstRefGraphCreate& refDep) { const DepCompAstRefAnal& stmtorder = collect.get_stmtref_info(); for (DepCompCopyArrayCollect::iterator arrays = collect.begin(); arrays != collect.end(); ++arrays) { DepCompCopyArrayCollect::CopyArrayUnit& curarray = *arrays; if (DebugCopyConfig()) std::cerr << IteratorToString2(curarray.refs.begin()) << std::endl; const DepCompAstRefGraphNode* initcut = 0, *savecut = 0; ComputeCutBoundary(refDep, stmtorder, curarray, initcut, savecut); CopyArrayConfig curconfig = ComputeCopyConfig(stmtorder, curarray, initcut); LoopTreeNode* repl = curarray.root; assert(repl != 0); LoopTreeNode* init = initcut->GetInfo().stmt; LoopTreeNode* save = savecut->GetInfo().stmt; CopyArrayOpt opt = curconfig.get_opt(); if (init != 0) { if (opt & SHIFT_COPY) init = curarray.root; else for ( ; init->Parent() != curarray.root; init=init->Parent()); } if ( (opt & SHIFT_COPY) && (init != 0 || save != 0)) save = curarray.root->LastChild(); else if (save != 0) for (; save->Parent()!=curarray.root; save=save->Parent()); ApplyXform(curarray, curconfig, repl, init,save); } }
void write(std::ostream& out) const { out << "slice stmt: \n"; stmt->write(out); out << "slice loop: \n"; loop->write(out); out << "alignment: " << alignInfo.mina << "->" << alignInfo.maxa << "\n"; }
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; }
void DependenceHoisting :: Analyze( LoopTreeDepComp &comp, CompSliceNest& result) { typedef PerfectLoopSlicable<DepInfoEdge,LoopTreeDepGraph> LoopSlicable; typedef PerfectLoopReversible<DepInfoEdge,LoopTreeDepGraph> LoopReversible; LoopTreeNode *root = comp.GetLoopTreeRoot(); int rootlevel = root->LoopLevel(), index = rootlevel-1; int stmtnum, stmtlevel; GetLoopTreeSize(root, stmtnum, stmtlevel); if (!stmtnum) return; result.Reset(stmtlevel - rootlevel ); LoopTreeDepGraph *dg = comp.GetDepGraph(); for (LoopTreeNode *n = root; n; n = (n->ChildCount() == 1)? n->FirstChild() : 0) { if (!n->IncreaseLoopLevel()) continue; index++; if (!LoopSlicable()(dg, index)) continue; CompSlice *slice = CreateCompSlice( rootlevel ); bool r = LoopReversible()(dg, index); LoopTreeTraverseSelectStmt stmtIter(n); for (LoopTreeNode *s; (s = stmtIter.Current()); stmtIter++) slice->SetSliceLoop( s, n, r, 0); result.Append(slice); } }
LoopTreeNode* DepCompCopyArrayCollect:: OutmostCopyRoot( CopyArrayUnit& unit, DepCompAstRefGraphCreate& refDep, LoopTreeNode* treeroot) { LoopTreeNode* origroot = unit.root; while (unit.root != 0) { DepCompCopyArrayCollect::CopyArrayUnit::CrossGraph crossgraph(&refDep, unit); GraphEdgeIterator<DepCompCopyArrayCollect::CopyArrayUnit::CrossGraph> edges(&crossgraph); if (!edges.ReachEnd()) break; DepCompCopyArrayCollect::CopyArrayUnit::InsideGraph insidegraph(&refDep, unit); GraphEdgeIterator<DepCompCopyArrayCollect::CopyArrayUnit::InsideGraph> ep(&insidegraph); for ( ; !ep.ReachEnd(); ++ep) { if (!(*ep)->GetInfo().is_precise()) { break; } } if (!ep.ReachEnd()) break; LoopTreeInterface interface; unit.root = GetEnclosingLoop(unit.root, interface); } LoopTreeNode* res = unit.root; if (res == 0) res = treeroot; else if (res->LoopLevel() +1 == origroot->LoopLevel() && origroot->Parent()->ChildCount() == 1) { res = origroot->Parent(); } unit.root = origroot; return res; }
LoopTreeNode* LoopBlocking:: ApplyBlocking( const CompSliceDepGraphNode::FullNestInfo& nestInfo, LoopTreeDepComp& comp, DependenceHoisting &op, LoopTreeNode *&top) { const CompSliceNest& slices = *nestInfo.GetNest(); if (DebugLoop()) { std::cerr << "\n Blocking slices: " << slices.toString() << "\n"; } LoopTreeNode *head = 0; AstInterface& fa = LoopTransformInterface::getAstInterface(); for (int j = FirstIndex(); j >= 0; j = NextIndex(j)) { top = op.Transform( comp, slices[j], top); SymbolicVal b = BlockSize(j); if (DebugLoop()) { std::cerr << "\n after slice " << j << " : \n"; //top->DumpTree(); comp.DumpTree(); comp.DumpDep(); std::cerr << "\n blocking size for this loop is " << b.toString() << "\n"; } if (!(b == 1)) { LoopTreeNode *n = LoopTreeBlockLoop()( top, SymbolicVar(fa.NewVar(fa.GetType("int")), AST_NULL), b); if (DebugLoop()) { std::cerr << "\n after tiling loop with size " << b.toString() << " : \n"; //top->DumpTree(); comp.DumpTree(); comp.DumpDep(); } if (head == 0) head = n; else { while (n->FirstChild() != head) LoopTreeSwapNodePos()( n->Parent(), n); } } } return head; }
LoopTreeNode* LoopBlocking:: ApplyBlocking( const CompSliceDepGraphNode::FullNestInfo& nestInfo, LoopTreeDepComp& comp, DependenceHoisting &op, LoopTreeNode *&top) { const CompSliceNest& slices = *nestInfo.GetNest(); LoopTreeNode *head = 0; AstInterface& fa = LoopTransformInterface::getAstInterface(); for (int j = FirstIndex(); j >= 0; j = NextIndex(j)) { top = op.Transform( comp, slices[j], top); SymbolicVal b = BlockSize(j); if (!(b == 1)) { LoopTreeNode *n = LoopTreeBlockLoop()( top, SymbolicVar(fa.NewVar(fa.GetType("int")), AST_NULL), b); if (head == 0) head = n; else { while (n->FirstChild() != head) LoopTreeSwapNodePos()( n->Parent(), n); } } } return head; }
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); } }
bool ParameterizeCopyArray:: CanBeBlocked( DepCompCopyArrayCollect::CopyArrayUnit& unit, int copydim) { if (copydim == 0) return false; int k = 0; /* number of sweeping loop dimensions */ for (int i = 0; i < copydim; ++i) { bool sweeping = false; /*QY: any sweeping loops*/ for (DepCompCopyArrayCollect::CopyArrayUnit::NodeSet::const_iterator p = unit.refs.begin(); !p.ReachEnd(); ++p) { int j = 0; /*number of sweeping loop dimensions per array dimension*/ for (LoopTreeNode* loop = (*p)->GetInfo().stmt->EnclosingLoop(); loop!=0 && loop != unit.root; loop = loop->EnclosingLoop()) { AstNodePtr ref = (*p)->GetInfo().orig; if (!ReferenceDimension(ref, loop->GetLoopInfo()->GetVar().GetVarName(),i)) { ++j; sweeping=true; break; } } if (j > 1) return false; /*QY: multiple loops sweeping a dimension*/ } if (sweeping) ++k; } if (k == 0) return false; /* QY: no sweeping dimensions*/ return true; }
LoopTreeNode* DependenceHoisting:: Transform ( LoopTreeDepComp &comp, const CompSlice *slice, LoopTreeNode *h1) { bool alreadySliced = true; for (CompSlice::ConstLoopIterator iter = slice->GetConstLoopIterator(); iter.Current() != 0; iter.Advance()) { if (iter.Current() != h1) { alreadySliced = false; break; } } if (alreadySliced) return h1; SymbolicVar ivar = SliceLoopIvar( LoopTransformInterface::getAstInterface(), slice); SymbolicVal step = SliceLoopStep( slice).step; SymbolicBound bound = SliceLoopRange( slice, h1); LoopTreeNode *h2 = (step > 0)? comp.GetLoopTreeCreate()->CreateLoopNode(ivar,bound.lb,bound.ub,step) : comp.GetLoopTreeCreate()->CreateLoopNode(ivar,bound.ub,bound.lb,step); LoopTreeTransform().InsertLoop(h2, h1, -1); CompSlice::ConstStmtIterator stmtIter=slice->GetConstStmtIterator(); for (LoopTreeNode *stmt; (stmt = stmtIter.Current()); stmtIter++) { CompSlice::SliceStmtInfo info = stmtIter.CurrentInfo(); LoopTreeMergeStmtLoop()( h2, info.loop, stmt, info.align); } CompSlice::UpdateLoopIterator loopIter= slice->GetUpdateLoopIterator(); LoopTreeNode* loop; while ((loop = loopIter.Current())) { loopIter++; DepCompDistributeLoop()(comp,loop); } for (loopIter.Reset(); (loop = loopIter.Current()); loopIter++) { if (loopIter.CurrentInfo().stmtcount < CountEnclosedStmts(loop)){ CompSlice::SliceLoopInfo info = loopIter.CurrentInfo(); LoopTreeTraverseSelectStmt inStmts(loop); for (LoopTreeNode *s; (s = inStmts.Current()); ) { inStmts.Advance(); CompSlice::SliceStmtInfo info1(slice->QuerySliceStmtInfo(s)); if (info1.loop != loop) { DepRel r ( DEPDIR_LE, info1.align - info.minalign); DepRel r1 = comp.GetDomain(s).Entry(info1.loop->LoopLevel(), loop->LoopLevel()); DepRel r2 = r & r1; if (r2 != r1 && !r2.IsTop()) LoopTreeSplitStmt()( s, info1.loop, loop, r); } } DepCompDistributeLoop()(comp, loop); loop = loopIter.Current(); while (loopIter.CurrentInfo().stmtcount < CountEnclosedStmts(loop)) { while (loop->ChildCount() == 1) { LoopTreeNode* child = loop->FirstChild(); LoopTreeSwapNodePos()( loop, child); if (child->IncreaseLoopLevel()) break; } DepCompDistributeLoop()( comp, loop ); } } } OptimizeLoopTree(h2); return h2; }
void DependenceHoisting :: Analyze( LoopTreeDepComp &comp, LoopTreeTransDepGraphCreate *tg, CompSliceNest& result) { LoopTreeInterface interface; LoopTreeNode *root = comp.GetLoopTreeRoot(); int rootlevel = root->LoopLevel(); int size, slicesize; GetLoopTreeSize(root, slicesize, size); size -= rootlevel; size *= slicesize; result.Reset(size); TransSlicingAnal* tmpSlices = new TransSlicingAnal[size]; LoopAlignInfo* buf1 = new LoopAlignInfo[slicesize], *buf2 = new LoopAlignInfo[slicesize]; for (int i = 0; i < size; ++i) tmpSlices[i].Reset(slicesize); /* QY: 6/2009: create a tmporary slice for each individual slicable loop; i.e. for each loop that can be placed at the outermost position */ LoopTreeTraverseSelectStmt stmtIter(root); LoopTreeNode *stmt = stmtIter.Current(); if (stmt == 0) return; size = 0; int index = stmt->LoopLevel()-1; for (LoopTreeNode *loop = GetEnclosingLoop(stmt, interface); index >= rootlevel; loop = GetEnclosingLoop(loop, interface)) { SliceInfo curloop(stmt, loop, index--); TransSlicingAnal anal; if (anal.LoopSlicible( comp, tg, curloop, buf1)) { tmpSlices[size++].CommitSliceInfo(curloop, buf1); } } /*QY:6/2009: try to expand each tmpSlice to include all statements */ for (int sliceindex = 0; sliceindex < size; ++sliceindex) { TransSlicingAnal &anal = tmpSlices[sliceindex]; stmtIter.Current() = anal.LastSliceStmt(); /* QY:for each stmt, find a surrounding slicing loop to go with the loops already in the current slice (stored in anal) */ for ( stmtIter++; (stmt= stmtIter.Current()); stmtIter++) { SliceInfo curloop(stmt); index = stmt->LoopLevel()-1; LoopTreeNode *loop = GetEnclosingLoop(stmt, interface); for ( ; index >= rootlevel; loop = GetEnclosingLoop(loop, interface)) { curloop.SetLoop(loop, index--); if (anal.LoopSlicible( comp, tg, curloop, buf1)) break; } if (loop == 0) /* QY: no slicable loop has been found for stmt */ { break; } else { for (loop = GetEnclosingLoop(loop, interface); index >= rootlevel; loop = GetEnclosingLoop(loop, interface)) { SliceInfo curloop1(stmt, loop,index--); if (anal.LoopSlicible( comp, tg, curloop1, buf2) ) { tmpSlices[size++] = anal; tmpSlices[size-1].CommitSliceInfo( curloop1, buf2); } } /* commit the current loop/stmt as part of the current slice */ anal.CommitSliceInfo(curloop, buf1); } } if (int(anal.NumberOfSliceStmts()) == slicesize) { /* QY: a slice is found that includes all statements */ CompSlice *slice = CreateCompSlice(rootlevel); for (int i = 0; i < slicesize; ++i) { SliceInfo& info = anal.SliceLoop(i); slice->SetSliceLoop(info.stmt, info.loop, info.reversible, info.alignInfo.mina); } result.Append( slice ); } } delete[] tmpSlices; delete[] buf1; delete[] buf2; }
void CopyArrayUnderSizeLimit:: ModifyCopyArrayCollect( DepCompCopyArrayCollect& collect, DepCompAstRefGraphCreate& refDep) { LoopTreeInterface interface; if (DebugCopyRoot()) std::cerr << "copydim = " << copydim << std::endl; for (DepCompCopyArrayCollect::iterator arrays = collect.begin(); arrays != collect.end(); ) { DepCompCopyArrayCollect::CopyArrayUnit& unit = *arrays; LoopTreeNode* origroot = unit.root; if (DebugCopySplit() || DebugCopyRoot()) std::cerr << " modifying copy unit: " << IteratorToString2(unit.refs.begin()) << " with root = " << ((unit.root == 0)? "null" : unit.root->toString()) << std::endl; unit.root = collect.OutmostCopyRoot(unit, refDep, collect.get_tree_root()); int curdim = -1; while (true) { DepCompCopyArrayCollect::CopyArrayUnit::NodeSet cuts; curdim = EnforceCopyDimension(unit, refDep, copydim, &cuts); if (cuts.size() == 0) break; if (cuts.size() == unit.refs.size()) { assert(origroot != unit.root); LoopTreeNode* n = origroot, *p = GetEnclosingLoop(n,interface); LoopTreeNode* rootloop = (unit.root->GetLoopInfo() == 0)? 0 : unit.root; while (n != rootloop && p != rootloop) { n = p; p = GetEnclosingLoop(p, interface); } if (DebugCopyRoot()) std::cerr << "resetting copy root to be " << n->toString() << std::endl; unit.root = n; unit.carrybyroot = true; continue; } if (DebugCopySplit()) std::cerr << "Enforce copy dimension by removing " << IteratorToString2(cuts.begin()) << std::endl; collect.AddCopyArray() = DepCompCopyArrayCollect::CopyArrayUnit(cuts, collect.ComputeCommonRoot(cuts)); unit.refs -= cuts; unit.root = origroot = collect.ComputeCommonRoot(unit.refs); unit.root = collect.OutmostCopyRoot(unit, refDep, collect.get_tree_root()); } DepCompCopyArrayCollect::CopyArrayUnit::NodeSet cuts; if (SplitDisconnectedUnit(collect, unit, refDep,cuts)) { origroot = collect.ComputeCommonRoot(cuts); DepCompCopyArrayCollect::CopyArrayUnit::NodeSet left = unit.refs; if (DebugCopySplit() || DebugCopyRoot()) std::cerr << " Spliting disconnected refs: removing " << IteratorToString2(cuts.begin()) << std::endl; left -= cuts; collect.AddCopyArray() = DepCompCopyArrayCollect::CopyArrayUnit(left,collect.ComputeCommonRoot(left)); unit.refs = cuts; curdim = EnforceCopyDimension(unit, refDep, copydim); assert(curdim <= (int)copydim); } if (origroot != 0 && unit.root != origroot) { int reuselevel = OutmostReuseLevel( unit, refDep); int copylevel = unit.copylevel(); if (reuselevel > copylevel) { LoopTreeNode *cur = origroot; for (int curlevel = origroot->LoopLevel(); reuselevel <= curlevel; cur = GetEnclosingLoop(cur, interface), --curlevel); if (DebugCopyRoot()) std::cerr << "After reuse anal, resetting copy root to be " << cur->toString() << std::endl; unit.root = cur; curdim -= (reuselevel - copylevel+1); } else if (DebugCopyRoot()) std::cerr << "do not reset copy root because copylevel = " << copylevel << " and copy root = " << unit.root->toString() << std::endl; } DepCompCopyArrayCollect::iterator tmp = arrays; ++arrays; if (IsRedundantCopy( unit, curdim)) { if (DebugCopyRemove()) { std::cerr << "remove redundant copy " << IteratorToString2(unit.refs.begin()) << " with root = " << unit.root->toString() << std::endl; } collect.RemoveCopyArray(tmp); } } }