+/* Not implemented
+void CDSPass::InsertRuntimeIgnores(Function &F) {
+ IRBuilder<> IRB(F.getEntryBlock().getFirstNonPHI());
+ IRB.CreateCall(CDSIgnoreBegin);
+ EscapeEnumerator EE(F, "cds_ignore_cleanup", ClHandleCxxExceptions);
+ while (IRBuilder<> *AtExit = EE.Next()) {
+ AtExit->CreateCall(CDSIgnoreEnd);
+ }
+}*/
+
+bool CDSPass::runOnFunction(Function &F) {
+ if (F.getName() == "main") {
+ F.setName("user_main");
+ errs() << "main replaced by user_main\n";
+ }
+
+ initializeCallbacks( *F.getParent() );
+ SmallVector<Instruction*, 8> AllLoadsAndStores;
+ SmallVector<Instruction*, 8> LocalLoadsAndStores;
+ SmallVector<Instruction*, 8> VolatileLoadsAndStores;
+ SmallVector<Instruction*, 8> AtomicAccesses;
+
+ bool Res = false;
+ bool HasCall = false;
+ bool HasAtomic = false;
+ bool HasVolatile = false;
+ const DataLayout &DL = F.getParent()->getDataLayout();
+
+ for (auto &BB : F) {
+ for (auto &Inst : BB) {
+ if ( (&Inst)->isAtomic() || isAtomicCall(&Inst) ) {
+ AtomicAccesses.push_back(&Inst);
+ HasAtomic = true;
+ } 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) {
+ VolatileLoadsAndStores.push_back(&Inst);
+ HasVolatile = true;
+ } else
+ LocalLoadsAndStores.push_back(&Inst);
+ } else if (isa<CallInst>(Inst) || isa<InvokeInst>(Inst)) {
+ /* TODO: To be added
+ if (CallInst *CI = dyn_cast<CallInst>(&Inst))
+ maybeMarkSanitizerLibraryCallNoBuiltin(CI, TLI);
+ if (isa<MemIntrinsic>(Inst))
+ MemIntrinCalls.push_back(&Inst);
+ HasCalls = true;
+ chooseInstructionsToInstrument(LocalLoadsAndStores, AllLoadsAndStores,
+ DL);
+ */
+ }
+ }
+
+ chooseInstructionsToInstrument(LocalLoadsAndStores, AllLoadsAndStores, DL);
+ }
+
+ for (auto Inst : AllLoadsAndStores) {
+ Res |= instrumentLoadOrStore(Inst, DL);
+ }
+
+ for (auto Inst : VolatileLoadsAndStores) {
+ Res |= instrumentVolatile(Inst, DL);
+ }
+
+ for (auto Inst : AtomicAccesses) {
+ Res |= instrumentAtomic(Inst, DL);
+ }
+
+ /* TODO
+ for (auto Inst : MemIntrinCalls) {
+ Res |= instrumentMemIntrinsic(Inst);
+ }
+ */
+
+ // Only instrument functions that contain atomics or volatiles
+ if (Res && ( HasAtomic || HasVolatile) ) {
+ IRBuilder<> IRB(F.getEntryBlock().getFirstNonPHI());
+ /* Unused for now
+ Value *ReturnAddress = IRB.CreateCall(
+ Intrinsic::getDeclaration(F.getParent(), Intrinsic::returnaddress),
+ IRB.getInt32(0));
+ */
+
+ Value * FuncName = IRB.CreateGlobalStringPtr(F.getName());
+ IRB.CreateCall(CDSFuncEntry, FuncName);
+
+ EscapeEnumerator EE(F, "cds_cleanup", true);
+ while (IRBuilder<> *AtExit = EE.Next()) {
+ AtExit->CreateCall(CDSFuncExit, FuncName);
+ }
+
+ Res = true;
+ }
+
+ return false;
+}