| //===- Dyncount.cpp - Test pass for using constraints -----------*- C++ -*-===// |
| // |
| // The SAFECode Compiler |
| // |
| // This file was developed by the LLVM research group and is distributed under |
| // the University of Illinois Open Source License. See LICENSE.TXT for details. |
| // |
| //===----------------------------------------------------------------------===// |
| // |
| // This file implements a test pass which helps test the generation of formulas |
| // and constraints. |
| // |
| //===----------------------------------------------------------------------===// |
| |
| #include "llvm/Pass.h" |
| #include "llvm/IR/Module.h" |
| #include "llvm/IR/Instructions.h" |
| #include "llvm/IR/Constants.h" |
| #include "dsa/TypeSafety.h" |
| |
| using namespace llvm; |
| class Dyncount : public ModulePass { |
| protected: |
| void instrumentLoad (GlobalVariable * Counter, LoadInst * LI); |
| void instrumentStore (GlobalVariable * Counter, StoreInst * SI); |
| dsa::TypeSafety<TDDataStructures> *TS; |
| |
| public: |
| static char ID; |
| Dyncount () : ModulePass (ID) { } |
| const char *getPassName() const { |
| return "Count safe/unsafe load/store"; |
| } |
| virtual bool runOnModule (Module & M); |
| virtual void getAnalysisUsage(AnalysisUsage &AU) const { |
| AU.addRequired<dsa::TypeSafety<TDDataStructures> >(); |
| } |
| }; |
| |
| char Dyncount::ID = 0; |
| static RegisterPass<Dyncount> |
| X ("dyncount", "Instrument code to count number of Load/Stores"); |
| |
| |
| void |
| Dyncount::instrumentLoad (GlobalVariable * Counter, LoadInst * LI) { |
| // |
| // Generate a load, increment, and store right before the GEP. |
| // |
| LLVMContext & Context = Counter->getParent()->getContext(); |
| ConstantInt * One = ConstantInt::get (Type::getInt64Ty(Context), 1); |
| LoadInst * OldValue = new LoadInst (Counter, "count", LI); |
| Instruction * NewValue = BinaryOperator::Create (BinaryOperator::Add, |
| OldValue, |
| One, |
| "count", |
| LI); |
| new StoreInst (NewValue, Counter, LI); |
| return; |
| } |
| void |
| Dyncount::instrumentStore (GlobalVariable * Counter, StoreInst * SI) { |
| // |
| // Generate a load, increment, and store right before the GEP. |
| // |
| LLVMContext & Context = Counter->getParent()->getContext(); |
| ConstantInt * One = ConstantInt::get (Type::getInt64Ty(Context), 1); |
| LoadInst * OldValue = new LoadInst (Counter, "count", SI); |
| Instruction * NewValue = BinaryOperator::Create (BinaryOperator::Add, |
| OldValue, |
| One, |
| "count", |
| SI); |
| new StoreInst (NewValue, Counter, SI); |
| return; |
| } |
| |
| // |
| // Method: runOnModule() |
| // |
| // Description: |
| // Entry point for this pass. |
| // |
| bool |
| Dyncount::runOnModule (Module & M) { |
| // |
| // Create two global counters within the module. |
| // |
| TS = &getAnalysis<dsa::TypeSafety<TDDataStructures> >(); |
| ConstantInt * Zero = ConstantInt::get (Type::getInt64Ty(M.getContext()), 0); |
| GlobalVariable * Total = new GlobalVariable (M, |
| Type::getInt64Ty(M.getContext()), |
| false, |
| GlobalValue::InternalLinkage, |
| Zero, |
| "Total"); |
| GlobalVariable * Safe = new GlobalVariable (M, |
| Type::getInt64Ty(M.getContext()), |
| false, |
| GlobalValue::InternalLinkage, |
| Zero, |
| "Safe"); |
| |
| for (Module::iterator F = M.begin(); F != M.end(); ++F){ |
| for (Function::iterator B = F->begin(), FE = F->end(); B != FE; ++B) { |
| for (BasicBlock::iterator I = B->begin(), BE = B->end(); I != BE; I++) { |
| if(LoadInst *LI = dyn_cast<LoadInst>(I)) { |
| instrumentLoad(Total, LI); |
| if(TS->isTypeSafe(LI->getOperand(0),LI->getParent()->getParent())) |
| instrumentLoad(Safe, LI); |
| |
| // check if safe |
| } else if(StoreInst *SI = dyn_cast<StoreInst>(I)) { |
| instrumentStore(Total, SI); |
| if(TS->isTypeSafe(SI->getOperand(1),SI->getParent()->getParent())) |
| instrumentStore(Safe, SI); |
| // check if safe |
| } |
| } |
| } |
| } |
| |
| // |
| // Add a call to main() that will record the values on exit(). |
| // |
| Function *MainFunc = M.getFunction("main") ? M.getFunction("main") |
| : M.getFunction ("MAIN__"); |
| |
| BasicBlock & BB = MainFunc->getEntryBlock(); |
| Constant * Setup = M.getOrInsertFunction ("DYN_COUNT_setup", Type::getVoidTy(M.getContext()), Total->getType(), Safe->getType(), NULL); |
| std::vector<Value *> args; |
| args.push_back (Total); |
| args.push_back (Safe); |
| CallInst::Create (Setup, args, "", BB.getFirstNonPHI()); |
| |
| |
| return true; |
| } |
| |