/// DisambiguateGlobalSymbols - Mangle symbols to guarantee uniqueness by /// modifying predominantly internal symbols rather than external ones. /// static void DisambiguateGlobalSymbols(Module *M) { // Try not to cause collisions by minimizing chances of renaming an // already-external symbol, so take in external globals and functions as-is. // The code should work correctly without disambiguation (assuming the same // mangler is used by the two code generators), but having symbols with the // same name causes warnings to be emitted by the code generator. Mangler Mang(*M); // Agree with the CBE on symbol naming Mang.markCharUnacceptable('.'); Mang.setPreserveAsmNames(true); for (Module::global_iterator I = M->global_begin(), E = M->global_end(); I != E; ++I) I->setName(Mang.getValueName(I)); for (Module::iterator I = M->begin(), E = M->end(); I != E; ++I) I->setName(Mang.getValueName(I)); }
void Preparer::replaceUndefsWithNull(Module &M) { ValueSet Replaced; for (Module::global_iterator GI = M.global_begin(); GI != M.global_end(); ++GI) { if (GI->hasInitializer()) { replaceUndefsWithNull(GI->getInitializer(), Replaced); } } for (Module::iterator F = M.begin(); F != M.end(); ++F) { for (Function::iterator BB = F->begin(); BB != F->end(); ++BB) { for (BasicBlock::iterator Ins = BB->begin(); Ins != BB->end(); ++Ins) { replaceUndefsWithNull(Ins, Replaced); } } } }
// StripDebugInfo - Strip debug info in the module if it exists. // To do this, we remove llvm.dbg.func.start, llvm.dbg.stoppoint, and // llvm.dbg.region.end calls, and any globals they point to if now dead. static bool StripDebugInfo(Module &M) { bool Changed = false; // Remove all of the calls to the debugger intrinsics, and remove them from // the module. if (Function *Declare = M.getFunction("llvm.dbg.declare")) { while (!Declare->use_empty()) { CallInst *CI = cast<CallInst>(Declare->use_back()); CI->eraseFromParent(); } Declare->eraseFromParent(); Changed = true; } if (Function *DbgVal = M.getFunction("llvm.dbg.value")) { while (!DbgVal->use_empty()) { CallInst *CI = cast<CallInst>(DbgVal->use_back()); CI->eraseFromParent(); } DbgVal->eraseFromParent(); Changed = true; } for (Module::named_metadata_iterator NMI = M.named_metadata_begin(), NME = M.named_metadata_end(); NMI != NME;) { NamedMDNode *NMD = NMI; ++NMI; if (NMD->getName().startswith("llvm.dbg.")) { NMD->eraseFromParent(); Changed = true; } } for (Module::iterator MI = M.begin(), ME = M.end(); MI != ME; ++MI) for (Function::iterator FI = MI->begin(), FE = MI->end(); FI != FE; ++FI) for (BasicBlock::iterator BI = FI->begin(), BE = FI->end(); BI != BE; ++BI) { if (!BI->getDebugLoc().isUnknown()) { Changed = true; BI->setDebugLoc(DebugLoc()); } } return Changed; }
bool MipsOs16::runOnModule(Module &M) { DEBUG(errs() << "Run on Module MipsOs16\n"); bool modified = false; for (Module::iterator F = M.begin(), E = M.end(); F != E; ++F) { if (F->isDeclaration()) continue; DEBUG(dbgs() << "Working on " << F->getName() << "\n"); if (needsFP(*F)) { DEBUG(dbgs() << " need to compile as nomips16 \n"); F->addFnAttr("nomips16"); } else { F->addFnAttr("mips16"); DEBUG(dbgs() << " no need to compile as nomips16 \n"); } } return modified; }
// Unfortunately, the LLVM C API doesn't provide an easy way of iterating over // all the functions in a module, so we do that manually here. You'll find // similar code in clang's BackendUtil.cpp file. extern "C" void LLVMRustRunFunctionPassManager(LLVMPassManagerRef PM, LLVMModuleRef M) { llvm::legacy::FunctionPassManager *P = unwrap<llvm::legacy::FunctionPassManager>(PM); P->doInitialization(); // Upgrade all calls to old intrinsics first. for (Module::iterator I = unwrap(M)->begin(), E = unwrap(M)->end(); I != E;) UpgradeCallsToIntrinsic(&*I++); // must be post-increment, as we remove for (Module::iterator I = unwrap(M)->begin(), E = unwrap(M)->end(); I != E; ++I) if (!I->isDeclaration()) P->run(*I); P->doFinalization(); }
bool IDManager::runOnModule(Module &M) { IDMapping.clear(); for (Module::iterator F = M.begin(); F != M.end(); ++F) { for (Function::iterator B = F->begin(); B != F->end(); ++B) { for (BasicBlock::iterator I = B->begin(); I != B->end(); ++I) { unsigned InsID = getInstructionID(I); if (InsID != INVALID_ID) IDMapping[InsID].push_back(I); } } } if (size() == 0) errs() << "[Warning] No ID information in this program.\n"; return false; }
/// findFunctionScopedAllocas - store all allocas that are known to be valid /// to the end of their function in a set. The current algorithm does this by /// finding all the allocas in the entry block that are before the first /// llvm.stacksave call (if any). /// /// FIXME: There can also be allocas elsewhere that get deallocated at the end /// of the function but they are pessimistically ignored for now. /// void ExactCheckOpt::findFunctionScopedAllocas(Module &M) { for (Module::iterator F = M.begin(), E = M.end(); F != E; ++F) { if (F->empty()) continue; BasicBlock &BB = F->getEntryBlock(); for (BasicBlock::iterator I = BB.begin(), E = BB.end(); I != E; ++I) { if (AllocaInst *AI = dyn_cast<AllocaInst>(I)) { FunctionScopedAllocas.insert(AI); } else if(CallInst *CI = dyn_cast<CallInst>(I)) { Function *CalledFunction = CI->getCalledFunction(); if (CalledFunction && CalledFunction->getName() == "llvm.stacksave") break; } } } }
/// deleteInstructionFromProgram - This method clones the current Program and /// deletes the specified instruction from the cloned module. It then runs a /// series of cleanup passes (ADCE and SimplifyCFG) to eliminate any code which /// depends on the value. The modified module is then returned. /// Module *BugDriver::deleteInstructionFromProgram(const Instruction *I, unsigned Simplification) const { Module *Result = CloneModule(Program); const BasicBlock *PBB = I->getParent(); const Function *PF = PBB->getParent(); Module::iterator RFI = Result->begin(); // Get iterator to corresponding fn std::advance(RFI, std::distance(PF->getParent()->begin(), Module::const_iterator(PF))); Function::iterator RBI = RFI->begin(); // Get iterator to corresponding BB std::advance(RBI, std::distance(PF->begin(), Function::const_iterator(PBB))); BasicBlock::iterator RI = RBI->begin(); // Get iterator to corresponding inst std::advance(RI, std::distance(PBB->begin(), BasicBlock::const_iterator(I))); Instruction *TheInst = RI; // Got the corresponding instruction! // If this instruction produces a value, replace any users with null values if (isa<StructType>(TheInst->getType())) TheInst->replaceAllUsesWith(UndefValue::get(TheInst->getType())); else if (TheInst->getType() != Type::getVoidTy(I->getContext())) TheInst->replaceAllUsesWith(Constant::getNullValue(TheInst->getType())); // Remove the instruction from the program. TheInst->getParent()->getInstList().erase(TheInst); //writeProgramToFile("current.bc", Result); // Spiff up the output a little bit. PassManager Passes; // Make sure that the appropriate target data is always used... Passes.add(new TargetData(Result)); /// FIXME: If this used runPasses() like the methods below, we could get rid /// of the -disable-* options! if (Simplification > 1 && !NoDCE) Passes.add(createDeadCodeEliminationPass()); if (Simplification && !DisableSimplifyCFG) Passes.add(createCFGSimplificationPass()); // Delete dead control flow Passes.add(createVerifierPass()); Passes.run(*Result); return Result; }
// Check the assumptions we made. void CheckInserter::checkFeatures(Module &M) { // Assume no function name starts with Loom. for (Module::iterator F = M.begin(); F != M.end(); ++F) { assert(!F->getName().startswith("Loom") && "Loom update engine seems already instrumented"); } // We do not support the situation where some important functions are called // via a function pointer, e.g. pthread_create, pthread_join and fork. for (Module::iterator F = M.begin(); F != M.end(); ++F) { if (F->getName() == "pthread_create" || F->getName() == "pthread_join" || F->getName() == "fork") { for (Value::use_iterator UI = F->use_begin(); UI != F->use_end(); ++UI) { User *Usr = *UI; assert(isa<CallInst>(Usr) || isa<InvokeInst>(Usr)); CallSite CS(cast<Instruction>(Usr)); for (unsigned i = 0; i < CS.arg_size(); ++i) assert(CS.getArgument(i) != F); } } } // pthread_cancel provides another way of terminating a thread, which we have // not supported yet. assert(M.getFunction("pthread_cancel") == NULL); }
/// Emit extern decls for functions imported from other modules, and emit /// global declarations for function defined in this module and which are /// available to other modules. /// void PIC16AsmPrinter::EmitFunctionDecls(Module &M) { // Emit declarations for external functions. O <<"\n"<<MAI->getCommentString() << "Function Declarations - BEGIN." <<"\n"; for (Module::iterator I = M.begin(), E = M.end(); I != E; I++) { if (I->isIntrinsic() || I->getName() == "@abort") continue; if (!I->isDeclaration() && !I->hasExternalLinkage()) continue; MCSymbol *Sym = Mang->getSymbol(I); // Do not emit memcpy, memset, and memmove here. // Calls to these routines can be generated in two ways, // 1. User calling the standard lib function // 2. Codegen generating these calls for llvm intrinsics. // In the first case a prototype is alread availale, while in // second case the call is via and externalsym and the prototype is missing. // So declarations for these are currently always getting printing by // tracking both kind of references in printInstrunction. if (I->isDeclaration() && PAN::isMemIntrinsic(Sym->getName())) continue; const char *directive = I->isDeclaration() ? MAI->getExternDirective() : MAI->getGlobalDirective(); O << directive << Sym->getName() << "\n"; O << directive << PAN::getRetvalLabel(Sym->getName()) << "\n"; O << directive << PAN::getArgsLabel(Sym->getName()) << "\n"; } O << MAI->getCommentString() << "Function Declarations - END." <<"\n"; }
bool DivCheckPass::runOnModule(Module &M) { Function *divZeroCheckFunction = 0; LLVMContext &ctx = M.getContext(); bool moduleChanged = false; for (Module::iterator f = M.begin(), fe = M.end(); f != fe; ++f) { for (Function::iterator b = f->begin(), be = f->end(); b != be; ++b) { for (BasicBlock::iterator i = b->begin(), ie = b->end(); i != ie; ++i) { if (BinaryOperator* binOp = dyn_cast<BinaryOperator>(i)) { // find all [s|u][div|mod] instructions Instruction::BinaryOps opcode = binOp->getOpcode(); if (opcode == Instruction::SDiv || opcode == Instruction::UDiv || opcode == Instruction::SRem || opcode == Instruction::URem) { CastInst *denominator = CastInst::CreateIntegerCast(i->getOperand(1), Type::getInt64Ty(ctx), false, /* sign doesn't matter */ "int_cast_to_i64", &*i); // Lazily bind the function to avoid always importing it. if (!divZeroCheckFunction) { Constant *fc = M.getOrInsertFunction("klee_div_zero_check", Type::getVoidTy(ctx), Type::getInt64Ty(ctx), NULL); divZeroCheckFunction = cast<Function>(fc); } CallInst * ci = CallInst::Create(divZeroCheckFunction, denominator, "", &*i); // Set debug location of checking call to that of the div/rem // operation so error locations are reported in the correct // location. ci->setDebugLoc(binOp->getDebugLoc()); moduleChanged = true; } } } } } return moduleChanged; }
bool ExpandByVal::runOnModule(Module &M) { bool Modified = false; DataLayout DL(&M); for (Module::iterator Func = M.begin(), E = M.end(); Func != E; ++Func) { AttributeSet NewAttrs = RemoveAttrs(Func->getContext(), Func->getAttributes()); Modified |= (NewAttrs != Func->getAttributes()); Func->setAttributes(NewAttrs); for (Function::iterator BB = Func->begin(), E = Func->end(); BB != E; ++BB) { for (BasicBlock::iterator Inst = BB->begin(), E = BB->end(); Inst != E; ++Inst) { if (CallInst *Call = dyn_cast<CallInst>(Inst)) { Modified |= ExpandCall(&DL, Call); } else if (InvokeInst *Call = dyn_cast<InvokeInst>(Inst)) { Modified |= ExpandCall(&DL, Call); } } } } return Modified; }
bool llvm::InputValues::runOnModule(Module& M) { module = &M; initializeWhiteList(); collectMainArguments(); for(Module::iterator Fit = M.begin(), Fend = M.end(); Fit != Fend; Fit++){ for (Function::iterator BBit = Fit->begin(), BBend = Fit->end(); BBit != BBend; BBit++) { for (BasicBlock::iterator Iit = BBit->begin(), Iend = BBit->end(); Iit != Iend; Iit++) { if (CallInst *CI = dyn_cast<CallInst>(Iit)) { if (isMarkedCallInst(CI)){ //Values returned by marked instructions insertInInputDepValues(CI); for(unsigned int i = 0; i < CI->getNumOperands(); i++){ if (CI->getOperand(i)->getType()->isPointerTy()){ //Arguments with pointer type of marked functions insertInInputDepValues(CI->getOperand(i)); } } } } } } } NumInputValues = inputValues.size(); //We don't modify anything, so we must return false; return false; }
std::unique_ptr<Module> BugDriver::deleteInstructionFromProgram(const Instruction *I, unsigned Simplification) { // FIXME, use vmap? Module *Clone = CloneModule(Program); const BasicBlock *PBB = I->getParent(); const Function *PF = PBB->getParent(); Module::iterator RFI = Clone->begin(); // Get iterator to corresponding fn std::advance(RFI, std::distance(PF->getParent()->begin(), Module::const_iterator(PF))); Function::iterator RBI = RFI->begin(); // Get iterator to corresponding BB std::advance(RBI, std::distance(PF->begin(), Function::const_iterator(PBB))); BasicBlock::iterator RI = RBI->begin(); // Get iterator to corresponding inst std::advance(RI, std::distance(PBB->begin(), BasicBlock::const_iterator(I))); Instruction *TheInst = RI; // Got the corresponding instruction! // If this instruction produces a value, replace any users with null values if (!TheInst->getType()->isVoidTy()) TheInst->replaceAllUsesWith(Constant::getNullValue(TheInst->getType())); // Remove the instruction from the program. TheInst->getParent()->getInstList().erase(TheInst); // Spiff up the output a little bit. std::vector<std::string> Passes; /// Can we get rid of the -disable-* options? if (Simplification > 1 && !NoDCE) Passes.push_back("dce"); if (Simplification && !DisableSimplifyCFG) Passes.push_back("simplifycfg"); // Delete dead control flow Passes.push_back("verify"); std::unique_ptr<Module> New = runPassesOn(Clone, Passes); delete Clone; if (!New) { errs() << "Instruction removal failed. Sorry. :( Please report a bug!\n"; exit(1); } return New; }
bool StripAttributes::runOnModule(Module &M) { DataLayout DL(&M); for (Module::iterator Func = M.begin(), E = M.end(); Func != E; ++Func) { // Avoid stripping attributes from intrinsics because the // constructor for Functions just adds them back again. It would // be confusing if the attributes were sometimes present on // intrinsics and sometimes not. if (!Func->isIntrinsic()) { stripGlobalValueAttrs(Func); stripFunctionAttrs(&DL, Func); } } for (Module::global_iterator GV = M.global_begin(), E = M.global_end(); GV != E; ++GV) { stripGlobalValueAttrs(GV); } return true; }
extern "C" void LLVMRustMarkAllFunctionsNounwind(LLVMModuleRef M) { for (Module::iterator GV = unwrap(M)->begin(), E = unwrap(M)->end(); GV != E; ++GV) { GV->setDoesNotThrow(); Function *F = dyn_cast<Function>(GV); if (F == nullptr) continue; for (Function::iterator B = F->begin(), BE = F->end(); B != BE; ++B) { for (BasicBlock::iterator I = B->begin(), IE = B->end(); I != IE; ++I) { if (isa<InvokeInst>(I)) { InvokeInst *CI = cast<InvokeInst>(I); CI->setDoesNotThrow(); } } } } }
bool RaiseAsmPass::runOnModule(Module &M) { bool changed = false; std::string Err; #if LLVM_VERSION_CODE >= LLVM_VERSION(3, 1) std::string HostTriple = llvm::sys::getDefaultTargetTriple(); #else std::string HostTriple = llvm::sys::getHostTriple(); #endif const Target *NativeTarget = TargetRegistry::lookupTarget(HostTriple, Err); TargetMachine * TM = 0; if (NativeTarget == 0) { klee_warning("Warning: unable to select native target: %s", Err.c_str()); TLI = 0; } else { #if LLVM_VERSION_CODE >= LLVM_VERSION(3, 1) TM = NativeTarget->createTargetMachine(HostTriple, "", "", TargetOptions()); #elif LLVM_VERSION_CODE >= LLVM_VERSION(3, 0) TM = NativeTarget->createTargetMachine(HostTriple, "", ""); #else TM = NativeTarget->createTargetMachine(HostTriple, ""); #endif TLI = TM->getTargetLowering(); triple = llvm::Triple(HostTriple); } for (Module::iterator fi = M.begin(), fe = M.end(); fi != fe; ++fi) { for (Function::iterator bi = fi->begin(), be = fi->end(); bi != be; ++bi) { for (BasicBlock::iterator ii = bi->begin(), ie = bi->end(); ii != ie;) { Instruction *i = ii; ++ii; changed |= runOnInstruction(M, i); } } } if (TM) delete TM; return changed; }
bool ReduceCrashingFunctions::TestFuncs(std::vector<Function*> &Funcs) { //if main isn't present, claim there is no problem if (KeepMain && find(Funcs.begin(), Funcs.end(), BD.getProgram()->getFunction("main")) == Funcs.end()) return false; // Clone the program to try hacking it apart... Module *M = CloneModule(BD.getProgram()); // Convert list to set for fast lookup... std::set<Function*> Functions; for (unsigned i = 0, e = Funcs.size(); i != e; ++i) { // FIXME: bugpoint should add names to all stripped symbols. assert(!Funcs[i]->getName().empty() && "Bugpoint doesn't work on stripped modules yet PR718!"); Function *CMF = M->getFunction(Funcs[i]->getName()); assert(CMF && "Function not in module?!"); assert(CMF->getFunctionType() == Funcs[i]->getFunctionType() && "wrong ty"); Functions.insert(CMF); } std::cout << "Checking for crash with only these functions: "; PrintFunctionList(Funcs); std::cout << ": "; // Loop over and delete any functions which we aren't supposed to be playing // with... for (Module::iterator I = M->begin(), E = M->end(); I != E; ++I) if (!I->isDeclaration() && !Functions.count(I)) DeleteFunctionBody(I); // Try running the hacked up program... if (TestFn(BD, M)) { BD.setNewProgram(M); // It crashed, keep the trimmed version... // Make sure to use function pointers that point into the now-current // module. Funcs.assign(Functions.begin(), Functions.end()); return true; } delete M; return false; }
bool Mutator::runOnModule(Module &M) { unsigned siteId = 0; OperatorManager *OMgr = OperatorManager::getInstance(); OperatorInfoList oplst; // Loop through all functions within module for (Module::iterator F = M.begin(), ME = M.end(); F != ME; ++F) { // Loop through all basic blocks within function for (Function::iterator B = F->begin(), FE = F->end(); B != FE; ++B) { // Loop through all instructions within basic block for (BasicBlock::iterator I = B->begin(), BE = B->end(); I != BE; I++) { // Consider only mutable instructions OMgr->getCompatibleOperators(I, oplst); bool mutated = false; for (OperatorInfoList::iterator opi = oplst.begin(); opi != oplst.end(); opi++) { cl::list<unsigned>::iterator sid = find (MutationIDS.begin(), MutationIDS.end(), siteId++); if (sid != MutationIDS.end()) { // One of the specified mutations was found if (!mutated) { MutationOperator *op = (*opi)->build(); Value *newv = op->apply(I); //cerr << *I << " --> " << *newv << "\n"; if (newv != NULL) { ReplaceInstWithValue(B->getInstList(), I, newv); } else { } mutated = true; } else { throw std::string("An instruction is being mutated twice! Aborting..."); } } } } } } // notify change of program return true; }
bool EnforcingLandmarks::runOnModule(Module &M) { if (EnforcingLandmarksFile == "") { const static size_t len = sizeof(DEFAULT_ENFORCING_LANDMARK_FUNCS) / sizeof(const char *[2]); for (size_t i = 0; i < len; ++i) { string func_name = DEFAULT_ENFORCING_LANDMARK_FUNCS[i][0]; string is_blocking = DEFAULT_ENFORCING_LANDMARK_FUNCS[i][1]; insert_enforcing_landmark_func(func_name, is_blocking); } } else { ifstream fin(EnforcingLandmarksFile.c_str()); string func_name, is_blocking; while (fin >> func_name >> is_blocking) insert_enforcing_landmark_func(func_name, is_blocking); } // Mark any function call to landmark functions as enforcing landmarks. for (Module::iterator f = M.begin(); f != M.end(); ++f) { if (f->getName() == "MyMalloc") continue; if (f->getName() == "MyFree") continue; if (f->getName() == "MyFreeNow") continue; if (f->getName() == "maketree") continue; for (Function::iterator bb = f->begin(); bb != f->end(); ++bb) { for (BasicBlock::iterator ins = bb->begin(); ins != bb->end(); ++ins) { CallSite cs(ins); if (cs.getInstruction()) { if (Function *callee = cs.getCalledFunction()) { StringRef callee_name = callee->getName(); if (enforcing_landmark_funcs.count(callee_name)) { if (OnlyMain && callee_name != "pthread_self" && f->getName() != "main") continue; if (callee_name.startswith("pthread_mutex") || callee_name.startswith("pthread_cond") || callee_name.startswith("pthread_barrier") || callee_name.startswith("pthread_rwlock") || callee_name.startswith("pthread_spin")) { if (rand() % 100 < PruningRate) continue; } enforcing_landmarks.insert(ins); } } } } } } return false; }
/// doInitialization - If this module uses the GC intrinsics, find them now. bool LowerIntrinsics::doInitialization(Module &M) { // FIXME: This is rather antisocial in the context of a JIT since it performs // work against the entire module. But this cannot be done at // runFunction time (initializeCustomLowering likely needs to change // the module). GCModuleInfo *MI = getAnalysisIfAvailable<GCModuleInfo>(); assert(MI && "LowerIntrinsics didn't require GCModuleInfo!?"); for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) if (!I->isDeclaration() && I->hasGC()) MI->getFunctionInfo(*I); // Instantiate the GC strategy. bool MadeChange = false; for (GCModuleInfo::iterator I = MI->begin(), E = MI->end(); I != E; ++I) if (NeedsCustomLoweringPass(**I)) if ((*I)->initializeCustomLowering(M)) MadeChange = true; return MadeChange; }
bool CreateCallDependency::runOnModule(Module &M) { doInitialization(M); for (Module::iterator f = M.begin(), fe = M.end(); f != fe; f++) { if (!f->isDeclaration()) { nameToCall[f->getName()] = f; } } findDependency(CallMainName); calls.insert(CallMainName); findUsedGlobalVar(M); doFinalization(); return true; }
// doInitialization - Initializes the vector of functions that have been // annotated with the noinline attribute. bool SimpleInliner::doInitialization(CallGraph &CG) { CA.setTargetData(getAnalysisIfAvailable<TargetData>()); Module &M = CG.getModule(); for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) if (!I->isDeclaration() && I->hasFnAttr(Attribute::NoInline)) NeverInline.insert(I); // Get llvm.noinline GlobalVariable *GV = M.getNamedGlobal("llvm.noinline"); if (GV == 0) return false; // Don't crash on invalid code if (!GV->hasDefinitiveInitializer()) return false; const ConstantArray *InitList = dyn_cast<ConstantArray>(GV->getInitializer()); if (InitList == 0) return false; // Iterate over each element and add to the NeverInline set for (unsigned i = 0, e = InitList->getNumOperands(); i != e; ++i) { // Get Source const Constant *Elt = InitList->getOperand(i); if (const ConstantExpr *CE = dyn_cast<ConstantExpr>(Elt)) if (CE->getOpcode() == Instruction::BitCast) Elt = CE->getOperand(0); // Insert into set of functions to never inline if (const Function *F = dyn_cast<Function>(Elt)) NeverInline.insert(F); } return false; }
// // Method: TransformCollapsedAllocas() // // Description: // Transform all stack allocated objects that are type-unknown // (i.e., are completely folded) to heap allocations. // void ConvertUnsafeAllocas::TransformCollapsedAllocas(Module &M) { // // Need to check if the following is incomplete because we are only looking // at scalars. // // It may be complete because every instruction actually is a scalar in // LLVM?! for (Module::iterator MI = M.begin(), ME = M.end(); MI != ME; ++MI) { if (!MI->isDeclaration()) { DSGraph *G = budsPass->getDSGraph(*MI); DSGraph::ScalarMapTy &SM = G->getScalarMap(); for (DSGraph::ScalarMapTy::iterator SMI = SM.begin(), SME = SM.end(); SMI != SME; ) { if (AllocaInst *AI = dyn_cast<AllocaInst>((Value *)(SMI->first))) { if (SMI->second.getNode()->isNodeCompletelyFolded()) { Value *AllocSize = ConstantInt::get(Int32Type, TD->getTypeAllocSize(AI->getAllocatedType())); if (AI->isArrayAllocation()) AllocSize = BinaryOperator::Create(Instruction::Mul, AllocSize, AI->getOperand(0), "sizetmp", AI); CallInst *CI = CallInst::Create (kmalloc, AllocSize, "", AI); Value * MI = castTo (CI, AI->getType(), "", AI); InsertFreesAtEnd(CI); AI->replaceAllUsesWith(MI); SMI->second.getNode()->setHeapMarker(); SM.erase(SMI++); AI->getParent()->getInstList().erase(AI); ++ConvAllocas; } else { ++SMI; } } else { ++SMI; } } } } }
static void getSymbols(Module*M, std::vector<std::string>& symbols) { // Loop over global variables for (Module::global_iterator GI = M->global_begin(), GE=M->global_end(); GI != GE; ++GI) if (!GI->isDeclaration() && !GI->hasLocalLinkage()) if (!GI->getName().empty()) symbols.push_back(GI->getName()); // Loop over functions for (Module::iterator FI = M->begin(), FE = M->end(); FI != FE; ++FI) if (!FI->isDeclaration() && !FI->hasLocalLinkage()) if (!FI->getName().empty()) symbols.push_back(FI->getName()); // Loop over aliases for (Module::alias_iterator AI = M->alias_begin(), AE = M->alias_end(); AI != AE; ++AI) { if (AI->hasName()) symbols.push_back(AI->getName()); } }
void Preparer::fillInAllocationSize(Module &M) { Function *MemAllocHook = M.getFunction(DynAAUtils::MemAllocHookName); // Skip this process if there's no HookMemAlloc. if (!MemAllocHook) return; for (Module::iterator F = M.begin(); F != M.end(); ++F) { for (Function::iterator BB = F->begin(); BB != F->end(); ++BB) { for (BasicBlock::iterator I = BB->begin(); I != BB->end(); ++I) { CallSite CS(I); if (CS && CS.getCalledFunction() == MemAllocHook) { // HookMemAlloc(ValueID, Base, Size = undef) assert(CS.arg_size() == 3); if (isa<UndefValue>(CS.getArgument(2))) fillInAllocationSize(CS); } } } } }
bool IPCP::runOnModule(Module &M) { bool Changed = false; bool LocalChange = true; // FIXME: instead of using smart algorithms, we just iterate until we stop // making changes. while (LocalChange) { LocalChange = false; for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) if (!I->isDeclaration()) { // Delete any klingons. I->removeDeadConstantUsers(); if (I->hasLocalLinkage()) LocalChange |= PropagateConstantsIntoArguments(*I); Changed |= PropagateConstantReturn(*I); } Changed |= LocalChange; } return Changed; }
void InterPro::print(raw_ostream &O, Module *M) { char pPath[100]; for(Module::iterator F = M->begin(); F != M->end(); F ++) { if(!F->getName().startswith("test")) { continue; } O << F->getName() << ":\n"; for(Function::iterator BB = F->begin(); BB != F->end(); ++ BB) { for(BasicBlock::iterator I = BB->begin(); I != BB->end(); I ++) { I->dump(); if( MDNode *N = I->getMetadata("dbg") ) { DILocation Loc(N); string sFileNameForInstruction = Loc.getDirectory().str() + "/" + Loc.getFilename().str(); realpath( sFileNameForInstruction.c_str() , pPath); sFileNameForInstruction = string(pPath); unsigned int uLineNoForInstruction = Loc.getLineNumber(); O << sFileNameForInstruction << ": " << uLineNoForInstruction << ": "; } O << this->InstBeforeSetMapping[I].size() << " "; O << this->InstAfterSetMapping[I].size() << "\n"; } } O << "*********************************************\n"; } }
bool IneqGraph::runOnModule(Module &M) { C = &M.getContext(); RA = (RangeAnalysis*)&getAnalysis<InterProceduralRACousot>(); AlfaConst = ConstantInt::get(Type::getInt64Ty(*C), 0, true); AlfaNode = getOrCreateNode(AlfaConst); for (Module::iterator F = M.begin(), E = M.end(); F != E; ++F) { if (F->isDeclaration()) continue; VS = &getAnalysis<vSSA>(*F); for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB) for (BasicBlock::iterator I = BB->begin(), E = BB->end(); I != E; ++I) addEdgesFor(&(*I)); } //if (isCurrentDebugType(DEBUG_TYPE)) // dumpToFile("ineq_graph.module.dot", M); return false; }
/// performFinalCleanups - This method clones the current Program and performs /// a series of cleanups intended to get rid of extra cruft on the module /// before handing it to the user. /// Module *BugDriver::performFinalCleanups(Module *M, bool MayModifySemantics) { // Make all functions external, so GlobalDCE doesn't delete them... for (Module::iterator I = M->begin(), E = M->end(); I != E; ++I) I->setLinkage(GlobalValue::ExternalLinkage); std::vector<std::string> CleanupPasses; CleanupPasses.push_back("globaldce"); if (MayModifySemantics) CleanupPasses.push_back("deadarghaX0r"); else CleanupPasses.push_back("deadargelim"); Module *New = runPassesOn(M, CleanupPasses); if (New == 0) { errs() << "Final cleanups failed. Sorry. :( Please report a bug!\n"; return M; } delete M; return New; }