Value *LocalValueMaterializer::materializeValueFor(Value *V) { auto *GO = dyn_cast<GlobalObject>(V); if (!GO) return nullptr; auto I = LocalVersions.find(GO); if (I != LocalVersions.end()) return I->second; if (!Dropped.count(GO)) return nullptr; Module &M = *GO->getParent(); GlobalValue::LinkageTypes L = GO->getLinkage(); GlobalObject *Declaration; if (auto *F = dyn_cast<Function>(GO)) { Declaration = Function::Create(F->getFunctionType(), L, "", &M); } else { auto *Var = cast<GlobalVariable>(GO); Declaration = new GlobalVariable(M, Var->getType()->getElementType(), Var->isConstant(), L, /*Initializer*/ nullptr); } Declaration->takeName(GO); Declaration->copyAttributesFrom(GO); GO->setLinkage(GlobalValue::InternalLinkage); GO->setName(Declaration->getName()); Dropped.erase(GO); GO->replaceAllUsesWith(Declaration); LocalVersions[Declaration] = GO; return GO; }
static GlobalObject *makeInternalReplacement(GlobalObject *GO) { Module *M = GO->getParent(); GlobalObject *Ret; if (auto *F = dyn_cast<Function>(GO)) { if (F->isMaterializable()) { if (F->materialize()) message(LDPL_FATAL, "LLVM gold plugin has failed to read a function"); } auto *NewF = Function::Create(F->getFunctionType(), F->getLinkage(), F->getName(), M); ValueToValueMapTy VM; Function::arg_iterator NewI = NewF->arg_begin(); for (auto &Arg : F->args()) { NewI->setName(Arg.getName()); VM[&Arg] = NewI; ++NewI; } NewF->getBasicBlockList().splice(NewF->end(), F->getBasicBlockList()); for (auto &BB : *NewF) { for (auto &Inst : BB) RemapInstruction(&Inst, VM, RF_IgnoreMissingEntries); } Ret = NewF; F->deleteBody(); } else { auto *Var = cast<GlobalVariable>(GO); Ret = new GlobalVariable( *M, Var->getType()->getElementType(), Var->isConstant(), Var->getLinkage(), Var->getInitializer(), Var->getName(), nullptr, Var->getThreadLocalMode(), Var->getType()->getAddressSpace(), Var->isExternallyInitialized()); Var->setInitializer(nullptr); } Ret->copyAttributesFrom(GO); Ret->setLinkage(GlobalValue::InternalLinkage); Ret->setComdat(GO->getComdat()); return Ret; }
static GlobalObject *makeInternalReplacement(GlobalObject *GO) { Module *M = GO->getParent(); GlobalObject *Ret; if (auto *F = dyn_cast<Function>(GO)) { auto *NewF = Function::Create( F->getFunctionType(), GlobalValue::InternalLinkage, F->getName(), M); NewF->getBasicBlockList().splice(NewF->end(), F->getBasicBlockList()); Ret = NewF; F->deleteBody(); } else { auto *Var = cast<GlobalVariable>(GO); Ret = new GlobalVariable( *M, Var->getType()->getElementType(), Var->isConstant(), GlobalValue::InternalLinkage, Var->getInitializer(), Var->getName(), nullptr, Var->getThreadLocalMode(), Var->getType()->getAddressSpace(), Var->isExternallyInitialized()); Var->setInitializer(nullptr); } Ret->copyAttributesFrom(GO); Ret->setComdat(GO->getComdat()); return Ret; }