X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=CDSPass.cpp;h=81d7d4ebb954a0f402b9943837891613154718a7;hb=b3ce03be63eb654f9f36664795d1b60fe410cae8;hp=9158baef37e6d41cc8e0bb82003c08995f95a095;hpb=0d737ead79278a1a67c5829f9c6bf84ee6a90cec;p=c11llvm.git diff --git a/CDSPass.cpp b/CDSPass.cpp index 9158bae..81d7d4e 100644 --- a/CDSPass.cpp +++ b/CDSPass.cpp @@ -1,4 +1,8 @@ +<<<<<<< HEAD +//===-- CDSPass.cpp - xxx -------------------------------===// +======= //===-- CdsPass.cpp - xxx -------------------------------===// +>>>>>>> 0d737ead79278a1a67c5829f9c6bf84ee6a90cec // // The LLVM Compiler Infrastructure // @@ -76,6 +80,17 @@ Type * Int64PtrTy; Type * VoidTy; +<<<<<<< HEAD +Constant * CDSLoad[FUNCARRAYSIZE]; +Constant * CDSStore[FUNCARRAYSIZE]; +Constant * CDSAtomicLoad[FUNCARRAYSIZE]; +Constant * CDSAtomicStore[FUNCARRAYSIZE]; +Constant * CDSAtomicRMW[AtomicRMWInst::LAST_BINOP + 1][FUNCARRAYSIZE]; +Constant * CDSAtomicCAS[FUNCARRAYSIZE]; +Constant * CDSAtomicThreadFence; + +bool start = false; +======= Constant * CdsLoad[FUNCARRAYSIZE]; Constant * CdsStore[FUNCARRAYSIZE]; Constant * CdsAtomicLoad[FUNCARRAYSIZE]; @@ -83,6 +98,7 @@ Constant * CdsAtomicStore[FUNCARRAYSIZE]; Constant * CdsAtomicRMW[AtomicRMWInst::LAST_BINOP + 1][FUNCARRAYSIZE]; Constant * CdsAtomicCAS[FUNCARRAYSIZE]; Constant * CdsAtomicThreadFence; +>>>>>>> 0d737ead79278a1a67c5829f9c6bf84ee6a90cec int getAtomicOrderIndex(AtomicOrdering order){ switch (order) { @@ -131,9 +147,15 @@ static int sizetoindex(int size) { } namespace { +<<<<<<< HEAD + struct CDSPass : public FunctionPass { + static char ID; + CDSPass() : FunctionPass(ID) {} +======= struct CdsPass : public FunctionPass { static char ID; CdsPass() : FunctionPass(ID) {} +>>>>>>> 0d737ead79278a1a67c5829f9c6bf84ee6a90cec bool runOnFunction(Function &F) override; private: @@ -147,7 +169,11 @@ namespace { }; } +<<<<<<< HEAD +void CDSPass::initializeCallbacks(Module &M) { +======= void CdsPass::initializeCallbacks(Module &M) { +>>>>>>> 0d737ead79278a1a67c5829f9c6bf84ee6a90cec LLVMContext &Ctx = M.getContext(); Int8Ty = Type::getInt8Ty(Ctx); @@ -182,6 +208,17 @@ void CdsPass::initializeCallbacks(Module &M) { SmallString<32> AtomicLoadName("cds_atomic_load" + BitSizeStr); SmallString<32> AtomicStoreName("cds_atomic_store" + BitSizeStr); +<<<<<<< HEAD +// CDSLoad[i] = M.getOrInsertFunction(LoadName, Ty, PtrTy); +// CDSStore[i] = M.getOrInsertFunction(StoreName, VoidTy, PtrTy, Ty); + CDSLoad[i] = M.getOrInsertFunction(LoadName, VoidTy, PtrTy); + CDSStore[i] = M.getOrInsertFunction(StoreName, VoidTy, PtrTy); + CDSAtomicLoad[i] = M.getOrInsertFunction(AtomicLoadName, Ty, PtrTy, OrdTy); + CDSAtomicStore[i] = M.getOrInsertFunction(AtomicStoreName, VoidTy, PtrTy, OrdTy, Ty); + + for (int op = AtomicRMWInst::FIRST_BINOP; op <= AtomicRMWInst::LAST_BINOP; ++op) { + CDSAtomicRMW[op][i] = nullptr; +======= // CdsLoad[i] = M.getOrInsertFunction(LoadName, Ty, PtrTy); // CdsStore[i] = M.getOrInsertFunction(StoreName, VoidTy, PtrTy, Ty); CdsLoad[i] = M.getOrInsertFunction(LoadName, VoidTy, PtrTy); @@ -191,6 +228,7 @@ void CdsPass::initializeCallbacks(Module &M) { for (int op = AtomicRMWInst::FIRST_BINOP; op <= AtomicRMWInst::LAST_BINOP; ++op) { CdsAtomicRMW[op][i] = nullptr; +>>>>>>> 0d737ead79278a1a67c5829f9c6bf84ee6a90cec std::string NamePart; if (op == AtomicRMWInst::Xchg) @@ -209,15 +247,26 @@ void CdsPass::initializeCallbacks(Module &M) { continue; SmallString<32> AtomicRMWName("cds_atomic" + NamePart + BitSizeStr); +<<<<<<< HEAD + CDSAtomicRMW[op][i] = M.getOrInsertFunction(AtomicRMWName, Ty, PtrTy, OrdTy, Ty); +======= CdsAtomicRMW[op][i] = M.getOrInsertFunction(AtomicRMWName, Ty, PtrTy, OrdTy, Ty); +>>>>>>> 0d737ead79278a1a67c5829f9c6bf84ee6a90cec } // only supportes strong version SmallString<32> AtomicCASName("cds_atomic_compare_exchange" + BitSizeStr); +<<<<<<< HEAD + CDSAtomicCAS[i] = M.getOrInsertFunction(AtomicCASName, Ty, PtrTy, Ty, Ty, OrdTy, OrdTy); + } + + CDSAtomicThreadFence = M.getOrInsertFunction("cds_atomic_thread_fence", VoidTy, OrdTy); +======= CdsAtomicCAS[i] = M.getOrInsertFunction(AtomicCASName, Ty, PtrTy, Ty, Ty, OrdTy, OrdTy); } CdsAtomicThreadFence = M.getOrInsertFunction("cds_atomic_thread_fence", VoidTy, OrdTy); +>>>>>>> 0d737ead79278a1a67c5829f9c6bf84ee6a90cec } static bool isVtableAccess(Instruction *I) { @@ -257,7 +306,11 @@ static bool shouldInstrumentReadWriteFromAddress(const Module *M, Value *Addr) { return true; } +<<<<<<< HEAD +bool CDSPass::addrPointsToConstantData(Value *Addr) { +======= bool CdsPass::addrPointsToConstantData(Value *Addr) { +>>>>>>> 0d737ead79278a1a67c5829f9c6bf84ee6a90cec // If this is a GEP, just analyze its pointer operand. if (GetElementPtrInst *GEP = dyn_cast(Addr)) Addr = GEP->getPointerOperand(); @@ -278,6 +331,56 @@ bool CdsPass::addrPointsToConstantData(Value *Addr) { return false; } +<<<<<<< HEAD +bool CDSPass::runOnFunction(Function &F) { + if (F.getName() == "main") { + F.setName("user_main"); + errs() << "main replaced by user_main\n"; + + initializeCallbacks( *F.getParent() ); + + SmallVector AllLoadsAndStores; + SmallVector LocalLoadsAndStores; + SmallVector AtomicAccesses; + + std::vector worklist; + + bool Res = false; + const DataLayout &DL = F.getParent()->getDataLayout(); + + errs() << "Before\n"; + F.dump(); + + for (auto &B : F) { + for (auto &I : B) { + if ( (&I)->isAtomic() ) { + AtomicAccesses.push_back(&I); + } else if (isa(I) || isa(I)) { + LocalLoadsAndStores.push_back(&I); + } else if (isa(I) || isa(I)) { + // not implemented yet + } + } + chooseInstructionsToInstrument(LocalLoadsAndStores, AllLoadsAndStores, DL); + } + + for (auto Inst : AllLoadsAndStores) { +// Res |= instrumentLoadOrStore(Inst, DL); +// errs() << "load and store are not replaced\n"; + } + + for (auto Inst : AtomicAccesses) { + Res |= instrumentAtomic(Inst); + } + + if (Res) { + errs() << F.getName(); + errs() << " has above instructions replaced\n"; + } + } +// errs() << "After\n"; +// F.dump(); +======= bool CdsPass::runOnFunction(Function &F) { if (F.getName() == "main") F.setName("user_main"); @@ -317,11 +420,16 @@ bool CdsPass::runOnFunction(Function &F) { errs() << "After\n"; F.dump(); +>>>>>>> 0d737ead79278a1a67c5829f9c6bf84ee6a90cec return false; } +<<<<<<< HEAD +void CDSPass::chooseInstructionsToInstrument( +======= void CdsPass::chooseInstructionsToInstrument( +>>>>>>> 0d737ead79278a1a67c5829f9c6bf84ee6a90cec SmallVectorImpl &Local, SmallVectorImpl &All, const DataLayout &DL) { SmallPtrSet WriteTargets; @@ -364,7 +472,11 @@ void CdsPass::chooseInstructionsToInstrument( } +<<<<<<< HEAD +bool CDSPass::instrumentLoadOrStore(Instruction *I, +======= bool CdsPass::instrumentLoadOrStore(Instruction *I, +>>>>>>> 0d737ead79278a1a67c5829f9c6bf84ee6a90cec const DataLayout &DL) { IRBuilder<> IRB(I); bool IsWrite = isa(*I); @@ -381,7 +493,11 @@ bool CdsPass::instrumentLoadOrStore(Instruction *I, int size = getTypeSize(Addr->getType()); int index = sizetoindex(size); +<<<<<<< HEAD +// not supported by CDS yet +======= // not supported by Cds yet +>>>>>>> 0d737ead79278a1a67c5829f9c6bf84ee6a90cec /* if (IsWrite && isVtableAccess(I)) { LLVM_DEBUG(dbgs() << " VPTR : " << *I << "\n"); Value *StoredValue = cast(I)->getValueOperand(); @@ -410,8 +526,22 @@ bool CdsPass::instrumentLoadOrStore(Instruction *I, */ Value *OnAccessFunc = nullptr; +<<<<<<< HEAD + OnAccessFunc = IsWrite ? CDSStore[index] : CDSLoad[index]; + + Type *ArgType = IRB.CreatePointerCast(Addr, Addr->getType())->getType(); + + if ( ArgType != Int8PtrTy && ArgType != Int16PtrTy && + ArgType != Int32PtrTy && ArgType != Int64PtrTy ) { + //errs() << "A load or store of type "; + //errs() << *ArgType; + //errs() << " is passed in\n"; + return false; // if other types of load or stores are passed in + } +======= OnAccessFunc = IsWrite ? CdsStore[index] : CdsLoad[index]; +>>>>>>> 0d737ead79278a1a67c5829f9c6bf84ee6a90cec IRB.CreateCall(OnAccessFunc, IRB.CreatePointerCast(Addr, Addr->getType())); if (IsWrite) NumInstrumentedWrites++; else NumInstrumentedReads++; @@ -419,7 +549,11 @@ bool CdsPass::instrumentLoadOrStore(Instruction *I, } +<<<<<<< HEAD +bool CDSPass::instrumentAtomic(Instruction * I) { +======= bool CdsPass::instrumentAtomic(Instruction * I) { +>>>>>>> 0d737ead79278a1a67c5829f9c6bf84ee6a90cec IRBuilder<> IRB(I); // LLVMContext &Ctx = IRB.getContext(); @@ -434,7 +568,11 @@ bool CdsPass::instrumentAtomic(Instruction * I) { int size=getTypeSize(ptr->getType()); int index=sizetoindex(size); +<<<<<<< HEAD + Instruction* funcInst=CallInst::Create(CDSAtomicStore[index], args,""); +======= Instruction* funcInst=CallInst::Create(CdsAtomicStore[index], args,""); +>>>>>>> 0d737ead79278a1a67c5829f9c6bf84ee6a90cec ReplaceInstWithInst(SI, funcInst); errs() << "Store replaced\n"; } else if (LoadInst *LI = dyn_cast(I)) { @@ -447,7 +585,11 @@ bool CdsPass::instrumentAtomic(Instruction * I) { int size=getTypeSize(ptr->getType()); int index=sizetoindex(size); +<<<<<<< HEAD + Instruction* funcInst=CallInst::Create(CDSAtomicLoad[index], args, ""); +======= Instruction* funcInst=CallInst::Create(CdsAtomicLoad[index], args, ""); +>>>>>>> 0d737ead79278a1a67c5829f9c6bf84ee6a90cec ReplaceInstWithInst(LI, funcInst); errs() << "Load Replaced\n"; } else if (AtomicRMWInst *RMWI = dyn_cast(I)) { @@ -461,7 +603,11 @@ bool CdsPass::instrumentAtomic(Instruction * I) { int size = getTypeSize(ptr->getType()); int index = sizetoindex(size); +<<<<<<< HEAD + Instruction* funcInst = CallInst::Create(CDSAtomicRMW[RMWI->getOperation()][index], args, ""); +======= Instruction* funcInst = CallInst::Create(CdsAtomicRMW[RMWI->getOperation()][index], args, ""); +>>>>>>> 0d737ead79278a1a67c5829f9c6bf84ee6a90cec ReplaceInstWithInst(RMWI, funcInst); errs() << RMWI->getOperationName(RMWI->getOperation()); errs() << " replaced\n"; @@ -489,7 +635,11 @@ bool CdsPass::instrumentAtomic(Instruction * I) { CmpOperand, NewOperand, order_succ, order_fail}; +<<<<<<< HEAD + CallInst *funcInst = IRB.CreateCall(CDSAtomicCAS[index], Args); +======= CallInst *funcInst = IRB.CreateCall(CdsAtomicCAS[index], Args); +>>>>>>> 0d737ead79278a1a67c5829f9c6bf84ee6a90cec Value *Success = IRB.CreateICmpEQ(funcInst, CmpOperand); Value *OldVal = funcInst; @@ -510,7 +660,11 @@ bool CdsPass::instrumentAtomic(Instruction * I) { Value *order = ConstantInt::get(OrdTy, atomic_order_index); Value *Args[] = {order}; +<<<<<<< HEAD + CallInst *funcInst = CallInst::Create(CDSAtomicThreadFence, Args); +======= CallInst *funcInst = CallInst::Create(CdsAtomicThreadFence, Args); +>>>>>>> 0d737ead79278a1a67c5829f9c6bf84ee6a90cec ReplaceInstWithInst(FI, funcInst); errs() << "Thread Fences replaced\n"; } @@ -519,6 +673,19 @@ bool CdsPass::instrumentAtomic(Instruction * I) { +<<<<<<< HEAD +char CDSPass::ID = 0; + +// Automatically enable the pass. +// http://adriansampson.net/blog/clangpass.html +static void registerCDSPass(const PassManagerBuilder &, + legacy::PassManagerBase &PM) { + PM.add(new CDSPass()); +} +static RegisterStandardPasses + RegisterMyPass(PassManagerBuilder::EP_EarlyAsPossible, +registerCDSPass); +======= char CdsPass::ID = 0; // Automatically enable the pass. @@ -529,4 +696,5 @@ static void registerCdsPass(const PassManagerBuilder &, } static RegisterStandardPasses RegisterMyPass(PassManagerBuilder::EP_EarlyAsPossible, -registerCdsPass); \ No newline at end of file +registerCdsPass); +>>>>>>> 0d737ead79278a1a67c5829f9c6bf84ee6a90cec