void ModuleLinker::dropReplacedComdat( GlobalValue &GV, const DenseSet<const Comdat *> &ReplacedDstComdats) { Comdat *C = GV.getComdat(); if (!C) return; if (!ReplacedDstComdats.count(C)) return; if (GV.use_empty()) { GV.eraseFromParent(); return; } if (auto *F = dyn_cast<Function>(&GV)) { F->deleteBody(); } else if (auto *Var = dyn_cast<GlobalVariable>(&GV)) { Var->setInitializer(nullptr); } else { auto &Alias = cast<GlobalAlias>(GV); Module &M = *Alias.getParent(); PointerType &Ty = *cast<PointerType>(Alias.getType()); GlobalValue *Declaration; if (auto *FTy = dyn_cast<FunctionType>(Alias.getValueType())) { Declaration = Function::Create(FTy, GlobalValue::ExternalLinkage, "", &M); } else { Declaration = new GlobalVariable(M, Ty.getElementType(), /*isConstant*/ false, GlobalValue::ExternalLinkage, /*Initializer*/ nullptr); } Declaration->takeName(&Alias); Alias.replaceAllUsesWith(Declaration); Alias.eraseFromParent(); } }
/// Predicate for Internalize pass. static bool mustPreserveGV(const GlobalValue &GV) { if (const Function *F = dyn_cast<Function>(&GV)) return F->isDeclaration() || AMDGPU::isEntryFunctionCC(F->getCallingConv()); return !GV.use_empty(); }
// RemoveUnusedGlobalValue - Loop over all of the uses of the specified // GlobalValue, looking for the constant pointer ref that may be pointing to it. // If found, check to see if the constant pointer ref is safe to destroy, and if // so, nuke it. This will reduce the reference count on the global value, which // might make it deader. // bool GlobalDCE::RemoveUnusedGlobalValue(GlobalValue &GV) { if (GV.use_empty()) return false; GV.removeDeadConstantUsers(); return GV.use_empty(); }
// 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; }