diff options
34 files changed, 191 insertions, 411 deletions
diff --git a/lld/ELF/Error.h b/lld/ELF/Error.h index 5887e4ce943..34e63c6dda7 100644 --- a/lld/ELF/Error.h +++ b/lld/ELF/Error.h @@ -12,6 +12,8 @@ #include "lld/Core/LLVM.h" +#include "llvm/Support/Error.h" + namespace lld { namespace elf { @@ -31,6 +33,13 @@ template <typename T> void error(const ErrorOr<T> &V, const Twine &Prefix) { LLVM_ATTRIBUTE_NORETURN void fatal(const Twine &Msg); LLVM_ATTRIBUTE_NORETURN void fatal(const Twine &Msg, const Twine &Prefix); +inline void check(Error E) { + handleAllErrors(std::move(E), [&](llvm::ErrorInfoBase &EIB) { + error(EIB.message()); + return Error::success(); + }); +} + template <class T> T check(ErrorOr<T> E) { if (auto EC = E.getError()) fatal(EC.message()); diff --git a/lld/ELF/InputFiles.cpp b/lld/ELF/InputFiles.cpp index 9ec47a05bd0..d13a0b31b34 100644 --- a/lld/ELF/InputFiles.cpp +++ b/lld/ELF/InputFiles.cpp @@ -20,6 +20,7 @@ #include "llvm/CodeGen/Analysis.h" #include "llvm/IR/LLVMContext.h" #include "llvm/IR/Module.h" +#include "llvm/LTO/LTO.h" #include "llvm/MC/StringTableBuilder.h" #include "llvm/Support/Path.h" #include "llvm/Support/raw_ostream.h" @@ -397,13 +398,12 @@ SymbolBody *elf::ObjectFile<ELFT>::createSymbolBody(const Elf_Sym *Sym) { case SHN_UNDEF: return elf::Symtab<ELFT>::X ->addUndefined(Name, Binding, Sym->st_other, Sym->getType(), - /*CanOmitFromDynSym*/ false, /*HasUnnamedAddr*/ false, - this) + /*CanOmitFromDynSym*/ false, this) ->body(); case SHN_COMMON: return elf::Symtab<ELFT>::X ->addCommon(Name, Sym->st_size, Sym->st_value, Binding, Sym->st_other, - Sym->getType(), /*HasUnnamedAddr*/ false, this) + Sym->getType(), this) ->body(); } @@ -416,8 +416,7 @@ SymbolBody *elf::ObjectFile<ELFT>::createSymbolBody(const Elf_Sym *Sym) { if (Sec == &InputSection<ELFT>::Discarded) return elf::Symtab<ELFT>::X ->addUndefined(Name, Binding, Sym->st_other, Sym->getType(), - /*CanOmitFromDynSym*/ false, - /*HasUnnamedAddr*/ false, this) + /*CanOmitFromDynSym*/ false, this) ->body(); return elf::Symtab<ELFT>::X->addRegular(Name, *Sym, Sec)->body(); } @@ -639,8 +638,8 @@ BitcodeFile::BitcodeFile(MemoryBufferRef MB) : InputFile(BitcodeKind, MB) { EMachine = getBitcodeMachineKind(MB); } -static uint8_t getGvVisibility(const GlobalValue *GV) { - switch (GV->getVisibility()) { +static uint8_t mapVisibility(GlobalValue::VisibilityTypes GvVisibility) { + switch (GvVisibility) { case GlobalValue::DefaultVisibility: return STV_DEFAULT; case GlobalValue::HiddenVisibility: @@ -652,84 +651,48 @@ static uint8_t getGvVisibility(const GlobalValue *GV) { } template <class ELFT> -Symbol *BitcodeFile::createSymbol(const DenseSet<const Comdat *> &KeptComdats, - const IRObjectFile &Obj, - const BasicSymbolRef &Sym) { - const GlobalValue *GV = Obj.getSymbolGV(Sym.getRawDataRefImpl()); - - SmallString<64> Name; - raw_svector_ostream OS(Name); - Sym.printName(OS); - StringRef NameRef = Saver.save(StringRef(Name)); - - uint32_t Flags = Sym.getFlags(); +static Symbol *createBitcodeSymbol(const DenseSet<const Comdat *> &KeptComdats, + const lto::InputFile::Symbol &ObjSym, + StringSaver &Saver, BitcodeFile *F) { + StringRef NameRef = Saver.save(ObjSym.getName()); + uint32_t Flags = ObjSym.getFlags(); uint32_t Binding = (Flags & BasicSymbolRef::SF_Weak) ? STB_WEAK : STB_GLOBAL; - uint8_t Type = STT_NOTYPE; - uint8_t Visibility; - bool CanOmitFromDynSym = false; - bool HasUnnamedAddr = false; - - // FIXME: Expose a thread-local flag for module asm symbols. - if (GV) { - if (GV->isThreadLocal()) - Type = STT_TLS; - CanOmitFromDynSym = canBeOmittedFromSymbolTable(GV); - Visibility = getGvVisibility(GV); - HasUnnamedAddr = - GV->getUnnamedAddr() == llvm::GlobalValue::UnnamedAddr::Global; - } else { - // FIXME: Set SF_Hidden flag correctly for module asm symbols, and expose - // protected visibility. - Visibility = STV_DEFAULT; - } + uint8_t Type = ObjSym.isTLS() ? STT_TLS : STT_NOTYPE; + uint8_t Visibility = mapVisibility(ObjSym.getVisibility()); + bool CanOmitFromDynSym = ObjSym.canBeOmittedFromSymbolTable(); - if (GV) - if (const Comdat *C = GV->getComdat()) - if (!KeptComdats.count(C)) - return Symtab<ELFT>::X->addUndefined(NameRef, Binding, Visibility, Type, - CanOmitFromDynSym, HasUnnamedAddr, - this); + if (const Comdat *C = check(ObjSym.getComdat())) + if (!KeptComdats.count(C)) + return Symtab<ELFT>::X->addUndefined(NameRef, Binding, Visibility, Type, + CanOmitFromDynSym, F); - const Module &M = Obj.getModule(); if (Flags & BasicSymbolRef::SF_Undefined) return Symtab<ELFT>::X->addUndefined(NameRef, Binding, Visibility, Type, - CanOmitFromDynSym, HasUnnamedAddr, - this); - if (Flags & BasicSymbolRef::SF_Common) { - // FIXME: Set SF_Common flag correctly for module asm symbols, and expose - // size and alignment. - assert(GV); - const DataLayout &DL = M.getDataLayout(); - uint64_t Size = DL.getTypeAllocSize(GV->getValueType()); - return Symtab<ELFT>::X->addCommon(NameRef, Size, GV->getAlignment(), - Binding, Visibility, STT_OBJECT, - HasUnnamedAddr, this); - } - return Symtab<ELFT>::X->addBitcode(NameRef, Binding, Visibility, Type, - CanOmitFromDynSym, HasUnnamedAddr, this); -} + CanOmitFromDynSym, F); + + if (Flags & BasicSymbolRef::SF_Common) + return Symtab<ELFT>::X->addCommon(NameRef, ObjSym.getCommonSize(), + ObjSym.getCommonAlignment(), Binding, + Visibility, STT_OBJECT, F); -bool BitcodeFile::shouldSkip(uint32_t Flags) { - return !(Flags & BasicSymbolRef::SF_Global) || - (Flags & BasicSymbolRef::SF_FormatSpecific); + return Symtab<ELFT>::X->addBitcode(NameRef, Binding, Visibility, Type, + CanOmitFromDynSym, F); } template <class ELFT> void BitcodeFile::parse(DenseSet<StringRef> &ComdatGroups) { - Obj = check(IRObjectFile::create(MB, Driver->Context)); - const Module &M = Obj->getModule(); - + Obj = check(lto::InputFile::create(MB)); DenseSet<const Comdat *> KeptComdats; - for (const auto &P : M.getComdatSymbolTable()) { + for (const auto &P : Obj->getComdatSymbolTable()) { StringRef N = Saver.save(P.first()); if (ComdatGroups.insert(N).second) KeptComdats.insert(&P.second); } - for (const BasicSymbolRef &Sym : Obj->symbols()) - if (!shouldSkip(Sym.getFlags())) - Symbols.push_back(createSymbol<ELFT>(KeptComdats, *Obj, Sym)); + for (const lto::InputFile::Symbol &ObjSym : Obj->symbols()) + Symbols.push_back( + createBitcodeSymbol<ELFT>(KeptComdats, ObjSym, Saver, this)); } template <template <class> class T> @@ -852,20 +815,12 @@ template <class ELFT> std::vector<StringRef> LazyObjectFile::getElfSymbols() { } std::vector<StringRef> LazyObjectFile::getBitcodeSymbols() { - LLVMContext Context; - std::unique_ptr<IRObjectFile> Obj = - check(IRObjectFile::create(this->MB, Context)); std::vector<StringRef> V; - for (const BasicSymbolRef &Sym : Obj->symbols()) { - uint32_t Flags = Sym.getFlags(); - if (BitcodeFile::shouldSkip(Flags)) - continue; - if (Flags & BasicSymbolRef::SF_Undefined) + std::unique_ptr<lto::InputFile> Obj = check(lto::InputFile::create(this->MB)); + for (auto &ObjSym : Obj->symbols()) { + if (ObjSym.getFlags() & BasicSymbolRef::SF_Undefined) continue; - SmallString<64> Name; - raw_svector_ostream OS(Name); - Sym.printName(OS); - V.push_back(Saver.save(StringRef(Name))); + V.push_back(Saver.save(ObjSym.getName())); } return V; } diff --git a/lld/ELF/InputFiles.h b/lld/ELF/InputFiles.h index 42115742a15..68b31e8fd14 100644 --- a/lld/ELF/InputFiles.h +++ b/lld/ELF/InputFiles.h @@ -27,6 +27,12 @@ #include <map> +namespace llvm { +namespace lto { +class InputFile; +} +} + namespace lld { namespace elf { @@ -247,17 +253,12 @@ public: template <class ELFT> void parse(llvm::DenseSet<StringRef> &ComdatGroups); ArrayRef<Symbol *> getSymbols() { return Symbols; } - static bool shouldSkip(uint32_t Flags); - std::unique_ptr<llvm::object::IRObjectFile> Obj; + std::unique_ptr<llvm::lto::InputFile> Obj; private: std::vector<Symbol *> Symbols; llvm::BumpPtrAllocator Alloc; llvm::StringSaver Saver{Alloc}; - template <class ELFT> - Symbol *createSymbol(const llvm::DenseSet<const llvm::Comdat *> &KeptComdats, - const llvm::object::IRObjectFile &Obj, - const llvm::object::BasicSymbolRef &Sym); }; // .so file. diff --git a/lld/ELF/LTO.cpp b/lld/ELF/LTO.cpp index 2334db36ebd..d74998e6c17 100644 --- a/lld/ELF/LTO.cpp +++ b/lld/ELF/LTO.cpp @@ -22,9 +22,11 @@ #include "llvm/CodeGen/CommandFlags.h" #include "llvm/CodeGen/ParallelCG.h" #include "llvm/IR/AutoUpgrade.h" +#include "llvm/IR/DiagnosticPrinter.h" #include "llvm/IR/LegacyPassManager.h" #include "llvm/IR/PassManager.h" #include "llvm/IR/Verifier.h" +#include "llvm/LTO/LTO.h" #include "llvm/LTO/legacy/UpdateCompilerUsed.h" #include "llvm/Linker/IRMover.h" #include "llvm/Passes/PassBuilder.h" @@ -51,283 +53,109 @@ static void saveBuffer(StringRef Buffer, const Twine &Path) { OS << Buffer; } -// This is for use when debugging LTO. -static void saveBCFile(Module &M, const Twine &Path) { - std::error_code EC; - raw_fd_ostream OS(Path.str(), EC, sys::fs::OpenFlags::F_None); - if (EC) - error(EC, "cannot create " + Path); - WriteBitcodeToFile(&M, OS, /* ShouldPreserveUseListOrder */ true); +static void diagnosticHandler(const DiagnosticInfo &DI) { + SmallString<128> ErrStorage; + raw_svector_ostream OS(ErrStorage); + DiagnosticPrinterRawOStream DP(OS); + DI.print(DP); + warning(ErrStorage); } -static void runNewCustomLtoPasses(Module &M, TargetMachine &TM) { - PassBuilder PB(&TM); - - AAManager AA; - - // Parse a custom AA pipeline if asked to. - if (!PB.parseAAPipeline(AA, Config->LtoAAPipeline)) { - error("unable to parse AA pipeline description: " + Config->LtoAAPipeline); - return; - } - - LoopAnalysisManager LAM; - FunctionAnalysisManager FAM; - CGSCCAnalysisManager CGAM; - ModuleAnalysisManager MAM; - - // Register the AA manager first so that our version is the one used. - FAM.registerPass([&] { return std::move(AA); }); - - // Register all the basic analyses with the managers. - PB.registerModuleAnalyses(MAM); - PB.registerCGSCCAnalyses(CGAM); - PB.registerFunctionAnalyses(FAM); - PB.registerLoopAnalyses(LAM); - PB.crossRegisterProxies(LAM, FAM, CGAM, MAM); - - ModulePassManager MPM; - if (!Config->DisableVerify) - MPM.addPass(VerifierPass()); +static std::unique_ptr<lto::LTO> createLTO() { + lto::Config Conf; + lto::ThinBackend Backend; - // Now, add all the passes we've been requested to. - if (!PB.parsePassPipeline(MPM, Config->LtoNewPmPasses)) { - error("unable to parse pass pipeline description: " + - Config->LtoNewPmPasses); - return; - } - - if (!Config->DisableVerify) - MPM.addPass(VerifierPass()); - MPM.run(M, MAM); -} + // LLD supports the new relocations. + Conf.Options = InitTargetOptionsFromCodeGenFlags(); + Conf.Options.RelaxELFRelocations = true; -static void runOldLtoPasses(Module &M, TargetMachine &TM) { - // Note that the gold plugin has a similar piece of code, so - // it is probably better to move this code to a common place. - legacy::PassManager LtoPasses; - LtoPasses.add(createTargetTransformInfoWrapperPass(TM.getTargetIRAnalysis())); - PassManagerBuilder PMB; - PMB.LibraryInfo = new TargetLibraryInfoImpl(Triple(TM.getTargetTriple())); - PMB.Inliner = createFunctionInliningPass(); - PMB.VerifyInput = PMB.VerifyOutput = !Config->DisableVerify; - PMB.LoopVectorize = true; - PMB.SLPVectorize = true; - PMB.OptLevel = Config->LtoO; - PMB.populateLTOPassManager(LtoPasses); - LtoPasses.run(M); -} + Conf.RelocModel = Config->Pic ? Reloc::PIC_ : Reloc::Static; + Conf.DisableVerify = Config->DisableVerify; + Conf.DiagHandler = diagnosticHandler; + Conf.OptLevel = Config->LtoO; -static void runLTOPasses(Module &M, TargetMachine &TM) { - if (!Config->LtoNewPmPasses.empty()) { - // The user explicitly asked for a set of passes to be run. - // This needs the new PM to work as there's no clean way to - // pass a set of passes to run in the legacy PM. - runNewCustomLtoPasses(M, TM); - if (HasError) - return; - } else { - // Run the 'default' set of LTO passes. This code still uses - // the legacy PM as the new one is not the default. - runOldLtoPasses(M, TM); - } + // Set up a custom pipeline if we've been asked to. + Conf.OptPipeline = Config->LtoNewPmPasses; + Conf.AAPipeline = Config->LtoAAPipeline; if (Config->SaveTemps) - saveBCFile(M, Config->OutputFile + ".lto.opt.bc"); -} + check(Conf.addSaveTemps(std::string(Config->OutputFile) + ".", + /*UseInputModulePath*/ true)); -static bool shouldInternalize(const SmallPtrSet<GlobalValue *, 8> &Used, - Symbol *S, GlobalValue *GV) { - if (S->IsUsedInRegularObj || Used.count(GV)) - return false; - return !S->includeInDynsym(); + return make_unique<lto::LTO>(std::move(Conf), Backend, Config->LtoJobs); } -BitcodeCompiler::BitcodeCompiler() - : Combined(new Module("ld-temp.o", Driver->Context)) {} +BitcodeCompiler::BitcodeCompiler() : LtoObj(createLTO()) {} + +BitcodeCompiler::~BitcodeCompiler() {} static void undefine(Symbol *S) { replaceBody<Undefined>(S, S->body()->getName(), STV_DEFAULT, S->body()->Type, nullptr); } -static void handleUndefinedAsmRefs(const BasicSymbolRef &Sym, GlobalValue *GV, - StringSet<> &AsmUndefinedRefs) { - // GV associated => not an assembly symbol, bail out. - if (GV) - return; - - // This is an undefined reference to a symbol in asm. We put that in - // compiler.used, so that we can preserve it from being dropped from - // the output, without necessarily preventing its internalization. - SmallString<64> Name; - raw_svector_ostream OS(Name); - Sym.printName(OS); - AsmUndefinedRefs.insert(Name.str()); -} - void BitcodeCompiler::add(BitcodeFile &F) { - std::unique_ptr<IRObjectFile> Obj = std::move(F.Obj); - std::vector<GlobalValue *> Keep; - unsigned BodyIndex = 0; - ArrayRef<Symbol *> Syms = F.getSymbols(); - - Module &M = Obj->getModule(); - if (M.getDataLayoutStr().empty()) + lto::InputFile &Obj = *F.Obj; + if (Obj.getDataLayoutStr().empty()) fatal("invalid bitcode file: " + F.getName() + " has no datalayout"); - // Discard non-compatible debug infos if necessary. - M.materializeMetadata(); - UpgradeDebugInfo(M); - - // If a symbol appears in @llvm.used, the linker is required - // to treat the symbol as there is a reference to the symbol - // that it cannot see. Therefore, we can't internalize. - SmallPtrSet<GlobalValue *, 8> Used; - collectUsedGlobalVariables(M, Used, /* CompilerUsed */ false); - - for (const BasicSymbolRef &Sym : Obj->symbols()) { - uint32_t Flags = Sym.getFlags(); - GlobalValue *GV = Obj->getSymbolGV(Sym.getRawDataRefImpl()); - if (GV && GV->hasAppendingLinkage()) - Keep.push_back(GV); - if (BitcodeFile::shouldSkip(Flags)) - continue; - Symbol *S = Syms[BodyIndex++]; - if (GV) - GV->setUnnamedAddr(S->HasUnnamedAddr ? GlobalValue::UnnamedAddr::Global - : GlobalValue::UnnamedAddr::None); - if (Flags & BasicSymbolRef::SF_Undefined) { - handleUndefinedAsmRefs(Sym, GV, AsmUndefinedRefs); - continue; - } - SymbolBody *B = S->body(); - if (B->File != &F) - continue; - - // We collect the set of symbols we want to internalize here - // and change the linkage after the IRMover executed, i.e. after - // we imported the symbols and satisfied undefined references - // to it. We can't just change linkage here because otherwise - // the IRMover will just rename the symbol. - if (GV && shouldInternalize(Used, S, GV)) - InternalizedSyms.insert(GV->getName()); - - // At this point we know that either the combined LTO object will provide a - // definition of a symbol, or we will internalize it. In either case, we - // need to undefine the symbol. In the former case, the real definition - // needs to be able to replace the original definition without conflicting. - // In the latter case, we need to allow the combined LTO object to provide a - // definition with the same name, for example when doing parallel codegen. - if (auto *C = dyn_cast<DefinedCommon>(B)) { - if (auto *GO = dyn_cast<GlobalObject>(GV)) - GO->setAlignment(C->Alignment); - } else { - undefine(S); - } - - if (!GV) - // Module asm symbol. - continue; - - switch (GV->getLinkage()) { - default: - break; - case GlobalValue::LinkOnceAnyLinkage: - GV->setLinkage(GlobalValue::WeakAnyLinkage); - break; - case GlobalValue::LinkOnceODRLinkage: - GV->setLinkage(GlobalValue::WeakODRLinkage); - break; - } - - Keep.push_back(GV); - } - - IRMover Mover(*Combined); - if (Error E = Mover.move(Obj->takeModule(), Keep, - [](GlobalValue &, IRMover::ValueAdder) {})) { - handleAllErrors(std::move(E), [&](const ErrorInfoBase &EIB) { - fatal("failed to link module " + F.getName() + ": " + EIB.message()); - }); - } -} - -static void internalize(GlobalValue &GV) { - assert(!GV.hasLocalLinkage() && - "Trying to internalize a symbol with local linkage!"); - GV.setLinkage(GlobalValue::InternalLinkage); -} - -std::vector<InputFile *> BitcodeCompiler::runSplitCodegen( - const std::function<std::unique_ptr<TargetMachine>()> &TMFactory) { - unsigned NumThreads = Config->LtoJobs; - OwningData.resize(NumThreads); - - std::list<raw_svector_ostream> OSs; - std::vector<raw_pwrite_stream *> OSPtrs; - for (SmallString<0> &Obj : OwningData) { - OSs.emplace_back(Obj); - OSPtrs.push_back(&OSs.back()); - } - - splitCodeGen(std::move(Combined), OSPtrs, {}, TMFactory); - - std::vector<InputFile *> ObjFiles; - for (SmallString<0> &Obj : OwningData) - ObjFiles.push_back(createObjectFile( - MemoryBufferRef(Obj, "LLD-INTERNAL-combined-lto-object"))); - - // If -save-temps is given, we need to save temporary objects to files. - // This is for debugging. - if (Config->SaveTemps) { - if (NumThreads == 1) { - saveBuffer(OwningData[0], Config->OutputFile + ".lto.o"); - } else { - for (unsigned I = 0; I < NumThreads; ++I) - saveBuffer(OwningData[I], Config->OutputFile + Twine(I) + ".lto.o"); - } + unsigned SymNum = 0; + std::vector<Symbol *> Syms = F.getSymbols(); + std::vector<lto::SymbolResolution> Resols(Syms.size()); + + // Provide a resolution to the LTO API for each symbol. + for (const lto::InputFile::Symbol &ObjSym : Obj.symbols()) { + Symbol *Sym = Syms[SymNum]; + lto::SymbolResolution &R = Resols[SymNum]; + ++SymNum; + SymbolBody *B = Sym->body(); + + // Ideally we shouldn't check for SF_Undefined but currently IRObjectFile + // reports two symbols for module ASM defined. Without this check, lld + // flags an undefined in IR with a definition in ASM as prevailing. + // Once IRObjectFile is fixed to report only one symbol this hack can + // be removed. + R.Prevailing = + !(ObjSym.getFlags() & object::BasicSymbolRef::SF_Undefined) && + B->File == &F; + + R.VisibleToRegularObj = + Sym->IsUsedInRegularObj || (R.Prevailing && Sym->includeInDynsym()); + if (R.Prevailing) + undefine(Sym); } - - return ObjFiles; + check(LtoObj->add(std::move(F.Obj), Resols)); } // Merge all the bitcode files we have seen, codegen the result -// and return the resulting ObjectFile. +// and return the resulting ObjectFile(s). std::vector<InputFile *> BitcodeCompiler::compile() { - for (const auto &Name : InternalizedSyms) { - GlobalValue *GV = Combined->getNamedValue(Name.first()); - assert(GV); - internalize(*GV); - } - - std::string TheTriple = Combined->getTargetTriple(); - std::string Msg; - const Target *T = TargetRegistry::lookupTarget(TheTriple, Msg); - if (!T) - fatal("target not found: " + Msg); - - // LLD supports the new relocations. - TargetOptions Options = InitTargetOptionsFromCodeGenFlags(); - Options.RelaxELFRelocations = true; - - auto CreateTargetMachine = [&]() { - return std::unique_ptr<TargetMachine>(T->createTargetMachine( - TheTriple, "", "", Options, Config->Pic ? Reloc::PIC_ : Reloc::Static)); + std::vector<InputFile *> Ret; + unsigned MaxTasks = LtoObj->getMaxTasks(); + Buff.resize(MaxTasks); + + auto AddStream = + [&](size_t Task) -> std::unique_ptr<lto::NativeObjectStream> { + return llvm::make_unique<lto::NativeObjectStream>( + llvm::make_unique<llvm::raw_svector_ostream>(Buff[Task])); }; - std::unique_ptr<TargetMachine> TM = CreateTargetMachine(); - - // Update llvm.compiler.used so that optimizations won't strip - // off AsmUndefinedReferences. - updateCompilerUsed(*Combined, *TM, AsmUndefinedRefs); - - if (Config->SaveTemps) - saveBCFile(*Combined, Config->OutputFile + ".lto.bc"); - - runLTOPasses(*Combined, *TM); + check(LtoObj->run(AddStream)); if (HasError) - return {}; + return Ret; - return runSplitCodegen(CreateTargetMachine); + for (unsigned I = 0; I != MaxTasks; ++I) { + if (Buff[I].empty()) + continue; + if (Config->SaveTemps) { + if (MaxTasks == 1) + saveBuffer(Buff[I], Config->OutputFile + ".lto.o"); + else + saveBuffer(Buff[I], Config->OutputFile + Twine(I) + ".lto.o"); + } + MemoryBufferRef CompiledObjRef(Buff[I], "lto.tmp"); + InputFile *Obj = createObjectFile(CompiledObjRef); + Ret.push_back(Obj); + } + return Ret; } diff --git a/lld/ELF/LTO.h b/lld/ELF/LTO.h index ec81fc84c18..916c01895e1 100644 --- a/lld/ELF/LTO.h +++ b/lld/ELF/LTO.h @@ -27,6 +27,12 @@ #include "llvm/IR/Module.h" #include "llvm/Linker/IRMover.h" +namespace llvm { +namespace lto { +class LTO; +} +} + namespace lld { namespace elf { @@ -36,17 +42,14 @@ class InputFile; class BitcodeCompiler { public: BitcodeCompiler(); + ~BitcodeCompiler(); void add(BitcodeFile &F); std::vector<InputFile *> compile(); -private: - std::vector<InputFile *> runSplitCodegen( - const std::function<std::unique_ptr<llvm::TargetMachine>()> &TMFactory); + std::unique_ptr<llvm::lto::LTO> LtoObj; - std::unique_ptr<llvm::Module> Combined; - std::vector<SmallString<0>> OwningData; - llvm::StringSet<> InternalizedSyms; - llvm::StringSet<> AsmUndefinedRefs; +private: + std::vector<SmallString<0>> Buff; }; } } diff --git a/lld/ELF/SymbolTable.cpp b/lld/ELF/SymbolTable.cpp index e72f7ef5a47..ac6a91a2654 100644 --- a/lld/ELF/SymbolTable.cpp +++ b/lld/ELF/SymbolTable.cpp @@ -216,7 +216,6 @@ std::pair<Symbol *, bool> SymbolTable<ELFT>::insert(StringRef &Name) { Sym->Binding = STB_WEAK; Sym->Visibility = STV_DEFAULT; Sym->IsUsedInRegularObj = false; - Sym->HasUnnamedAddr = true; Sym->ExportDynamic = false; Sym->Traced = V.Traced; std::tie(Name, Sym->VersionId) = getSymbolVersion(Name); @@ -232,15 +231,12 @@ std::pair<Symbol *, bool> SymbolTable<ELFT>::insert(StringRef &Name) { template <class ELFT> std::pair<Symbol *, bool> SymbolTable<ELFT>::insert(StringRef &Name, uint8_t Type, uint8_t Visibility, - bool CanOmitFromDynSym, bool HasUnnamedAddr, - InputFile *File) { + bool CanOmitFromDynSym, InputFile *File) { bool IsUsedInRegularObj = !File || File->kind() == InputFile::ObjectKind; Symbol *S; bool WasInserted; std::tie(S, WasInserted) = insert(Name); - // Merge in the new unnamed_addr attribute. - S->HasUnnamedAddr &= HasUnnamedAddr; // Merge in the new symbol's visibility. S->Visibility = getMinVisibility(S->Visibility, Visibility); if (!CanOmitFromDynSym && (Config->Shared || Config->ExportDynamic)) @@ -269,19 +265,18 @@ std::string SymbolTable<ELFT>::conflictMsg(SymbolBody *Existing, template <class ELFT> Symbol *SymbolTable<ELFT>::addUndefined(StringRef Name) { return addUndefined(Name, STB_GLOBAL, STV_DEFAULT, /*Type*/ 0, - /*CanOmitFromDynSym*/ false, /*HasUnnamedAddr*/ false, - /*File*/ nullptr); + /*CanOmitFromDynSym*/ false, /*File*/ nullptr); } template <class ELFT> Symbol *SymbolTable<ELFT>::addUndefined(StringRef Name, uint8_t Binding, uint8_t StOther, uint8_t Type, bool CanOmitFromDynSym, - bool HasUnnamedAddr, InputFile *File) { + InputFile *File) { Symbol *S; bool WasInserted; std::tie(S, WasInserted) = - insert(Name, Type, StOther & 3, CanOmitFromDynSym, HasUnnamedAddr, File); + insert(Name, Type, StOther & 3, CanOmitFromDynSym, File); if (WasInserted) { S->Binding = Binding; replaceBody<Undefined>(S, Name, StOther, Type, File); @@ -343,11 +338,11 @@ template <class ELFT> Symbol *SymbolTable<ELFT>::addCommon(StringRef N, uint64_t Size, uint64_t Alignment, uint8_t Binding, uint8_t StOther, uint8_t Type, - bool HasUnnamedAddr, InputFile *File) { + InputFile *File) { Symbol *S; bool WasInserted; - std::tie(S, WasInserted) = insert( - N, Type, StOther & 3, /*CanOmitFromDynSym*/ false, HasUnnamedAddr, File); + std::tie(S, WasInserted) = + insert(N, Type, StOther & 3, /*CanOmitFromDynSym*/ false, File); int Cmp = compareDefined(S, WasInserted, Binding); if (Cmp > 0) { S->Binding = Binding; @@ -386,10 +381,9 @@ Symbol *SymbolTable<ELFT>::addRegular(StringRef Name, const Elf_Sym &Sym, InputSectionBase<ELFT> *Section) { Symbol *S; bool WasInserted; - std::tie(S, WasInserted) = - insert(Name, Sym.getType(), Sym.getVisibility(), - /*CanOmitFromDynSym*/ false, /*HasUnnamedAddr*/ false, - Section ? Section->getFile() : nullptr); + std::tie(S, WasInserted) = insert(Name, Sym.getType(), Sym.getVisibility(), + /*CanOmitFromDynSym*/ false, + Section ? Section->getFile() : nullptr); int Cmp = compareDefinedNonCommon(S, WasInserted, Sym.getBinding()); if (Cmp > 0) replaceBody<DefinedRegular<ELFT>>(S, Name, Sym, Section); @@ -403,9 +397,8 @@ Symbol *SymbolTable<ELFT>::addRegular(StringRef Name, uint8_t Binding, uint8_t StOther) { Symbol *S; bool WasInserted; - std::tie(S, WasInserted) = - insert(Name, STT_NOTYPE, StOther & 3, /*CanOmitFromDynSym*/ false, - /*HasUnnamedAddr*/ false, nullptr); + std::tie(S, WasInserted) = insert(Name, STT_NOTYPE, StOther & 3, + /*CanOmitFromDynSym*/ false, nullptr); int Cmp = compareDefinedNonCommon(S, WasInserted, Binding); if (Cmp > 0) replaceBody<DefinedRegular<ELFT>>(S, Name, StOther); @@ -421,8 +414,7 @@ Symbol *SymbolTable<ELFT>::addSynthetic(StringRef N, Symbol *S; bool WasInserted; std::tie(S, WasInserted) = insert(N, STT_NOTYPE, /*Visibility*/ StOther & 0x3, - /*CanOmitFromDynSym*/ false, - /*HasUnnamedAddr*/ false, nullptr); + /*CanOmitFromDynSym*/ false, nullptr); int Cmp = compareDefinedNonCommon(S, WasInserted, STB_GLOBAL); if (Cmp > 0) replaceBody<DefinedSynthetic<ELFT>>(S, N, Value, Section); @@ -441,8 +433,7 @@ void SymbolTable<ELFT>::addShared(SharedFile<ELFT> *F, StringRef Name, Symbol *S; bool WasInserted; std::tie(S, WasInserted) = - insert(Name, Sym.getType(), STV_DEFAULT, /*CanOmitFromDynSym*/ true, - /*HasUnnamedAddr*/ false, F); + insert(Name, Sym.getType(), STV_DEFAULT, /*CanOmitFromDynSym*/ true, F); // Make sure we preempt DSO symbols with default visibility. if (Sym.getVisibility() == STV_DEFAULT) S->ExportDynamic = true; @@ -456,12 +447,11 @@ void SymbolTable<ELFT>::addShared(SharedFile<ELFT> *F, StringRef Name, template <class ELFT> Symbol *SymbolTable<ELFT>::addBitcode(StringRef Name, uint8_t Binding, uint8_t StOther, uint8_t Type, - bool CanOmitFromDynSym, - bool HasUnnamedAddr, BitcodeFile *F) { + bool CanOmitFromDynSym, BitcodeFile *F) { Symbol *S; bool WasInserted; std::tie(S, WasInserted) = - insert(Name, Type, StOther & 3, CanOmitFromDynSym, HasUnnamedAddr, F); + insert(Name, Type, StOther & 3, CanOmitFromDynSym, F); int Cmp = compareDefinedNonCommon(S, WasInserted, Binding); if (Cmp > 0) replaceBody<DefinedRegular<ELFT>>(S, Name, StOther, Type, F); diff --git a/lld/ELF/SymbolTable.h b/lld/ELF/SymbolTable.h index 8059e61f77a..90480624504 100644 --- a/lld/ELF/SymbolTable.h +++ b/lld/ELF/SymbolTable.h @@ -60,8 +60,7 @@ public: Symbol *addUndefined(StringRef Name); Symbol *addUndefined(StringRef Name, uint8_t Binding, uint8_t StOther, - uint8_t Type, bool CanOmitFromDynSym, - bool HasUnnamedAddr, InputFile *File); + uint8_t Type, bool CanOmitFromDynSym, InputFile *File); Symbol *addRegular(StringRef Name, const Elf_Sym &Sym, InputSectionBase<ELFT> *Section); @@ -74,12 +73,11 @@ public: void addLazyArchive(ArchiveFile *F, const llvm::object::Archive::Symbol S); void addLazyObject(StringRef Name, LazyObjectFile &Obj); Symbol *addBitcode(StringRef Name, uint8_t Binding, uint8_t StOther, - uint8_t Type, bool CanOmitFromDynSym, bool HasUnnamedAddr, - BitcodeFile *File); + uint8_t Type, bool CanOmitFromDynSym, BitcodeFile *File); Symbol *addCommon(StringRef N, uint64_t Size, uint64_t Alignment, uint8_t Binding, uint8_t StOther, uint8_t Type, - bool HasUnnamedAddr, InputFile *File); + InputFile *File); void scanUndefinedFlags(); void scanShlibUndefined(); @@ -96,7 +94,7 @@ private: std::pair<Symbol *, bool> insert(StringRef &Name); std::pair<Symbol *, bool> insert(StringRef &Name, uint8_t Type, uint8_t Visibility, bool CanOmitFromDynSym, - bool HasUnnamedAddr, InputFile *File); + InputFile *File); std::string conflictMsg(SymbolBody *Existing, InputFile *NewFile); void reportDuplicate(SymbolBody *Existing, InputFile *NewFile); diff --git a/lld/ELF/Symbols.h b/lld/ELF/Symbols.h index 52c658cdaba..c067e9c1f7d 100644 --- a/lld/ELF/Symbols.h +++ b/lld/ELF/Symbols.h @@ -410,9 +410,6 @@ struct Symbol { // observed non-DSO symbols. unsigned Visibility : 2; - // True if the symbol has unnamed_addr. - unsigned HasUnnamedAddr : 1; - // True if the symbol was used for linking and thus need to be added to the // output file's symbol table. This is true for all symbols except for // unreferenced DSO symbols and bitcode symbols that are unreferenced except diff --git a/lld/test/ELF/lto/archive-3.ll b/lld/test/ELF/lto/archive-3.ll index 350c8929c9d..0322e412539 100644 --- a/lld/test/ELF/lto/archive-3.ll +++ b/lld/test/ELF/lto/archive-3.ll @@ -3,12 +3,12 @@ ; RUN: llvm-as %s -o %t2.o ; RUN: ld.lld -m elf_x86_64 %t1.o %t2.o -o %t3 -save-temps -; RUN: llvm-dis %t3.lto.bc -o - | FileCheck %s +; RUN: llvm-dis %t3.0.2.internalize.bc -o - | FileCheck %s ; RUN: rm -f %t.a ; RUN: llvm-ar rcs %t.a %t1.o ; RUN: ld.lld -m elf_x86_64 %t.a %t1.o %t2.o -o %t3 -save-temps -; RUN: llvm-dis %t3.lto.bc -o - | FileCheck %s +; RUN: llvm-dis %t3.0.2.internalize.bc -o - | FileCheck %s ; CHECK: define internal void @foo() { diff --git a/lld/test/ELF/lto/asmundef.ll b/lld/test/ELF/lto/asmundef.ll index d76e418fce8..1c87cd01fad 100644 --- a/lld/test/ELF/lto/asmundef.ll +++ b/lld/test/ELF/lto/asmundef.ll @@ -1,7 +1,7 @@ ; REQUIRES: x86 ; RUN: llvm-as %s -o %t.o ; RUN: ld.lld -m elf_x86_64 %t.o -o %t -save-temps -; RUN: llvm-dis %t.lto.bc -o - | FileCheck %s +; RUN: llvm-dis %t.0.4.opt.bc -o - | FileCheck %s target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" target triple = "x86_64-unknown-linux-gnu" diff --git a/lld/test/ELF/lto/available-externally.ll b/lld/test/ELF/lto/available-externally.ll index 74aa86002c9..181042b9d1e 100644 --- a/lld/test/ELF/lto/available-externally.ll +++ b/lld/test/ELF/lto/available-externally.ll @@ -1,7 +1,7 @@ ; RUN: llvm-as %s -o %t1.o ; RUN: llvm-as %p/Inputs/available-externally.ll -o %t2.o ; RUN: ld.lld %t1.o %t2.o -m elf_x86_64 -o %t.so -shared -save-temps -; RUN: llvm-dis < %t.so.lto.bc | FileCheck %s +; RUN: llvm-dis < %t.so.0.2.internalize.bc | FileCheck %s target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" target triple = "x86_64-unknown-linux-gnu" diff --git a/lld/test/ELF/lto/common2.ll b/lld/test/ELF/lto/common2.ll index 6b740c4be70..b44bbac4fda 100644 --- a/lld/test/ELF/lto/common2.ll +++ b/lld/test/ELF/lto/common2.ll @@ -1,6 +1,6 @@ ; RUN: llvm-as %s -o %t1.o ; RUN: ld.lld -m elf_x86_64 %t1.o -o %t -shared -save-temps -; RUN: llvm-dis < %t.lto.bc | FileCheck %s +; RUN: llvm-dis < %t.0.2.internalize.bc | FileCheck %s ; RUN: llvm-readobj -t %t | FileCheck %s --check-prefix=SHARED target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" diff --git a/lld/test/ELF/lto/common3.ll b/lld/test/ELF/lto/common3.ll index a6020ca8c92..6d40de547fc 100644 --- a/lld/test/ELF/lto/common3.ll +++ b/lld/test/ELF/lto/common3.ll @@ -1,7 +1,7 @@ ; RUN: llvm-as %s -o %t1.o ; RUN: llvm-as %S/Inputs/common3.ll -o %t2.o ; RUN: ld.lld -m elf_x86_64 %t1.o %t2.o -o %t -shared -save-temps -; RUN: llvm-dis < %t.lto.bc | FileCheck %s +; RUN: llvm-dis < %t.0.2.internalize.bc | FileCheck %s target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" target triple = "x86_64-unknown-linux-gnu" diff --git a/lld/test/ELF/lto/discard-value-names.ll b/lld/test/ELF/lto/discard-value-names.ll index c6cd94fd2e1..c71dc386113 100644 --- a/lld/test/ELF/lto/discard-value-names.ll +++ b/lld/test/ELF/lto/discard-value-names.ll @@ -1,7 +1,7 @@ ; RUN: llvm-as %s -o %t.o ; RUN: ld.lld -m elf_x86_64 -shared -save-temps %t.o -o %t2.o -; RUN: llvm-dis < %t2.o.lto.bc | FileCheck %s +; RUN: llvm-dis < %t2.o.0.0.preopt.bc | FileCheck %s ; CHECK: @GlobalValueName ; CHECK: @foo(i32 %in) diff --git a/lld/test/ELF/lto/drop-debug-info.ll b/lld/test/ELF/lto/drop-debug-info.ll index 7a7ed5ea41d..27c0260080e 100644 --- a/lld/test/ELF/lto/drop-debug-info.ll +++ b/lld/test/ELF/lto/drop-debug-info.ll @@ -5,5 +5,5 @@ ; ; RUN: ld.lld -m elf_x86_64 -shared %p/Inputs/drop-debug-info.bc \ ; RUN: -disable-verify 2>&1 | FileCheck %s -; CHECK: warning: ignoring debug info with an invalid version (1) in {{.*}}drop-debug-info.bc +; CHECK: ignoring debug info with an invalid version (1) in {{.*}}drop-debug-info.bc diff --git a/lld/test/ELF/lto/drop-linkage.ll b/lld/test/ELF/lto/drop-linkage.ll index fd111c18bd1..1ff179666f0 100644 --- a/lld/test/ELF/lto/drop-linkage.ll +++ b/lld/test/ELF/lto/drop-linkage.ll @@ -5,7 +5,7 @@ target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" ; RUN: llc %s -o %t.o -filetype=obj ; RUN: llvm-as %p/Inputs/drop-linkage.ll -o %t2.o ; RUN: ld.lld %t.o %t2.o -o %t.so -save-temps -shared -; RUN: llvm-dis %t.so.lto.opt.bc -o - | FileCheck %s +; RUN: llvm-dis %t.so.0.4.opt.bc -o - | FileCheck %s define void @foo() { ret void diff --git a/lld/test/ELF/lto/internalize-basic.ll b/lld/test/ELF/lto/internalize-basic.ll index 396b9cb60f1..43c1837528f 100644 --- a/lld/test/ELF/lto/internalize-basic.ll +++ b/lld/test/ELF/lto/internalize-basic.ll @@ -1,7 +1,7 @@ ; REQUIRES: x86 ; RUN: llvm-as %s -o %t.o ; RUN: ld.lld -m elf_x86_64 %t.o -o %t2 -save-temps -; RUN: llvm-dis < %t2.lto.bc | FileCheck %s +; RUN: llvm-dis < %t2.0.2.internalize.bc | FileCheck %s target triple = "x86_64-unknown-linux-gnu" target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" diff --git a/lld/test/ELF/lto/internalize-exportdyn.ll b/lld/test/ELF/lto/internalize-exportdyn.ll index bee9a1e6a1e..2034a2b3ab7 100644 --- a/lld/test/ELF/lto/internalize-exportdyn.ll +++ b/lld/test/ELF/lto/internalize-exportdyn.ll @@ -2,7 +2,7 @@ ; RUN: llvm-as %s -o %t.o ; RUN: llvm-as %p/Inputs/internalize-exportdyn.ll -o %t2.o ; RUN: ld.lld -m elf_x86_64 %t.o %t2.o -o %t2 --export-dynamic -save-temps -; RUN: llvm-dis < %t2.lto.bc | FileCheck %s +; RUN: llvm-dis < %t2.0.2.internalize.bc | FileCheck %s target triple = "x86_64-unknown-linux-gnu" target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" diff --git a/lld/test/ELF/lto/internalize-llvmused.ll b/lld/test/ELF/lto/internalize-llvmused.ll index 46c90a65ff7..253dcb26d04 100644 --- a/lld/test/ELF/lto/internalize-llvmused.ll +++ b/lld/test/ELF/lto/internalize-llvmused.ll @@ -1,7 +1,7 @@ ; REQUIRES: x86 ; RUN: llvm-as %s -o %t.o ; RUN: ld.lld -m elf_x86_64 %t.o -o %t2 -save-temps -; RUN: llvm-dis < %t2.lto.bc | FileCheck %s +; RUN: llvm-dis < %t2.0.2.internalize.bc | FileCheck %s target triple = "x86_64-unknown-linux-gnu" target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" diff --git a/lld/test/ELF/lto/internalize-undef.ll b/lld/test/ELF/lto/internalize-undef.ll index 5d74c31eee8..f76528bda3b 100644 --- a/lld/test/ELF/lto/internalize-undef.ll +++ b/lld/test/ELF/lto/internalize-undef.ll @@ -2,7 +2,7 @@ ; RUN: llvm-as %s -o %t.o ; RUN: llvm-as %p/Inputs/internalize-undef.ll -o %t2.o ; RUN: ld.lld -m elf_x86_64 %t.o %t2.o -o %t -save-temps -; RUN: llvm-dis < %t.lto.bc | FileCheck %s +; RUN: llvm-dis < %t.0.2.internalize.bc | FileCheck %s target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" target triple = "x86_64-unknown-linux-gnu" diff --git a/lld/test/ELF/lto/internalize-version-script.ll b/lld/test/ELF/lto/internalize-version-script.ll index c25328fb56e..c577e43b50e 100644 --- a/lld/test/ELF/lto/internalize-version-script.ll +++ b/lld/test/ELF/lto/internalize-version-script.ll @@ -2,7 +2,7 @@ ; RUN: llvm-as %s -o %t.o ; RUN: echo "{ global: foo; local: *; };" > %t.script ; RUN: ld.lld -m elf_x86_64 %t.o -o %t2 -shared --version-script %t.script -save-temps -; RUN: llvm-dis < %t2.lto.bc | FileCheck %s +; RUN: llvm-dis < %t2.0.2.internalize.bc | FileCheck %s target triple = "x86_64-unknown-linux-gnu" target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" diff --git a/lld/test/ELF/lto/irmover-error.ll b/lld/test/ELF/lto/irmover-error.ll index aee411441c4..8b9836d23ca 100644 --- a/lld/test/ELF/lto/irmover-error.ll +++ b/lld/test/ELF/lto/irmover-error.ll @@ -2,7 +2,7 @@ ; RUN: llvm-as -o %t2.bc %S/Inputs/irmover-error.ll ; RUN: not ld.lld -m elf_x86_64 %t1.bc %t2.bc -o %t 2>&1 | FileCheck %s -; CHECK: failed to link module {{.*}}2.bc: linking module flags 'foo': IDs have conflicting values +; CHECK: linking module flags 'foo': IDs have conflicting values target triple = "x86_64-unknown-linux-gnu" target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" diff --git a/lld/test/ELF/lto/linkonce-odr.ll b/lld/test/ELF/lto/linkonce-odr.ll index 569e2715454..44233513d1f 100644 --- a/lld/test/ELF/lto/linkonce-odr.ll +++ b/lld/test/ELF/lto/linkonce-odr.ll @@ -2,7 +2,7 @@ ; RUN: llvm-as %p/Inputs/linkonce-odr.ll -o %t1.o ; RUN: llc -relocation-model=pic %s -o %t2.o -filetype=obj ; RUN: ld.lld %t1.o %t2.o -o %t.so -shared -save-temps -; RUN: llvm-dis %t.so.lto.opt.bc -o - | FileCheck %s +; RUN: llvm-dis %t.so.0.4.opt.bc -o - | FileCheck %s target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" target triple = "x86_64-unknown-linux-gnu" diff --git a/lld/test/ELF/lto/linkonce.ll b/lld/test/ELF/lto/linkonce.ll index f980eff887b..6dba6a3fded 100644 --- a/lld/test/ELF/lto/linkonce.ll +++ b/lld/test/ELF/lto/linkonce.ll @@ -2,7 +2,7 @@ ; RUN: llvm-as %p/Inputs/linkonce.ll -o %t1.o ; RUN: llc -relocation-model=pic %s -o %t2.o -filetype=obj ; RUN: ld.lld %t1.o %t2.o -o %t.so -shared -save-temps -; RUN: llvm-dis %t.so.lto.opt.bc -o - | FileCheck %s +; RUN: llvm-dis %t.so.0.4.opt.bc -o - | FileCheck %s target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" target triple = "x86_64-unknown-linux-gnu" diff --git a/lld/test/ELF/lto/ltopasses-basic.ll b/lld/test/ELF/lto/ltopasses-basic.ll index 5bd5f4122fd..0c4ad8b9f17 100644 --- a/lld/test/ELF/lto/ltopasses-basic.ll +++ b/lld/test/ELF/lto/ltopasses-basic.ll @@ -1,8 +1,7 @@ ; REQUIRES: x86 -; RUN: rm -f %t.so.lto.bc %t.so.lto.opt.bc %t.so.lto.o ; RUN: llvm-as %s -o %t.o ; RUN: ld.lld -m elf_x86_64 %t.o -o %t.so -save-temps -mllvm -debug-pass=Arguments -shared 2>&1 | FileCheck %s --check-prefix=MLLVM -; RUN: llvm-dis %t.so.lto.opt.bc -o - | FileCheck %s +; RUN: llvm-dis %t.so.0.4.opt.bc -o - | FileCheck %s target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" target triple = "x86_64-unknown-linux-gnu" diff --git a/lld/test/ELF/lto/ltopasses-custom.ll b/lld/test/ELF/lto/ltopasses-custom.ll index 147411aca14..a48959a3299 100644 --- a/lld/test/ELF/lto/ltopasses-custom.ll +++ b/lld/test/ELF/lto/ltopasses-custom.ll @@ -3,8 +3,8 @@ ; RUN: ld.lld -m elf_x86_64 %t.o -o %t.so -save-temps --lto-aa-pipeline=basic-aa \ ; RUN: --lto-newpm-passes=ipsccp -shared ; RUN: ld.lld -m elf_x86_64 %t.o -o %t2.so -save-temps --lto-newpm-passes=loweratomic -shared -; RUN: llvm-dis %t.so.lto.opt.bc -o - | FileCheck %s -; RUN: llvm-dis %t2.so.lto.opt.bc -o - | FileCheck %s --check-prefix=ATOMIC +; RUN: llvm-dis %t.so.0.4.opt.bc -o - | FileCheck %s +; RUN: llvm-dis %t2.so.0.4.opt.bc -o - | FileCheck %s --check-prefix=ATOMIC target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" target triple = "x86_64-unknown-linux-gnu" diff --git a/lld/test/ELF/lto/save-temps.ll b/lld/test/ELF/lto/save-temps.ll index 0b0f939c53f..f7af99ed40a 100644 --- a/lld/test/ELF/lto/save-temps.ll +++ b/lld/test/ELF/lto/save-temps.ll @@ -5,9 +5,9 @@ ; RUN: llvm-as %p/Inputs/save-temps.ll -o %t2.o ; RUN: ld.lld -shared -m elf_x86_64 %t.o %t2.o -save-temps ; RUN: llvm-nm a.out | FileCheck %s -; RUN: llvm-nm a.out.lto.bc | FileCheck %s +; RUN: llvm-nm a.out.0.0.preopt.bc | FileCheck %s ; RUN: llvm-nm a.out.lto.o | FileCheck %s -; RUN: llvm-dis a.out.lto.bc +; RUN: llvm-dis a.out.0.0.preopt.bc target triple = "x86_64-unknown-linux-gnu" target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" diff --git a/lld/test/ELF/lto/type-merge.ll b/lld/test/ELF/lto/type-merge.ll index 98db53970b0..d6f196d7c3b 100644 --- a/lld/test/ELF/lto/type-merge.ll +++ b/lld/test/ELF/lto/type-merge.ll @@ -2,7 +2,7 @@ ; RUN: llvm-as %s -o %t.o ; RUN: llvm-as %p/Inputs/type-merge.ll -o %t2.o ; RUN: ld.lld -m elf_x86_64 %t.o %t2.o -o %t -shared -save-temps -; RUN: llvm-dis < %t.lto.bc | FileCheck %s +; RUN: llvm-dis < %t.0.0.preopt.bc | FileCheck %s target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" target triple = "x86_64-unknown-linux-gnu" diff --git a/lld/test/ELF/lto/type-merge2.ll b/lld/test/ELF/lto/type-merge2.ll index f0931ddc9d5..45777a7e6a4 100644 --- a/lld/test/ELF/lto/type-merge2.ll +++ b/lld/test/ELF/lto/type-merge2.ll @@ -1,7 +1,7 @@ ; RUN: llvm-as %s -o %t.o ; RUN: llvm-as %p/Inputs/type-merge2.ll -o %t2.o ; RUN: ld.lld -m elf_x86_64 %t.o %t2.o -o %t.so -shared -save-temps -; RUN: llvm-dis %t.so.lto.bc -o - | FileCheck %s +; RUN: llvm-dis %t.so.0.0.preopt.bc -o - | FileCheck %s target triple = "x86_64-unknown-linux-gnu" target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" diff --git a/lld/test/ELF/lto/unnamed-addr-comdat.ll b/lld/test/ELF/lto/unnamed-addr-comdat.ll index c8c36de88d4..ed48f3ba5e0 100644 --- a/lld/test/ELF/lto/unnamed-addr-comdat.ll +++ b/lld/test/ELF/lto/unnamed-addr-comdat.ll @@ -1,6 +1,6 @@ ; RUN: llvm-as %s -o %t.o ; RUN: ld.lld -m elf_x86_64 %t.o %t.o -o %t.so -save-temps -shared -; RUN: llvm-dis %t.so.lto.bc -o - | FileCheck %s +; RUN: llvm-dis %t.so.0.2.internalize.bc -o - | FileCheck %s target triple = "x86_64-unknown-linux-gnu" target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" diff --git a/lld/test/ELF/lto/unnamed-addr-drop.ll b/lld/test/ELF/lto/unnamed-addr-drop.ll index 09bfd110c5a..9142537fe57 100644 --- a/lld/test/ELF/lto/unnamed-addr-drop.ll +++ b/lld/test/ELF/lto/unnamed-addr-drop.ll @@ -1,7 +1,7 @@ ; RUN: llvm-as %s -o %t1.o ; RUN: llvm-as %S/Inputs/unnamed-addr-drop.ll -o %t2.o ; RUN: ld.lld -m elf_x86_64 %t1.o %t2.o -o %t.so -save-temps -shared -; RUN: llvm-dis %t.so.lto.bc -o - | FileCheck %s +; RUN: llvm-dis %t.so.0.2.internalize.bc -o - | FileCheck %s target triple = "x86_64-unknown-linux-gnu" target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" diff --git a/lld/test/ELF/lto/unnamed-addr-lib.ll b/lld/test/ELF/lto/unnamed-addr-lib.ll index fa0fe337bd6..c2bc6016efd 100644 --- a/lld/test/ELF/lto/unnamed-addr-lib.ll +++ b/lld/test/ELF/lto/unnamed-addr-lib.ll @@ -3,7 +3,7 @@ ; RUN: llvm-mc %p/Inputs/unnamed-addr-lib.s -o %t2.o -filetype=obj -triple=x86_64-pc-linux ; RUN: ld.lld %t2.o -shared -o %t2.so ; RUN: ld.lld -m elf_x86_64 %t.o %t2.so -o %t.so -save-temps -shared -; RUN: llvm-dis %t.so.lto.bc -o - | FileCheck %s +; RUN: llvm-dis %t.so.0.2.internalize.bc -o - | FileCheck %s ; This documents a small limitation of lld's internalization logic. We decide ; that bar should be in the symbol table because if it is it will preempt the @@ -11,8 +11,8 @@ ; We could add one extra bit for ODR so that we know that preemption is not ; necessary, but that is probably not worth it. -; CHECK: @foo = internal constant i8 42 -; CHECK: @bar = weak_odr constant i8 42 +; CHECK: @foo = internal unnamed_addr constant i8 42 +; CHECK: @bar = weak_odr unnamed_addr constant i8 42 target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" target triple = "x86_64-unknown-linux-gnu" diff --git a/lld/test/ELF/lto/unnamed-addr.ll b/lld/test/ELF/lto/unnamed-addr.ll index a2c0105fd85..6a6dd73dad8 100644 --- a/lld/test/ELF/lto/unnamed-addr.ll +++ b/lld/test/ELF/lto/unnamed-addr.ll @@ -1,6 +1,6 @@ ; RUN: llvm-as %s -o %t.o ; RUN: ld.lld -m elf_x86_64 %t.o -o %t.so -save-temps -shared -; RUN: llvm-dis %t.so.lto.opt.bc -o - | FileCheck %s +; RUN: llvm-dis %t.so.0.4.opt.bc -o - | FileCheck %s target triple = "x86_64-unknown-linux-gnu" target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" diff --git a/lld/test/ELF/lto/version-script.ll b/lld/test/ELF/lto/version-script.ll index 11a7f073ab5..c43b443ff74 100644 --- a/lld/test/ELF/lto/version-script.ll +++ b/lld/test/ELF/lto/version-script.ll @@ -2,7 +2,7 @@ ; RUN: llvm-as %s -o %t.o ; RUN: echo "VERSION_1.0{ global: foo; local: *; }; VERSION_2.0{ global: bar; local: *; };" > %t.script ; RUN: ld.lld -m elf_x86_64 %t.o -o %t2 -shared --version-script %t.script -save-temps -; RUN: llvm-dis < %t2.lto.bc | FileCheck %s +; RUN: llvm-dis < %t2.0.0.preopt.bc | FileCheck %s ; RUN: llvm-readobj -V -dyn-symbols %t2 | FileCheck --check-prefix=DSO %s target triple = "x86_64-unknown-linux-gnu" |

