Module *MCJIT::findModuleForSymbol(const std::string &Name, bool CheckFunctionsOnly) { StringRef DemangledName = Name; if (DemangledName[0] == getDataLayout().getGlobalPrefix()) DemangledName = DemangledName.substr(1); MutexGuard locked(lock); // If it hasn't already been generated, see if it's in one of our modules. for (ModulePtrSet::iterator I = OwnedModules.begin_added(), E = OwnedModules.end_added(); I != E; ++I) { Module *M = *I; Function *F = M->getFunction(DemangledName); if (F && !F->isDeclaration()) return M; if (!CheckFunctionsOnly) { GlobalVariable *G = M->getGlobalVariable(DemangledName); if (G && !G->isDeclaration()) return M; // FIXME: Do we need to worry about global aliases? } } // We didn't find the symbol in any of our modules. return nullptr; }
bool StripDeadPrototypesPass::runOnModule(Module &M) { bool MadeChange = false; // Erase dead function prototypes. for (Module::iterator I = M.begin(), E = M.end(); I != E; ) { Function *F = I++; // Function must be a prototype and unused. if (F->isDeclaration() && F->use_empty()) { F->eraseFromParent(); ++NumDeadPrototypes; MadeChange = true; } } // Erase dead global var prototypes. for (Module::global_iterator I = M.global_begin(), E = M.global_end(); I != E; ) { GlobalVariable *GV = I++; // Global must be a prototype and unused. if (GV->isDeclaration() && GV->use_empty()) GV->eraseFromParent(); } // Return an indication of whether we changed anything or not. return MadeChange; }
/// runStaticConstructorsDestructors - This method is used to execute all of /// the static constructors or destructors for a module, depending on the /// value of isDtors. void ExecutionEngine::runStaticConstructorsDestructors(Module *module, bool isDtors) { const char *Name = isDtors ? "llvm.global_dtors" : "llvm.global_ctors"; // Execute global ctors/dtors for each module in the program. GlobalVariable *GV = module->getNamedGlobal(Name); // If this global has internal linkage, or if it has a use, then it must be // an old-style (llvmgcc3) static ctor with __main linked in and in use. If // this is the case, don't execute any of the global ctors, __main will do // it. if (!GV || GV->isDeclaration() || GV->hasLocalLinkage()) return; // Should be an array of '{ int, void ()* }' structs. The first value is // the init priority, which we ignore. ConstantArray *InitList = dyn_cast<ConstantArray>(GV->getInitializer()); if (!InitList) return; for (unsigned i = 0, e = InitList->getNumOperands(); i != e; ++i) if (ConstantStruct *CS = dyn_cast<ConstantStruct>(InitList->getOperand(i))) { if (CS->getNumOperands() != 2) return; // Not array of 2-element structs. Constant *FP = CS->getOperand(1); if (FP->isNullValue()) break; // Found a null terminator, exit. if (ConstantExpr *CE = dyn_cast<ConstantExpr>(FP)) if (CE->isCast()) FP = CE->getOperand(0); if (Function *F = dyn_cast<Function>(FP)) { // Execute the ctor/dtor function! runFunction(F, std::vector<GenericValue>()); } } }
GlobalVariable *ExecutionEngine::FindGlobalVariableNamed(const char *Name, bool AllowInternal) { for (unsigned i = 0, e = Modules.size(); i != e; ++i) { GlobalVariable *GV = Modules[i]->getGlobalVariable(Name,AllowInternal); if (GV && !GV->isDeclaration()) return GV; } return nullptr; }
/// SplitStaticCtorDtor - A module was recently split into two parts, M1/M2, and /// M1 has all of the global variables. If M2 contains any functions that are /// static ctors/dtors, we need to add an llvm.global_[cd]tors global to M2, and /// prune appropriate entries out of M1s list. static void SplitStaticCtorDtor(const char *GlobalName, Module *M1, Module *M2, DenseMap<const Value*, Value*> ValueMap) { GlobalVariable *GV = M1->getNamedGlobal(GlobalName); if (!GV || GV->isDeclaration() || GV->hasLocalLinkage() || !GV->use_empty()) return; std::vector<std::pair<Function*, int> > M1Tors, M2Tors; ConstantArray *InitList = dyn_cast<ConstantArray>(GV->getInitializer()); if (!InitList) return; for (unsigned i = 0, e = InitList->getNumOperands(); i != e; ++i) { if (ConstantStruct *CS = dyn_cast<ConstantStruct>(InitList->getOperand(i))){ if (CS->getNumOperands() != 2) return; // Not array of 2-element structs. if (CS->getOperand(1)->isNullValue()) break; // Found a null terminator, stop here. ConstantInt *CI = dyn_cast<ConstantInt>(CS->getOperand(0)); int Priority = CI ? CI->getSExtValue() : 0; Constant *FP = CS->getOperand(1); if (ConstantExpr *CE = dyn_cast<ConstantExpr>(FP)) if (CE->isCast()) FP = CE->getOperand(0); if (Function *F = dyn_cast<Function>(FP)) { if (!F->isDeclaration()) M1Tors.push_back(std::make_pair(F, Priority)); else { // Map to M2's version of the function. F = cast<Function>(ValueMap[F]); M2Tors.push_back(std::make_pair(F, Priority)); } } } } GV->eraseFromParent(); if (!M1Tors.empty()) { Constant *M1Init = GetTorInit(M1Tors); new GlobalVariable(*M1, M1Init->getType(), false, GlobalValue::AppendingLinkage, M1Init, GlobalName); } GV = M2->getNamedGlobal(GlobalName); assert(GV && "Not a clone of M1?"); assert(GV->use_empty() && "llvm.ctors shouldn't have uses!"); GV->eraseFromParent(); if (!M2Tors.empty()) { Constant *M2Init = GetTorInit(M2Tors); new GlobalVariable(*M2, M2Init->getType(), false, GlobalValue::AppendingLinkage, M2Init, GlobalName); } }
GlobalVariable *MCJIT::FindGlobalVariableNamedInModulePtrSet(const char *Name, bool AllowInternal, ModulePtrSet::iterator I, ModulePtrSet::iterator E) { for (; I != E; ++I) { GlobalVariable *GV = (*I)->getGlobalVariable(Name, AllowInternal); if (GV && !GV->isDeclaration()) return GV; } return nullptr; }
// add external declarations and the necessary code to resolve them void add_decls(FILE *outfile) { for (Module::global_iterator i = ops->global_begin(), e = ops->global_end(); i != e; ++i) { GlobalVariable *g = (GlobalVariable *) i; if (g->isDeclaration() || true) { fprintf(outfile, "extern char %s;\n", g->getName().c_str()); } } for (Module::iterator i = ops->begin(), e = ops->end(); i != e; ++i) { Function *f = (Function *) i; if (f->isDeclaration()) { fprintf(outfile, "extern char %s;\n", f->getName().c_str()); } } }
bool RegisterGlobals::runOnModule(Module &M) { TD = &getAnalysis<TargetData>(); VoidTy = Type::getVoidTy(M.getContext()); VoidPtrTy = Type::getInt8PtrTy(M.getContext()); SizeTy = IntegerType::getInt64Ty(M.getContext()); // Create the function prototype M.getOrInsertFunction("__pool_register_global", VoidTy, VoidPtrTy, SizeTy, NULL); RegisterGlobalPoolFunction = M.getFunction("__pool_register_global"); // Create the function that will contain the registration calls createRegistrationFunction(M); Module::global_iterator GI = M.global_begin(), GE = M.global_end(); for ( ; GI != GE; ++GI) { GlobalVariable *GV = GI; // Skip globals without a size if (!GV->getType()->getElementType()->isSized()) continue; // Optionally avoid registering globals with uncertain size. if (!RegUncertain) { // Linking can change the size of declarations if (GV->isDeclaration()) continue; // Linking can't change the size of defined globals with eternal linkage. // Linking can't change the size of globals with local linkage. if (!GV->hasExternalLinkage() && !GV->hasLocalLinkage()) continue; } // Thread-local globals would have to be registered for each thread. // FIXME: add support for thread-local globals if (GV->isThreadLocal()) continue; registerGlobal(GV); } return true; }
void add_resolv(FILE *outfile) { for (Module::global_iterator i = ops->global_begin(), e = ops->global_end(); i != e; ++i) { GlobalVariable *g = (GlobalVariable *) i; if (g->isDeclaration() || true) { fprintf(outfile, "EE->addGlobalMapping(M->getNamedGlobal(\"%s\"), &%s);\n", g->getName().c_str(), g->getName().c_str()); } } for (Module::iterator i = ops->begin(), e = ops->end(); i != e; ++i) { Function *f = (Function *) i; if (f->isDeclaration()) { fprintf(outfile, "EE->addGlobalMapping(M->getFunction(\"%s\"), &%s);\n", f->getName().c_str(), f->getName().c_str()); } } }
Module *MCJIT::findModuleForSymbol(const std::string &Name, bool CheckFunctionsOnly) { MutexGuard locked(lock); // If it hasn't already been generated, see if it's in one of our modules. for (ModulePtrSet::iterator I = OwnedModules.begin_added(), E = OwnedModules.end_added(); I != E; ++I) { Module *M = *I; Function *F = M->getFunction(Name); if (F && !F->isDeclaration()) return M; if (!CheckFunctionsOnly) { GlobalVariable *G = M->getGlobalVariable(Name); if (G && !G->isDeclaration()) return M; // FIXME: Do we need to worry about global aliases? } } // We didn't find the symbol in any of our modules. return NULL; }
void MemoryInstrumenter::lowerGlobalCtors(Module &M) { // Find llvm.global_ctors. GlobalVariable *GV = M.getNamedGlobal("llvm.global_ctors"); if (!GV) return; assert(!GV->isDeclaration() && !GV->hasLocalLinkage()); // Should be an array of '{ int, void ()* }' structs. The first value is // the init priority, which must be 65535 if the bitcode is generated using // clang. if (ConstantArray *InitList = dyn_cast<ConstantArray>(GV->getInitializer())) { for (unsigned i = 0, e = InitList->getNumOperands(); i != e; ++i) { ConstantStruct *CS = dyn_cast<ConstantStruct>(InitList->getOperand(i)); assert(CS); assert(CS->getNumOperands() == 2); // Get the priority. ConstantInt *Priority = dyn_cast<ConstantInt>(CS->getOperand(0)); assert(Priority); // TODO: For now, we assume all priorities must be 65535. assert(Priority->equalsInt(65535)); // Get the constructor function. Constant *FP = CS->getOperand(1); if (FP->isNullValue()) break; // Found a null terminator, exit. // Explicitly call the constructor at the main entry. CallInst::Create(FP, "", Main->begin()->getFirstNonPHI()); } } // Clear the global_ctors array. // Use eraseFromParent() instead of removeFromParent(). GV->eraseFromParent(); }
// destructively move the contents of src into dest // this assumes that the targets of the two modules are the same // including the DataLayout and ModuleFlags (for example) // and that there is no module-level assembly static void jl_merge_module(Module *dest, std::unique_ptr<Module> src) { assert(dest != src.get()); for (Module::global_iterator I = src->global_begin(), E = src->global_end(); I != E;) { GlobalVariable *sG = &*I; GlobalValue *dG = dest->getNamedValue(sG->getName()); ++I; // Replace a declaration with the definition: if (dG) { if (sG->isDeclaration()) { sG->replaceAllUsesWith(dG); sG->eraseFromParent(); continue; } else { dG->replaceAllUsesWith(sG); dG->eraseFromParent(); } } // Reparent the global variable: sG->removeFromParent(); dest->getGlobalList().push_back(sG); // Comdat is owned by the Module, recreate it in the new parent: addComdat(sG); } for (Module::iterator I = src->begin(), E = src->end(); I != E;) { Function *sG = &*I; GlobalValue *dG = dest->getNamedValue(sG->getName()); ++I; // Replace a declaration with the definition: if (dG) { if (sG->isDeclaration()) { sG->replaceAllUsesWith(dG); sG->eraseFromParent(); continue; } else { dG->replaceAllUsesWith(sG); dG->eraseFromParent(); } } // Reparent the global variable: sG->removeFromParent(); dest->getFunctionList().push_back(sG); // Comdat is owned by the Module, recreate it in the new parent: addComdat(sG); } for (Module::alias_iterator I = src->alias_begin(), E = src->alias_end(); I != E;) { GlobalAlias *sG = &*I; GlobalValue *dG = dest->getNamedValue(sG->getName()); ++I; if (dG) { if (!dG->isDeclaration()) { // aliases are always definitions, so this test is reversed from the above two sG->replaceAllUsesWith(dG); sG->eraseFromParent(); continue; } else { dG->replaceAllUsesWith(sG); dG->eraseFromParent(); } } sG->removeFromParent(); dest->getAliasList().push_back(sG); } // metadata nodes need to be explicitly merged not just copied // so there are special passes here for each known type of metadata NamedMDNode *sNMD = src->getNamedMetadata("llvm.dbg.cu"); if (sNMD) { NamedMDNode *dNMD = dest->getOrInsertNamedMetadata("llvm.dbg.cu"); #ifdef LLVM35 for (NamedMDNode::op_iterator I = sNMD->op_begin(), E = sNMD->op_end(); I != E; ++I) { dNMD->addOperand(*I); } #else for (unsigned i = 0, l = sNMD->getNumOperands(); i < l; i++) { dNMD->addOperand(sNMD->getOperand(i)); } #endif } }
// // Method: postOrderInline() // // Description: // This methods does a post order traversal of the call graph and performs // bottom-up inlining of the DSGraphs. // void BUDataStructures::postOrderInline (Module & M) { // Variables used for Tarjan SCC-finding algorithm. These are passed into // the recursive function used to find SCCs. std::vector<const Function*> Stack; std::map<const Function*, unsigned> ValMap; unsigned NextID = 1; // Do post order traversal on the global ctors. Use this information to update // the globals graph. const char *Name = "llvm.global_ctors"; GlobalVariable *GV = M.getNamedGlobal(Name); if (GV && !(GV->isDeclaration()) && !(GV->hasLocalLinkage())) { // Should be an array of '{ int, void ()* }' structs. The first value is // the init priority, which we ignore. ConstantArray *InitList = dyn_cast<ConstantArray>(GV->getInitializer()); if (InitList) { for (unsigned i = 0, e = InitList->getNumOperands(); i != e; ++i) if (ConstantStruct *CS = dyn_cast<ConstantStruct>(InitList->getOperand(i))) { if (CS->getNumOperands() != 2) break; // Not array of 2-element structs. Constant *FP = CS->getOperand(1); if (FP->isNullValue()) break; // Found a null terminator, exit. if (ConstantExpr *CE = dyn_cast<ConstantExpr>(FP)) if (CE->isCast()) FP = CE->getOperand(0); Function *F = dyn_cast<Function>(FP); if (F && !F->isDeclaration() && !ValMap.count(F)) { calculateGraphs(F, Stack, NextID, ValMap); CloneAuxIntoGlobal(getDSGraph(*F)); } } GlobalsGraph->removeTriviallyDeadNodes(); GlobalsGraph->maskIncompleteMarkers(); // Mark external globals incomplete. GlobalsGraph->markIncompleteNodes(DSGraph::IgnoreGlobals); GlobalsGraph->computeExternalFlags(DSGraph::DontMarkFormalsExternal); GlobalsGraph->computeIntPtrFlags(); // // Create equivalence classes for aliasing globals so that we only need to // record one global per DSNode. // formGlobalECs(); // propogte information calculated // from the globals graph to the other graphs. for (Module::iterator F = M.begin(); F != M.end(); ++F) { if (!(F->isDeclaration())){ DSGraph *Graph = getDSGraph(*F); cloneGlobalsInto(Graph, DSGraph::DontCloneCallNodes | DSGraph::DontCloneAuxCallNodes); Graph->buildCallGraph(callgraph, GlobalFunctionList, filterCallees); Graph->maskIncompleteMarkers(); Graph->markIncompleteNodes(DSGraph::MarkFormalArgs | DSGraph::IgnoreGlobals); Graph->computeExternalFlags(DSGraph::DontMarkFormalsExternal); Graph->computeIntPtrFlags(); } } } } // // Start the post order traversal with the main() function. If there is no // main() function, don't worry; we'll have a separate traversal for inlining // graphs for functions not reachable from main(). // Function *MainFunc = M.getFunction ("main"); if (MainFunc && !MainFunc->isDeclaration()) { calculateGraphs(MainFunc, Stack, NextID, ValMap); CloneAuxIntoGlobal(getDSGraph(*MainFunc)); } // // Calculate the graphs for any functions that are unreachable from main... // for (Function &F : M) if (!F.isDeclaration() && !ValMap.count(&F)) { if (MainFunc) DEBUG(errs() << debugname << ": Function unreachable from main: " << F.getName() << "\n"); calculateGraphs(&F, Stack, NextID, ValMap); // Calculate all graphs. CloneAuxIntoGlobal(getDSGraph(F)); // Mark this graph as processed. Do this by finding all functions // in the graph that map to it, and mark them visited. // Note that this really should be handled neatly by calculateGraphs // itself, not here. However this catches the worst offenders. DSGraph *G = getDSGraph(F); for(DSGraph::retnodes_iterator RI = G->retnodes_begin(), RE = G->retnodes_end(); RI != RE; ++RI) { if (getDSGraph(*RI->first) == G) { if (!ValMap.count(RI->first)) ValMap[RI->first] = ~0U; else assert(ValMap[RI->first] == ~0U); } } } return; }