diff options
Diffstat (limited to 'compiler/rustc_llvm/llvm-wrapper')
| -rw-r--r-- | compiler/rustc_llvm/llvm-wrapper/ArchiveWrapper.cpp | 5 | ||||
| -rw-r--r-- | compiler/rustc_llvm/llvm-wrapper/CoverageMappingWrapper.cpp | 26 | ||||
| -rw-r--r-- | compiler/rustc_llvm/llvm-wrapper/LLVMWrapper.h | 3 | ||||
| -rw-r--r-- | compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp | 201 | ||||
| -rw-r--r-- | compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp | 113 | ||||
| -rw-r--r-- | compiler/rustc_llvm/llvm-wrapper/SymbolWrapper.cpp | 1 |
6 files changed, 264 insertions, 85 deletions
diff --git a/compiler/rustc_llvm/llvm-wrapper/ArchiveWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/ArchiveWrapper.cpp index 35d6b9ed7a4..54fdc84c77d 100644 --- a/compiler/rustc_llvm/llvm-wrapper/ArchiveWrapper.cpp +++ b/compiler/rustc_llvm/llvm-wrapper/ArchiveWrapper.cpp @@ -203,7 +203,12 @@ LLVMRustWriteArchive(char *Dst, size_t NumMembers, } } +#if LLVM_VERSION_LT(18, 0) auto Result = writeArchive(Dst, Members, WriteSymbtab, Kind, true, false); +#else + auto SymtabMode = WriteSymbtab ? SymtabWritingMode::NormalSymtab : SymtabWritingMode::NoSymtab; + auto Result = writeArchive(Dst, Members, SymtabMode, Kind, true, false); +#endif if (!Result) return LLVMRustResult::Success; LLVMRustSetLastError(toString(std::move(Result)).c_str()); diff --git a/compiler/rustc_llvm/llvm-wrapper/CoverageMappingWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/CoverageMappingWrapper.cpp index 87906dee4d3..d61ec0b641c 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<std::string,32> 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<std::string>(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<Function>(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 af6f4d5eaf9..3f2bf2c9b44 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 eb3d67e720f..b729c40228b 100644 --- a/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp +++ b/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp @@ -1,5 +1,7 @@ #include <stdio.h> +#include <cstddef> +#include <iomanip> #include <vector> #include <set> @@ -8,6 +10,7 @@ #include "llvm/Analysis/AliasAnalysis.h" #include "llvm/Analysis/TargetLibraryInfo.h" #include "llvm/Analysis/TargetTransformInfo.h" +#include "llvm/CodeGen/CommandFlags.h" #include "llvm/CodeGen/TargetSubtargetInfo.h" #include "llvm/IR/AutoUpgrade.h" #include "llvm/IR/AssemblyAnnotationWriter.h" @@ -24,11 +27,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" @@ -49,6 +52,8 @@ using namespace llvm; +static codegen::RegisterCodeGenFlags CGF; + typedef struct LLVMOpaquePass *LLVMPassRef; typedef struct LLVMOpaqueTargetMachine *LLVMTargetMachineRef; @@ -104,6 +109,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 +169,7 @@ extern "C" void LLVMTimeTraceProfilerFinish(const char* FileName) { SUBTARGET_AARCH64 \ SUBTARGET_AVR \ SUBTARGET_M68K \ + SUBTARGET_CSKY \ SUBTARGET_MIPS \ SUBTARGET_PPC \ SUBTARGET_SYSTEMZ \ @@ -227,16 +239,22 @@ enum class LLVMRustCodeGenOptLevel { Aggressive, }; -static CodeGenOpt::Level fromRust(LLVMRustCodeGenOptLevel Level) { +#if LLVM_VERSION_GE(18, 0) + using CodeGenOptLevelEnum = llvm::CodeGenOptLevel; +#else + using CodeGenOptLevelEnum = llvm::CodeGenOpt::Level; +#endif + +static CodeGenOptLevelEnum fromRust(LLVMRustCodeGenOptLevel Level) { switch (Level) { case LLVMRustCodeGenOptLevel::None: - return CodeGenOpt::None; + return CodeGenOptLevelEnum::None; case LLVMRustCodeGenOptLevel::Less: - return CodeGenOpt::Less; + return CodeGenOptLevelEnum::Less; case LLVMRustCodeGenOptLevel::Default: - return CodeGenOpt::Default; + return CodeGenOptLevelEnum::Default; case LLVMRustCodeGenOptLevel::Aggressive: - return CodeGenOpt::Aggressive; + return CodeGenOptLevelEnum::Aggressive; default: report_fatal_error("Bad CodeGenOptLevel."); } @@ -306,44 +324,53 @@ static size_t getLongestEntryLength(ArrayRef<KV> 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 MCSubtargetInfo *MCInfo = Target->getMCSubtargetInfo(); const ArrayRef<SubtargetSubTypeKV> CPUTable = MCInfo->getAllProcessorDescriptions(); -#elif defined(LLVM_RUSTLLVM) - const ArrayRef<SubtargetSubTypeKV> 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<SubtargetSubTypeKV> 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) { @@ -389,7 +416,10 @@ extern "C" LLVMTargetMachineRef LLVMRustCreateTargetMachine( bool RelaxELFRelocations, bool UseInitArray, const char *SplitDwarfFile, - bool ForceEmulatedTls) { + const char *OutputObjFile, + const char *DebugInfoCompression, + bool ForceEmulatedTls, + const char *ArgsCstrBuff, size_t ArgsCstrBuffLen) { auto OptLevel = fromRust(RustOptLevel); auto RM = fromRust(RustReloc); @@ -404,7 +434,7 @@ extern "C" LLVMTargetMachineRef LLVMRustCreateTargetMachine( return nullptr; } - TargetOptions Options; + TargetOptions Options = codegen::InitTargetOptionsFromCodeGenFlags(Trip); Options.FloatABIType = FloatABI::Default; if (UseSoftFloat) { @@ -419,6 +449,19 @@ extern "C" LLVMTargetMachineRef LLVMRustCreateTargetMachine( if (SplitDwarfFile) { Options.MCOptions.SplitDwarfFile = SplitDwarfFile; } + if (OutputObjFile) { + Options.ObjectFilenameForDebug = OutputObjFile; + } +#if LLVM_VERSION_GE(16, 0) + if (!strcmp("zlib", DebugInfoCompression) && llvm::compression::zlib::isAvailable()) { + Options.CompressDebugSections = DebugCompressionType::Zlib; + } else if (!strcmp("zstd", DebugInfoCompression) && llvm::compression::zstd::isAvailable()) { + Options.CompressDebugSections = DebugCompressionType::Zstd; + } else if (!strcmp("none", DebugInfoCompression)) { + Options.CompressDebugSections = DebugCompressionType::None; + } +#endif + Options.RelaxELFRelocations = RelaxELFRelocations; Options.UseInitArray = UseInitArray; @@ -445,12 +488,48 @@ extern "C" LLVMTargetMachineRef LLVMRustCreateTargetMachine( Options.EmitStackSizeSection = EmitStackSizeSection; + + if (ArgsCstrBuff != nullptr) + { + int buffer_offset = 0; + assert(ArgsCstrBuff[ArgsCstrBuffLen - 1] == '\0'); + + const size_t arg0_len = std::strlen(ArgsCstrBuff); + char* arg0 = new char[arg0_len + 1]; + memcpy(arg0, ArgsCstrBuff, arg0_len); + arg0[arg0_len] = '\0'; + buffer_offset += arg0_len + 1; + + const int num_cmd_arg_strings = + std::count(&ArgsCstrBuff[buffer_offset], &ArgsCstrBuff[ArgsCstrBuffLen], '\0'); + + std::string* cmd_arg_strings = new std::string[num_cmd_arg_strings]; + for (int i = 0; i < num_cmd_arg_strings; ++i) + { + assert(buffer_offset < ArgsCstrBuffLen); + const int len = std::strlen(ArgsCstrBuff + buffer_offset); + cmd_arg_strings[i] = std::string(&ArgsCstrBuff[buffer_offset], len); + buffer_offset += len + 1; + } + + assert(buffer_offset == ArgsCstrBuffLen); + + Options.MCOptions.Argv0 = arg0; + Options.MCOptions.CommandLineArgs = + llvm::ArrayRef<std::string>(cmd_arg_strings, num_cmd_arg_strings); + } + TargetMachine *TM = TheTarget->createTargetMachine( Trip.getTriple(), CPU, Feature, Options, RM, CM, OptLevel); return wrap(TM); } extern "C" void LLVMRustDisposeTargetMachine(LLVMTargetMachineRef TM) { + + MCTargetOptions& MCOptions = unwrap(TM)->Options.MCOptions; + delete[] MCOptions.Argv0; + delete[] MCOptions.CommandLineArgs.data(); + delete unwrap(TM); } @@ -485,9 +564,17 @@ enum class LLVMRustFileType { static CodeGenFileType fromRust(LLVMRustFileType Type) { switch (Type) { case LLVMRustFileType::AssemblyFile: +#if LLVM_VERSION_GE(18, 0) + return CodeGenFileType::AssemblyFile; +#else return CGFT_AssemblyFile; +#endif case LLVMRustFileType::ObjectFile: +#if LLVM_VERSION_GE(18, 0) + return CodeGenFileType::ObjectFile; +#else return CGFT_ObjectFile; +#endif default: report_fatal_error("Bad FileType."); } @@ -599,6 +686,8 @@ enum class LLVMRustOptStage { struct LLVMRustSanitizerOptions { bool SanitizeAddress; bool SanitizeAddressRecover; + bool SanitizeCFI; + bool SanitizeKCFI; bool SanitizeMemory; bool SanitizeMemoryRecover; int SanitizeMemoryTrackOrigins; @@ -615,6 +704,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, @@ -726,6 +816,18 @@ LLVMRustOptimize( std::vector<std::function<void(ModulePassManager &, OptimizationLevel)>> 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) { @@ -789,9 +891,6 @@ LLVMRustOptimize( OptimizerLastEPCallbacks.push_back( [SanitizerOptions](ModulePassManager &MPM, OptimizationLevel Level) { auto CompileKernel = SanitizerOptions->SanitizeKernelAddress; -#if LLVM_VERSION_LT(15, 0) - MPM.addPass(RequireAnalysisPass<ASanGlobalsMetadataAnalysis, Module>()); -#endif AddressSanitizerOptions opts = AddressSanitizerOptions{ CompileKernel, SanitizerOptions->SanitizeAddressRecover @@ -1029,6 +1128,13 @@ extern "C" void LLVMRustPrintPasses() { extern "C" void LLVMRustRunRestrictionPass(LLVMModuleRef M, char **Symbols, size_t Len) { auto PreserveFunctions = [=](const GlobalValue &GV) { + // Preserve LLVM-injected, ASAN-related symbols. + // See also https://github.com/rust-lang/rust/issues/113404. + if (GV.getName() == "___asan_globals_registered") { + return true; + } + + // Preserve symbols exported from Rust modules. for (size_t I = 0; I < Len; I++) { if (GV.getName() == Symbols[I]) { return true; @@ -1111,9 +1217,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<StringRef, FunctionImporter::ImportMapTy> ImportLists; + DenseMap<StringRef, FunctionImporter::ExportSetTy> ExportLists; + DenseMap<StringRef, GVSummaryMapTy> ModuleToDefinedGVSummaries; +#else StringMap<FunctionImporter::ImportMapTy> ImportLists; StringMap<FunctionImporter::ExportSetTy> ExportLists; StringMap<GVSummaryMapTy> ModuleToDefinedGVSummaries; +#endif StringMap<std::map<GlobalValue::GUID, GlobalValue::LinkageTypes>> ResolvedODR; LLVMRustThinLTOData() : Index(/* HaveGVs = */ false) {} @@ -1167,7 +1279,11 @@ LLVMRustCreateThinLTOData(LLVMRustThinLTOModule *modules, Ret->ModuleMap[module->identifier] = mem_buffer; +#if LLVM_VERSION_GE(18, 0) + if (Error Err = readModuleSummaryIndex(mem_buffer, Ret->Index)) { +#else if (Error Err = readModuleSummaryIndex(mem_buffer, Ret->Index, i)) { +#endif LLVMRustSetLastError(toString(std::move(Err)).c_str()); return nullptr; } @@ -1354,6 +1470,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); @@ -1467,6 +1588,38 @@ LLVMRustGetBitcodeSliceFromObjectData(const char *data, return BitcodeOrError->getBufferStart(); } +// Find a section of an object file by name. Fail if the section is missing or +// empty. +extern "C" const char *LLVMRustGetSliceFromObjectDataByName(const char *data, + size_t len, + const char *name, + size_t *out_len) { + *out_len = 0; + StringRef Data(data, len); + MemoryBufferRef Buffer(Data, ""); // The id is unused. + file_magic Type = identify_magic(Buffer.getBuffer()); + Expected<std::unique_ptr<object::ObjectFile>> ObjFileOrError = + object::ObjectFile::createObjectFile(Buffer, Type); + if (!ObjFileOrError) { + LLVMRustSetLastError(toString(ObjFileOrError.takeError()).c_str()); + return nullptr; + } + for (const object::SectionRef &Sec : (*ObjFileOrError)->sections()) { + Expected<StringRef> Name = Sec.getName(); + if (Name && *Name == name) { + Expected<StringRef> SectionOrError = Sec.getContents(); + if (!SectionOrError) { + LLVMRustSetLastError(toString(SectionOrError.takeError()).c_str()); + return nullptr; + } + *out_len = SectionOrError->size(); + return SectionOrError->data(); + } + } + LLVMRustSetLastError("could not find requested section"); + return nullptr; +} + // Computes the LTO cache key for the provided 'ModId' in the given 'Data', // storing the result in 'KeyOut'. // Currently, this cache key is a SHA-1 hash of anything that could affect diff --git a/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp index ab5fa961b95..4390486b0de 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<uint64_t>(allocKindFromRust(static_cast<LLVMRustAllocKindFlags>(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<FunctionType>(Ty), - StringRef(Constraints, ConstraintsLen)); -#else // llvm::Error converts to true if it is an error. return !llvm::errorToBool(InlineAsm::verify( unwrap<FunctionType>(Ty), StringRef(Constraints, ConstraintsLen))); -#endif } typedef DIBuilder *LLVMRustDIBuilderRef; @@ -1631,19 +1626,11 @@ extern "C" bool LLVMRustConstInt128Get(LLVMValueRef CV, bool sext, uint64_t *hig auto C = unwrap<llvm::ConstantInt>(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; @@ -1882,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 { @@ -1905,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<DiagnosticInfoOptimizationBase>(&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<DiagnosticInfoOptimizationBase>(&DI)) { + if (OptDiagBase->isEnabled()) { + if (this->LlvmRemarkStreamer) { this->LlvmRemarkStreamer->emit(*OptDiagBase); return true; } + } else { + return true; } } if (DiagnosticHandlerCallback) { @@ -1973,6 +1968,11 @@ extern "C" void LLVMRustContextConfigureDiagnosticHandler( std::unique_ptr<LLVMRemarkStreamer> 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<ToolOutputFile>( RemarkFilePath, @@ -2019,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<Constant>(C)->getAggregateElement(Idx)); -} -#endif - extern "C" int32_t LLVMRustGetElementTypeArgIndex(LLVMValueRef CallSite) { -#if LLVM_VERSION_GE(15, 0) auto *CB = unwrap<CallBase>(CallSite); switch (CB->getIntrinsicID()) { case Intrinsic::arm_ldrex: @@ -2036,10 +2027,36 @@ 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<Value>(V)->getType()->isPointerTy()) { + if (auto *GV = dyn_cast<GlobalValue>(unwrap<Value>(V))) { + if (GV->getValueType()->isFunctionTy()) + return false; + } + return true; + } + return false; +} + +extern "C" bool LLVMRustLLVMHasZlibCompressionForDebugSymbols() { +#if LLVM_VERSION_GE(16, 0) + return llvm::compression::zlib::isAvailable(); +#else + return false; +#endif +} + +extern "C" bool LLVMRustLLVMHasZstdCompressionForDebugSymbols() { +#if LLVM_VERSION_GE(16, 0) + return llvm::compression::zstd::isAvailable(); +#else + return false; +#endif +} diff --git a/compiler/rustc_llvm/llvm-wrapper/SymbolWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/SymbolWrapper.cpp index 0493d6b05d0..bf00d11edf6 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" |
