Index: lld/COFF/Driver.h =================================================================== --- lld/COFF/Driver.h +++ lld/COFF/Driver.h @@ -115,8 +115,6 @@ StringRef findDefaultEntry(); WindowsSubsystem inferSubsystem(); - void invokeMSVC(llvm::opt::InputArgList &Args); - void addBuffer(std::unique_ptr MB, bool WholeArchive); void addArchiveBuffer(MemoryBufferRef MBRef, StringRef SymName, StringRef ParentName); Index: lld/COFF/Driver.cpp =================================================================== --- lld/COFF/Driver.cpp +++ lld/COFF/Driver.cpp @@ -677,131 +677,6 @@ } } -// A helper function for filterBitcodeFiles. -static bool needsRebuilding(MemoryBufferRef MB) { - // The MSVC linker doesn't support thin archives, so if it's a thin - // archive, we always need to rebuild it. - std::unique_ptr File = - CHECK(Archive::create(MB), "Failed to read " + MB.getBufferIdentifier()); - if (File->isThin()) - return true; - - // Returns true if the archive contains at least one bitcode file. - for (MemoryBufferRef Member : getArchiveMembers(File.get())) - if (identify_magic(Member.getBuffer()) == file_magic::bitcode) - return true; - return false; -} - -// Opens a given path as an archive file and removes bitcode files -// from them if exists. This function is to appease the MSVC linker as -// their linker doesn't like archive files containing non-native -// object files. -// -// If a given archive doesn't contain bitcode files, the archive path -// is returned as-is. Otherwise, a new temporary file is created and -// its path is returned. -static Optional -filterBitcodeFiles(StringRef Path, std::vector &TemporaryFiles) { - std::unique_ptr MB = CHECK( - MemoryBuffer::getFile(Path, -1, false, true), "could not open " + Path); - MemoryBufferRef MBRef = MB->getMemBufferRef(); - file_magic Magic = identify_magic(MBRef.getBuffer()); - - if (Magic == file_magic::bitcode) - return None; - if (Magic != file_magic::archive) - return Path.str(); - if (!needsRebuilding(MBRef)) - return Path.str(); - - std::unique_ptr File = - CHECK(Archive::create(MBRef), - MBRef.getBufferIdentifier() + ": failed to parse archive"); - - std::vector New; - for (MemoryBufferRef Member : getArchiveMembers(File.get())) - if (identify_magic(Member.getBuffer()) != file_magic::bitcode) - New.emplace_back(Member); - - if (New.empty()) - return None; - - log("Creating a temporary archive for " + Path + " to remove bitcode files"); - - SmallString<128> S; - if (std::error_code EC = sys::fs::createTemporaryFile( - "lld-" + sys::path::stem(Path), ".lib", S)) - fatal("cannot create a temporary file: " + EC.message()); - std::string Temp = S.str(); - TemporaryFiles.push_back(Temp); - - Error E = - llvm::writeArchive(Temp, New, /*WriteSymtab=*/true, Archive::Kind::K_GNU, - /*Deterministics=*/true, - /*Thin=*/false); - handleAllErrors(std::move(E), [&](const ErrorInfoBase &EI) { - error("failed to create a new archive " + S.str() + ": " + EI.message()); - }); - return Temp; -} - -// Create response file contents and invoke the MSVC linker. -void LinkerDriver::invokeMSVC(opt::InputArgList &Args) { - std::string Rsp = "/nologo\n"; - std::vector Temps; - - // Write out archive members that we used in symbol resolution and pass these - // to MSVC before any archives, so that MSVC uses the same objects to satisfy - // references. - for (ObjFile *Obj : ObjFile::Instances) { - if (Obj->ParentName.empty()) - continue; - SmallString<128> S; - int Fd; - if (auto EC = sys::fs::createTemporaryFile( - "lld-" + sys::path::filename(Obj->ParentName), ".obj", Fd, S)) - fatal("cannot create a temporary file: " + EC.message()); - raw_fd_ostream OS(Fd, /*shouldClose*/ true); - OS << Obj->MB.getBuffer(); - Temps.push_back(S.str()); - Rsp += quote(S) + "\n"; - } - - for (auto *Arg : Args) { - switch (Arg->getOption().getID()) { - case OPT_linkrepro: - case OPT_lldmap: - case OPT_lldmap_file: - case OPT_lldsavetemps: - case OPT_msvclto: - // LLD-specific options are stripped. - break; - case OPT_opt: - if (!StringRef(Arg->getValue()).startswith("lld")) - Rsp += toString(*Arg) + " "; - break; - case OPT_INPUT: { - if (Optional Path = doFindFile(Arg->getValue())) { - if (Optional S = filterBitcodeFiles(*Path, Temps)) - Rsp += quote(*S) + "\n"; - continue; - } - Rsp += quote(Arg->getValue()) + "\n"; - break; - } - default: - Rsp += toString(*Arg) + "\n"; - } - } - - std::vector ObjFiles = Symtab->compileBitcodeFiles(); - runMSVCLinker(Rsp, ObjFiles); - - for (StringRef Path : Temps) - sys::fs::remove(Path); -} - void LinkerDriver::enqueueTask(std::function Task) { TaskQueue.push_back(std::move(Task)); } @@ -1472,13 +1347,6 @@ if (errorCount()) return; - // If /msvclto is given, we use the MSVC linker to link LTO output files. - // This is useful because MSVC link.exe can generate complete PDBs. - if (Args.hasArg(OPT_msvclto)) { - invokeMSVC(Args); - return; - } - // Do LTO by compiling bitcode input files to a set of native COFF files then // link those files. Symtab->addCombinedLTOObjects(); Index: lld/COFF/DriverUtils.cpp =================================================================== --- lld/COFF/DriverUtils.cpp +++ lld/COFF/DriverUtils.cpp @@ -713,26 +713,6 @@ return MBRef; } -// Run MSVC link.exe for given in-memory object files. -// Command line options are copied from those given to LLD. -// This is for the /msvclto option. -void runMSVCLinker(std::string Rsp, ArrayRef Objects) { - // Write the in-memory object files to disk. - std::vector Temps; - for (StringRef S : Objects) { - Temps.emplace_back("lto", "obj", S); - Rsp += quote(Temps.back().Path) + "\n"; - } - - log("link.exe " + Rsp); - - // Run MSVC link.exe. - Temps.emplace_back("lto", "rsp", Rsp); - Executor E("link.exe"); - E.add(Twine("@" + Temps.back().Path)); - E.run(); -} - // Create OptTable // Create prefix string literals used in Options.td Index: lld/COFF/Options.td =================================================================== --- lld/COFF/Options.td +++ lld/COFF/Options.td @@ -145,7 +145,6 @@ def export_all_symbols : F<"export-all-symbols">; def kill_at : F<"kill-at">; def lldmingw : F<"lldmingw">; -def msvclto : F<"msvclto">; def output_def : Joined<["/", "-"], "output-def:">; def pdb_source_path : P<"pdbsourcepath", "Base path used to make relative source file path absolute in PDB">; Index: lld/test/COFF/msvclto-archive.ll =================================================================== --- lld/test/COFF/msvclto-archive.ll +++ /dev/null @@ -1,40 +0,0 @@ -; REQUIRES: x86 -;; Make sure we re-create archive files to strip bitcode files. - -;; Do not create empty archives because the MSVC linker -;; doesn't support them. -; RUN: llvm-as -o %t.obj %s -; RUN: rm -f %t-main1.a -; RUN: llvm-ar cru %t-main1.a %t.obj -; RUN: mkdir -p %t.dir -; RUN: llvm-mc -triple=x86_64-pc-windows-msvc -filetype=obj -o %t.dir/bitcode.obj %p/Inputs/msvclto.s -; RUN: lld-link %t-main1.a %t.dir/bitcode.obj /msvclto /out:%t.exe /opt:lldlto=1 /opt:icf \ -; RUN: /entry:main /verbose 2> %t.log || true -; RUN: FileCheck -check-prefix=BC %s < %t.log -; BC-NOT: Creating a temporary archive for - -; RUN: rm -f %t-main2.a -; RUN: llvm-ar cru %t-main2.a %t.dir/bitcode.obj -; RUN: lld-link %t.obj %t-main2.a /msvclto /out:%t.exe /opt:lldlto=1 /opt:icf \ -; RUN: /entry:main /verbose 2> %t.log || true -; RUN: FileCheck -check-prefix=OBJ %s < %t.log -; OBJ-NOT: Creating a temporary archive - -;; Make sure that we always rebuild thin archives because -;; the MSVC linker doesn't support thin archives. -; RUN: rm -f %t-main3.a -; RUN: llvm-ar cruT %t-main3.a %t.dir/bitcode.obj -; RUN: lld-link %t.obj %t-main3.a /msvclto /out:%t.exe /opt:lldlto=1 /opt:icf \ -; RUN: /entry:main /verbose 2> %t.log || true -; RUN: FileCheck -check-prefix=THIN %s < %t.log -; THIN: Creating a temporary archive - -target datalayout = "e-m:w-i64:64-f80:128-n8:16:32:64-S128" -target triple = "x86_64-pc-windows-msvc" - -declare void @foo() - -define i32 @main() { - call void @foo() - ret i32 0 -} Index: lld/test/COFF/msvclto-order.ll =================================================================== --- lld/test/COFF/msvclto-order.ll +++ /dev/null @@ -1,25 +0,0 @@ -; REQUIRES: x86 -; RUN: opt -thinlto-bc %s -o %t.obj -; RUN: llc -filetype=obj %S/Inputs/msvclto-order-a.ll -o %T/msvclto-order-a.obj -; RUN: llvm-ar crs %T/msvclto-order-a.lib %T/msvclto-order-a.obj -; RUN: llc -filetype=obj %S/Inputs/msvclto-order-b.ll -o %T/msvclto-order-b.obj -; RUN: llvm-ar crs %T/msvclto-order-b.lib %T/msvclto-order-b.obj -; RUN: lld-link /verbose /msvclto /out:%t.exe /entry:main %t.obj \ -; RUN: %T/msvclto-order-a.lib %T/msvclto-order-b.lib 2> %t.log || true -; RUN: FileCheck %s < %t.log - -; CHECK: : link.exe -; CHECK-NOT: .lib{{$}} -; CHECK: lld-msvclto-order-a{{.*}}.obj -; CHECK-NOT: lld-msvclto-order-b{{.*}}.obj -; CHECK: .lib{{$}} - -target datalayout = "e-m:w-i64:64-f80:128-n8:16:32:64-S128" -target triple = "x86_64-pc-windows-msvc" - -declare void @foo() - -define i32 @main() { - call void @foo() - ret i32 0 -} Index: lld/test/COFF/msvclto.ll =================================================================== --- lld/test/COFF/msvclto.ll +++ /dev/null @@ -1,20 +0,0 @@ -; REQUIRES: x86 -; RUN: llvm-as -o %t.obj %s -; RUN: mkdir -p %t.dir -; RUN: llvm-mc -triple=x86_64-pc-windows-msvc -filetype=obj -o %t.dir/bitcode.obj %p/Inputs/msvclto.s -; RUN: lld-link %t.obj %t.dir/bitcode.obj /msvclto /out:%t.exe /opt:lldlto=1 /opt:icf \ -; RUN: /entry:main /verbose 2> %t.log || true -; RUN: FileCheck %s < %t.log - -; CHECK: /opt:icf /entry:main -; CHECK: /verbose - -target datalayout = "e-m:w-i64:64-f80:128-n8:16:32:64-S128" -target triple = "x86_64-pc-windows-msvc" - -declare void @foo() - -define i32 @main() { - call void @foo() - ret i32 0 -}