void LTOCodeGenerator::applyScopeRestrictions() { if ( !_scopeRestrictionsDone ) { Module* mergedModule = _linker.getModule(); // Start off with a verification pass. PassManager passes; passes.add(createVerifierPass()); // mark which symbols can not be internalized if ( !_mustPreserveSymbols.empty() ) { Mangler mangler(*mergedModule, _target->getTargetAsmInfo()->getGlobalPrefix()); std::vector<const char*> mustPreserveList; for (Module::iterator f = mergedModule->begin(), e = mergedModule->end(); f != e; ++f) { if ( !f->isDeclaration() && _mustPreserveSymbols.count(mangler.getMangledName(f)) ) mustPreserveList.push_back(::strdup(f->getNameStr().c_str())); } for (Module::global_iterator v = mergedModule->global_begin(), e = mergedModule->global_end(); v != e; ++v) { if ( !v->isDeclaration() && _mustPreserveSymbols.count(mangler.getMangledName(v)) ) mustPreserveList.push_back(::strdup(v->getNameStr().c_str())); } passes.add(createInternalizePass(mustPreserveList)); } // apply scope restrictions passes.run(*mergedModule); _scopeRestrictionsDone = true; } }
/** * Print the static class initialization method. */ void JVMWriter::printClInit() { //out << ".method public <clinit>()V\n"; out << ".method public initialiseEnvironment(Llljvm/runtime/Environment;)V\n"; printSimpleInstruction(".limit stack 5"); printSimpleInstruction(".limit locals 2"); out << "\n\t; load environment into class\n"; printSimpleInstruction("aload_0"); // this. printSimpleInstruction("aload_1"); // value printSimpleInstruction("putfield "+classname+"/__env Llljvm/runtime/Environment;"); out << "\n\t; allocate global variables\n"; for(Module::global_iterator i = module->global_begin(), e = module->global_end(); i != e; i++) { if(!i->isDeclaration()) { const GlobalVariable *g = i; const Constant *c = g->getInitializer(); printLoadMemoryToStack(); printConstLoad( APInt(32, targetData->getTypeAllocSize(c->getType()), false)); printSimpleInstruction("invokevirtual", "lljvm/runtime/Memory/allocateData(I)I"); printSimpleInstruction("aload_0"); // "this" printSimpleInstruction("swap"); // move this 1 down the stack printSimpleInstruction("putfield", classname + "/" + getValueName(g) + " I"); } } out << "\n\t; initialise global variables\n"; for(Module::global_iterator i = module->global_begin(), e = module->global_end(); i != e; i++) { if(!i->isDeclaration()) { const GlobalVariable *g = i; const Constant *c = g->getInitializer(); printSimpleInstruction("aload_0"); // "this" printSimpleInstruction("getfield", classname + "/" + getValueName(g) + " I"); printStaticConstant(c); printSimpleInstruction("pop"); out << '\n'; } } printSimpleInstruction("return"); out << ".end method\n\n"; }
/** * Print the static class initialization method. */ void JVMWriter::printClInit() { out << ".method public <clinit>()V\n"; printSimpleInstruction(".limit stack 4"); out << "\n\t; allocate global variables\n"; for(Module::global_iterator i = module->global_begin(), e = module->global_end(); i != e; i++) { if(!i->isDeclaration()) { const GlobalVariable *g = i; const Constant *c = g->getInitializer(); printConstLoad( APInt(32, targetData->getTypeAllocSize(c->getType()), false)); printSimpleInstruction("invokestatic", "lljvm/runtime/Memory/allocateData(I)I"); printSimpleInstruction("putstatic", classname + "/" + getValueName(g) + " I"); } } out << "\n\t; initialise global variables\n"; for(Module::global_iterator i = module->global_begin(), e = module->global_end(); i != e; i++) { if(!i->isDeclaration()) { const GlobalVariable *g = i; const Constant *c = g->getInitializer(); printSimpleInstruction("getstatic", classname + "/" + getValueName(g) + " I"); printStaticConstant(c); printSimpleInstruction("pop"); out << '\n'; } } printSimpleInstruction("return"); out << ".end method\n\n"; }
/// 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 }
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 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; }
/// OptimizeGlobals - This method uses information taken from DSA to optimize /// global variables. /// bool DSOpt::OptimizeGlobals(Module &M) { DSGraph* GG = TD->getGlobalsGraph(); const DSGraph::ScalarMapTy &SM = GG->getScalarMap(); bool Changed = false; for (Module::global_iterator I = M.global_begin(), E = M.global_end(); I != E; ++I) if (!I->isDeclaration()) { // Loop over all of the non-external globals... // Look up the node corresponding to this global, if it exists. DSNode *GNode = 0; DSGraph::ScalarMapTy::const_iterator SMI = SM.find(I); if (SMI != SM.end()) GNode = SMI->second.getNode(); if (GNode == 0 && I->hasInternalLinkage()) { // If there is no entry in the scalar map for this global, it was never // referenced in the program. If it has internal linkage, that means we // can delete it. We don't ACTUALLY want to delete the global, just // remove anything that references the global: later passes will take // care of nuking it. if (!I->use_empty()) { I->replaceAllUsesWith(ConstantPointerNull::get(I->getType())); ++NumGlobalsIsolated; } } else if (GNode && GNode->NodeType.isCompleteNode()) { // If the node has not been read or written, and it is not externally // visible, kill any references to it so it can be DCE'd. if (!GNode->NodeType.isModifiedNode() && !GNode->NodeType.isReadNode() &&I->hasInternalLinkage()){ if (!I->use_empty()) { I->replaceAllUsesWith(ConstantPointerNull::get(I->getType())); ++NumGlobalsIsolated; } } // We expect that there will almost always be a node for this global. // If there is, and the node doesn't have the M bit set, we can set the // 'constant' bit on the global. if (!GNode->NodeType.isModifiedNode() && !I->isConstant()) { I->setConstant(true); ++NumGlobalsConstanted; Changed = true; } } } return Changed; }
/** * Print the field declarations. */ void JVMWriter::printFields() { out << "; Fields\n"; for(Module::global_iterator i = module->global_begin(), e = module->global_end(); i != e; i++) { if(i->isDeclaration()) { out << ".extern field "; externRefs.insert(i); } else out << ".field " << (i->hasLocalLinkage() ? "private " : "public ") << "static final "; out << getValueName(i) << ' ' << getTypeDescriptor(i->getType()); if(debug >= 3) out << " ; " << *i; else out << '\n'; } out << '\n'; }
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()); } }
/// doInitialization - Perform Module level initializations here. /// One task that we do here is to sectionize all global variables. /// The MemSelOptimizer pass depends on the sectionizing. /// bool PIC16AsmPrinter::doInitialization(Module &M) { bool Result = AsmPrinter::doInitialization(M); // Every asmbly contains these std headers. O << "\n#include p16f1xxx.inc"; O << "\n#include stdmacros.inc"; // Set the section names for all globals. for (Module::global_iterator I = M.global_begin(), E = M.global_end(); I != E; ++I) { // Record External Var Decls. if (I->isDeclaration()) { ExternalVarDecls.push_back(I); continue; } // Record Exteranl Var Defs. if (I->hasExternalLinkage() || I->hasCommonLinkage()) { ExternalVarDefs.push_back(I); } // Sectionify actual data. if (!I->hasAvailableExternallyLinkage()) { const MCSection *S = getObjFileLowering().SectionForGlobal(I, Mang, TM); I->setSection(((const PIC16Section *)S)->getName()); } } DbgInfo.BeginModule(M); EmitFunctionDecls(M); EmitUndefinedVars(M); EmitDefinedVars(M); EmitIData(M); EmitUData(M); EmitRomData(M); EmitSharedUdata(M); EmitUserSections(M); return Result; }
void LTOModule::lazyParseSymbols() { if ( !_symbolsParsed ) { _symbolsParsed = true; // Use mangler to add GlobalPrefix to names to match linker names. Mangler mangler(*_module, _target->getTargetAsmInfo()->getGlobalPrefix()); // add functions for (Module::iterator f = _module->begin(); f != _module->end(); ++f) { if ( f->isDeclaration() ) addPotentialUndefinedSymbol(f, mangler); else addDefinedFunctionSymbol(f, mangler); } // add data for (Module::global_iterator v = _module->global_begin(), e = _module->global_end(); v != e; ++v) { if ( v->isDeclaration() ) addPotentialUndefinedSymbol(v, mangler); else addDefinedDataSymbol(v, mangler); } // make symbols for all undefines for (StringSet::iterator it=_undefines.begin(); it != _undefines.end(); ++it) { // if this symbol also has a definition, then don't make an undefine // because it is a tentative definition if ( _defines.count(it->getKeyData(), it->getKeyData()+ it->getKeyLength()) == 0 ) { NameAndAttributes info; info.name = it->getKeyData(); info.attributes = LTO_SYMBOL_DEFINITION_UNDEFINED; _symbols.push_back(info); } } } }
bool InternalizePass::runOnModule(Module &M) { CallGraph *CG = getAnalysisIfAvailable<CallGraph>(); CallGraphNode *ExternalNode = CG ? CG->getExternalCallingNode() : 0; bool Changed = false; // Never internalize functions which code-gen might insert. // FIXME: We should probably add this (and the __stack_chk_guard) via some // type of call-back in CodeGen. ExternalNames.insert("__stack_chk_fail"); // Mark all functions not in the api as internal. // FIXME: maybe use private linkage? for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) if (!I->isDeclaration() && // Function must be defined here // Available externally is really just a "declaration with a body". !I->hasAvailableExternallyLinkage() && !I->hasLocalLinkage() && // Can't already have internal linkage !ExternalNames.count(I->getName())) {// Not marked to keep external? I->setLinkage(GlobalValue::InternalLinkage); // Remove a callgraph edge from the external node to this function. if (ExternalNode) ExternalNode->removeOneAbstractEdgeTo((*CG)[I]); Changed = true; ++NumFunctions; DEBUG(dbgs() << "Internalizing func " << I->getName() << "\n"); } // Never internalize the llvm.used symbol. It is used to implement // attribute((used)). // FIXME: Shouldn't this just filter on llvm.metadata section?? ExternalNames.insert("llvm.used"); ExternalNames.insert("llvm.compiler.used"); // Never internalize anchors used by the machine module info, else the info // won't find them. (see MachineModuleInfo.) ExternalNames.insert("llvm.global_ctors"); ExternalNames.insert("llvm.global_dtors"); ExternalNames.insert("llvm.global.annotations"); // Never internalize symbols code-gen inserts. ExternalNames.insert("__stack_chk_guard"); // Mark all global variables with initializers that are not in the api as // internal as well. // FIXME: maybe use private linkage? for (Module::global_iterator I = M.global_begin(), E = M.global_end(); I != E; ++I) if (!I->isDeclaration() && !I->hasLocalLinkage() && // Available externally is really just a "declaration with a body". !I->hasAvailableExternallyLinkage() && !ExternalNames.count(I->getName())) { I->setLinkage(GlobalValue::InternalLinkage); Changed = true; ++NumGlobals; DEBUG(dbgs() << "Internalized gvar " << I->getName() << "\n"); } // Mark all aliases that are not in the api as internal as well. for (Module::alias_iterator I = M.alias_begin(), E = M.alias_end(); I != E; ++I) if (!I->isDeclaration() && !I->hasInternalLinkage() && // Available externally is really just a "declaration with a body". !I->hasAvailableExternallyLinkage() && !ExternalNames.count(I->getName())) { I->setLinkage(GlobalValue::InternalLinkage); Changed = true; ++NumAliases; DEBUG(dbgs() << "Internalized alias " << I->getName() << "\n"); } return Changed; }
bool GlobalDCE::runOnModule(Module &M) { bool Changed = false; // Loop over the module, adding globals which are obviously necessary. for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) { Changed |= RemoveUnusedGlobalValue(*I); // Functions with external linkage are needed if they have a body if (!I->isDiscardableIfUnused() && !I->isDeclaration() && !I->hasAvailableExternallyLinkage()) GlobalIsNeeded(I); } for (Module::global_iterator I = M.global_begin(), E = M.global_end(); I != E; ++I) { Changed |= RemoveUnusedGlobalValue(*I); // Externally visible & appending globals are needed, if they have an // initializer. if (!I->isDiscardableIfUnused() && !I->isDeclaration() && !I->hasAvailableExternallyLinkage()) GlobalIsNeeded(I); } for (Module::alias_iterator I = M.alias_begin(), E = M.alias_end(); I != E; ++I) { Changed |= RemoveUnusedGlobalValue(*I); // Externally visible aliases are needed. if (!I->isDiscardableIfUnused()) GlobalIsNeeded(I); } // Now that all globals which are needed are in the AliveGlobals set, we loop // through the program, deleting those which are not alive. // // The first pass is to drop initializers of global variables which are dead. std::vector<GlobalVariable*> DeadGlobalVars; // Keep track of dead globals for (Module::global_iterator I = M.global_begin(), E = M.global_end(); I != E; ++I) if (!AliveGlobals.count(I)) { DeadGlobalVars.push_back(I); // Keep track of dead globals I->setInitializer(0); } // The second pass drops the bodies of functions which are dead... std::vector<Function*> DeadFunctions; for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) if (!AliveGlobals.count(I)) { DeadFunctions.push_back(I); // Keep track of dead globals if (!I->isDeclaration()) I->deleteBody(); } // The third pass drops targets of aliases which are dead... std::vector<GlobalAlias*> DeadAliases; for (Module::alias_iterator I = M.alias_begin(), E = M.alias_end(); I != E; ++I) if (!AliveGlobals.count(I)) { DeadAliases.push_back(I); I->setAliasee(0); } if (!DeadFunctions.empty()) { // Now that all interferences have been dropped, delete the actual objects // themselves. for (unsigned i = 0, e = DeadFunctions.size(); i != e; ++i) { RemoveUnusedGlobalValue(*DeadFunctions[i]); M.getFunctionList().erase(DeadFunctions[i]); } NumFunctions += DeadFunctions.size(); Changed = true; } if (!DeadGlobalVars.empty()) { for (unsigned i = 0, e = DeadGlobalVars.size(); i != e; ++i) { RemoveUnusedGlobalValue(*DeadGlobalVars[i]); M.getGlobalList().erase(DeadGlobalVars[i]); } NumVariables += DeadGlobalVars.size(); Changed = true; } // Now delete any dead aliases. if (!DeadAliases.empty()) { for (unsigned i = 0, e = DeadAliases.size(); i != e; ++i) { RemoveUnusedGlobalValue(*DeadAliases[i]); M.getAliasList().erase(DeadAliases[i]); } NumAliases += DeadAliases.size(); Changed = true; } // Make sure that all memory is released AliveGlobals.clear(); return Changed; }
bool GlobalMerge::doInitialization(Module &M) { if (!EnableGlobalMerge) return false; auto &DL = M.getDataLayout(); DenseMap<unsigned, SmallVector<GlobalVariable*, 16> > Globals, ConstGlobals, BSSGlobals; bool Changed = false; setMustKeepGlobalVariables(M); // Grab all non-const globals. for (Module::global_iterator I = M.global_begin(), E = M.global_end(); I != E; ++I) { // Merge is safe for "normal" internal or external globals only if (I->isDeclaration() || I->isThreadLocal() || I->hasSection()) continue; if (!(EnableGlobalMergeOnExternal && I->hasExternalLinkage()) && !I->hasInternalLinkage()) continue; PointerType *PT = dyn_cast<PointerType>(I->getType()); assert(PT && "Global variable is not a pointer!"); unsigned AddressSpace = PT->getAddressSpace(); // Ignore fancy-aligned globals for now. unsigned Alignment = DL.getPreferredAlignment(I); Type *Ty = I->getType()->getElementType(); if (Alignment > DL.getABITypeAlignment(Ty)) continue; // Ignore all 'special' globals. if (I->getName().startswith("llvm.") || I->getName().startswith(".llvm.")) continue; // Ignore all "required" globals: if (isMustKeepGlobalVariable(I)) continue; if (DL.getTypeAllocSize(Ty) < MaxOffset) { if (TargetLoweringObjectFile::getKindForGlobal(I, *TM).isBSSLocal()) BSSGlobals[AddressSpace].push_back(I); else if (I->isConstant()) ConstGlobals[AddressSpace].push_back(I); else Globals[AddressSpace].push_back(I); } } for (DenseMap<unsigned, SmallVector<GlobalVariable*, 16> >::iterator I = Globals.begin(), E = Globals.end(); I != E; ++I) if (I->second.size() > 1) Changed |= doMerge(I->second, M, false, I->first); for (DenseMap<unsigned, SmallVector<GlobalVariable*, 16> >::iterator I = BSSGlobals.begin(), E = BSSGlobals.end(); I != E; ++I) if (I->second.size() > 1) Changed |= doMerge(I->second, M, false, I->first); if (EnableGlobalMergeOnConst) for (DenseMap<unsigned, SmallVector<GlobalVariable*, 16> >::iterator I = ConstGlobals.begin(), E = ConstGlobals.end(); I != E; ++I) if (I->second.size() > 1) Changed |= doMerge(I->second, M, true, I->first); return Changed; }
/// Based on GetAllUndefinedSymbols() from LLVM3.2 /// /// 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) { static const std::string llvmIntrinsicPrefix="llvm."; std::set<std::string> DefinedSymbols; UndefinedSymbols.clear(); KLEE_DEBUG_WITH_TYPE("klee_linker", dbgs() << "*** Computing undefined symbols ***\n"); 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()) { #if LLVM_VERSION_CODE < LLVM_VERSION(3, 5) assert(!I->hasDLLImportLinkage() && "Found dllimported non-external symbol!"); #else assert(!I->hasDLLImportStorageClass() && "Found dllimported non-external symbol!"); #endif 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()) { #if LLVM_VERSION_CODE < LLVM_VERSION(3, 5) assert(!I->hasDLLImportLinkage() && "Found dllimported non-external symbol!"); #else assert(!I->hasDLLImportStorageClass() && "Found dllimported non-external symbol!"); #endif 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 // and other symbols we don't want to treat as an undefined symbol std::vector<std::string> SymbolsToRemove; for (std::set<std::string>::iterator I = UndefinedSymbols.begin(); I != UndefinedSymbols.end(); ++I ) { if (DefinedSymbols.count(*I)) { SymbolsToRemove.push_back(*I); continue; } // Strip out llvm intrinsics if ( (I->size() >= llvmIntrinsicPrefix.size() ) && (I->compare(0, llvmIntrinsicPrefix.size(), llvmIntrinsicPrefix) == 0) ) { KLEE_DEBUG_WITH_TYPE("klee_linker", dbgs() << "LLVM intrinsic " << *I << " has will be removed from undefined symbols"<< "\n"); SymbolsToRemove.push_back(*I); continue; } // Symbol really is undefined KLEE_DEBUG_WITH_TYPE("klee_linker", dbgs() << "Symbol " << *I << " is undefined.\n"); } // Remove KLEE intrinsics from set of undefined symbols for (SpecialFunctionHandler::const_iterator sf = SpecialFunctionHandler::begin(), se = SpecialFunctionHandler::end(); sf != se; ++sf) { if (UndefinedSymbols.find(sf->name) == UndefinedSymbols.end()) continue; SymbolsToRemove.push_back(sf->name); KLEE_DEBUG_WITH_TYPE("klee_linker", dbgs() << "KLEE intrinsic " << sf->name << " has will be removed from undefined symbols"<< "\n"); } // Now remove the symbols from undefined set. for (size_t i = 0, j = SymbolsToRemove.size(); i < j; ++i ) UndefinedSymbols.erase(SymbolsToRemove[i]); KLEE_DEBUG_WITH_TYPE("klee_linker", dbgs() << "*** Finished computing undefined symbols ***\n"); }
int main(int argc, char **argv) { LLVMContext &Context = getGlobalContext(); llvm_shutdown_obj Y; // Call llvm_shutdown() on exit. cl::ParseCommandLineOptions(argc, argv, "libclc builtin preparation tool\n"); std::string ErrorMessage; std::auto_ptr<Module> M; { OwningPtr<MemoryBuffer> BufferPtr; if (error_code ec = MemoryBuffer::getFileOrSTDIN(InputFilename, BufferPtr)) ErrorMessage = ec.message(); else M.reset(ParseBitcodeFile(BufferPtr.get(), Context, &ErrorMessage)); } if (M.get() == 0) { errs() << argv[0] << ": "; if (ErrorMessage.size()) errs() << ErrorMessage << "\n"; else errs() << "bitcode didn't read correctly.\n"; return 1; } // Set linkage of every external definition to linkonce_odr. for (Module::iterator i = M->begin(), e = M->end(); i != e; ++i) { if (!i->isDeclaration() && i->getLinkage() == GlobalValue::ExternalLinkage) { i->setLinkage(GlobalValue::LinkOnceODRLinkage); //i->addFnAttr(Attributes::AlwaysInline); } } for (Module::global_iterator i = M->global_begin(), e = M->global_end(); i != e; ++i) { if (!i->isDeclaration() && i->getLinkage() == GlobalValue::ExternalLinkage) { i->setLinkage(GlobalValue::LinkOnceAnyLinkage); } } if (OutputFilename.empty()) { errs() << "no output file\n"; return 1; } std::string ErrorInfo; OwningPtr<tool_output_file> Out (new tool_output_file(OutputFilename.c_str(), ErrorInfo, raw_fd_ostream::F_Binary)); if (!ErrorInfo.empty()) { errs() << ErrorInfo << '\n'; exit(1); } WriteBitcodeToFile(M.get(), Out->os()); // Declare success. Out->keep(); return 0; }
/// InputFilename is a LLVM bitcode file. Read it using bitcode reader. /// Collect global functions and symbol names in symbols vector. /// Collect external references in references vector. /// Return LTO_READ_SUCCESS if there is no error. enum LTOStatus LTO::readLLVMObjectFile(const std::string &InputFilename, NameToSymbolMap &symbols, std::set<std::string> &references) { Module *m = getModule(InputFilename); if (!m) return LTO_READ_FAILURE; // Collect Target info getTarget(m); if (!Target) return LTO_READ_FAILURE; // Use mangler to add GlobalPrefix to names to match linker names. // FIXME : Instead of hard coding "-" use GlobalPrefix. Mangler mangler(*m, Target->getTargetAsmInfo()->getGlobalPrefix()); modules.push_back(m); for (Module::iterator f = m->begin(), e = m->end(); f != e; ++f) { LTOLinkageTypes lt = getLTOLinkageType(f); LTOVisibilityTypes vis = getLTOVisibilityType(f); if (!f->isDeclaration() && lt != LTOInternalLinkage && strncmp (f->getName().c_str(), "llvm.", 5)) { int alignment = ( 16 > f->getAlignment() ? 16 : f->getAlignment()); LLVMSymbol *newSymbol = new LLVMSymbol(lt, vis, f, f->getName(), mangler.getValueName(f), Log2_32(alignment)); symbols[newSymbol->getMangledName()] = newSymbol; allSymbols[newSymbol->getMangledName()] = newSymbol; } // Collect external symbols referenced by this function. for (Function::iterator b = f->begin(), fe = f->end(); b != fe; ++b) for (BasicBlock::iterator i = b->begin(), be = b->end(); i != be; ++i) { for (unsigned count = 0, total = i->getNumOperands(); count != total; ++count) findExternalRefs(i->getOperand(count), references, mangler); } } for (Module::global_iterator v = m->global_begin(), e = m->global_end(); v != e; ++v) { LTOLinkageTypes lt = getLTOLinkageType(v); LTOVisibilityTypes vis = getLTOVisibilityType(v); if (!v->isDeclaration() && lt != LTOInternalLinkage && strncmp (v->getName().c_str(), "llvm.", 5)) { const TargetData *TD = Target->getTargetData(); LLVMSymbol *newSymbol = new LLVMSymbol(lt, vis, v, v->getName(), mangler.getValueName(v), TD->getPreferredAlignmentLog(v)); symbols[newSymbol->getMangledName()] = newSymbol; allSymbols[newSymbol->getMangledName()] = newSymbol; for (unsigned count = 0, total = v->getNumOperands(); count != total; ++count) findExternalRefs(v->getOperand(count), references, mangler); } } return LTO_READ_SUCCESS; }
bool InternalizePass::runOnModule(Module &M) { CallGraph *CG = getAnalysisIfAvailable<CallGraph>(); CallGraphNode *ExternalNode = CG ? CG->getExternalCallingNode() : 0; if (ExternalNames.empty()) { // Return if we're not in 'all but main' mode and have no external api if (!AllButMain) return false; // If no list or file of symbols was specified, check to see if there is a // "main" symbol defined in the module. If so, use it, otherwise do not // internalize the module, it must be a library or something. // Function *MainFunc = M.getFunction("main"); if (MainFunc == 0 || MainFunc->isDeclaration()) return false; // No main found, must be a library... // Preserve main, internalize all else. ExternalNames.insert(MainFunc->getName()); } bool Changed = false; // Never internalize functions which code-gen might insert. ExternalNames.insert("__stack_chk_fail"); // Mark all functions not in the api as internal. // FIXME: maybe use private linkage? for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) if (!I->isDeclaration() && // Function must be defined here // Available externally is really just a "declaration with a body". !I->hasAvailableExternallyLinkage() && !I->hasLocalLinkage() && // Can't already have internal linkage !ExternalNames.count(I->getName())) {// Not marked to keep external? I->setLinkage(GlobalValue::InternalLinkage); // Remove a callgraph edge from the external node to this function. if (ExternalNode) ExternalNode->removeOneAbstractEdgeTo((*CG)[I]); Changed = true; ++NumFunctions; DEBUG(dbgs() << "Internalizing func " << I->getName() << "\n"); } // Never internalize the llvm.used symbol. It is used to implement // attribute((used)). // FIXME: Shouldn't this just filter on llvm.metadata section?? ExternalNames.insert("llvm.used"); ExternalNames.insert("llvm.compiler.used"); // Never internalize anchors used by the machine module info, else the info // won't find them. (see MachineModuleInfo.) ExternalNames.insert("llvm.global_ctors"); ExternalNames.insert("llvm.global_dtors"); ExternalNames.insert("llvm.global.annotations"); // Never internalize symbols code-gen inserts. ExternalNames.insert("__stack_chk_guard"); // Mark all global variables with initializers that are not in the api as // internal as well. // FIXME: maybe use private linkage? for (Module::global_iterator I = M.global_begin(), E = M.global_end(); I != E; ++I) if (!I->isDeclaration() && !I->hasLocalLinkage() && // Available externally is really just a "declaration with a body". !I->hasAvailableExternallyLinkage() && !ExternalNames.count(I->getName())) { I->setLinkage(GlobalValue::InternalLinkage); Changed = true; ++NumGlobals; DEBUG(dbgs() << "Internalized gvar " << I->getName() << "\n"); } // Mark all aliases that are not in the api as internal as well. for (Module::alias_iterator I = M.alias_begin(), E = M.alias_end(); I != E; ++I) if (!I->isDeclaration() && !I->hasInternalLinkage() && // Available externally is really just a "declaration with a body". !I->hasAvailableExternallyLinkage() && !ExternalNames.count(I->getName())) { I->setLinkage(GlobalValue::InternalLinkage); Changed = true; ++NumAliases; DEBUG(dbgs() << "Internalized alias " << I->getName() << "\n"); } return Changed; }
/** * Print the class constructor. */ void JVMWriter::printConstructor() { out << "; Constructor\n" ".method public <init>()V\n"; printSimpleInstruction("aload_0"); printSimpleInstruction("invokespecial","java/lang/Object/<init>()V"); printSimpleInstruction("return"); printSimpleInstruction(".limit stack 1"); printSimpleInstruction(".limit locals 1"); out << ".end method\n\n"; out << ".method public initialize(Llljvm/runtime/Context;)V\n"; printSimpleInstruction(".limit stack 12"); printSimpleInstruction(".limit locals 2"); out << "\n;;;START LINKER INITIALIZATIONS;;;\n"; printInitLinkerFields(); out << ";;;END LINKER INITIALIZATIONS;;;\n\n"; out << "\n\t; allocate global variables\n"; for(Module::global_iterator i = module->global_begin(), e = module->global_end(); i != e; i++) { if(!i->isDeclaration()) { const GlobalVariable *g = i; const Constant *c = g->getInitializer(); printSimpleInstruction("aload_0"); printStartInvocationTag(); printConstLoad( APInt(32, targetData->getTypeAllocSize(c->getType()), false)); printEndInvocationTag("lljvm/runtime/Memory/allocateData(I)I"); printSimpleInstruction("putfield", classname + "/" + getValueName(g) + " I"); } } out << "\n\t; initialize global variables\n"; for(Module::global_iterator i = module->global_begin(), e = module->global_end(); i != e; i++) { if(!i->isDeclaration()) { const GlobalVariable *g = i; const Constant *c = g->getInitializer(); printSimpleInstruction("aload_0"); printSimpleInstruction("getfield", classname + "/" + getValueName(g) + " I"); printStaticConstant(c); printSimpleInstruction("pop"); out << '\n'; } } out << "\n" "\treturn\n" ".end method\n\n"; out << ".method public destroy(Llljvm/runtime/Context;)V\n"; printSimpleInstruction("return"); printSimpleInstruction(".limit stack 0"); printSimpleInstruction(".limit locals 2"); out << ".end method\n\n"; }