#include "llvm/Bitcode/ReaderWriter.h"
#include "llvm/CodeGen/Analysis.h"
#include "llvm/CodeGen/CommandFlags.h"
+#include "llvm/IR/Constants.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/Verifier.h"
message(LDPL_ERROR, "Failed to get a view of %s", file->name);
return LDPS_ERR;
}
- BufferRef = MemoryBufferRef(StringRef((char *)view, file->filesize), "");
+ BufferRef = MemoryBufferRef(StringRef((const char *)view, file->filesize), "");
} else {
int64_t offset = 0;
// Gold has found what might be IR part-way inside of a file, such as
BufferRef = Buffer->getMemBufferRef();
}
- ErrorOr<object::IRObjectFile *> ObjOrErr =
+ ErrorOr<std::unique_ptr<object::IRObjectFile>> ObjOrErr =
object::IRObjectFile::createIRObjectFile(BufferRef, Context);
std::error_code EC = ObjOrErr.getError();
- if (EC == BitcodeError::InvalidBitcodeSignature)
+ if (EC == BitcodeError::InvalidBitcodeSignature ||
+ EC == object::object_error::invalid_file_type ||
+ EC == object::object_error::bitcode_section_not_found)
return LDPS_OK;
*claimed = 1;
EC.message().c_str());
return LDPS_ERR;
}
- std::unique_ptr<object::IRObjectFile> Obj(ObjOrErr.get());
+ std::unique_ptr<object::IRObjectFile> Obj = std::move(*ObjOrErr);
Modules.resize(Modules.size() + 1);
claimed_file &cf = Modules.back();
assert(!GV.isDiscardableIfUnused());
}
-static bool isDeclaration(const GlobalValue &V) {
- if (V.hasAvailableExternallyLinkage())
- return true;
-
- if (V.isMaterializable())
- return false;
-
- return V.isDeclaration();
-}
-
static void internalize(GlobalValue &GV) {
- if (isDeclaration(GV))
+ if (GV.isDeclarationForLinker())
return; // We get here if there is a matching asm definition.
if (!GV.hasLocalLinkage())
GV.setLinkage(GlobalValue::InternalLinkage);
/*Initializer*/ nullptr);
Var->takeName(&Alias);
Alias.replaceAllUsesWith(Var);
+ Alias.eraseFromParent();
}
static const char *getResolutionName(ld_plugin_symbol_resolution R) {
case LDPR_PREVAILING_DEF_IRONLY_EXP:
return "PREVAILING_DEF_IRONLY_EXP";
}
+ llvm_unreachable("Unknown resolution");
}
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);
+ 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(),
- GlobalValue::InternalLinkage, Var->getInitializer(), Var->getName(),
+ 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;
if (get_view(F.handle, &View) != LDPS_OK)
message(LDPL_FATAL, "Failed to get a view of file");
- std::unique_ptr<MemoryBuffer> Buffer = MemoryBuffer::getMemBuffer(
- StringRef((char *)View, File.filesize), "", false);
+ llvm::ErrorOr<MemoryBufferRef> MBOrErr =
+ object::IRObjectFile::findBitcodeInMemBuffer(
+ MemoryBufferRef(StringRef((const char *)View, File.filesize), ""));
+ if (std::error_code EC = MBOrErr.getError())
+ message(LDPL_FATAL, "Could not read bitcode from file : %s",
+ EC.message().c_str());
+
+ std::unique_ptr<MemoryBuffer> Buffer =
+ MemoryBuffer::getMemBuffer(MBOrErr->getBuffer(), "", false);
if (release_input_file(F.handle) != LDPS_OK)
message(LDPL_FATAL, "Failed to release file information");
- ErrorOr<Module *> MOrErr = getLazyBitcodeModule(Buffer, Context);
+ ErrorOr<Module *> MOrErr = getLazyBitcodeModule(std::move(Buffer), Context);
if (std::error_code EC = MOrErr.getError())
message(LDPL_FATAL, "Could not read bitcode from file : %s",
if (!GV)
continue; // Asm symbol.
+ if (Resolution != LDPR_PREVAILING_DEF_IRONLY && GV->hasCommonLinkage()) {
+ // Common linkage is special. There is no single symbol that wins the
+ // resolution. Instead we have to collect the maximum alignment and size.
+ // The IR linker does that for us if we just pass it every common GV.
+ // We still have to keep track of LDPR_PREVAILING_DEF_IRONLY so we
+ // internalize once the IR linker has done its job.
+ continue;
+ }
+
switch (Resolution) {
case LDPR_UNKNOWN:
llvm_unreachable("Unexpected resolution");
case LDPR_RESOLVED_EXEC:
case LDPR_RESOLVED_DYN:
case LDPR_UNDEF:
- assert(isDeclaration(*GV));
+ assert(GV->isDeclarationForLinker());
break;
case LDPR_PREVAILING_DEF_IRONLY: {
keepGlobalValue(*GV, KeptAliases);
break;
- case LDPR_PREEMPTED_REG:
case LDPR_PREEMPTED_IR:
+ // Gold might have selected a linkonce_odr and preempted a weak_odr.
+ // In that case we have to make sure we don't end up internalizing it.
+ if (!GV->isDiscardableIfUnused())
+ Maybe.erase(Sym.name);
+
+ // fall-through
+ case LDPR_PREEMPTED_REG:
Drop.insert(GV);
break;
Sym.comdat_key = nullptr;
}
- if (!Drop.empty())
- // This is horrible. Given how lazy loading is implemented, dropping
- // the body while there is a materializer present doesn't work, the
- // linker will just read the body back.
- M->materializeAllPermanently();
-
ValueToValueMapTy VM;
LocalValueMaterializer Materializer(Drop);
for (GlobalAlias *GA : KeptAliases) {
runLTOPasses(M, *TM);
PassManager CodeGenPasses;
- CodeGenPasses.add(new DataLayoutPass(&M));
+ CodeGenPasses.add(new DataLayoutPass());
SmallString<128> Filename;
int FD;
M->setTargetTriple(DefaultTriple);
}
- std::string ErrMsg;
- if (L.linkInModule(M.get(), &ErrMsg))
- message(LDPL_FATAL, "Failed to link module: %s", ErrMsg.c_str());
+ if (L.linkInModule(M.get()))
+ message(LDPL_FATAL, "Failed to link module");
}
for (const auto &Name : Internalize) {