@@ -140,9 +140,6 @@ static std::list<SmallString<128>> TempFiles;
140140// / Codegen flags for LTO backend.
141141static codegen::RegisterCodeGenFlags CodeGenFlags;
142142
143- // / Global flag to indicate that the LTO pipeline threw an error.
144- static std::atomic<bool > LTOError;
145-
146143using OffloadingImage = OffloadBinary::OffloadingImage;
147144
148145namespace llvm {
@@ -293,12 +290,10 @@ Expected<std::string> findProgram(StringRef Name, ArrayRef<StringRef> Paths) {
293290 return *Path;
294291}
295292
296- // / We will defer LTO to the target's linker if we are not doing JIT and it is
297- // / supported by the toolchain.
298293bool linkerSupportsLTO (const ArgList &Args) {
299294 llvm::Triple Triple (Args.getLastArgValue (OPT_triple_EQ));
300295 return Triple.isNVPTX () || Triple.isAMDGPU () ||
301- Args.getLastArgValue (OPT_linker_path_EQ).ends_with (" ld. lld" );
296+ Args.getLastArgValue (OPT_linker_path_EQ).ends_with (" lld" );
302297}
303298
304299// / Returns the hashed value for a constant string.
@@ -653,7 +648,6 @@ void diagnosticHandler(const DiagnosticInfo &DI) {
653648 switch (DI.getSeverity ()) {
654649 case DS_Error:
655650 WithColor::error (errs (), LinkerExecutable) << ErrStorage << " \n " ;
656- LTOError = true ;
657651 break ;
658652 case DS_Warning:
659653 WithColor::warning (errs (), LinkerExecutable) << ErrStorage << " \n " ;
@@ -667,334 +661,6 @@ void diagnosticHandler(const DiagnosticInfo &DI) {
667661 }
668662}
669663
670- // Get the list of target features from the input file and unify them such that
671- // if there are multiple +xxx or -xxx features we only keep the last one.
672- std::vector<std::string> getTargetFeatures (ArrayRef<OffloadFile> InputFiles) {
673- SmallVector<StringRef> Features;
674- for (const OffloadFile &File : InputFiles) {
675- for (auto Arg : llvm::split (File.getBinary ()->getString (" feature" ), " ," ))
676- Features.emplace_back (Arg);
677- }
678-
679- // Only add a feature if it hasn't been seen before starting from the end.
680- std::vector<std::string> UnifiedFeatures;
681- DenseSet<StringRef> UsedFeatures;
682- for (StringRef Feature : llvm::reverse (Features)) {
683- if (UsedFeatures.insert (Feature.drop_front ()).second )
684- UnifiedFeatures.push_back (Feature.str ());
685- }
686-
687- return UnifiedFeatures;
688- }
689-
690- template <typename ModuleHook = function_ref<bool (size_t , const Module &)>>
691- std::unique_ptr<lto::LTO> createLTO(
692- const ArgList &Args, const std::vector<std::string> &Features,
693- ModuleHook Hook = [](size_t , const Module &) { return true ; }) {
694- const llvm::Triple Triple (Args.getLastArgValue (OPT_triple_EQ));
695- // We need to remove AMD's target-id from the processor if present.
696- StringRef TargetID = Args.getLastArgValue (OPT_arch_EQ);
697- StringRef Arch = clang::getProcessorFromTargetID (Triple, TargetID);
698- lto::Config Conf;
699- lto::ThinBackend Backend;
700- // TODO: Handle index-only thin-LTO
701- Backend =
702- lto::createInProcessThinBackend (llvm::heavyweight_hardware_concurrency ());
703-
704- Conf.CPU = Arch.str ();
705- Conf.Options = codegen::InitTargetOptionsFromCodeGenFlags (Triple);
706-
707- Conf.RemarksFilename = RemarksFilename;
708- Conf.RemarksPasses = RemarksPasses;
709- Conf.RemarksWithHotness = RemarksWithHotness;
710- Conf.RemarksHotnessThreshold = RemarksHotnessThreshold;
711- Conf.RemarksFormat = RemarksFormat;
712-
713- StringRef OptLevel = Args.getLastArgValue (OPT_opt_level, " O2" );
714- Conf.MAttrs = Features;
715- std::optional<CodeGenOptLevel> CGOptLevelOrNone =
716- CodeGenOpt::parseLevel (OptLevel[1 ]);
717- assert (CGOptLevelOrNone && " Invalid optimization level" );
718- Conf.CGOptLevel = *CGOptLevelOrNone;
719- Conf.OptLevel = OptLevel[1 ] - ' 0' ;
720- Conf.DefaultTriple = Triple.getTriple ();
721-
722- // TODO: Should we complain about combining --opt-level and -passes, as opt
723- // does? That might be too limiting in clang-linker-wrapper, so for now we
724- // just warn in the help entry for -passes that the default<O?> corresponding
725- // to --opt-level=O? should be included there. The problem is that
726- // --opt-level produces effects in clang-linker-wrapper beyond what -passes
727- // appears to be able to achieve, so rejecting the combination of --opt-level
728- // and -passes would apparently make it impossible to combine those effects
729- // with a custom pass pipeline.
730- Conf.OptPipeline = PassPipeline;
731- Conf.PassPlugins = PassPlugins;
732-
733- LTOError = false ;
734- Conf.DiagHandler = diagnosticHandler;
735-
736- Conf.PTO .LoopVectorization = Conf.OptLevel > 1 ;
737- Conf.PTO .SLPVectorization = Conf.OptLevel > 1 ;
738-
739- if (SaveTemps) {
740- std::string TempName = (sys::path::filename (ExecutableName) + " ." +
741- Triple.getTriple () + " ." + TargetID)
742- .str ();
743- Conf.PostInternalizeModuleHook = [=](size_t Task, const Module &M) {
744- std::string File =
745- !Task ? TempName + " .postlink.bc"
746- : TempName + " ." + std::to_string (Task) + " .postlink.bc" ;
747- error_code EC;
748- raw_fd_ostream LinkedBitcode (File, EC, sys::fs::OF_None);
749- if (EC)
750- reportError (errorCodeToError (EC));
751- WriteBitcodeToFile (M, LinkedBitcode);
752- return true ;
753- };
754- Conf.PreCodeGenModuleHook = [=](size_t Task, const Module &M) {
755- std::string File =
756- !Task ? TempName + " .postopt.bc"
757- : TempName + " ." + std::to_string (Task) + " .postopt.bc" ;
758- error_code EC;
759- raw_fd_ostream LinkedBitcode (File, EC, sys::fs::OF_None);
760- if (EC)
761- reportError (errorCodeToError (EC));
762- WriteBitcodeToFile (M, LinkedBitcode);
763- return true ;
764- };
765- }
766- Conf.PostOptModuleHook = Hook;
767- Conf.CGFileType = (Triple.isNVPTX () || SaveTemps)
768- ? CodeGenFileType::AssemblyFile
769- : CodeGenFileType::ObjectFile;
770-
771- // TODO: Handle remark files
772- Conf.HasWholeProgramVisibility = Args.hasArg (OPT_whole_program);
773-
774- return std::make_unique<lto::LTO>(std::move (Conf), Backend);
775- }
776-
777- // Returns true if \p S is valid as a C language identifier and will be given
778- // `__start_` and `__stop_` symbols.
779- bool isValidCIdentifier (StringRef S) {
780- return !S.empty () && (isAlpha (S[0 ]) || S[0 ] == ' _' ) &&
781- llvm::all_of (llvm::drop_begin (S),
782- [](char C) { return C == ' _' || isAlnum (C); });
783- }
784-
785- Error linkBitcodeFiles (SmallVectorImpl<OffloadFile> &InputFiles,
786- SmallVectorImpl<StringRef> &OutputFiles,
787- const ArgList &Args) {
788- llvm::TimeTraceScope TimeScope (" Link bitcode files" );
789- const llvm::Triple Triple (Args.getLastArgValue (OPT_triple_EQ));
790- StringRef Arch = Args.getLastArgValue (OPT_arch_EQ);
791-
792- SmallVector<OffloadFile, 4 > BitcodeInputFiles;
793- DenseSet<StringRef> StrongResolutions;
794- DenseSet<StringRef> UsedInRegularObj;
795- DenseSet<StringRef> UsedInSharedLib;
796- BumpPtrAllocator Alloc;
797- StringSaver Saver (Alloc);
798-
799- // Search for bitcode files in the input and create an LTO input file. If
800- // it is not a bitcode file, scan its symbol table for symbols we need to
801- // save.
802- for (OffloadFile &File : InputFiles) {
803- MemoryBufferRef Buffer = MemoryBufferRef (File.getBinary ()->getImage (), " " );
804-
805- file_magic Type = identify_magic (Buffer.getBuffer ());
806- switch (Type) {
807- case file_magic::bitcode: {
808- Expected<IRSymtabFile> IRSymtabOrErr = readIRSymtab (Buffer);
809- if (!IRSymtabOrErr)
810- return IRSymtabOrErr.takeError ();
811-
812- // Check for any strong resolutions we need to preserve.
813- for (unsigned I = 0 ; I != IRSymtabOrErr->Mods .size (); ++I) {
814- for (const auto &Sym : IRSymtabOrErr->TheReader .module_symbols (I)) {
815- if (!Sym.isFormatSpecific () && Sym.isGlobal () && !Sym.isWeak () &&
816- !Sym.isUndefined ())
817- StrongResolutions.insert (Saver.save (Sym.Name ));
818- }
819- }
820- BitcodeInputFiles.emplace_back (std::move (File));
821- continue ;
822- }
823- case file_magic::elf_relocatable:
824- case file_magic::elf_shared_object: {
825- Expected<std::unique_ptr<ObjectFile>> ObjFile =
826- ObjectFile::createObjectFile (Buffer);
827- if (!ObjFile)
828- continue ;
829-
830- for (SymbolRef Sym : (*ObjFile)->symbols ()) {
831- Expected<StringRef> Name = Sym.getName ();
832- if (!Name)
833- return Name.takeError ();
834-
835- // Record if we've seen these symbols in any object or shared
836- // libraries.
837- if ((*ObjFile)->isRelocatableObject ())
838- UsedInRegularObj.insert (Saver.save (*Name));
839- else
840- UsedInSharedLib.insert (Saver.save (*Name));
841- }
842- continue ;
843- }
844- default :
845- continue ;
846- }
847- }
848-
849- if (BitcodeInputFiles.empty ())
850- return Error::success ();
851-
852- // Remove all the bitcode files that we moved from the original input.
853- llvm::erase_if (InputFiles, [](OffloadFile &F) { return !F.getBinary (); });
854-
855- // LTO Module hook to output bitcode without running the backend.
856- SmallVector<StringRef> BitcodeOutput;
857- auto OutputBitcode = [&](size_t , const Module &M) {
858- auto TempFileOrErr = createOutputFile (sys::path::filename (ExecutableName) +
859- " -jit-" + Triple.getTriple (),
860- " bc" );
861- if (!TempFileOrErr)
862- reportError (TempFileOrErr.takeError ());
863-
864- std::error_code EC;
865- raw_fd_ostream LinkedBitcode (*TempFileOrErr, EC, sys::fs::OF_None);
866- if (EC)
867- reportError (errorCodeToError (EC));
868- WriteBitcodeToFile (M, LinkedBitcode);
869- BitcodeOutput.push_back (*TempFileOrErr);
870- return false ;
871- };
872-
873- // We assume visibility of the whole program if every input file was
874- // bitcode.
875- auto Features = getTargetFeatures (BitcodeInputFiles);
876- auto LTOBackend = Args.hasArg (OPT_embed_bitcode) ||
877- Args.hasArg (OPT_builtin_bitcode_EQ) ||
878- Args.hasArg (OPT_clang_backend)
879- ? createLTO (Args, Features, OutputBitcode)
880- : createLTO (Args, Features);
881-
882- // We need to resolve the symbols so the LTO backend knows which symbols
883- // need to be kept or can be internalized. This is a simplified symbol
884- // resolution scheme to approximate the full resolution a linker would do.
885- uint64_t Idx = 0 ;
886- DenseSet<StringRef> PrevailingSymbols;
887- for (auto &BitcodeInput : BitcodeInputFiles) {
888- // Get a semi-unique buffer identifier for Thin-LTO.
889- StringRef Identifier = Saver.save (
890- std::to_string (Idx++) + " ." +
891- BitcodeInput.getBinary ()->getMemoryBufferRef ().getBufferIdentifier ());
892- MemoryBufferRef Buffer =
893- MemoryBufferRef (BitcodeInput.getBinary ()->getImage (), Identifier);
894- Expected<std::unique_ptr<lto::InputFile>> BitcodeFileOrErr =
895- llvm::lto::InputFile::create (Buffer);
896- if (!BitcodeFileOrErr)
897- return BitcodeFileOrErr.takeError ();
898-
899- // Save the input file and the buffer associated with its memory.
900- const auto Symbols = (*BitcodeFileOrErr)->symbols ();
901- SmallVector<lto::SymbolResolution, 16 > Resolutions (Symbols.size ());
902- size_t Idx = 0 ;
903- for (auto &Sym : Symbols) {
904- lto::SymbolResolution &Res = Resolutions[Idx++];
905-
906- // We will use this as the prevailing symbol definition in LTO unless
907- // it is undefined or another definition has already been used.
908- Res.Prevailing =
909- !Sym.isUndefined () &&
910- !(Sym.isWeak () && StrongResolutions.contains (Sym.getName ())) &&
911- PrevailingSymbols.insert (Saver.save (Sym.getName ())).second ;
912-
913- // We need LTO to preseve the following global symbols:
914- // 1) Symbols used in regular objects.
915- // 2) Sections that will be given a __start/__stop symbol.
916- // 3) Prevailing symbols that are needed visible to external
917- // libraries.
918- Res.VisibleToRegularObj =
919- UsedInRegularObj.contains (Sym.getName ()) ||
920- isValidCIdentifier (Sym.getSectionName ()) ||
921- (Res.Prevailing &&
922- (Sym.getVisibility () != GlobalValue::HiddenVisibility &&
923- !Sym.canBeOmittedFromSymbolTable ()));
924-
925- // Identify symbols that must be exported dynamically and can be
926- // referenced by other files.
927- Res.ExportDynamic =
928- Sym.getVisibility () != GlobalValue::HiddenVisibility &&
929- (UsedInSharedLib.contains (Sym.getName ()) ||
930- !Sym.canBeOmittedFromSymbolTable ());
931-
932- // The final definition will reside in this linkage unit if the symbol
933- // is defined and local to the module. This only checks for bitcode
934- // files, full assertion will require complete symbol resolution.
935- Res.FinalDefinitionInLinkageUnit =
936- Sym.getVisibility () != GlobalValue::DefaultVisibility &&
937- (!Sym.isUndefined () && !Sym.isCommon ());
938-
939- // We do not support linker redefined symbols (e.g. --wrap) for device
940- // image linking, so the symbols will not be changed after LTO.
941- Res.LinkerRedefined = false ;
942- }
943-
944- // Add the bitcode file with its resolved symbols to the LTO job.
945- if (Error Err = LTOBackend->add (std::move (*BitcodeFileOrErr), Resolutions))
946- return Err;
947- }
948-
949- // Run the LTO job to compile the bitcode.
950- size_t MaxTasks = LTOBackend->getMaxTasks ();
951- SmallVector<StringRef> Files (MaxTasks);
952- auto AddStream =
953- [&](size_t Task,
954- const Twine &ModuleName) -> std::unique_ptr<CachedFileStream> {
955- int FD = -1 ;
956- auto &TempFile = Files[Task];
957- StringRef Extension = (Triple.isNVPTX () || SaveTemps) ? " s" : " o" ;
958- std::string TaskStr = Task ? " ." + std::to_string (Task) : " " ;
959- auto TempFileOrErr =
960- createOutputFile (sys::path::filename (ExecutableName) + " ." +
961- Triple.getTriple () + " ." + Arch + TaskStr,
962- Extension);
963- if (!TempFileOrErr)
964- reportError (TempFileOrErr.takeError ());
965- TempFile = *TempFileOrErr;
966- if (std::error_code EC = sys::fs::openFileForWrite (TempFile, FD))
967- reportError (errorCodeToError (EC));
968- return std::make_unique<CachedFileStream>(
969- std::make_unique<llvm::raw_fd_ostream>(FD, true ));
970- };
971-
972- if (Error Err = LTOBackend->run (AddStream))
973- return Err;
974-
975- if (LTOError)
976- return createStringError (" Errors encountered inside the LTO pipeline." );
977-
978- // If we are embedding bitcode we only need the intermediate output.
979- bool SingleOutput = Files.size () == 1 ;
980- if (Args.hasArg (OPT_embed_bitcode)) {
981- if (BitcodeOutput.size () != 1 || !SingleOutput)
982- return createStringError (" Cannot embed bitcode with multiple files." );
983- OutputFiles.push_back (Args.MakeArgString (BitcodeOutput.front ()));
984- return Error::success ();
985- }
986-
987- // Append the new inputs to the device linker input. If the user requested
988- // an internalizing link we need to pass the bitcode to clang.
989- for (StringRef File :
990- Args.hasArg (OPT_clang_backend) || Args.hasArg (OPT_builtin_bitcode_EQ)
991- ? BitcodeOutput
992- : Files)
993- OutputFiles.push_back (File);
994-
995- return Error::success ();
996- }
997-
998664Expected<StringRef> writeOffloadFile (const OffloadFile &File) {
999665 const OffloadBinary &Binary = *File.getBinary ();
1000666
@@ -1325,15 +991,8 @@ Expected<SmallVector<StringRef>> linkAndWrapDeviceFiles(
1325991 if (File.getBinary ()->getOffloadKind () != OFK_None)
1326992 ActiveOffloadKinds.insert (File.getBinary ()->getOffloadKind ());
1327993
1328- // First link and remove all the input files containing bitcode if
1329- // the target linker does not support it natively.
994+ // Write any remaining device inputs to an output file.
1330995 SmallVector<StringRef> InputFiles;
1331- if (!linkerSupportsLTO (LinkerArgs))
1332- if (Error Err = linkBitcodeFiles (Input, InputFiles, LinkerArgs))
1333- return Err;
1334-
1335- // Write any remaining device inputs to an output file for the
1336- // linker.
1337996 for (const OffloadFile &File : Input) {
1338997 auto FileNameOrErr = writeOffloadFile (File);
1339998 if (!FileNameOrErr)
0 commit comments