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; }
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* 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); } } }