static void convertAliasToDeclaration(GlobalAlias &GA, Module &M) { GlobalValue *GVal = GA.getBaseObject(); GlobalValue *NewGV; if (auto *GVar = dyn_cast<GlobalVariable>(GVal)) { GlobalVariable *NewGVar = new GlobalVariable( M, GVar->getType()->getElementType(), GVar->isConstant(), GVar->getLinkage(), /*init*/ nullptr, GA.getName(), GVar, GVar->getThreadLocalMode(), GVar->getType()->getAddressSpace()); NewGV = NewGVar; NewGV->copyAttributesFrom(GVar); } else { auto *F = dyn_cast<Function>(GVal); assert(F); Function *NewF = Function::Create(F->getFunctionType(), F->getLinkage(), GA.getName(), &M); NewGV = NewF; NewGV->copyAttributesFrom(F); } GA.replaceAllUsesWith(ConstantExpr::getBitCast(NewGV, GA.getType())); GA.eraseFromParent(); }
// Replace G with an alias to F and delete G. void MergeFunctions::writeAlias(Function *F, Function *G) { Constant *BitcastF = ConstantExpr::getBitCast(F, G->getType()); GlobalAlias *GA = new GlobalAlias(G->getType(), G->getLinkage(), "", BitcastF, G->getParent()); F->setAlignment(std::max(F->getAlignment(), G->getAlignment())); GA->takeName(G); GA->setVisibility(G->getVisibility()); removeUsers(G); G->replaceAllUsesWith(GA); G->eraseFromParent(); DEBUG(dbgs() << "writeAlias: " << GA->getName() << '\n'); ++NumAliasesWritten; }
Module * llvmutil_extractmodule(Module * OrigMod, TargetMachine * TM, std::vector<Function*> * livefns, std::vector<std::string> * symbolnames) { assert(symbolnames == NULL || livefns->size() == symbolnames->size()); ValueToValueMapTy VMap; Module * M = CloneModule(OrigMod, VMap); PassManager * MPM = new PassManager(); llvmutil_addtargetspecificpasses(MPM, TM); std::vector<const char *> names; for(size_t i = 0; i < livefns->size(); i++) { Function * fn = cast<Function>(VMap[(*livefns)[i]]); const char * name; if(symbolnames) { GlobalAlias * ga = new GlobalAlias(fn->getType(), Function::ExternalLinkage, (*symbolnames)[i], fn, M); name = copyName(ga->getName()); } else { name = copyName(fn->getName()); } names.push_back(name); //internalize pass has weird interface, so we need to copy the names here } //at this point we run optimizations on the module //first internalize all functions not mentioned in "names" using an internalize pass and then perform //standard optimizations MPM->add(createVerifierPass()); //make sure we haven't messed stuff up yet MPM->add(createInternalizePass(names)); MPM->add(createGlobalDCEPass()); //run this early since anything not in the table of exported functions is still in this module //this will remove dead functions //clean up the name list for(size_t i = 0; i < names.size(); i++) { free((char*)names[i]); names[i] = NULL; } PassManagerBuilder PMB; PMB.OptLevel = 3; PMB.DisableUnrollLoops = true; PMB.populateModulePassManager(*MPM); //PMB.populateLTOPassManager(*MPM, false, false); //no need to re-internalize, we already did it MPM->run(*M); delete MPM; MPM = NULL; return M; }
static void computeAliasSummary(ModuleSummaryIndex &Index, const GlobalAlias &A, DenseSet<GlobalValue::GUID> &CantBePromoted) { bool NonRenamableLocal = isNonRenamableLocal(A); GlobalValueSummary::GVFlags Flags(A.getLinkage(), NonRenamableLocal, /* LiveRoot = */ false); auto AS = llvm::make_unique<AliasSummary>(Flags, ArrayRef<ValueInfo>{}); auto *Aliasee = A.getBaseObject(); auto *AliaseeSummary = Index.getGlobalValueSummary(*Aliasee); assert(AliaseeSummary && "Alias expects aliasee summary to be parsed"); AS->setAliasee(AliaseeSummary); if (NonRenamableLocal) CantBePromoted.insert(A.getGUID()); Index.addGlobalValueSummary(A.getName(), std::move(AS)); }
// 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 } }