From 044eb2f6afba375a914ac9d8024f8f5142bb912e Mon Sep 17 00:00:00 2001 From: Dimitry Andric Date: Mon, 18 Dec 2017 20:10:56 +0000 Subject: Vendor import of llvm trunk r321017: https://llvm.org/svn/llvm-project/llvm/trunk@321017 --- lib/LTO/Caching.cpp | 80 ++++++++++----- lib/LTO/LTO.cpp | 210 +++++++++++++++++++++++++-------------- lib/LTO/LTOBackend.cpp | 31 +++--- lib/LTO/LTOCodeGenerator.cpp | 68 ++++++------- lib/LTO/LTOModule.cpp | 43 ++++---- lib/LTO/ThinLTOCodeGenerator.cpp | 10 +- lib/LTO/UpdateCompilerUsed.cpp | 5 +- 7 files changed, 266 insertions(+), 181 deletions(-) (limited to 'lib/LTO') diff --git a/lib/LTO/Caching.cpp b/lib/LTO/Caching.cpp index e32e46c4c3c8..dd47eb584b7f 100644 --- a/lib/LTO/Caching.cpp +++ b/lib/LTO/Caching.cpp @@ -14,9 +14,9 @@ #include "llvm/LTO/Caching.h" #include "llvm/ADT/StringExtras.h" #include "llvm/Support/Errc.h" -#include "llvm/Support/FileSystem.h" #include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/Path.h" +#include "llvm/Support/Process.h" #include "llvm/Support/raw_ostream.h" using namespace llvm; @@ -36,7 +36,7 @@ Expected lto::localCache(StringRef CacheDirectoryPath, ErrorOr> MBOrErr = MemoryBuffer::getFile(EntryPath); if (MBOrErr) { - AddBuffer(Task, std::move(*MBOrErr)); + AddBuffer(Task, std::move(*MBOrErr), EntryPath); return AddStreamFn(); } @@ -48,54 +48,80 @@ Expected lto::localCache(StringRef CacheDirectoryPath, // file to the cache and calling AddBuffer to add it to the link. struct CacheStream : NativeObjectStream { AddBufferFn AddBuffer; - std::string TempFilename; + sys::fs::TempFile TempFile; std::string EntryPath; unsigned Task; CacheStream(std::unique_ptr OS, AddBufferFn AddBuffer, - std::string TempFilename, std::string EntryPath, + sys::fs::TempFile TempFile, std::string EntryPath, unsigned Task) : NativeObjectStream(std::move(OS)), AddBuffer(std::move(AddBuffer)), - TempFilename(std::move(TempFilename)), - EntryPath(std::move(EntryPath)), Task(Task) {} + TempFile(std::move(TempFile)), EntryPath(std::move(EntryPath)), + Task(Task) {} ~CacheStream() { - // FIXME: This code could race with the cache pruner, but it is unlikely - // that the cache pruner will choose to remove a newly created file. - - // Make sure the file is closed before committing it. + // Make sure the stream is closed before committing it. OS.reset(); - // This is atomic on POSIX systems. - if (auto EC = sys::fs::rename(TempFilename, EntryPath)) - report_fatal_error(Twine("Failed to rename temporary file ") + - TempFilename + ": " + EC.message() + "\n"); + // Open the file first to avoid racing with a cache pruner. ErrorOr> MBOrErr = - MemoryBuffer::getFile(EntryPath); + MemoryBuffer::getOpenFile(TempFile.FD, TempFile.TmpName, + /*FileSize*/ -1, + /*RequiresNullTerminator*/ false); if (!MBOrErr) - report_fatal_error(Twine("Failed to open cache file ") + EntryPath + - ": " + MBOrErr.getError().message() + "\n"); - AddBuffer(Task, std::move(*MBOrErr)); + report_fatal_error(Twine("Failed to open new cache file ") + + TempFile.TmpName + ": " + + MBOrErr.getError().message() + "\n"); + + // On POSIX systems, this will atomically replace the destination if + // it already exists. We try to emulate this on Windows, but this may + // fail with a permission denied error (for example, if the destination + // is currently opened by another process that does not give us the + // sharing permissions we need). Since the existing file should be + // semantically equivalent to the one we are trying to write, we give + // AddBuffer a copy of the bytes we wrote in that case. We do this + // instead of just using the existing file, because the pruner might + // delete the file before we get a chance to use it. + Error E = TempFile.keep(EntryPath); + E = handleErrors(std::move(E), [&](const ECError &E) -> Error { + std::error_code EC = E.convertToErrorCode(); + if (EC != errc::permission_denied) + return errorCodeToError(EC); + + auto MBCopy = MemoryBuffer::getMemBufferCopy((*MBOrErr)->getBuffer(), + EntryPath); + MBOrErr = std::move(MBCopy); + + // FIXME: should we consume the discard error? + consumeError(TempFile.discard()); + + return Error::success(); + }); + + if (E) + report_fatal_error(Twine("Failed to rename temporary file ") + + TempFile.TmpName + " to " + EntryPath + ": " + + toString(std::move(E)) + "\n"); + + AddBuffer(Task, std::move(*MBOrErr), EntryPath); } }; return [=](size_t Task) -> std::unique_ptr { // Write to a temporary to avoid race condition - int TempFD; - SmallString<64> TempFilenameModel, TempFilename; + SmallString<64> TempFilenameModel; sys::path::append(TempFilenameModel, CacheDirectoryPath, "Thin-%%%%%%.tmp.o"); - std::error_code EC = - sys::fs::createUniqueFile(TempFilenameModel, TempFD, TempFilename, - sys::fs::owner_read | sys::fs::owner_write); - if (EC) { - errs() << "Error: " << EC.message() << "\n"; + Expected Temp = sys::fs::TempFile::create( + TempFilenameModel, sys::fs::owner_read | sys::fs::owner_write); + if (!Temp) { + errs() << "Error: " << toString(Temp.takeError()) << "\n"; report_fatal_error("ThinLTO: Can't get a temporary file"); } // This CacheStream will move the temporary file into the cache when done. return llvm::make_unique( - llvm::make_unique(TempFD, /* ShouldClose */ true), - AddBuffer, TempFilename.str(), EntryPath.str(), Task); + llvm::make_unique(Temp->FD, /* ShouldClose */ false), + AddBuffer, std::move(*Temp), EntryPath.str(), Task); }; }; } diff --git a/lib/LTO/LTO.cpp b/lib/LTO/LTO.cpp index 19973946ac5a..64e5186255bd 100644 --- a/lib/LTO/LTO.cpp +++ b/lib/LTO/LTO.cpp @@ -65,7 +65,9 @@ static void computeCacheKey( const FunctionImporter::ExportSetTy &ExportList, const std::map &ResolvedODR, const GVSummaryMapTy &DefinedGlobals, - const TypeIdSummariesByGuidTy &TypeIdSummariesByGuid) { + const TypeIdSummariesByGuidTy &TypeIdSummariesByGuid, + const std::set &CfiFunctionDefs, + const std::set &CfiFunctionDecls) { // Compute the unique hash for this entry. // This is based on the current compiler version, the module itself, the // export list, the hash for every single module in the import list, the @@ -118,7 +120,10 @@ static void computeCacheKey( AddUnsigned(*Conf.RelocModel); else AddUnsigned(-1); - AddUnsigned(Conf.CodeModel); + if (Conf.CodeModel) + AddUnsigned(*Conf.CodeModel); + else + AddUnsigned(-1); AddUnsigned(Conf.CGOptLevel); AddUnsigned(Conf.CGFileType); AddUnsigned(Conf.OptLevel); @@ -155,22 +160,39 @@ static void computeCacheKey( sizeof(GlobalValue::LinkageTypes))); } + // Members of CfiFunctionDefs and CfiFunctionDecls that are referenced or + // defined in this module. + std::set UsedCfiDefs; + std::set UsedCfiDecls; + + // Typeids used in this module. std::set UsedTypeIds; - auto AddUsedTypeIds = [&](GlobalValueSummary *GS) { - auto *FS = dyn_cast_or_null(GS); - if (!FS) - return; - for (auto &TT : FS->type_tests()) - UsedTypeIds.insert(TT); - for (auto &TT : FS->type_test_assume_vcalls()) - UsedTypeIds.insert(TT.GUID); - for (auto &TT : FS->type_checked_load_vcalls()) - UsedTypeIds.insert(TT.GUID); - for (auto &TT : FS->type_test_assume_const_vcalls()) - UsedTypeIds.insert(TT.VFunc.GUID); - for (auto &TT : FS->type_checked_load_const_vcalls()) - UsedTypeIds.insert(TT.VFunc.GUID); + auto AddUsedCfiGlobal = [&](GlobalValue::GUID ValueGUID) { + if (CfiFunctionDefs.count(ValueGUID)) + UsedCfiDefs.insert(ValueGUID); + if (CfiFunctionDecls.count(ValueGUID)) + UsedCfiDecls.insert(ValueGUID); + }; + + auto AddUsedThings = [&](GlobalValueSummary *GS) { + if (!GS) return; + for (const ValueInfo &VI : GS->refs()) + AddUsedCfiGlobal(VI.getGUID()); + if (auto *FS = dyn_cast(GS)) { + for (auto &TT : FS->type_tests()) + UsedTypeIds.insert(TT); + for (auto &TT : FS->type_test_assume_vcalls()) + UsedTypeIds.insert(TT.GUID); + for (auto &TT : FS->type_checked_load_vcalls()) + UsedTypeIds.insert(TT.GUID); + for (auto &TT : FS->type_test_assume_const_vcalls()) + UsedTypeIds.insert(TT.VFunc.GUID); + for (auto &TT : FS->type_checked_load_const_vcalls()) + UsedTypeIds.insert(TT.VFunc.GUID); + for (auto &ET : FS->calls()) + AddUsedCfiGlobal(ET.first.getGUID()); + } }; // Include the hash for the linkage type to reflect internalization and weak @@ -179,14 +201,15 @@ static void computeCacheKey( GlobalValue::LinkageTypes Linkage = GS.second->linkage(); Hasher.update( ArrayRef((const uint8_t *)&Linkage, sizeof(Linkage))); - AddUsedTypeIds(GS.second); + AddUsedCfiGlobal(GS.first); + AddUsedThings(GS.second); } // Imported functions may introduce new uses of type identifier resolutions, // so we need to collect their used resolutions as well. for (auto &ImpM : ImportList) for (auto &ImpF : ImpM.second) - AddUsedTypeIds(Index.findSummaryInModule(ImpF.first, ImpM.first())); + AddUsedThings(Index.findSummaryInModule(ImpF.first, ImpM.first())); auto AddTypeIdSummary = [&](StringRef TId, const TypeIdSummary &S) { AddString(TId); @@ -194,6 +217,11 @@ static void computeCacheKey( AddUnsigned(S.TTRes.TheKind); AddUnsigned(S.TTRes.SizeM1BitWidth); + AddUint64(S.TTRes.AlignLog2); + AddUint64(S.TTRes.SizeM1); + AddUint64(S.TTRes.BitMask); + AddUint64(S.TTRes.InlineBits); + AddUint64(S.WPDRes.size()); for (auto &WPD : S.WPDRes) { AddUnsigned(WPD.first); @@ -207,6 +235,8 @@ static void computeCacheKey( AddUint64(Arg); AddUnsigned(ByArg.second.TheKind); AddUint64(ByArg.second.Info); + AddUnsigned(ByArg.second.Byte); + AddUnsigned(ByArg.second.Bit); } } }; @@ -219,6 +249,14 @@ static void computeCacheKey( AddTypeIdSummary(Summary->first, Summary->second); } + AddUnsigned(UsedCfiDefs.size()); + for (auto &V : UsedCfiDefs) + AddUint64(V); + + AddUnsigned(UsedCfiDecls.size()); + for (auto &V : UsedCfiDecls) + AddUint64(V); + if (!Conf.SampleProfile.empty()) { auto FileOrErr = MemoryBuffer::getFile(Conf.SampleProfile); if (FileOrErr) @@ -347,7 +385,8 @@ StringRef InputFile::getName() const { LTO::RegularLTOState::RegularLTOState(unsigned ParallelCodeGenParallelismLevel, Config &Conf) : ParallelCodeGenParallelismLevel(ParallelCodeGenParallelismLevel), - Ctx(Conf) {} + Ctx(Conf), CombinedModule(llvm::make_unique("ld-temp.o", Ctx)), + Mover(llvm::make_unique(*CombinedModule)) {} LTO::ThinLTOState::ThinLTOState(ThinBackend Backend) : Backend(Backend) { if (!Backend) @@ -378,8 +417,11 @@ void LTO::addModuleToGlobalRes(ArrayRef Syms, auto &GlobalRes = GlobalResolutions[Sym.getName()]; GlobalRes.UnnamedAddr &= Sym.isUnnamedAddr(); - if (Res.Prevailing) + if (Res.Prevailing) { + assert(GlobalRes.IRName.empty() && + "Multiple prevailing defs are not allowed"); GlobalRes.IRName = Sym.getIRName(); + } // Set the partition to external if we know it is re-defined by the linker // with -defsym or -wrap options, used elsewhere, e.g. it is visible to a @@ -431,6 +473,9 @@ Error LTO::add(std::unique_ptr Input, if (Conf.ResolutionFile) writeToResolutionFile(*Conf.ResolutionFile, Input.get(), Res); + if (RegularLTO.CombinedModule->getTargetTriple().empty()) + RegularLTO.CombinedModule->setTargetTriple(Input->getTargetTriple()); + const SymbolResolution *ResI = Res.begin(); for (unsigned I = 0; I != Input->Mods.size(); ++I) if (Error Err = addModule(*Input, I, ResI, Res.end())) @@ -592,6 +637,9 @@ LTO::addRegularLTO(BitcodeModule BM, ArrayRef Syms, NonPrevailingComdats.insert(GV->getComdat()); cast(GV)->setComdat(nullptr); } + + // Set the 'local' flag based on the linker resolution for this symbol. + GV->setDSOLocal(Res.FinalDefinitionInLinkageUnit); } // Common resolution: collect the maximum size/alignment over all commons. // We also record if we see an instance of a common as prevailing, so that @@ -605,7 +653,6 @@ LTO::addRegularLTO(BitcodeModule BM, ArrayRef Syms, CommonRes.Prevailing |= Res.Prevailing; } - // FIXME: use proposed local attribute for FinalDefinitionInLinkageUnit. } if (!M.getComdatSymbolTable().empty()) for (GlobalValue &GV : M.global_values()) @@ -616,12 +663,6 @@ LTO::addRegularLTO(BitcodeModule BM, ArrayRef Syms, Error LTO::linkRegularLTO(RegularLTOState::AddedModule Mod, bool LivenessFromIndex) { - if (!RegularLTO.CombinedModule) { - RegularLTO.CombinedModule = - llvm::make_unique("ld-temp.o", RegularLTO.Ctx); - RegularLTO.Mover = llvm::make_unique(*RegularLTO.CombinedModule); - } - std::vector Keep; for (GlobalValue *GV : Mod.Keep) { if (LivenessFromIndex && !ThinLTO.CombinedIndex.isGUIDLive(GV->getGUID())) @@ -660,10 +701,10 @@ Error LTO::addThinLTO(BitcodeModule BM, ArrayRef Syms, assert(ResI != ResE); SymbolResolution Res = *ResI++; - if (Res.Prevailing) { - if (!Sym.getIRName().empty()) { - auto GUID = GlobalValue::getGUID(GlobalValue::getGlobalIdentifier( - Sym.getIRName(), GlobalValue::ExternalLinkage, "")); + if (!Sym.getIRName().empty()) { + auto GUID = GlobalValue::getGUID(GlobalValue::getGlobalIdentifier( + Sym.getIRName(), GlobalValue::ExternalLinkage, "")); + if (Res.Prevailing) { ThinLTO.PrevailingModuleForGUID[GUID] = BM.getModuleIdentifier(); // For linker redefined symbols (via --wrap or --defsym) we want to @@ -675,6 +716,15 @@ Error LTO::addThinLTO(BitcodeModule BM, ArrayRef Syms, GUID, BM.getModuleIdentifier())) S->setLinkage(GlobalValue::WeakAnyLinkage); } + + // If the linker resolved the symbol to a local definition then mark it + // as local in the summary for the module we are adding. + if (Res.FinalDefinitionInLinkageUnit) { + if (auto S = ThinLTO.CombinedIndex.findSummaryInModule( + GUID, BM.getModuleIdentifier())) { + S->setDSOLocal(true); + } + } } } @@ -705,16 +755,9 @@ Error LTO::run(AddStreamFn AddStream, NativeObjectCache Cache) { computeDeadSymbols(ThinLTO.CombinedIndex, GUIDPreservedSymbols); - // Save the status of having a regularLTO combined module, as - // this is needed for generating the ThinLTO Task ID, and - // the CombinedModule will be moved at the end of runRegularLTO. - bool HasRegularLTO = RegularLTO.CombinedModule != nullptr || - !RegularLTO.ModsWithSummaries.empty(); - // Invoke regular LTO if there was a regular LTO module to start with. - if (HasRegularLTO) - if (auto E = runRegularLTO(AddStream)) - return E; - return runThinLTO(AddStream, Cache, HasRegularLTO); + if (auto E = runRegularLTO(AddStream)) + return E; + return runThinLTO(AddStream, Cache); } Error LTO::runRegularLTO(AddStreamFn AddStream) { @@ -812,6 +855,8 @@ class InProcessThinBackend : public ThinBackendProc { AddStreamFn AddStream; NativeObjectCache Cache; TypeIdSummariesByGuidTy TypeIdSummariesByGuid; + std::set CfiFunctionDefs; + std::set CfiFunctionDecls; Optional Err; std::mutex ErrMu; @@ -831,6 +876,12 @@ public: // each function without needing to compute GUIDs in each backend. for (auto &TId : CombinedIndex.typeIds()) TypeIdSummariesByGuid[GlobalValue::getGUID(TId.first)].push_back(&TId); + for (auto &Name : CombinedIndex.cfiFunctionDefs()) + CfiFunctionDefs.insert( + GlobalValue::getGUID(GlobalValue::dropLLVMManglingEscape(Name))); + for (auto &Name : CombinedIndex.cfiFunctionDecls()) + CfiFunctionDecls.insert( + GlobalValue::getGUID(GlobalValue::dropLLVMManglingEscape(Name))); } Error runThinLTOBackendThread( @@ -864,7 +915,8 @@ public: SmallString<40> Key; // The module may be cached, this helps handling it. computeCacheKey(Key, Conf, CombinedIndex, ModuleID, ImportList, ExportList, - ResolvedODR, DefinedGlobals, TypeIdSummariesByGuid); + ResolvedODR, DefinedGlobals, TypeIdSummariesByGuid, + CfiFunctionDefs, CfiFunctionDecls); if (AddStreamFn CacheAddStream = Cache(Task, Key)) return RunThinBackend(CacheAddStream); @@ -1020,8 +1072,7 @@ ThinBackend lto::createWriteIndexesThinBackend(std::string OldPrefix, }; } -Error LTO::runThinLTO(AddStreamFn AddStream, NativeObjectCache Cache, - bool HasRegularLTO) { +Error LTO::runThinLTO(AddStreamFn AddStream, NativeObjectCache Cache) { if (ThinLTO.ModuleMap.empty()) return Error::success(); @@ -1051,36 +1102,45 @@ Error LTO::runThinLTO(AddStreamFn AddStream, NativeObjectCache Cache, ThinLTO.ModuleMap.size()); StringMap> ResolvedODR; - if (Conf.OptLevel > 0) { + if (Conf.OptLevel > 0) ComputeCrossModuleImport(ThinLTO.CombinedIndex, ModuleToDefinedGVSummaries, ImportLists, ExportLists); - std::set ExportedGUIDs; - for (auto &Res : GlobalResolutions) { - // First check if the symbol was flagged as having external references. - if (Res.second.Partition != GlobalResolution::External) - continue; - // IRName will be defined if we have seen the prevailing copy of - // this value. If not, no need to mark as exported from a ThinLTO - // partition (and we can't get the GUID). - if (Res.second.IRName.empty()) - continue; - auto GUID = GlobalValue::getGUID( - GlobalValue::dropLLVMManglingEscape(Res.second.IRName)); - // Mark exported unless index-based analysis determined it to be dead. - if (ThinLTO.CombinedIndex.isGUIDLive(GUID)) - ExportedGUIDs.insert(GUID); - } - - auto isExported = [&](StringRef ModuleIdentifier, GlobalValue::GUID GUID) { - const auto &ExportList = ExportLists.find(ModuleIdentifier); - return (ExportList != ExportLists.end() && - ExportList->second.count(GUID)) || - ExportedGUIDs.count(GUID); - }; - thinLTOInternalizeAndPromoteInIndex(ThinLTO.CombinedIndex, isExported); + // Figure out which symbols need to be internalized. This also needs to happen + // at -O0 because summary-based DCE is implemented using internalization, and + // we must apply DCE consistently with the full LTO module in order to avoid + // undefined references during the final link. + std::set ExportedGUIDs; + for (auto &Res : GlobalResolutions) { + // First check if the symbol was flagged as having external references. + if (Res.second.Partition != GlobalResolution::External) + continue; + // IRName will be defined if we have seen the prevailing copy of + // this value. If not, no need to mark as exported from a ThinLTO + // partition (and we can't get the GUID). + if (Res.second.IRName.empty()) + continue; + auto GUID = GlobalValue::getGUID( + GlobalValue::dropLLVMManglingEscape(Res.second.IRName)); + // Mark exported unless index-based analysis determined it to be dead. + if (ThinLTO.CombinedIndex.isGUIDLive(GUID)) + ExportedGUIDs.insert(GUID); } + // Any functions referenced by the jump table in the regular LTO object must + // be exported. + for (auto &Def : ThinLTO.CombinedIndex.cfiFunctionDefs()) + ExportedGUIDs.insert( + GlobalValue::getGUID(GlobalValue::dropLLVMManglingEscape(Def))); + + auto isExported = [&](StringRef ModuleIdentifier, GlobalValue::GUID GUID) { + const auto &ExportList = ExportLists.find(ModuleIdentifier); + return (ExportList != ExportLists.end() && + ExportList->second.count(GUID)) || + ExportedGUIDs.count(GUID); + }; + thinLTOInternalizeAndPromoteInIndex(ThinLTO.CombinedIndex, isExported); + auto isPrevailing = [&](GlobalValue::GUID GUID, const GlobalValueSummary *S) { return ThinLTO.PrevailingModuleForGUID[GUID] == S->modulePath(); @@ -1097,11 +1157,9 @@ Error LTO::runThinLTO(AddStreamFn AddStream, NativeObjectCache Cache, ThinLTO.Backend(Conf, ThinLTO.CombinedIndex, ModuleToDefinedGVSummaries, AddStream, Cache); - // Task numbers start at ParallelCodeGenParallelismLevel if an LTO - // module is present, as tasks 0 through ParallelCodeGenParallelismLevel-1 - // are reserved for parallel code generation partitions. - unsigned Task = - HasRegularLTO ? RegularLTO.ParallelCodeGenParallelismLevel : 0; + // Tasks 0 through ParallelCodeGenParallelismLevel-1 are reserved for combined + // module and parallel code generation partitions. + unsigned Task = RegularLTO.ParallelCodeGenParallelismLevel; for (auto &Mod : ThinLTO.ModuleMap) { if (Error E = BackendProc->start(Task, Mod.second, ImportLists[Mod.first], ExportLists[Mod.first], @@ -1113,7 +1171,7 @@ Error LTO::runThinLTO(AddStreamFn AddStream, NativeObjectCache Cache, return BackendProc->wait(); } -Expected> +Expected> lto::setupOptimizationRemarks(LLVMContext &Context, StringRef LTORemarksFilename, bool LTOPassRemarksWithHotness, int Count) { @@ -1126,7 +1184,7 @@ lto::setupOptimizationRemarks(LLVMContext &Context, std::error_code EC; auto DiagnosticFile = - llvm::make_unique(Filename, EC, sys::fs::F_None); + llvm::make_unique(Filename, EC, sys::fs::F_None); if (EC) return errorCodeToError(EC); Context.setDiagnosticsOutputFile( diff --git a/lib/LTO/LTOBackend.cpp b/lib/LTO/LTOBackend.cpp index 3f72e446cdf2..501d6284117b 100644 --- a/lib/LTO/LTOBackend.cpp +++ b/lib/LTO/LTOBackend.cpp @@ -131,18 +131,23 @@ createTargetMachine(Config &Conf, const Target *TheTarget, Module &M) { Conf.CodeModel, Conf.CGOptLevel)); } -static void runNewPMPasses(Module &Mod, TargetMachine *TM, unsigned OptLevel, - bool IsThinLTO) { - PassBuilder PB(TM); +static void runNewPMPasses(Config &Conf, Module &Mod, TargetMachine *TM, + unsigned OptLevel, bool IsThinLTO) { + Optional PGOOpt; + if (!Conf.SampleProfile.empty()) + PGOOpt = PGOOptions("", "", Conf.SampleProfile, false, true); + + PassBuilder PB(TM, PGOOpt); AAManager AA; // Parse a custom AA pipeline if asked to. - assert(PB.parseAAPipeline(AA, "default")); + if (!PB.parseAAPipeline(AA, "default")) + report_fatal_error("Error parsing default AA pipeline"); - LoopAnalysisManager LAM; - FunctionAnalysisManager FAM; - CGSCCAnalysisManager CGAM; - ModuleAnalysisManager MAM; + LoopAnalysisManager LAM(Conf.DebugPassManager); + FunctionAnalysisManager FAM(Conf.DebugPassManager); + CGSCCAnalysisManager CGAM(Conf.DebugPassManager); + ModuleAnalysisManager MAM(Conf.DebugPassManager); // Register the AA manager first so that our version is the one used. FAM.registerPass([&] { return std::move(AA); }); @@ -154,7 +159,7 @@ static void runNewPMPasses(Module &Mod, TargetMachine *TM, unsigned OptLevel, PB.registerLoopAnalyses(LAM); PB.crossRegisterProxies(LAM, FAM, CGAM, MAM); - ModulePassManager MPM; + ModulePassManager MPM(Conf.DebugPassManager); // FIXME (davide): verify the input. PassBuilder::OptimizationLevel OL; @@ -177,9 +182,9 @@ static void runNewPMPasses(Module &Mod, TargetMachine *TM, unsigned OptLevel, } if (IsThinLTO) - MPM = PB.buildThinLTODefaultPipeline(OL, false /* DebugLogging */); + MPM = PB.buildThinLTODefaultPipeline(OL, Conf.DebugPassManager); else - MPM = PB.buildLTODefaultPipeline(OL, false /* DebugLogging */); + MPM = PB.buildLTODefaultPipeline(OL, Conf.DebugPassManager); MPM.run(Mod, MAM); // FIXME (davide): verify the output. @@ -262,7 +267,7 @@ bool opt(Config &Conf, TargetMachine *TM, unsigned Task, Module &Mod, runNewPMCustomPasses(Mod, TM, Conf.OptPipeline, Conf.AAPipeline, Conf.DisableVerify); else if (Conf.UseNewPM) - runNewPMPasses(Mod, TM, Conf.OptLevel, IsThinLTO); + runNewPMPasses(Conf, Mod, TM, Conf.OptLevel, IsThinLTO); else runOldPMPasses(Conf, Mod, TM, IsThinLTO, ExportSummary, ImportSummary); return !Conf.PostOptModuleHook || Conf.PostOptModuleHook(Task, Mod); @@ -344,7 +349,7 @@ Expected initAndLookupTarget(Config &C, Module &Mod) { } static void -finalizeOptimizationRemarks(std::unique_ptr DiagOutputFile) { +finalizeOptimizationRemarks(std::unique_ptr DiagOutputFile) { // Make sure we flush the diagnostic remarks file in case the linker doesn't // call the global destructors before exiting. if (!DiagOutputFile) diff --git a/lib/LTO/LTOCodeGenerator.cpp b/lib/LTO/LTOCodeGenerator.cpp index 6a275560dc92..c7306df95d3d 100644 --- a/lib/LTO/LTOCodeGenerator.cpp +++ b/lib/LTO/LTOCodeGenerator.cpp @@ -21,7 +21,7 @@ #include "llvm/Analysis/TargetTransformInfo.h" #include "llvm/Bitcode/BitcodeWriter.h" #include "llvm/CodeGen/ParallelCG.h" -#include "llvm/CodeGen/RuntimeLibcalls.h" +#include "llvm/CodeGen/TargetSubtargetInfo.h" #include "llvm/Config/config.h" #include "llvm/IR/Constants.h" #include "llvm/IR/DataLayout.h" @@ -52,10 +52,7 @@ #include "llvm/Support/ToolOutputFile.h" #include "llvm/Support/YAMLTraits.h" #include "llvm/Support/raw_ostream.h" -#include "llvm/Target/TargetLowering.h" #include "llvm/Target/TargetOptions.h" -#include "llvm/Target/TargetRegisterInfo.h" -#include "llvm/Target/TargetSubtargetInfo.h" #include "llvm/Transforms/IPO.h" #include "llvm/Transforms/IPO/Internalize.h" #include "llvm/Transforms/IPO/PassManagerBuilder.h" @@ -83,16 +80,6 @@ cl::opt LTODiscardValueNames( #endif cl::Hidden); -cl::opt LTOStripInvalidDebugInfo( - "lto-strip-invalid-debug-info", - cl::desc("Strip invalid debug info metadata during LTO instead of aborting."), -#ifdef NDEBUG - cl::init(true), -#else - cl::init(false), -#endif - cl::Hidden); - cl::opt LTORemarksFilename("lto-pass-remarks-output", cl::desc("Output filename for pass remarks"), @@ -141,7 +128,6 @@ void LTOCodeGenerator::initializeLTOPasses() { initializeMemCpyOptLegacyPassPass(R); initializeDCELegacyPassPass(R); initializeCFGSimplifyPassPass(R); - initializeLateCFGSimplifyPassPass(R); } void LTOCodeGenerator::setAsmUndefinedRefs(LTOModule *Mod) { @@ -225,10 +211,10 @@ bool LTOCodeGenerator::writeMergedModules(StringRef Path) { // create output file std::error_code EC; - tool_output_file Out(Path, EC, sys::fs::F_None); + ToolOutputFile Out(Path, EC, sys::fs::F_None); if (EC) { std::string ErrMsg = "could not open bitcode file for writing: "; - ErrMsg += Path; + ErrMsg += Path.str() + ": " + EC.message(); emitError(ErrMsg); return false; } @@ -239,7 +225,7 @@ bool LTOCodeGenerator::writeMergedModules(StringRef Path) { if (Out.os().has_error()) { std::string ErrMsg = "could not write bitcode file: "; - ErrMsg += Path; + ErrMsg += Path.str() + ": " + Out.os().error().message(); emitError(ErrMsg); Out.os().clear_error(); return false; @@ -265,12 +251,14 @@ bool LTOCodeGenerator::compileOptimizedToFile(const char **Name) { } // generate object file - tool_output_file objFile(Filename, FD); + ToolOutputFile objFile(Filename, FD); bool genResult = compileOptimized(&objFile.os()); objFile.os().close(); if (objFile.os().has_error()) { - emitError((Twine("could not write object file: ") + Filename).str()); + emitError((Twine("could not write object file: ") + Filename + ": " + + objFile.os().error().message()) + .str()); objFile.os().clear_error(); sys::fs::remove(Twine(Filename)); return false; @@ -368,9 +356,8 @@ bool LTOCodeGenerator::determineTarget() { } std::unique_ptr LTOCodeGenerator::createTargetMachine() { - return std::unique_ptr( - MArch->createTargetMachine(TripleStr, MCpu, FeatureStr, Options, - RelocModel, CodeModel::Default, CGOptLevel)); + return std::unique_ptr(MArch->createTargetMachine( + TripleStr, MCpu, FeatureStr, Options, RelocModel, None, CGOptLevel)); } // If a linkonce global is present in the MustPreserveSymbols, we need to make @@ -482,11 +469,9 @@ void LTOCodeGenerator::restoreLinkageForExternals() { GV.setLinkage(I->second); }; - std::for_each(MergedModule->begin(), MergedModule->end(), externalize); - std::for_each(MergedModule->global_begin(), MergedModule->global_end(), - externalize); - std::for_each(MergedModule->alias_begin(), MergedModule->alias_end(), - externalize); + llvm::for_each(MergedModule->functions(), externalize); + llvm::for_each(MergedModule->globals(), externalize); + llvm::for_each(MergedModule->aliases(), externalize); } void LTOCodeGenerator::verifyMergedModuleOnce() { @@ -496,8 +481,7 @@ void LTOCodeGenerator::verifyMergedModuleOnce() { HasVerifiedInput = true; bool BrokenDebugInfo = false; - if (verifyModule(*MergedModule, &dbgs(), - LTOStripInvalidDebugInfo ? &BrokenDebugInfo : nullptr)) + if (verifyModule(*MergedModule, &dbgs(), &BrokenDebugInfo)) report_fatal_error("Broken module found, compilation aborted!"); if (BrokenDebugInfo) { emitWarning("Invalid debug info found, debug info will be stripped"); @@ -623,12 +607,8 @@ void LTOCodeGenerator::parseCodeGenDebugOptions() { } } -void LTOCodeGenerator::DiagnosticHandler(const DiagnosticInfo &DI, - void *Context) { - ((LTOCodeGenerator *)Context)->DiagnosticHandler2(DI); -} -void LTOCodeGenerator::DiagnosticHandler2(const DiagnosticInfo &DI) { +void LTOCodeGenerator::DiagnosticHandler(const DiagnosticInfo &DI) { // Map the LLVM internal diagnostic severity to the LTO diagnostic severity. lto_codegen_diagnostic_severity_t Severity; switch (DI.getSeverity()) { @@ -658,17 +638,29 @@ void LTOCodeGenerator::DiagnosticHandler2(const DiagnosticInfo &DI) { (*DiagHandler)(Severity, MsgStorage.c_str(), DiagContext); } +namespace { +struct LTODiagnosticHandler : public DiagnosticHandler { + LTOCodeGenerator *CodeGenerator; + LTODiagnosticHandler(LTOCodeGenerator *CodeGenPtr) + : CodeGenerator(CodeGenPtr) {} + bool handleDiagnostics(const DiagnosticInfo &DI) override { + CodeGenerator->DiagnosticHandler(DI); + return true; + } +}; +} + void LTOCodeGenerator::setDiagnosticHandler(lto_diagnostic_handler_t DiagHandler, void *Ctxt) { this->DiagHandler = DiagHandler; this->DiagContext = Ctxt; if (!DiagHandler) - return Context.setDiagnosticHandler(nullptr, nullptr); + return Context.setDiagnosticHandler(nullptr); // Register the LTOCodeGenerator stub in the LLVMContext to forward the // diagnostic to the external DiagHandler. - Context.setDiagnosticHandler(LTOCodeGenerator::DiagnosticHandler, this, - /* RespectFilters */ true); + Context.setDiagnosticHandler(llvm::make_unique(this), + true); } namespace { diff --git a/lib/LTO/LTOModule.cpp b/lib/LTO/LTOModule.cpp index 3cc8b7d0e770..51b4f225939f 100644 --- a/lib/LTO/LTOModule.cpp +++ b/lib/LTO/LTOModule.cpp @@ -16,17 +16,16 @@ #include "llvm/ADT/Triple.h" #include "llvm/Analysis/ObjectUtils.h" #include "llvm/Bitcode/BitcodeReader.h" +#include "llvm/CodeGen/TargetLoweringObjectFile.h" +#include "llvm/CodeGen/TargetSubtargetInfo.h" #include "llvm/IR/Constants.h" -#include "llvm/IR/DiagnosticPrinter.h" #include "llvm/IR/LLVMContext.h" #include "llvm/IR/Mangler.h" #include "llvm/IR/Metadata.h" #include "llvm/IR/Module.h" #include "llvm/MC/MCExpr.h" #include "llvm/MC/MCInst.h" -#include "llvm/MC/MCInstrInfo.h" #include "llvm/MC/MCParser/MCAsmParser.h" -#include "llvm/MC/MCParser/MCTargetAsmParser.h" #include "llvm/MC/MCSection.h" #include "llvm/MC/MCSubtargetInfo.h" #include "llvm/MC/MCSymbol.h" @@ -40,10 +39,6 @@ #include "llvm/Support/SourceMgr.h" #include "llvm/Support/TargetRegistry.h" #include "llvm/Support/TargetSelect.h" -#include "llvm/Target/TargetLowering.h" -#include "llvm/Target/TargetLoweringObjectFile.h" -#include "llvm/Target/TargetRegisterInfo.h" -#include "llvm/Target/TargetSubtargetInfo.h" #include "llvm/Transforms/Utils/GlobalStatus.h" #include using namespace llvm; @@ -60,9 +55,13 @@ LTOModule::~LTOModule() {} /// isBitcodeFile - Returns 'true' if the file (or memory contents) is LLVM /// bitcode. bool LTOModule::isBitcodeFile(const void *Mem, size_t Length) { - ErrorOr BCData = IRObjectFile::findBitcodeInMemBuffer( + Expected BCData = IRObjectFile::findBitcodeInMemBuffer( MemoryBufferRef(StringRef((const char *)Mem, Length), "")); - return bool(BCData); + if (!BCData) { + consumeError(BCData.takeError()); + return false; + } + return true; } bool LTOModule::isBitcodeFile(StringRef Path) { @@ -71,9 +70,13 @@ bool LTOModule::isBitcodeFile(StringRef Path) { if (!BufferOrErr) return false; - ErrorOr BCData = IRObjectFile::findBitcodeInMemBuffer( + Expected BCData = IRObjectFile::findBitcodeInMemBuffer( BufferOrErr.get()->getMemBufferRef()); - return bool(BCData); + if (!BCData) { + consumeError(BCData.takeError()); + return false; + } + return true; } bool LTOModule::isThinLTO() { @@ -87,10 +90,12 @@ bool LTOModule::isThinLTO() { bool LTOModule::isBitcodeForTarget(MemoryBuffer *Buffer, StringRef TriplePrefix) { - ErrorOr BCOrErr = + Expected BCOrErr = IRObjectFile::findBitcodeInMemBuffer(Buffer->getMemBufferRef()); - if (!BCOrErr) + if (!BCOrErr) { + consumeError(BCOrErr.takeError()); return false; + } LLVMContext Context; ErrorOr TripleOrErr = expectedToErrorOrAndEmitErrors(Context, getBitcodeTargetTriple(*BCOrErr)); @@ -100,10 +105,12 @@ bool LTOModule::isBitcodeForTarget(MemoryBuffer *Buffer, } std::string LTOModule::getProducerString(MemoryBuffer *Buffer) { - ErrorOr BCOrErr = + Expected BCOrErr = IRObjectFile::findBitcodeInMemBuffer(Buffer->getMemBufferRef()); - if (!BCOrErr) + if (!BCOrErr) { + consumeError(BCOrErr.takeError()); return ""; + } LLVMContext Context; ErrorOr ProducerOrErr = expectedToErrorOrAndEmitErrors( Context, getBitcodeProducerString(*BCOrErr)); @@ -174,11 +181,11 @@ LTOModule::createInLocalContext(std::unique_ptr Context, static ErrorOr> parseBitcodeFileImpl(MemoryBufferRef Buffer, LLVMContext &Context, bool ShouldBeLazy) { - // Find the buffer. - ErrorOr MBOrErr = + Expected MBOrErr = IRObjectFile::findBitcodeInMemBuffer(Buffer); - if (std::error_code EC = MBOrErr.getError()) { + if (Error E = MBOrErr.takeError()) { + std::error_code EC = errorToErrorCode(std::move(E)); Context.emitError(EC.message()); return EC; } diff --git a/lib/LTO/ThinLTOCodeGenerator.cpp b/lib/LTO/ThinLTOCodeGenerator.cpp index 1efd481b246c..c8b3892375f6 100644 --- a/lib/LTO/ThinLTOCodeGenerator.cpp +++ b/lib/LTO/ThinLTOCodeGenerator.cpp @@ -63,7 +63,6 @@ namespace llvm { extern cl::opt LTODiscardValueNames; extern cl::opt LTORemarksFilename; extern cl::opt LTOPassRemarksWithHotness; -extern cl::opt LTOStripInvalidDebugInfo; } namespace { @@ -158,8 +157,7 @@ public: /// Verify the module and strip broken debug info. static void verifyLoadedModule(Module &TheModule) { bool BrokenDebugInfo = false; - if (verifyModule(TheModule, &dbgs(), - LTOStripInvalidDebugInfo ? &BrokenDebugInfo : nullptr)) + if (verifyModule(TheModule, &dbgs(), &BrokenDebugInfo)) report_fatal_error("Broken module found, compilation aborted!"); if (BrokenDebugInfo) { TheModule.getContext().diagnose(ThinLTODiagnosticInfo( @@ -583,9 +581,9 @@ std::unique_ptr TargetMachineBuilder::create() const { Features.getDefaultSubtargetFeatures(TheTriple); std::string FeatureStr = Features.getString(); - return std::unique_ptr(TheTarget->createTargetMachine( - TheTriple.str(), MCpu, FeatureStr, Options, RelocModel, - CodeModel::Default, CGOptLevel)); + return std::unique_ptr( + TheTarget->createTargetMachine(TheTriple.str(), MCpu, FeatureStr, Options, + RelocModel, None, CGOptLevel)); } /** diff --git a/lib/LTO/UpdateCompilerUsed.cpp b/lib/LTO/UpdateCompilerUsed.cpp index 5165cc965038..c982a5b0e5aa 100644 --- a/lib/LTO/UpdateCompilerUsed.cpp +++ b/lib/LTO/UpdateCompilerUsed.cpp @@ -13,11 +13,10 @@ #include "llvm/LTO/legacy/UpdateCompilerUsed.h" #include "llvm/Analysis/TargetLibraryInfo.h" +#include "llvm/CodeGen/TargetLowering.h" +#include "llvm/CodeGen/TargetSubtargetInfo.h" #include "llvm/IR/LegacyPassManager.h" #include "llvm/IR/Mangler.h" -#include "llvm/Target/TargetLowering.h" -#include "llvm/Target/TargetSubtargetInfo.h" -#include "llvm/Transforms/IPO/Internalize.h" #include "llvm/Transforms/Utils/ModuleUtils.h" using namespace llvm; -- cgit v1.3