@@ -147,9 +147,6 @@ static std::list<SmallString<128>> TempFiles;
147147// / Codegen flags for LTO backend.
148148static codegen::RegisterCodeGenFlags CodeGenFlags;
149149
150- // / Global flag to indicate that the LTO pipeline threw an error.
151- static std::atomic<bool > LTOError;
152-
153150static std::optional<llvm::module_split::IRSplitMode> SYCLModuleSplitMode;
154151
155152static bool UseSYCLPostLinkTool;
@@ -1706,338 +1703,6 @@ void diagnosticHandler(const DiagnosticInfo &DI) {
17061703 }
17071704}
17081705
1709- // Get the list of target features from the input file and unify them such that
1710- // if there are multiple +xxx or -xxx features we only keep the last one.
1711- std::vector<std::string> getTargetFeatures (ArrayRef<OffloadFile> InputFiles) {
1712- SmallVector<StringRef> Features;
1713- for (const OffloadFile &File : InputFiles) {
1714- for (auto &Arg : llvm::split (File.getBinary ()->getString (" feature" ), " ," ))
1715- Features.emplace_back (Arg);
1716- }
1717-
1718- // Only add a feature if it hasn't been seen before starting from the end.
1719- std::vector<std::string> UnifiedFeatures;
1720- DenseSet<StringRef> UsedFeatures;
1721- for (StringRef Feature : llvm::reverse (Features)) {
1722- if (UsedFeatures.insert (Feature.drop_front ()).second )
1723- UnifiedFeatures.push_back (Feature.str ());
1724- }
1725-
1726- return UnifiedFeatures;
1727- }
1728-
1729- template <typename ModuleHook = function_ref<bool (size_t , const Module &)>>
1730- std::unique_ptr<lto::LTO> createLTO (
1731- const ArgList &Args, const std::vector<std::string> &Features,
1732- ModuleHook Hook = [](size_t , const Module &) { return true ; }) {
1733- const llvm::Triple Triple (Args.getLastArgValue (OPT_triple_EQ));
1734- // We need to remove AMD's target-id from the processor if present.
1735- StringRef TargetID = Args.getLastArgValue (OPT_arch_EQ);
1736- StringRef Arch = clang::getProcessorFromTargetID (Triple, TargetID);
1737- lto::Config Conf;
1738- lto::ThinBackend Backend;
1739- // TODO: Handle index-only thin-LTO
1740- Backend =
1741- lto::createInProcessThinBackend (llvm::heavyweight_hardware_concurrency ());
1742-
1743- Conf.CPU = Arch.str ();
1744- Conf.Options = codegen::InitTargetOptionsFromCodeGenFlags (Triple);
1745-
1746- Conf.RemarksFilename = RemarksFilename;
1747- Conf.RemarksPasses = RemarksPasses;
1748- Conf.RemarksWithHotness = RemarksWithHotness;
1749- Conf.RemarksHotnessThreshold = RemarksHotnessThreshold;
1750- Conf.RemarksFormat = RemarksFormat;
1751-
1752- StringRef OptLevel = Args.getLastArgValue (OPT_opt_level, " O2" );
1753- Conf.MAttrs = Features;
1754- std::optional<CodeGenOptLevel> CGOptLevelOrNone =
1755- CodeGenOpt::parseLevel (OptLevel[1 ]);
1756- assert (CGOptLevelOrNone && " Invalid optimization level" );
1757- Conf.CGOptLevel = *CGOptLevelOrNone;
1758- Conf.OptLevel = OptLevel[1 ] - ' 0' ;
1759- Conf.DefaultTriple = Triple.getTriple ();
1760-
1761- // TODO: Should we complain about combining --opt-level and -passes, as opt
1762- // does? That might be too limiting in clang-linker-wrapper, so for now we
1763- // just warn in the help entry for -passes that the default<O?> corresponding
1764- // to --opt-level=O? should be included there. The problem is that
1765- // --opt-level produces effects in clang-linker-wrapper beyond what -passes
1766- // appears to be able to achieve, so rejecting the combination of --opt-level
1767- // and -passes would apparently make it impossible to combine those effects
1768- // with a custom pass pipeline.
1769- Conf.OptPipeline = PassPipeline;
1770- Conf.PassPlugins = PassPlugins;
1771-
1772- LTOError = false ;
1773- Conf.DiagHandler = diagnosticHandler;
1774-
1775- Conf.PTO .LoopVectorization = Conf.OptLevel > 1 ;
1776- Conf.PTO .SLPVectorization = Conf.OptLevel > 1 ;
1777-
1778- if (SaveTemps) {
1779- std::string TempName = (sys::path::filename (ExecutableName) + " ." +
1780- Triple.getTriple () + " ." + TargetID)
1781- .str ();
1782- Conf.PostInternalizeModuleHook = [=](size_t Task, const Module &M) {
1783- std::string File =
1784- !Task ? TempName + " .postlink.bc"
1785- : TempName + " ." + std::to_string (Task) + " .postlink.bc" ;
1786- error_code EC;
1787- raw_fd_ostream LinkedBitcode (File, EC, sys::fs::OF_None);
1788- if (EC)
1789- reportError (errorCodeToError (EC));
1790- WriteBitcodeToFile (M, LinkedBitcode);
1791- return true ;
1792- };
1793- Conf.PreCodeGenModuleHook = [=](size_t Task, const Module &M) {
1794- std::string File =
1795- !Task ? TempName + " .postopt.bc"
1796- : TempName + " ." + std::to_string (Task) + " .postopt.bc" ;
1797- error_code EC;
1798- raw_fd_ostream LinkedBitcode (File, EC, sys::fs::OF_None);
1799- if (EC)
1800- reportError (errorCodeToError (EC));
1801- WriteBitcodeToFile (M, LinkedBitcode);
1802- return true ;
1803- };
1804- }
1805- Conf.PostOptModuleHook = Hook;
1806- Conf.CGFileType = (Triple.isNVPTX () || SaveTemps)
1807- ? CodeGenFileType::AssemblyFile
1808- : CodeGenFileType::ObjectFile;
1809-
1810- // TODO: Handle remark files
1811- Conf.HasWholeProgramVisibility = Args.hasArg (OPT_whole_program);
1812-
1813- return std::make_unique<lto::LTO>(std::move (Conf), Backend);
1814- }
1815-
1816- // Returns true if \p S is valid as a C language identifier and will be given
1817- // `__start_` and `__stop_` symbols.
1818- bool isValidCIdentifier (StringRef S) {
1819- return !S.empty () && (isAlpha (S[0 ]) || S[0 ] == ' _' ) &&
1820- llvm::all_of (llvm::drop_begin (S),
1821- [](char C) { return C == ' _' || isAlnum (C); });
1822- }
1823-
1824- Error linkBitcodeFiles (SmallVectorImpl<OffloadFile> &InputFiles,
1825- SmallVectorImpl<StringRef> &OutputFiles,
1826- const ArgList &Args) {
1827- llvm::TimeTraceScope TimeScope (" Link bitcode files" );
1828- const llvm::Triple Triple (Args.getLastArgValue (OPT_triple_EQ));
1829- StringRef Arch = Args.getLastArgValue (OPT_arch_EQ);
1830-
1831- // Early exit for SPIR targets
1832- if (Triple.isSPIROrSPIRV ())
1833- return Error::success ();
1834-
1835- SmallVector<OffloadFile, 4 > BitcodeInputFiles;
1836- DenseSet<StringRef> StrongResolutions;
1837- DenseSet<StringRef> UsedInRegularObj;
1838- DenseSet<StringRef> UsedInSharedLib;
1839- BumpPtrAllocator Alloc;
1840- StringSaver Saver (Alloc);
1841-
1842- // Search for bitcode files in the input and create an LTO input file. If
1843- // it is not a bitcode file, scan its symbol table for symbols we need to
1844- // save.
1845- for (OffloadFile &File : InputFiles) {
1846- MemoryBufferRef Buffer = MemoryBufferRef (File.getBinary ()->getImage (), " " );
1847-
1848- file_magic Type = identify_magic (Buffer.getBuffer ());
1849- switch (Type) {
1850- case file_magic::bitcode: {
1851- Expected<IRSymtabFile> IRSymtabOrErr = readIRSymtab (Buffer);
1852- if (!IRSymtabOrErr)
1853- return IRSymtabOrErr.takeError ();
1854-
1855- // Check for any strong resolutions we need to preserve.
1856- for (unsigned I = 0 ; I != IRSymtabOrErr->Mods .size (); ++I) {
1857- for (const auto &Sym : IRSymtabOrErr->TheReader .module_symbols (I)) {
1858- if (!Sym.isFormatSpecific () && Sym.isGlobal () && !Sym.isWeak () &&
1859- !Sym.isUndefined ())
1860- StrongResolutions.insert (Saver.save (Sym.Name ));
1861- }
1862- }
1863- BitcodeInputFiles.emplace_back (std::move (File));
1864- continue ;
1865- }
1866- case file_magic::elf_relocatable:
1867- case file_magic::elf_shared_object: {
1868- Expected<std::unique_ptr<ObjectFile>> ObjFile =
1869- ObjectFile::createObjectFile (Buffer);
1870- if (!ObjFile)
1871- continue ;
1872-
1873- for (SymbolRef Sym : (*ObjFile)->symbols ()) {
1874- Expected<StringRef> Name = Sym.getName ();
1875- if (!Name)
1876- return Name.takeError ();
1877-
1878- // Record if we've seen these symbols in any object or shared
1879- // libraries.
1880- if ((*ObjFile)->isRelocatableObject ())
1881- UsedInRegularObj.insert (Saver.save (*Name));
1882- else
1883- UsedInSharedLib.insert (Saver.save (*Name));
1884- }
1885- continue ;
1886- }
1887- default :
1888- continue ;
1889- }
1890- }
1891-
1892- if (BitcodeInputFiles.empty ())
1893- return Error::success ();
1894-
1895- // Remove all the bitcode files that we moved from the original input.
1896- llvm::erase_if (InputFiles, [](OffloadFile &F) { return !F.getBinary (); });
1897-
1898- // LTO Module hook to output bitcode without running the backend.
1899- SmallVector<StringRef> BitcodeOutput;
1900- auto OutputBitcode = [&](size_t , const Module &M) {
1901- auto TempFileOrErr = createOutputFile (sys::path::filename (ExecutableName) +
1902- " -jit-" + Triple.getTriple (),
1903- " bc" );
1904- if (!TempFileOrErr)
1905- reportError (TempFileOrErr.takeError ());
1906-
1907- std::error_code EC;
1908- raw_fd_ostream LinkedBitcode (*TempFileOrErr, EC, sys::fs::OF_None);
1909- if (EC)
1910- reportError (errorCodeToError (EC));
1911- WriteBitcodeToFile (M, LinkedBitcode);
1912- BitcodeOutput.push_back (*TempFileOrErr);
1913- return false ;
1914- };
1915-
1916- // We assume visibility of the whole program if every input file was
1917- // bitcode.
1918- auto Features = getTargetFeatures (BitcodeInputFiles);
1919- auto LTOBackend = Args.hasArg (OPT_embed_bitcode) ||
1920- Args.hasArg (OPT_builtin_bitcode_EQ) ||
1921- Args.hasArg (OPT_clang_backend)
1922- ? createLTO (Args, Features, OutputBitcode)
1923- : createLTO (Args, Features);
1924-
1925- // We need to resolve the symbols so the LTO backend knows which symbols
1926- // need to be kept or can be internalized. This is a simplified symbol
1927- // resolution scheme to approximate the full resolution a linker would do.
1928- uint64_t Idx = 0 ;
1929- DenseSet<StringRef> PrevailingSymbols;
1930- for (auto &BitcodeInput : BitcodeInputFiles) {
1931- // Get a semi-unique buffer identifier for Thin-LTO.
1932- StringRef Identifier = Saver.save (
1933- std::to_string (Idx++) + " ." +
1934- BitcodeInput.getBinary ()->getMemoryBufferRef ().getBufferIdentifier ());
1935- MemoryBufferRef Buffer =
1936- MemoryBufferRef (BitcodeInput.getBinary ()->getImage (), Identifier);
1937- Expected<std::unique_ptr<lto::InputFile>> BitcodeFileOrErr =
1938- llvm::lto::InputFile::create (Buffer);
1939- if (!BitcodeFileOrErr)
1940- return BitcodeFileOrErr.takeError ();
1941-
1942- // Save the input file and the buffer associated with its memory.
1943- const auto Symbols = (*BitcodeFileOrErr)->symbols ();
1944- SmallVector<lto::SymbolResolution, 16 > Resolutions (Symbols.size ());
1945- size_t Idx = 0 ;
1946- for (auto &Sym : Symbols) {
1947- lto::SymbolResolution &Res = Resolutions[Idx++];
1948-
1949- // We will use this as the prevailing symbol definition in LTO unless
1950- // it is undefined or another definition has already been used.
1951- Res.Prevailing =
1952- !Sym.isUndefined () &&
1953- !(Sym.isWeak () && StrongResolutions.contains (Sym.getName ())) &&
1954- PrevailingSymbols.insert (Saver.save (Sym.getName ())).second ;
1955-
1956- // We need LTO to preseve the following global symbols:
1957- // 1) Symbols used in regular objects.
1958- // 2) Sections that will be given a __start/__stop symbol.
1959- // 3) Prevailing symbols that are needed visible to external
1960- // libraries.
1961- Res.VisibleToRegularObj =
1962- UsedInRegularObj.contains (Sym.getName ()) ||
1963- isValidCIdentifier (Sym.getSectionName ()) ||
1964- (Res.Prevailing &&
1965- (Sym.getVisibility () != GlobalValue::HiddenVisibility &&
1966- !Sym.canBeOmittedFromSymbolTable ()));
1967-
1968- // Identify symbols that must be exported dynamically and can be
1969- // referenced by other files.
1970- Res.ExportDynamic =
1971- Sym.getVisibility () != GlobalValue::HiddenVisibility &&
1972- (UsedInSharedLib.contains (Sym.getName ()) ||
1973- !Sym.canBeOmittedFromSymbolTable ());
1974-
1975- // The final definition will reside in this linkage unit if the symbol
1976- // is defined and local to the module. This only checks for bitcode
1977- // files, full assertion will require complete symbol resolution.
1978- Res.FinalDefinitionInLinkageUnit =
1979- Sym.getVisibility () != GlobalValue::DefaultVisibility &&
1980- (!Sym.isUndefined () && !Sym.isCommon ());
1981-
1982- // We do not support linker redefined symbols (e.g. --wrap) for device
1983- // image linking, so the symbols will not be changed after LTO.
1984- Res.LinkerRedefined = false ;
1985- }
1986-
1987- // Add the bitcode file with its resolved symbols to the LTO job.
1988- if (Error Err = LTOBackend->add (std::move (*BitcodeFileOrErr), Resolutions))
1989- return Err;
1990- }
1991-
1992- // Run the LTO job to compile the bitcode.
1993- size_t MaxTasks = LTOBackend->getMaxTasks ();
1994- SmallVector<StringRef> Files (MaxTasks);
1995- auto AddStream =
1996- [&](size_t Task,
1997- const Twine &ModuleName) -> std::unique_ptr<CachedFileStream> {
1998- int FD = -1 ;
1999- auto &TempFile = Files[Task];
2000- StringRef Extension = (Triple.isNVPTX () || SaveTemps) ? " s" : " o" ;
2001- std::string TaskStr = Task ? " ." + std::to_string (Task) : " " ;
2002- auto TempFileOrErr =
2003- createOutputFile (sys::path::filename (ExecutableName) + " ." +
2004- Triple.getTriple () + " ." + Arch + TaskStr,
2005- Extension);
2006- if (!TempFileOrErr)
2007- reportError (TempFileOrErr.takeError ());
2008- TempFile = *TempFileOrErr;
2009- if (std::error_code EC = sys::fs::openFileForWrite (TempFile, FD))
2010- reportError (errorCodeToError (EC));
2011- return std::make_unique<CachedFileStream>(
2012- std::make_unique<llvm::raw_fd_ostream>(FD, true ));
2013- };
2014-
2015- if (Error Err = LTOBackend->run (AddStream))
2016- return Err;
2017-
2018- if (LTOError)
2019- return createStringError (" Errors encountered inside the LTO pipeline." );
2020-
2021- // If we are embedding bitcode we only need the intermediate output.
2022- bool SingleOutput = Files.size () == 1 ;
2023- if (Args.hasArg (OPT_embed_bitcode)) {
2024- if (BitcodeOutput.size () != 1 || !SingleOutput)
2025- return createStringError (" Cannot embed bitcode with multiple files." );
2026- OutputFiles.push_back (Args.MakeArgString (BitcodeOutput.front ()));
2027- return Error::success ();
2028- }
2029-
2030- // Append the new inputs to the device linker input. If the user requested
2031- // an internalizing link we need to pass the bitcode to clang.
2032- for (StringRef File :
2033- Args.hasArg (OPT_clang_backend) || Args.hasArg (OPT_builtin_bitcode_EQ)
2034- ? BitcodeOutput
2035- : Files)
2036- OutputFiles.push_back (File);
2037-
2038- return Error::success ();
2039- }
2040-
20411706// Compile the module to an object file using the appropriate target machine for
20421707// the host triple.
20431708Expected<StringRef> compileModule (Module &M, OffloadKind Kind) {
@@ -2370,15 +2035,8 @@ Expected<SmallVector<StringRef>> linkAndWrapDeviceFiles(
23702035 return FileNameOrErr.takeError ();
23712036 InputFiles.emplace_back (*FileNameOrErr);
23722037 }
2038+
23732039 if (HasSYCLOffloadKind) {
2374- SmallVector<StringRef> InputFiles;
2375- // Write device inputs to an output file for the linker.
2376- for (const OffloadFile &File : Input) {
2377- auto FileNameOrErr = writeOffloadFile (File);
2378- if (!FileNameOrErr)
2379- return FileNameOrErr.takeError ();
2380- InputFiles.emplace_back (*FileNameOrErr);
2381- }
23822040 // Link the input device files using the device linker for SYCL
23832041 // offload.
23842042 auto TmpOutputOrErr = sycl::linkDevice (InputFiles, LinkerArgs);
@@ -2458,12 +2116,8 @@ Expected<SmallVector<StringRef>> linkAndWrapDeviceFiles(
24582116 std::scoped_lock Guard (ImageMtx);
24592117 WrappedOutput.push_back (*OutputFile);
24602118 }
2461- if (HasNonSYCLOffloadKinds) {
2462- // First link and remove all the input files containing bitcode.
2463- SmallVector<StringRef> InputFiles;
2464- if (Error Err = linkBitcodeFiles (Input, InputFiles, LinkerArgs))
2465- return Err;
24662119
2120+ if (HasNonSYCLOffloadKinds) {
24672121 // Write any remaining device inputs to an output file for the linker.
24682122 for (const OffloadFile &File : Input) {
24692123 auto FileNameOrErr = writeOffloadFile (File);
@@ -2473,9 +2127,7 @@ Expected<SmallVector<StringRef>> linkAndWrapDeviceFiles(
24732127 }
24742128
24752129 // Link the remaining device files using the device linker.
2476- auto OutputOrErr = !Args.hasArg (OPT_embed_bitcode)
2477- ? linkDevice (InputFiles, LinkerArgs)
2478- : InputFiles.front ();
2130+ auto OutputOrErr = linkDevice (InputFiles, LinkerArgs);
24792131 if (!OutputOrErr)
24802132 return OutputOrErr.takeError ();
24812133 // Store the offloading image for each linked output file.
0 commit comments