bool ResolveAliases::runOnModule(Module &M) { bool Modified = false; for (auto I = M.alias_begin(), E = M.alias_end(); I != E;) { GlobalAlias *Alias = &*I++; Alias->replaceAllUsesWith(Alias->getAliasee()); Alias->eraseFromParent(); Modified = true; } return Modified; }
// // Method: runOnModule() // // Description: // Entry point for this LLVM pass. // Replace all internal aliases with the // aliasee value // // Inputs: // M - A reference to the LLVM module to transform // // Outputs: // M - The transformed LLVM module. // // Return value: // true - The module was modified. // false - The module was not modified. // bool FuncSimplify::runOnModule(Module& M) { std::vector<GlobalAlias*> toDelete; for (Module::alias_iterator I = M.alias_begin(); I != M.alias_end(); ++I) { if(!I->hasInternalLinkage()) continue; I->replaceAllUsesWith(I->getAliasee()); toDelete.push_back(I); } numChanged += toDelete.size(); while(!toDelete.empty()) { GlobalAlias *I = toDelete.back(); toDelete.pop_back(); I->eraseFromParent(); } return true; }
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(); }
// 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 } }
// emit_alias_to_llvm - Given decl and target emit alias to target. void emit_alias_to_llvm(tree decl, tree target, tree target_decl) { if (errorcount || sorrycount) return; timevar_push(TV_LLVM_GLOBALS); // Get or create LLVM global for our alias. GlobalValue *V = cast<GlobalValue>(DECL_LLVM(decl)); GlobalValue *Aliasee = NULL; if (target_decl) Aliasee = cast<GlobalValue>(DECL_LLVM(target_decl)); else { // This is something insane. Probably only LTHUNKs can be here // Try to grab decl from IDENTIFIER_NODE // Query SymTab for aliasee const char* AliaseeName = IDENTIFIER_POINTER(target); Aliasee = dyn_cast_or_null<GlobalValue>(TheModule-> getValueSymbolTable().lookup(AliaseeName)); // Last resort. Query for name set via __asm__ if (!Aliasee) { std::string starred = std::string("\001") + AliaseeName; Aliasee = dyn_cast_or_null<GlobalValue>(TheModule-> getValueSymbolTable().lookup(starred)); } if (!Aliasee) { error ("%J%qD aliased to undefined symbol %qE", decl, decl, target); timevar_pop(TV_LLVM_GLOBALS); return; } } GlobalValue::LinkageTypes Linkage; // Check for external weak linkage if (DECL_EXTERNAL(decl) && DECL_WEAK(decl)) Linkage = GlobalValue::WeakLinkage; else if (!TREE_PUBLIC(decl)) Linkage = GlobalValue::InternalLinkage; else Linkage = GlobalValue::ExternalLinkage; GlobalAlias* GA = new GlobalAlias(Aliasee->getType(), Linkage, "", Aliasee, TheModule); // Handle visibility style if (TREE_PUBLIC(decl)) { if (DECL_VISIBILITY(decl) == VISIBILITY_HIDDEN) GA->setVisibility(GlobalValue::HiddenVisibility); else if (DECL_VISIBILITY(decl) == VISIBILITY_PROTECTED) GA->setVisibility(GlobalValue::ProtectedVisibility); } if (V->getType() == GA->getType()) V->replaceAllUsesWith(GA); else if (!V->use_empty()) { error ("%J Alias %qD used with invalid type!", decl, decl); timevar_pop(TV_LLVM_GLOBALS); return; } changeLLVMValue(V, GA); GA->takeName(V); if (GlobalVariable *GV = dyn_cast<GlobalVariable>(V)) GV->eraseFromParent(); else if (GlobalAlias *GA = dyn_cast<GlobalAlias>(V)) GA->eraseFromParent(); else if (Function *F = dyn_cast<Function>(V)) F->eraseFromParent(); else assert(0 && "Unsuported global value"); TREE_ASM_WRITTEN(decl) = 1; timevar_pop(TV_LLVM_GLOBALS); return; }