From d1b2d29528b7794b41e66fc2136e395a02f8529b Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Thu, 30 May 2024 05:59:35 +0200 Subject: Merging upstream version 1.73.0+dfsg1. Signed-off-by: Daniel Baumann --- .../llvm-wrapper/CoverageMappingWrapper.cpp | 26 +++-- compiler/rustc_llvm/llvm-wrapper/LLVMWrapper.h | 3 - compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp | 76 ++++++++++++--- compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp | 108 ++++++++++----------- compiler/rustc_llvm/llvm-wrapper/SymbolWrapper.cpp | 1 + 5 files changed, 126 insertions(+), 88 deletions(-) (limited to 'compiler/rustc_llvm/llvm-wrapper') diff --git a/compiler/rustc_llvm/llvm-wrapper/CoverageMappingWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/CoverageMappingWrapper.cpp index 87906dee4..d61ec0b64 100644 --- a/compiler/rustc_llvm/llvm-wrapper/CoverageMappingWrapper.cpp +++ b/compiler/rustc_llvm/llvm-wrapper/CoverageMappingWrapper.cpp @@ -103,12 +103,20 @@ fromRust(LLVMRustCounterExprKind Kind) { } extern "C" void LLVMRustCoverageWriteFilenamesSectionToBuffer( - const char* const Filenames[], + const char *const Filenames[], size_t FilenamesLen, + const size_t *const Lengths, + size_t LengthsLen, RustStringRef BufferOut) { + if (FilenamesLen != LengthsLen) { + report_fatal_error( + "Mismatched lengths in LLVMRustCoverageWriteFilenamesSectionToBuffer"); + } + SmallVector FilenameRefs; + FilenameRefs.reserve(FilenamesLen); for (size_t i = 0; i < FilenamesLen; i++) { - FilenameRefs.push_back(std::string(Filenames[i])); + FilenameRefs.emplace_back(Filenames[i], Lengths[i]); } auto FilenamesWriter = coverage::CoverageFilenamesSectionWriter(ArrayRef(FilenameRefs)); @@ -153,19 +161,17 @@ extern "C" void LLVMRustCoverageWriteMappingToBuffer( CoverageMappingWriter.write(OS); } -extern "C" LLVMValueRef LLVMRustCoverageCreatePGOFuncNameVar(LLVMValueRef F, const char *FuncName) { - StringRef FuncNameRef(FuncName); +extern "C" LLVMValueRef LLVMRustCoverageCreatePGOFuncNameVar( + LLVMValueRef F, + const char *FuncName, + size_t FuncNameLen) { + StringRef FuncNameRef(FuncName, FuncNameLen); return wrap(createPGOFuncNameVar(*cast(unwrap(F)), FuncNameRef)); } -extern "C" uint64_t LLVMRustCoverageHashCString(const char *StrVal) { - StringRef StrRef(StrVal); - return IndexedInstrProf::ComputeHash(StrRef); -} - extern "C" uint64_t LLVMRustCoverageHashByteArray( const char *Bytes, - unsigned NumBytes) { + size_t NumBytes) { StringRef StrRef(Bytes, NumBytes); return IndexedInstrProf::ComputeHash(StrRef); } diff --git a/compiler/rustc_llvm/llvm-wrapper/LLVMWrapper.h b/compiler/rustc_llvm/llvm-wrapper/LLVMWrapper.h index af6f4d5ea..3f2bf2c9b 100644 --- a/compiler/rustc_llvm/llvm-wrapper/LLVMWrapper.h +++ b/compiler/rustc_llvm/llvm-wrapper/LLVMWrapper.h @@ -15,7 +15,6 @@ #include "llvm/Support/DynamicLibrary.h" #include "llvm/Support/FormattedStream.h" #include "llvm/Support/JSON.h" -#include "llvm/Support/Host.h" #include "llvm/Support/Memory.h" #include "llvm/Support/SourceMgr.h" #include "llvm/Support/TargetSelect.h" @@ -92,10 +91,8 @@ enum LLVMRustAttribute { NoCfCheck = 35, ShadowCallStack = 36, AllocSize = 37, -#if LLVM_VERSION_GE(15, 0) AllocatedPointer = 38, AllocAlign = 39, -#endif SanitizeSafeStack = 40, }; diff --git a/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp index c43a02724..b566ea496 100644 --- a/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp +++ b/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp @@ -1,5 +1,6 @@ #include +#include #include #include @@ -24,11 +25,11 @@ #if LLVM_VERSION_GE(17, 0) #include "llvm/Support/VirtualFileSystem.h" #endif -#include "llvm/Support/Host.h" #include "llvm/Target/TargetMachine.h" #include "llvm/Transforms/IPO/AlwaysInliner.h" #include "llvm/Transforms/IPO/FunctionImport.h" #include "llvm/Transforms/IPO/Internalize.h" +#include "llvm/Transforms/IPO/LowerTypeTests.h" #include "llvm/Transforms/IPO/ThinLTOBitcodeWriter.h" #include "llvm/Transforms/Utils/AddDiscriminators.h" #include "llvm/Transforms/Utils/FunctionImportUtils.h" @@ -104,6 +105,12 @@ extern "C" void LLVMTimeTraceProfilerFinish(const char* FileName) { #define SUBTARGET_M68K #endif +#ifdef LLVM_COMPONENT_CSKY +#define SUBTARGET_CSKY SUBTARGET(CSKY) +#else +#define SUBTARGET_CSKY +#endif + #ifdef LLVM_COMPONENT_MIPS #define SUBTARGET_MIPS SUBTARGET(Mips) #else @@ -158,6 +165,7 @@ extern "C" void LLVMTimeTraceProfilerFinish(const char* FileName) { SUBTARGET_AARCH64 \ SUBTARGET_AVR \ SUBTARGET_M68K \ + SUBTARGET_CSKY \ SUBTARGET_MIPS \ SUBTARGET_PPC \ SUBTARGET_SYSTEMZ \ @@ -306,44 +314,53 @@ static size_t getLongestEntryLength(ArrayRef Table) { return MaxLen; } -extern "C" void LLVMRustPrintTargetCPUs(LLVMTargetMachineRef TM, const char* TargetCPU) { +using PrintBackendInfo = void(void*, const char* Data, size_t Len); + +extern "C" void LLVMRustPrintTargetCPUs(LLVMTargetMachineRef TM, + const char* TargetCPU, + PrintBackendInfo Print, + void* Out) { const TargetMachine *Target = unwrap(TM); const MCSubtargetInfo *MCInfo = Target->getMCSubtargetInfo(); const Triple::ArchType HostArch = Triple(sys::getDefaultTargetTriple()).getArch(); const Triple::ArchType TargetArch = Target->getTargetTriple().getArch(); + std::ostringstream Buf; + #if LLVM_VERSION_GE(17, 0) const ArrayRef CPUTable = MCInfo->getAllProcessorDescriptions(); -#elif defined(LLVM_RUSTLLVM) - const ArrayRef CPUTable = MCInfo->getCPUTable(); #else - printf("Full target CPU help is not supported by this LLVM version.\n\n"); + Buf << "Full target CPU help is not supported by this LLVM version.\n\n"; SubtargetSubTypeKV TargetCPUKV = { TargetCPU, {{}}, {{}} }; const ArrayRef CPUTable = TargetCPUKV; #endif unsigned MaxCPULen = getLongestEntryLength(CPUTable); - printf("Available CPUs for this target:\n"); + Buf << "Available CPUs for this target:\n"; // Don't print the "native" entry when the user specifies --target with a // different arch since that could be wrong or misleading. if (HostArch == TargetArch) { MaxCPULen = std::max(MaxCPULen, (unsigned) std::strlen("native")); const StringRef HostCPU = sys::getHostCPUName(); - printf(" %-*s - Select the CPU of the current host (currently %.*s).\n", - MaxCPULen, "native", (int)HostCPU.size(), HostCPU.data()); + Buf << " " << std::left << std::setw(MaxCPULen) << "native" + << " - Select the CPU of the current host " + "(currently " << HostCPU.str() << ").\n"; } for (auto &CPU : CPUTable) { // Compare cpu against current target to label the default if (strcmp(CPU.Key, TargetCPU) == 0) { - printf(" %-*s - This is the default target CPU" - " for the current build target (currently %s).", - MaxCPULen, CPU.Key, Target->getTargetTriple().str().c_str()); + Buf << " " << std::left << std::setw(MaxCPULen) << CPU.Key + << " - This is the default target CPU for the current build target " + "(currently " << Target->getTargetTriple().str() << ")."; } else { - printf(" %-*s", MaxCPULen, CPU.Key); + Buf << " " << CPU.Key; } - printf("\n"); + Buf << "\n"; } + + const auto &BufString = Buf.str(); + Print(Out, BufString.data(), BufString.size()); } extern "C" size_t LLVMRustGetTargetFeaturesCount(LLVMTargetMachineRef TM) { @@ -599,6 +616,8 @@ enum class LLVMRustOptStage { struct LLVMRustSanitizerOptions { bool SanitizeAddress; bool SanitizeAddressRecover; + bool SanitizeCFI; + bool SanitizeKCFI; bool SanitizeMemory; bool SanitizeMemoryRecover; int SanitizeMemoryTrackOrigins; @@ -615,6 +634,7 @@ LLVMRustOptimize( LLVMTargetMachineRef TMRef, LLVMRustPassBuilderOptLevel OptLevelRust, LLVMRustOptStage OptStage, + bool IsLinkerPluginLTO, bool NoPrepopulatePasses, bool VerifyIR, bool UseThinLTOBuffers, bool MergeFunctions, bool UnrollLoops, bool SLPVectorize, bool LoopVectorize, bool DisableSimplifyLibCalls, bool EmitLifetimeMarkers, @@ -667,6 +687,7 @@ LLVMRustOptimize( assert(!PGOUsePath && !PGOSampleUsePath); PGOOpt = PGOOptions(PGOGenPath, "", "", #if LLVM_VERSION_GE(17, 0) + "", FS, #endif PGOOptions::IRInstr, PGOOptions::NoCSAction, @@ -675,6 +696,7 @@ LLVMRustOptimize( assert(!PGOSampleUsePath); PGOOpt = PGOOptions(PGOUsePath, "", "", #if LLVM_VERSION_GE(17, 0) + "", FS, #endif PGOOptions::IRUse, PGOOptions::NoCSAction, @@ -682,6 +704,7 @@ LLVMRustOptimize( } else if (PGOSampleUsePath) { PGOOpt = PGOOptions(PGOSampleUsePath, "", "", #if LLVM_VERSION_GE(17, 0) + "", FS, #endif PGOOptions::SampleUse, PGOOptions::NoCSAction, @@ -689,6 +712,7 @@ LLVMRustOptimize( } else if (DebugInfoForProfiling) { PGOOpt = PGOOptions("", "", "", #if LLVM_VERSION_GE(17, 0) + "", FS, #endif PGOOptions::NoAction, PGOOptions::NoCSAction, @@ -722,6 +746,18 @@ LLVMRustOptimize( std::vector> OptimizerLastEPCallbacks; + if (!IsLinkerPluginLTO + && SanitizerOptions && SanitizerOptions->SanitizeCFI + && !NoPrepopulatePasses) { + PipelineStartEPCallbacks.push_back( + [](ModulePassManager &MPM, OptimizationLevel Level) { + MPM.addPass(LowerTypeTestsPass(/*ExportSummary=*/nullptr, + /*ImportSummary=*/nullptr, + /*DropTypeTests=*/false)); + } + ); + } + if (VerifyIR) { PipelineStartEPCallbacks.push_back( [VerifyIR](ModulePassManager &MPM, OptimizationLevel Level) { @@ -785,9 +821,6 @@ LLVMRustOptimize( OptimizerLastEPCallbacks.push_back( [SanitizerOptions](ModulePassManager &MPM, OptimizationLevel Level) { auto CompileKernel = SanitizerOptions->SanitizeKernelAddress; -#if LLVM_VERSION_LT(15, 0) - MPM.addPass(RequireAnalysisPass()); -#endif AddressSanitizerOptions opts = AddressSanitizerOptions{ CompileKernel, SanitizerOptions->SanitizeAddressRecover @@ -1107,9 +1140,15 @@ struct LLVMRustThinLTOData { // Not 100% sure what these are, but they impact what's internalized and // what's inlined across modules, I believe. +#if LLVM_VERSION_GE(18, 0) + DenseMap ImportLists; + DenseMap ExportLists; + DenseMap ModuleToDefinedGVSummaries; +#else StringMap ImportLists; StringMap ExportLists; StringMap ModuleToDefinedGVSummaries; +#endif StringMap> ResolvedODR; LLVMRustThinLTOData() : Index(/* HaveGVs = */ false) {} @@ -1350,6 +1389,11 @@ LLVMRustPrepareThinLTOImport(const LLVMRustThinLTOData *Data, LLVMModuleRef M, if (WasmCustomSections) WasmCustomSections->eraseFromParent(); + // `llvm.ident` named metadata also gets duplicated. + auto *llvmIdent = (*MOrErr)->getNamedMetadata("llvm.ident"); + if (llvmIdent) + llvmIdent->eraseFromParent(); + return MOrErr; }; bool ClearDSOLocal = clearDSOLocalOnDeclarations(Mod, Target); diff --git a/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp index bb7510b3a..70cdf3d6d 100644 --- a/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp +++ b/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp @@ -1,4 +1,5 @@ #include "LLVMWrapper.h" +#include "llvm/ADT/Statistic.h" #include "llvm/IR/DebugInfoMetadata.h" #include "llvm/IR/DiagnosticHandler.h" #include "llvm/IR/DiagnosticInfo.h" @@ -111,9 +112,26 @@ extern "C" void LLVMRustSetNormalizedTarget(LLVMModuleRef M, unwrap(M)->setTargetTriple(Triple::normalize(Triple)); } -extern "C" void LLVMRustPrintPassTimings() { - raw_fd_ostream OS(2, false); // stderr. - TimerGroup::printAll(OS); +extern "C" const char *LLVMRustPrintPassTimings(size_t *Len) { + std::string buf; + raw_string_ostream SS(buf); + TimerGroup::printAll(SS); + SS.flush(); + *Len = buf.length(); + char *CStr = (char *)malloc(*Len); + memcpy(CStr, buf.c_str(), *Len); + return CStr; +} + +extern "C" const char *LLVMRustPrintStatistics(size_t *Len) { + std::string buf; + raw_string_ostream SS(buf); + llvm::PrintStatistics(SS); + SS.flush(); + *Len = buf.length(); + char *CStr = (char *)malloc(*Len); + memcpy(CStr, buf.c_str(), *Len); + return CStr; } extern "C" LLVMValueRef LLVMRustGetNamedValue(LLVMModuleRef M, const char *Name, @@ -259,12 +277,10 @@ static Attribute::AttrKind fromRust(LLVMRustAttribute Kind) { return Attribute::ShadowCallStack; case AllocSize: return Attribute::AllocSize; -#if LLVM_VERSION_GE(15, 0) case AllocatedPointer: return Attribute::AllocatedPointer; case AllocAlign: return Attribute::AllocAlign; -#endif case SanitizeSafeStack: return Attribute::SafeStack; } @@ -322,20 +338,12 @@ extern "C" LLVMAttributeRef LLVMRustCreateStructRetAttr(LLVMContextRef C, LLVMTy } extern "C" LLVMAttributeRef LLVMRustCreateElementTypeAttr(LLVMContextRef C, LLVMTypeRef Ty) { -#if LLVM_VERSION_GE(15, 0) return wrap(Attribute::get(*unwrap(C), Attribute::ElementType, unwrap(Ty))); -#else - report_fatal_error("Should not be needed on LLVM < 15"); -#endif } extern "C" LLVMAttributeRef LLVMRustCreateUWTableAttr(LLVMContextRef C, bool Async) { -#if LLVM_VERSION_LT(15, 0) - return wrap(Attribute::get(*unwrap(C), Attribute::UWTable)); -#else return wrap(Attribute::getWithUWTableKind( *unwrap(C), Async ? UWTableKind::Async : UWTableKind::Sync)); -#endif } extern "C" LLVMAttributeRef LLVMRustCreateAllocSizeAttr(LLVMContextRef C, uint32_t ElementSizeArg) { @@ -348,8 +356,6 @@ extern "C" LLVMAttributeRef LLVMRustCreateAllocSizeAttr(LLVMContextRef C, uint32 )); } -#if LLVM_VERSION_GE(15, 0) - // These values **must** match ffi::AllocKindFlags. // It _happens_ to match the LLVM values of llvm::AllocFnKind, // but that's happenstance and we do explicit conversions before @@ -393,16 +399,10 @@ static llvm::AllocFnKind allocKindFromRust(LLVMRustAllocKindFlags F) { } return AFK; } -#endif extern "C" LLVMAttributeRef LLVMRustCreateAllocKindAttr(LLVMContextRef C, uint64_t AllocKindArg) { -#if LLVM_VERSION_GE(15, 0) return wrap(Attribute::get(*unwrap(C), Attribute::AllocKind, static_cast(allocKindFromRust(static_cast(AllocKindArg))))); -#else - report_fatal_error( - "allockind attributes are new in LLVM 15 and should not be used on older LLVMs"); -#endif } // Simplified representation of `MemoryEffects` across the FFI boundary. @@ -499,14 +499,9 @@ LLVMRustInlineAsm(LLVMTypeRef Ty, char *AsmString, size_t AsmStringLen, extern "C" bool LLVMRustInlineAsmVerify(LLVMTypeRef Ty, char *Constraints, size_t ConstraintsLen) { -#if LLVM_VERSION_LT(15, 0) - return InlineAsm::Verify(unwrap(Ty), - StringRef(Constraints, ConstraintsLen)); -#else // llvm::Error converts to true if it is an error. return !llvm::errorToBool(InlineAsm::verify( unwrap(Ty), StringRef(Constraints, ConstraintsLen))); -#endif } typedef DIBuilder *LLVMRustDIBuilderRef; @@ -1616,17 +1611,6 @@ extern "C" void LLVMRustSetLinkage(LLVMValueRef V, LLVMSetLinkage(V, fromRust(RustLinkage)); } -// FIXME: replace with LLVMConstInBoundsGEP2 when bumped minimal version to llvm-14 -extern "C" LLVMValueRef LLVMRustConstInBoundsGEP2(LLVMTypeRef Ty, - LLVMValueRef ConstantVal, - LLVMValueRef *ConstantIndices, - unsigned NumIndices) { - ArrayRef IdxList(unwrap(ConstantIndices, NumIndices), - NumIndices); - Constant *Val = unwrap(ConstantVal); - return wrap(ConstantExpr::getInBoundsGetElementPtr(unwrap(Ty), Val, IdxList)); -} - extern "C" bool LLVMRustConstIntGetZExtValue(LLVMValueRef CV, uint64_t *value) { auto C = unwrap(CV); if (C->getBitWidth() > 64) @@ -1642,19 +1626,11 @@ extern "C" bool LLVMRustConstInt128Get(LLVMValueRef CV, bool sext, uint64_t *hig auto C = unwrap(CV); if (C->getBitWidth() > 128) { return false; } APInt AP; -#if LLVM_VERSION_GE(15, 0) if (sext) { AP = C->getValue().sext(128); } else { AP = C->getValue().zext(128); } -#else - if (sext) { - AP = C->getValue().sextOrSelf(128); - } else { - AP = C->getValue().zextOrSelf(128); - } -#endif *low = AP.getLoBits(64).getZExtValue(); *high = AP.getHiBits(64).getZExtValue(); return true; @@ -1893,7 +1869,8 @@ extern "C" void LLVMRustContextConfigureDiagnosticHandler( LLVMContextRef C, LLVMDiagnosticHandlerTy DiagnosticHandlerCallback, void *DiagnosticHandlerContext, bool RemarkAllPasses, const char * const * RemarkPasses, size_t RemarkPassesLen, - const char * RemarkFilePath + const char * RemarkFilePath, + bool PGOAvailable ) { class RustDiagnosticHandler final : public DiagnosticHandler { @@ -1916,12 +1893,19 @@ extern "C" void LLVMRustContextConfigureDiagnosticHandler( LlvmRemarkStreamer(std::move(LlvmRemarkStreamer)) {} virtual bool handleDiagnostics(const DiagnosticInfo &DI) override { - if (this->LlvmRemarkStreamer) { - if (auto *OptDiagBase = dyn_cast(&DI)) { - if (OptDiagBase->isEnabled()) { + // If this diagnostic is one of the optimization remark kinds, we can check if it's enabled + // before emitting it. This can avoid many short-lived allocations when unpacking the + // diagnostic and converting its various C++ strings into rust strings. + // FIXME: some diagnostic infos still allocate before we get here, and avoiding that would be + // good in the future. That will require changing a few call sites in LLVM. + if (auto *OptDiagBase = dyn_cast(&DI)) { + if (OptDiagBase->isEnabled()) { + if (this->LlvmRemarkStreamer) { this->LlvmRemarkStreamer->emit(*OptDiagBase); return true; } + } else { + return true; } } if (DiagnosticHandlerCallback) { @@ -1984,6 +1968,11 @@ extern "C" void LLVMRustContextConfigureDiagnosticHandler( std::unique_ptr LlvmRemarkStreamer; if (RemarkFilePath != nullptr) { + if (PGOAvailable) { + // Enable PGO hotness data for remarks, if available + unwrap(C)->setDiagnosticsHotnessRequested(true); + } + std::error_code EC; RemarkFile = std::make_unique( RemarkFilePath, @@ -2030,16 +2019,7 @@ extern "C" void LLVMRustGetMangledName(LLVMValueRef V, RustStringRef Str) { Mangler().getNameWithPrefix(OS, GV, true); } -// LLVMGetAggregateElement was added in LLVM 15. For earlier LLVM versions just -// use its implementation. -#if LLVM_VERSION_LT(15, 0) -extern "C" LLVMValueRef LLVMGetAggregateElement(LLVMValueRef C, unsigned Idx) { - return wrap(unwrap(C)->getAggregateElement(Idx)); -} -#endif - extern "C" int32_t LLVMRustGetElementTypeArgIndex(LLVMValueRef CallSite) { -#if LLVM_VERSION_GE(15, 0) auto *CB = unwrap(CallSite); switch (CB->getIntrinsicID()) { case Intrinsic::arm_ldrex: @@ -2047,10 +2027,20 @@ extern "C" int32_t LLVMRustGetElementTypeArgIndex(LLVMValueRef CallSite) { case Intrinsic::arm_strex: return 1; } -#endif return -1; } extern "C" bool LLVMRustIsBitcode(char *ptr, size_t len) { return identify_magic(StringRef(ptr, len)) == file_magic::bitcode; } + +extern "C" bool LLVMRustIsNonGVFunctionPointerTy(LLVMValueRef V) { + if (unwrap(V)->getType()->isPointerTy()) { + if (auto *GV = dyn_cast(unwrap(V))) { + if (GV->getValueType()->isFunctionTy()) + return false; + } + return true; + } + return false; +} diff --git a/compiler/rustc_llvm/llvm-wrapper/SymbolWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/SymbolWrapper.cpp index 0493d6b05..bf00d11ed 100644 --- a/compiler/rustc_llvm/llvm-wrapper/SymbolWrapper.cpp +++ b/compiler/rustc_llvm/llvm-wrapper/SymbolWrapper.cpp @@ -7,6 +7,7 @@ // * https://github.com/llvm/llvm-project/blob/8ef3e895ad8ab1724e2b87cabad1dacdc7a397a3/llvm/include/llvm/Object/ArchiveWriter.h // * https://github.com/llvm/llvm-project/blob/8ef3e895ad8ab1724e2b87cabad1dacdc7a397a3/llvm/lib/Object/ArchiveWriter.cpp +#include "llvm/ADT/SmallString.h" #include "llvm/IR/LLVMContext.h" #include "llvm/Object/ObjectFile.h" -- cgit v1.2.3