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