+bool CDSPass::instrumentLoops(Function &F)
+{
+ DominatorTree DT(F);
+ LoopInfo LI(DT);
+
+ SmallVector<Loop *, 4> Loops = LI.getLoopsInPreorder();
+ bool instrumented = false;
+
+ // Do a post-order traversal of the loops so that counter updates can be
+ // iteratively hoisted outside the loop nest.
+ for (auto *Loop : llvm::reverse(Loops)) {
+ bool instrument_loop = false;
+
+ // Iterator over loop blocks and search for atomics and volatiles
+ Loop::block_iterator it;
+ for (it = Loop->block_begin(); it != Loop->block_end(); it++) {
+ BasicBlock * block = *it;
+ for (auto &Inst : *block) {
+ if ( (&Inst)->isAtomic() ) {
+ instrument_loop = true;
+ break;
+ } else if (isAtomicCall(&Inst)) {
+ instrument_loop = true;
+ break;
+ } else if (isa<LoadInst>(Inst) || isa<StoreInst>(Inst)) {
+ LoadInst *LI = dyn_cast<LoadInst>(&Inst);
+ StoreInst *SI = dyn_cast<StoreInst>(&Inst);
+ bool isVolatile = ( LI ? LI->isVolatile() : SI->isVolatile() );
+
+ if (isVolatile) {
+ instrument_loop = true;
+ break;
+ }
+ }
+ }
+
+ if (instrument_loop)
+ break;
+ }
+
+ if (instrument_loop) {
+ // TODO: what to instrument?
+ errs() << "Function: " << F.getName() << "\n";
+ BasicBlock * header = Loop->getHeader();
+ header->dump();
+
+ instrumented = true;
+ }
+ }
+
+ return instrumented;
+}