void EmitAssemblyHelper::EmitAssembly(BackendAction Action, raw_ostream *OS) { TimeRegion Region(llvm::TimePassesIsEnabled ? &CodeGenerationTime : 0); llvm::formatted_raw_ostream FormattedOS; bool UsesCodeGen = (Action != Backend_EmitNothing && Action != Backend_EmitBC && Action != Backend_EmitLL); if (!TM) TM.reset(CreateTargetMachine(UsesCodeGen)); if (UsesCodeGen && !TM) return; CreatePasses(); switch (Action) { case Backend_EmitNothing: break; case Backend_EmitBC: getPerModulePasses()->add(createBitcodeWriterPass(*OS)); break; case Backend_EmitLL: FormattedOS.setStream(*OS, formatted_raw_ostream::PRESERVE_STREAM); getPerModulePasses()->add(createPrintModulePass(&FormattedOS)); break; default: FormattedOS.setStream(*OS, formatted_raw_ostream::PRESERVE_STREAM); if (!AddEmitPasses(Action, FormattedOS)) return; } // Before executing passes, print the final values of the LLVM options. cl::PrintOptionValues(); // Run passes. For now we do all passes at once, but eventually we // would like to have the option of streaming code generation. if (PerFunctionPasses) { PrettyStackTraceString CrashInfo("Per-function optimization"); PerFunctionPasses->doInitialization(); for (Module::iterator I = TheModule->begin(), E = TheModule->end(); I != E; ++I) if (!I->isDeclaration()) PerFunctionPasses->run(*I); PerFunctionPasses->doFinalization(); } if (PerModulePasses) { PrettyStackTraceString CrashInfo("Per-module optimization passes"); PerModulePasses->run(*TheModule); } if (CodeGenPasses) { PrettyStackTraceString CrashInfo("Code generation"); CodeGenPasses->run(*TheModule); } }
// run - On a module, we run this pass by initializing, runOnFunction'ing once // for every function in the module, then by finalizing. // bool FunctionPass::runOnModule(Module &M) { bool Changed = doInitialization(M); for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) if (!I->isDeclaration()) // Passes are not run on external functions! Changed |= runOnFunction(*I); return Changed | doFinalization(M); }
// create a reference table for functions defined in the path profile file void PathProfileLoaderPass::buildFunctionRefs (Module &M) { _functions.push_back(0); // make the 0 index a null pointer for (Module::iterator F = M.begin(), E = M.end(); F != E; F++) { if (F->isDeclaration()) continue; _functions.push_back(F); } }
bool CreateIDBitcode::runOnModule(Module &M) { for(Module::iterator f = M.begin(), fe = M.end(); f != fe; f++) { if (!f->isDeclaration()) { runOnFunction(*f); } } return true; }
bool MemoryInstrumenter::runOnModule(Module &M) { // Check whether there are unsupported language features. checkFeatures(M); // Setup scalar types. setupScalarTypes(M); // Find the main function. Main = M.getFunction("main"); assert(Main && !Main->isDeclaration() && !Main->hasLocalLinkage()); // Setup hook function declarations. setupHooks(M); // Hook global variable allocations. instrumentGlobals(M); // Hook memory allocations and memory accesses. for (Module::iterator F = M.begin(); F != M.end(); ++F) { if (F->isDeclaration()) continue; if (!isWhiteListed(*F)) continue; // The second argument of main(int argc, char *argv[]) needs special // handling, which is done in instrumentMainArgs. // We should treat argv as a memory allocation instead of a regular // pointer. if (Main != F) instrumentPointerParameters(F); if (F->isVarArg()) instrumentVarArgFunction(F); for (Function::iterator BB = F->begin(); BB != F->end(); ++BB) { for (BasicBlock::iterator I = BB->begin(); I != BB->end(); ++I) instrumentInstructionIfNecessary(I); } } // main(argc, argv) // argv is allocated by outside. instrumentMainArgs(M); // Lower global constructors. lowerGlobalCtors(M); #if 0 // Add HookGlobalsAlloc to the global_ctors list. addNewGlobalCtor(M); #endif // Call the memory hook initializer and the global variable allocation hook // at the very beginning. Instruction *OldEntry = Main->begin()->getFirstNonPHI(); CallInst::Create(MemHooksIniter, "", OldEntry); CallInst::Create(GlobalsAllocHook, "", OldEntry); return true; }
/// doInitialization - If this module uses the GC intrinsics, find them now. bool LowerIntrinsics::doInitialization(Module &M) { 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. return false; }
void MemoryInstrumenter::checkFeatures(Module &M) { // Check whether any memory allocation function can // potentially be pointed by function pointers. // Also, all intrinsic functions will be called directly, // i.e. not via function pointers. for (Module::iterator F = M.begin(); F != M.end(); ++F) { if (DynAAUtils::IsMalloc(F) || F->isIntrinsic()) { 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); } } } // Check whether memory allocation functions are captured. for (Module::iterator F = M.begin(); F != M.end(); ++F) { // 0 is the return, 1 is the first parameter. if (F->isDeclaration() && F->doesNotAlias(0) && !DynAAUtils::IsMalloc(F)) { errs().changeColor(raw_ostream::RED); errs() << F->getName() << "'s return value is marked noalias, "; errs() << "but the function is not treated as malloc.\n"; errs().resetColor(); } } // Global variables shouldn't be of the array type. for (Module::global_iterator GI = M.global_begin(), E = M.global_end(); GI != E; ++GI) { assert(!GI->getType()->isArrayTy()); } // A function parameter or an instruction can be an array, but we don't // instrument such constructs for now. Issue a warning on such cases. for (Module::iterator F = M.begin(), E = M.end(); F != E; ++F) { for (Function::arg_iterator AI = F->arg_begin(); AI != F->arg_end(); ++AI) { if (AI->getType()->isArrayTy()) { errs().changeColor(raw_ostream::RED); errs() << F->getName() << ":" << *AI << " is an array\n"; errs().resetColor(); } } } 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) { if (Ins->getType()->isArrayTy()) { errs().changeColor(raw_ostream::RED); errs() << F->getName() << ":" << *Ins << " is an array\n"; errs().resetColor(); } } } } }
// doInitialization - Initializes the vector of functions that have not // been annotated with the "always inline" attribute. bool AlwaysInliner::doInitialization(CallGraph &CG) { Module &M = CG.getModule(); for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) if (!I->isDeclaration() && !I->hasFnAttr(Attribute::AlwaysInline)) NeverInline.insert(I); return false; }
ProgramStructure::ProgramStructure(Module &M) { for (Module::iterator f = M.begin(); f != M.end(); ++f) if (!f->isDeclaration() && !memoryManStuff(&*f)) for (inst_iterator i = inst_begin(*f); i != inst_end(*f); ++i) if (const StoreInst *s = dyn_cast<StoreInst>(&*i)) { const Value *l = elimConstExpr(s->getPointerOperand()); this->getContainer()[&*f].push_back(ProgramStructure::Command( hasExtraReference(l) ? CMD_VAR : CMD_DREF_VAR, l)); } }
// // This pass only makes sense when the underlying chip has floating point but // we are compiling as mips16. // For all mips16 functions (that are not stubs we have already generated), or // declared via attributes as nomips16, we must: // 1) fixup all returns of float, double, single and double complex // by calling a helper function before the actual return. // 2) generate helper functions (stubs) that can be called by mips32 functions // that will move parameters passed normally passed in floating point // registers the soft float equivalents. (Coming in a later patch). // 3) in the case of static relocation, generate helper functions so that // mips16 functions can call extern functions of unknown type (mips16 or // mips32). (Coming in a later patch). // 4) TBD. For pic, calls to extern functions of unknown type are handled by // predefined helper functions in libc but this work is currently done // during call lowering but it should be moved here in the future. // bool Mips16HardFloat::runOnModule(Module &M) { DEBUG(errs() << "Run on Module Mips16HardFloat\n"); bool Modified = false; for (Module::iterator F = M.begin(), E = M.end(); F != E; ++F) { if (F->isDeclaration() || F->hasFnAttribute("mips16_fp_stub") || F->hasFnAttribute("nomips16")) continue; Modified |= fixupFPReturnAndCall(*F, &M, Subtarget); } 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) { FunctionPassManager *P = unwrap<FunctionPassManager>(PM); P->doInitialization(); for (Module::iterator I = unwrap(M)->begin(), E = unwrap(M)->end(); I != E; ++I) if (!I->isDeclaration()) P->run(*I); P->doFinalization(); }
bool StaticSlicer::sliceModule() { bool modified = false; for (Slicers::iterator s = slicers.begin(); s != slicers.end(); ++s) modified |= s->second->slice(); if (modified) for (Module::iterator I = module.begin(), E = module.end(); I != E; ++I) if (!I->isDeclaration()) FunctionStaticSlicer::removeUndefBranches(MP, *I); return modified; }
bool MergeFunctions::runOnModule(Module &M) { bool Changed = false; std::map<unsigned long, std::vector<Function *> > FnMap; for (Module::iterator F = M.begin(), E = M.end(); F != E; ++F) { if (F->isDeclaration() || F->isIntrinsic()) continue; if (!F->hasLocalLinkage() && !F->hasExternalLinkage() && !F->hasWeakLinkage()) continue; if (hasAddressTaken(F)) continue; FnMap[hash(F)].push_back(F); } // TODO: instead of running in a loop, we could also fold functions in callgraph // order. Constructing the CFG probably isn't cheaper than just running in a loop. bool LocalChanged; do { LocalChanged = false; for (std::map<unsigned long, std::vector<Function *> >::iterator I = FnMap.begin(), E = FnMap.end(); I != E; ++I) { DOUT << "size: " << FnMap.size() << "\n"; std::vector<Function *> &FnVec = I->second; DOUT << "hash (" << I->first << "): " << FnVec.size() << "\n"; for (int i = 0, e = FnVec.size(); i != e; ++i) { for (int j = i + 1; j != e; ++j) { bool isEqual = equals(FnVec[i], FnVec[j]); DOUT << " " << FnVec[i]->getName() << (isEqual ? " == " : " != ") << FnVec[j]->getName() << "\n"; if (isEqual) { if (fold(FnVec, i, j)) { LocalChanged = true; FnVec.erase(FnVec.begin() + j); --j, --e; } } } } } Changed |= LocalChanged; } while (LocalChanged); return Changed; }
/* * Find stores to arguments that are overwritten before being read. */ void DeadStoreEliminationPass::runOverwrittenDeadStoreAnalysis(Module &M) { DEBUG(errs() << "Running overwritten dead store analysis...\n"); for (Module::iterator F = M.begin(), E = M.end(); F != E; ++F) { if (!F->isDeclaration()) { FunctionsCount++; CallsCount += F->getNumUses(); runOverwrittenDeadStoreAnalysisOnFn(*F); } } DEBUG(errs() << "\n"); }
void MemoryInstrumenter::checkFeatures(Module &M) { // Check whether any memory allocation function can // potentially be pointed by function pointers. // Also, all intrinsic functions will be called directly, // i.e. not via function pointers. for (Module::iterator F = M.begin(); F != M.end(); ++F) { if (DynAAUtils::IsMalloc(F) || F->isIntrinsic()) { 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); } } } // Check whether memory allocation functions are captured. for (Module::iterator F = M.begin(); F != M.end(); ++F) { // 0 is the return, 1 is the first parameter. if (F->isDeclaration() && F->doesNotAlias(0) && !DynAAUtils::IsMalloc(F)) { errs().changeColor(raw_ostream::RED); errs() << F->getName() << "'s return value is marked noalias, "; errs() << "but the function is not treated as malloc.\n"; errs().resetColor(); } } // Sequential types except pointer types shouldn't be used as the type of // an instruction, a function parameter, or a global variable. for (Module::global_iterator GI = M.global_begin(), E = M.global_end(); GI != E; ++GI) { if (isa<SequentialType>(GI->getType())) assert(GI->getType()->isPointerTy()); } for (Module::iterator F = M.begin(), E = M.end(); F != E; ++F) { for (Function::arg_iterator AI = F->arg_begin(); AI != F->arg_end(); ++AI) { if (isa<SequentialType>(AI->getType())) assert(AI->getType()->isPointerTy()); } } 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) { if (isa<SequentialType>(Ins->getType())) assert(Ins->getType()->isPointerTy()); } } } // We don't support multi-process programs for now. if (!HookFork) assert(M.getFunction("fork") == NULL); }
bool MergeFunctions::runOnModule(Module &M) { bool Changed = false; DataLayoutPass *DLP = getAnalysisIfAvailable<DataLayoutPass>(); DL = DLP ? &DLP->getDataLayout() : nullptr; for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) { if (!I->isDeclaration() && !I->hasAvailableExternallyLinkage()) Deferred.push_back(WeakVH(I)); } FnSet.resize(Deferred.size()); do { std::vector<WeakVH> Worklist; Deferred.swap(Worklist); DEBUG(dbgs() << "size of module: " << M.size() << '\n'); DEBUG(dbgs() << "size of worklist: " << Worklist.size() << '\n'); // Insert only strong functions and merge them. Strong function merging // always deletes one of them. for (std::vector<WeakVH>::iterator I = Worklist.begin(), E = Worklist.end(); I != E; ++I) { if (!*I) continue; Function *F = cast<Function>(*I); if (!F->isDeclaration() && !F->hasAvailableExternallyLinkage() && !F->mayBeOverridden()) { ComparableFunction CF = ComparableFunction(F, DL); Changed |= insert(CF); } } // Insert only weak functions and merge them. By doing these second we // create thunks to the strong function when possible. When two weak // functions are identical, we create a new strong function with two weak // weak thunks to it which are identical but not mergable. for (std::vector<WeakVH>::iterator I = Worklist.begin(), E = Worklist.end(); I != E; ++I) { if (!*I) continue; Function *F = cast<Function>(*I); if (!F->isDeclaration() && !F->hasAvailableExternallyLinkage() && F->mayBeOverridden()) { ComparableFunction CF = ComparableFunction(F, DL); Changed |= insert(CF); } } DEBUG(dbgs() << "size of FnSet: " << FnSet.size() << '\n'); } while (!Deferred.empty()); FnSet.clear(); return Changed; }
bool MeasureMetric::runOnModule(Module &M) { doInitialization(M); for(Module::iterator f = M.begin(), fe = M.end(); f != fe; f++) { if (!f->isDeclaration()) { runOnFunction(*f); } } doFinalization(); return false; }
std::vector<Function*> functions(Module &M) { std::vector<Function*> functions; for (Module::iterator F = M.begin(); F != M.end(); ++F) { if (!F->isDeclaration()) { F->addFnAttr("kernel"); } functions.push_back(F); } return functions; }
bool MergeFunctions::runOnModule(Module &M) { typedef DenseSet<ComparableFunction *, MergeFunctionsEqualityInfo> FnSetType; bool Changed = false; TD = getAnalysisIfAvailable<TargetData>(); std::vector<Function *> Funcs; for (Module::iterator F = M.begin(), E = M.end(); F != E; ++F) { if (!F->isDeclaration() && !F->hasAvailableExternallyLinkage()) Funcs.push_back(F); } bool LocalChanged; do { LocalChanged = false; FnSetType FnSet; for (unsigned i = 0, e = Funcs.size(); i != e;) { Function *F = Funcs[i]; ComparableFunction *NewF = new ComparableFunction(F, TD); std::pair<FnSetType::iterator, bool> Result = FnSet.insert(NewF); if (!Result.second) { ComparableFunction *&OldF = *Result.first; assert(OldF && "Expected a hash collision"); // NewF will be deleted in favour of OldF unless NewF is strong and // OldF is weak in which case swap them to keep the strong definition. if (OldF->Func->isWeakForLinker() && !NewF->Func->isWeakForLinker()) std::swap(OldF, NewF); DEBUG(dbgs() << " " << OldF->Func->getName() << " == " << NewF->Func->getName() << '\n'); Funcs.erase(Funcs.begin() + i); --e; Function *DeleteF = NewF->Func; delete NewF; MergeTwoFunctions(OldF->Func, DeleteF); LocalChanged = true; Changed = true; } else { ++i; } } DeleteContainerPointers(FnSet); } while (LocalChanged); return Changed; }
void ClassHierarchyUtils::cacheAllCalleesForVirtualCalls(Module& M) { if (!cachingDone) { for (Module::iterator F = M.begin(), E = M.end(); F != E; ++F) { if (F->isDeclaration()) continue; for (inst_iterator I = inst_begin(F), E = inst_end(F); I != E; ++I) { if (CallInst* C = dyn_cast<CallInst>(&*I)) { GlobalVariable* definingTypeVTableVar = NULL; GlobalVariable* staticTypeVTableVar = NULL; bool hasMetadata = false; if (MDNode* N = I->getMetadata("soaap_defining_vtable_var")) { definingTypeVTableVar = cast<GlobalVariable>(N->getOperand(0)); hasMetadata = true; } else if (MDNode* N = I->getMetadata("soaap_defining_vtable_name")) { ConstantDataArray* definingTypeVTableConstant = cast<ConstantDataArray>(N->getOperand(0)); string definingTypeVTableConstantStr = definingTypeVTableConstant->getAsString().str(); //dbgs() << "definingTypeVTableConstantStr: " << definingTypeVTableConstantStr << "\n"; definingTypeVTableVar = M.getGlobalVariable(definingTypeVTableConstantStr, true); hasMetadata = true; } if (MDNode* N = I->getMetadata("soaap_static_vtable_var")) { staticTypeVTableVar = cast<GlobalVariable>(N->getOperand(0)); hasMetadata = true; } else if (MDNode* N = I->getMetadata("soaap_static_vtable_name")) { ConstantDataArray* staticTypeVTableConstant = cast<ConstantDataArray>(N->getOperand(0)); string staticTypeVTableConstantStr = staticTypeVTableConstant->getAsString().str(); //dbgs() << "staticTypeVTableConstantStr: " << staticTypeVTableConstantStr << "\n"; staticTypeVTableVar = M.getGlobalVariable(staticTypeVTableConstantStr, true); hasMetadata = true; } if (definingTypeVTableVar != NULL) { SDEBUG("soaap.util.classhierarchy", 3, dbgs() << "Found definingVTableVar: " << *definingTypeVTableVar << "\n"); if (staticTypeVTableVar == NULL) { dbgs() << "definingVTableVar is not null, but staticTypeVTableVar is NULL\n"; // This could be the case if no instance of the static type is ever created staticTypeVTableVar = definingTypeVTableVar; } callToCalleesCache[C] = findAllCalleesForVirtualCall(C, definingTypeVTableVar, staticTypeVTableVar, M); } else if (hasMetadata) { dbgs() << "Defining VTable is NULL!\n"; I->dump(); } } } } cachingDone = true; } }
// // This pass only makes sense when the underlying chip has floating point but // we are compiling as mips16. // For all mips16 functions (that are not stubs we have already generated), or // declared via attributes as nomips16, we must: // 1) fixup all returns of float, double, single and double complex // by calling a helper function before the actual return. // 2) generate helper functions (stubs) that can be called by mips32 functions // that will move parameters passed normally passed in floating point // registers the soft float equivalents. // 3) in the case of static relocation, generate helper functions so that // mips16 functions can call extern functions of unknown type (mips16 or // mips32). // 4) TBD. For pic, calls to extern functions of unknown type are handled by // predefined helper functions in libc but this work is currently done // during call lowering but it should be moved here in the future. // bool Mips16HardFloat::runOnModule(Module &M) { DEBUG(errs() << "Run on Module Mips16HardFloat\n"); bool Modified = false; for (Module::iterator F = M.begin(), E = M.end(); F != E; ++F) { if (F->isDeclaration() || F->hasFnAttribute("mips16_fp_stub") || F->hasFnAttribute("nomips16")) continue; Modified |= fixupFPReturnAndCall(*F, &M, Subtarget); FPParamVariant V = whichFPParamVariantNeeded(*F); if (V != NoSig) { Modified = true; createFPFnStub(F, &M, V, Subtarget); } } return Modified; }
/// GetAllUndefinedSymbols - calculates the set of undefined symbols that still /// exist in an LLVM module. This is a bit tricky because there may be two /// symbols with the same name but different LLVM types that will be resolved to /// each other but aren't currently (thus we need to treat it as resolved). /// /// Inputs: /// M - The module in which to find undefined symbols. /// /// Outputs: /// UndefinedSymbols - A set of C++ strings containing the name of all /// undefined symbols. /// static void GetAllUndefinedSymbols(Module *M, std::set<std::string> &UndefinedSymbols) { std::set<std::string> DefinedSymbols; UndefinedSymbols.clear(); // If the program doesn't define a main, try pulling one in from a .a file. // This is needed for programs where the main function is defined in an // archive, such f2c'd programs. Function *Main = M->getFunction("main"); if (Main == 0 || Main->isDeclaration()) UndefinedSymbols.insert("main"); for (Module::iterator I = M->begin(), E = M->end(); I != E; ++I) if (I->hasName()) { if (I->isDeclaration()) UndefinedSymbols.insert(I->getName()); else if (!I->hasLocalLinkage()) { assert(!I->hasDLLImportLinkage() && "Found dllimported non-external symbol!"); DefinedSymbols.insert(I->getName()); } } for (Module::global_iterator I = M->global_begin(), E = M->global_end(); I != E; ++I) if (I->hasName()) { if (I->isDeclaration()) UndefinedSymbols.insert(I->getName()); else if (!I->hasLocalLinkage()) { assert(!I->hasDLLImportLinkage() && "Found dllimported non-external symbol!"); DefinedSymbols.insert(I->getName()); } } for (Module::alias_iterator I = M->alias_begin(), E = M->alias_end(); I != E; ++I) if (I->hasName()) DefinedSymbols.insert(I->getName()); // Prune out any defined symbols from the undefined symbols set... for (std::set<std::string>::iterator I = UndefinedSymbols.begin(); I != UndefinedSymbols.end(); ) if (DefinedSymbols.count(*I)) UndefinedSymbols.erase(I++); // This symbol really is defined! else ++I; // Keep this symbol in the undefined symbols list }
bool ProgramAnalysis :: runOnModule(Module &M) { PI = &getAnalysis<ProfileInfo>(); //Code to set the Hot trace pointer for the Function ; MergeBlocks ; Function HOTTRACEBLOCKCOUNT = -1; MERGEBLOCKCOUNT = -1; for (Module::iterator i = M.begin(), e = M.end(); i!=e; ++i ) { if(i->isDeclaration()) continue; AnalyseFunction(*i); FUNCTIONCOUNT++; HOTTRACEBLOCKCOUNT += HotTraceCounter; HotTraceLink.push_back(HOTTRACEBLOCKCOUNT); MERGEBLOCKCOUNT += MergeCounter; MergeBlockLink.push_back(MERGEBLOCKCOUNT); } // Save things to a File ; Things to be saved: vectors: MergeBlocks && HotTrace // Vectors: BasicBlock Link; MergeBlock Link //Two files created: arrays stores HotTrace and MergeBlocks, seperated by Commas // Each is separated by \n // HotTrace and MergeBlocks are Seperated by -- FILE *fhottrace,*fmerge,*fhotlink,*fmergelink; if((fhottrace=fopen("hottrace", "w"))==NULL) printf("Cannot open file hottrace for reading.\n"); if((fmerge=fopen("merge", "w"))==NULL) printf("Cannot open file merge for reading.\n"); if((fhotlink=fopen("hotlinks", "w"))==NULL) printf("Cannot open file hotlink for reading.\n"); if((fmergelink=fopen("mergelinks", "w"))==NULL) printf("Cannot open file mergelink for reading.\n"); for(int i=0; i<(int)HotTrace.size();i++) fprintf(fhottrace, "%s\n", (HotTrace.at(i)->getName())); for(int i=0; i<(int)MergeBlocks.size();i++) fprintf(fmerge, "%s\n", (MergeBlocks.at(i)->getName())); for(int i=0; i<(int)HotTraceLink.size();i++) fprintf(fhotlink, "%d\n", HotTraceLink.at(i)); for(int i=0; i<(int)MergeBlockLink.size();i++) fprintf(fmergelink, "%d\n", MergeBlockLink.at(i)); printAnalysis(); //Code to set the Hot trace pointer for the Function ; MergeBlocks ; Function End Pointers return false; }
/* Change linkages of global values, in order to * improve alias analysis. */ bool DeadStoreEliminationPass::changeLinkageTypes(Module &M) { DEBUG(errs() << "Changing linkages to private...\n"); for (Module::global_iterator git = M.global_begin(), gitE = M.global_end(); git != gitE; ++git) { DEBUG(errs() << " " << *git << "\n"); if (!git->hasExternalLinkage() && !git->hasAppendingLinkage()) git->setLinkage(GlobalValue::PrivateLinkage); } for (Module::iterator F = M.begin(), E = M.end(); F != E; ++F) { if (!F->isDeclaration()) { if (!F->hasExternalLinkage() && !F->hasAppendingLinkage()) F->setLinkage(GlobalValue::PrivateLinkage); DEBUG(errs() << " " << F->getName() << "\n"); } } DEBUG(errs() << "\n"); return true; }
bool ProfileInfoConverter::runOnModule(Module &M) { ProfileInfo& PI = getAnalysis<ProfileInfo>(); std::vector<unsigned> Counters; for (Module::iterator F = M.begin(), E = M.end(); F != E; ++F) { if (F->isDeclaration()) continue; for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB){ Counters.push_back(PI.getExecutionCount(BB)); } } Writer.write(BlockInfo, Counters); return false; }
void AndroidBitcodeLinker::GetAllSymbols(Module *M, std::set<std::string> &UndefinedSymbols, std::set<std::string> &DefinedSymbols) { UndefinedSymbols.clear(); DefinedSymbols.clear(); Function *Main = M->getFunction("main"); if (Main == 0 || Main->isDeclaration()) UndefinedSymbols.insert("main"); for (Module::iterator I = M->begin(), E = M->end(); I != E; ++I) if (I->hasName()) { if (I->isDeclaration()) UndefinedSymbols.insert(I->getName()); else if (!I->hasLocalLinkage()) { assert(!I->hasDLLImportStorageClass() && "Found dllimported non-external symbol!"); DefinedSymbols.insert(I->getName()); } } for (Module::global_iterator I = M->global_begin(), E = M->global_end(); I != E; ++I) if (I->hasName()) { if (I->isDeclaration()) UndefinedSymbols.insert(I->getName()); else if (!I->hasLocalLinkage()) { assert(!I->hasDLLImportStorageClass() && "Found dllimported non-external symbol!"); DefinedSymbols.insert(I->getName()); } } for (Module::alias_iterator I = M->alias_begin(), E = M->alias_end(); I != E; ++I) if (I->hasName()) DefinedSymbols.insert(I->getName()); for (std::set<std::string>::iterator I = UndefinedSymbols.begin(); I != UndefinedSymbols.end(); ) if (DefinedSymbols.count(*I)) UndefinedSymbols.erase(I++); else ++I; }
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 StripExternals::runOnModule(Module &M) { bool Changed = false; for (Module::iterator I = M.begin(); I != M.end(); ) { if (I->hasAvailableExternallyLinkage()) { assert(!I->isDeclaration()&&"Declarations can't be available_externally"); Changed = true; ++NumFunctions; if (I->use_empty()) { DEBUG(errs() << "Deleting function: " << *I); Module::iterator todelete = I; ++I; todelete->eraseFromParent(); continue; } else { I->deleteBody(); DEBUG(errs() << "Deleted function body: " << *I); } } ++I; } for (Module::global_iterator I = M.global_begin(); I != M.global_end(); ) { if (I->hasAvailableExternallyLinkage()) { assert(!I->isDeclaration()&&"Declarations can't be available_externally"); Changed = true; ++NumVariables; if (I->use_empty()) { DEBUG(errs() << "Deleting global: " << *I); Module::global_iterator todelete = I; ++I; todelete->eraseFromParent(); continue; } else { I->setInitializer(0); I->setLinkage(GlobalValue::ExternalLinkage); DEBUG(errs() << "Deleted initializer: " << *I); } } ++I; } 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; }