@@ -33,6 +33,7 @@ using namespace std;
3333
3434#undef DEBUG_TYPE
3535#define DEBUG_TYPE " clang-swap"
36+ #define DEBUG_PREFIX " [LoopSwap]: "
3637
3738char ClangLoopSwapPass::ID = 0 ;
3839
@@ -96,6 +97,9 @@ void ClangLoopSwapPass::getAnalysisUsage(AnalysisUsage &AU) const {
9697ModulePass *llvm::createClangLoopSwapPass () { return new ClangLoopSwapPass (); }
9798
9899namespace {
100+ inline void dbgPrintln (const char * Msg) {
101+ LLVM_DEBUG (dbgs () << DEBUG_PREFIX << Msg << " \n " );
102+ }
99103class SwapClauseVisitor : public RecursiveASTVisitor <SwapClauseVisitor> {
100104public:
101105 bool VisitStringLiteral (clang::StringLiteral *SL) {
@@ -119,7 +123,8 @@ class ClangLoopSwapVisitor : public RecursiveASTVisitor<ClangLoopSwapVisitor> {
119123 mContext(TfmCtx->getContext ()), mSrcMgr(mRewriter .getSourceMgr()),
120124 mLangOpts(mRewriter .getLangOpts()), mPass(Pass), mModule(M),
121125 mStatus(SEARCH_PRAGMA), mGO(NULL ), mDIAT(NULL ), mDIDepInfo(NULL ),
122- mMemMatcher(NULL ), mPerfectLoopInfo(NULL ), mCurrentLoops(NULL ) {}
126+ mMemMatcher(NULL ), mPerfectLoopInfo(NULL ), mCurrentLoops(NULL ),
127+ mIsStrict(false ) {}
123128 const CanonicalLoopInfo *getLoopInfo (ForStmt *FS) {
124129 if (!FS)
125130 return NULL ;
@@ -137,14 +142,16 @@ class ClangLoopSwapVisitor : public RecursiveASTVisitor<ClangLoopSwapVisitor> {
137142 auto LI = getLoopInfo (FS);
138143 bool IsCanonical;
139144 bool IsPerfect;
145+ clang::ValueDecl *VD = NULL ;
140146 if (LI) {
141147 IsCanonical = LI->isCanonical ();
142148 IsPerfect = mPerfectLoopInfo ->count (LI->getLoop ());
143149 // to get Value name it is necessary to match IR Value* to AST
144150 // ValueDecl*, it is possible that on Linux 'Value->getName()' doesn't
145151 // works
146- mInductions .push_back (std::pair<clang::ValueDecl *, clang::ForStmt *>(
147- mMemMatcher ->find <IR>(LI->getInduction ())->get <AST>(), FS));
152+ VD = mMemMatcher ->find <IR>(LI->getInduction ())->get <AST>();
153+ mInductions .push_back (
154+ std::pair<clang::ValueDecl *, clang::ForStmt *>(VD, FS));
148155 } else {
149156 // if it's not canonical loop, gathering induction is difficult, there
150157 // may be no induction at all; so just set a NULL stub
@@ -161,6 +168,30 @@ class ClangLoopSwapVisitor : public RecursiveASTVisitor<ClangLoopSwapVisitor> {
161168 mLoopsKinds .push_back (NOT_CANONICAL);
162169 else
163170 mLoopsKinds .push_back (NOT_CANONICAL_AND_PERFECT);
171+ // check only if canonical and perfect, otherwise it's not necessary or
172+ // there is no LoopInfo
173+ if (mIsStrict && IsCanonical && IsPerfect) {
174+ bool Dependency = false ;
175+ auto *Loop = LI->getLoop ()->getLoop ();
176+ auto *LoopID = Loop->getLoopID ();
177+ auto DepItr = mDIDepInfo ->find (LoopID);
178+ auto &DIDepSet = DepItr->get <DIDependenceSet>();
179+ DenseSet<const DIAliasNode *> Coverage;
180+ accessCoverage<bcl::SimpleInserter>(DIDepSet, *mDIAT , Coverage,
181+ mGO ->IgnoreRedundantMemory );
182+ if (!Coverage.empty ()) {
183+ for (auto &DIAT : DIDepSet) {
184+ if (!Coverage.count (DIAT.getNode ()))
185+ continue ;
186+ if (DIAT.is_any <trait::Output, trait::Anti, trait::Flow>()) {
187+ Dependency = true ;
188+ }
189+ }
190+ }
191+ if (Dependency) {
192+ mLoopsKinds [mLoopsKinds .size () - 1 ] = HAS_DEPENDENCY;
193+ }
194+ }
164195
165196 return RecursiveASTVisitor::TraverseForStmt (FS);
166197 } else {
@@ -184,9 +215,25 @@ class ClangLoopSwapVisitor : public RecursiveASTVisitor<ClangLoopSwapVisitor> {
184215 case Status::SEARCH_PRAGMA: {
185216 Pragma P (*S);
186217 llvm::SmallVector<clang::Stmt *, 1 > Clauses;
187- // if found expand clause
188- bool Found = false ;
189218 if (findClause (P, ClauseId::LoopSwap, Clauses)) {
219+ dbgPrintln (" Pragma -> start" );
220+ // collect info from clauses
221+ SwapClauseVisitor SCV;
222+ for (auto C : Clauses)
223+ SCV.TraverseStmt (C);
224+ auto &Literals = SCV.getLiterals ();
225+ for (auto L : Literals) {
226+ mSwaps .push_back (L);
227+ }
228+ // also check for nostrict clause
229+ mIsStrict = true ;
230+ auto Csize = Clauses.size ();
231+ findClause (P, ClauseId::NoStrict, Clauses);
232+ if (Csize != Clauses.size ()) {
233+ mIsStrict = false ;
234+ dbgPrintln (" Found nostrict clause" );
235+ }
236+ // remove clauses
190237 llvm::SmallVector<clang::CharSourceRange, 8 > ToRemove;
191238 auto IsPossible =
192239 pragmaRangeToRemove (P, Clauses, mSrcMgr , mLangOpts , ToRemove);
@@ -206,13 +253,6 @@ class ClangLoopSwapVisitor : public RecursiveASTVisitor<ClangLoopSwapVisitor> {
206253 RemoveEmptyLine.RemoveLineIfEmpty = false ;
207254 for (auto SR : ToRemove)
208255 mRewriter .RemoveText (SR, RemoveEmptyLine);
209- SwapClauseVisitor SCV;
210- for (auto C : Clauses)
211- SCV.TraverseStmt (C);
212- auto &Literals = SCV.getLiterals ();
213- for (auto L : Literals) {
214- mSwaps .push_back (L);
215- }
216256 Clauses.clear ();
217257 mStatus = Status::TRAVERSE_STMT;
218258 return true ;
@@ -309,6 +349,10 @@ class ClangLoopSwapVisitor : public RecursiveASTVisitor<ClangLoopSwapVisitor> {
309349 IsPossible = false ;
310350 toDiag (mSrcMgr .getDiagnostics (), mInductions [i].second ->getBeginLoc (),
311351 diag::warn_loopswap_not_perfect);
352+ } else if (mLoopsKinds [i] == HAS_DEPENDENCY) {
353+ IsPossible = false ;
354+ toDiag (mSrcMgr .getDiagnostics (), mInductions [i].second ->getBeginLoc (),
355+ diag::err_loopswap_dependency);
312356 }
313357 }
314358 if (!IsPossible) {
@@ -343,6 +387,7 @@ class ClangLoopSwapVisitor : public RecursiveASTVisitor<ClangLoopSwapVisitor> {
343387 }
344388 }
345389
390+ dbgPrintln (" Pragma -> done" );
346391 resetVisitor ();
347392 return res;
348393 }
@@ -361,6 +406,7 @@ class ClangLoopSwapVisitor : public RecursiveASTVisitor<ClangLoopSwapVisitor> {
361406 mSwaps .clear ();
362407 mInductions .clear ();
363408 mLoopsKinds .clear ();
409+ mIsStrict = false ;
364410 }
365411
366412private:
@@ -398,12 +444,13 @@ class ClangLoopSwapVisitor : public RecursiveASTVisitor<ClangLoopSwapVisitor> {
398444 const tsar::GlobalOptions *mGO ;
399445 tsar::MemoryMatchInfo::MemoryMatcher *mMemMatcher ;
400446 tsar::PerfectLoopInfo *mPerfectLoopInfo ;
401-
447+ bool mIsStrict ;
402448 enum LoopKind {
403449 CANONICAL_AND_PERFECT,
404450 NOT_PERFECT,
405451 NOT_CANONICAL,
406- NOT_CANONICAL_AND_PERFECT
452+ NOT_CANONICAL_AND_PERFECT,
453+ HAS_DEPENDENCY
407454 };
408455 llvm::SmallVector<LoopKind, 2 > mLoopsKinds ;
409456 llvm::SmallVector<std::pair<clang::ValueDecl *, clang::ForStmt *>, 2 >
@@ -415,7 +462,7 @@ class ClangLoopSwapVisitor : public RecursiveASTVisitor<ClangLoopSwapVisitor> {
415462} // namespace
416463
417464bool ClangLoopSwapPass::runOnModule (llvm::Module &M) {
418- errs () << " Start loop swap pass\n " ;
465+ dbgPrintln ( " Start Loop Swap pass" ) ;
419466 auto TfmCtx = getAnalysis<TransformationEnginePass>().getContext (M);
420467 if (!TfmCtx || !TfmCtx->hasInstance ()) {
421468 M.getContext ().emitError (" can not transform sources"
@@ -446,6 +493,6 @@ bool ClangLoopSwapPass::runOnModule(llvm::Module &M) {
446493 auto &GIP = getAnalysis<ClangGlobalInfoPass>();
447494 ClangLoopSwapVisitor vis (TfmCtx, GIP.getRawInfo (), *this , M);
448495 vis.TraverseDecl (TfmCtx->getContext ().getTranslationUnitDecl ());
449- errs () << " Finish loop swap pass\n " ;
496+ dbgPrintln ( " Finish Loop Swap pass" ) ;
450497 return false ;
451498}
0 commit comments