about summary refs log tree commit diff
path: root/compiler/rustc_llvm/llvm-wrapper
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/rustc_llvm/llvm-wrapper')
-rw-r--r--compiler/rustc_llvm/llvm-wrapper/CoverageMappingWrapper.cpp58
-rw-r--r--compiler/rustc_llvm/llvm-wrapper/LLVMWrapper.h103
-rw-r--r--compiler/rustc_llvm/llvm-wrapper/Linker.cpp8
-rw-r--r--compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp168
-rw-r--r--compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp192
-rw-r--r--compiler/rustc_llvm/llvm-wrapper/SymbolWrapper.cpp4
6 files changed, 254 insertions, 279 deletions
diff --git a/compiler/rustc_llvm/llvm-wrapper/CoverageMappingWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/CoverageMappingWrapper.cpp
index b32af5e5e75..0471baa1f9c 100644
--- a/compiler/rustc_llvm/llvm-wrapper/CoverageMappingWrapper.cpp
+++ b/compiler/rustc_llvm/llvm-wrapper/CoverageMappingWrapper.cpp
@@ -1,5 +1,9 @@
 #include "LLVMWrapper.h"
+
 #include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/IR/Module.h"
 #include "llvm/ProfileData/Coverage/CoverageMapping.h"
 #include "llvm/ProfileData/Coverage/CoverageMappingWriter.h"
 #include "llvm/ProfileData/InstrProf.h"
@@ -123,13 +127,13 @@ fromRust(LLVMRustCounterExprKind Kind) {
   report_fatal_error("Bad LLVMRustCounterExprKind!");
 }
 
-extern "C" void LLVMRustCoverageWriteFilenamesSectionToBuffer(
+extern "C" void LLVMRustCoverageWriteFilenamesToBuffer(
     const char *const Filenames[], size_t FilenamesLen, // String start pointers
     const size_t *const Lengths, size_t LengthsLen,     // Corresponding lengths
     RustStringRef BufferOut) {
   if (FilenamesLen != LengthsLen) {
     report_fatal_error(
-        "Mismatched lengths in LLVMRustCoverageWriteFilenamesSectionToBuffer");
+        "Mismatched lengths in LLVMRustCoverageWriteFilenamesToBuffer");
   }
 
   SmallVector<std::string, 32> FilenameRefs;
@@ -143,16 +147,15 @@ extern "C" void LLVMRustCoverageWriteFilenamesSectionToBuffer(
   FilenamesWriter.write(OS);
 }
 
-extern "C" void LLVMRustCoverageWriteMappingToBuffer(
-    const unsigned *VirtualFileMappingIDs, unsigned NumVirtualFileMappingIDs,
-    const LLVMRustCounterExpression *RustExpressions, unsigned NumExpressions,
-    const LLVMRustCoverageCodeRegion *CodeRegions, unsigned NumCodeRegions,
-    const LLVMRustCoverageBranchRegion *BranchRegions,
-    unsigned NumBranchRegions,
+extern "C" void LLVMRustCoverageWriteFunctionMappingsToBuffer(
+    const unsigned *VirtualFileMappingIDs, size_t NumVirtualFileMappingIDs,
+    const LLVMRustCounterExpression *RustExpressions, size_t NumExpressions,
+    const LLVMRustCoverageCodeRegion *CodeRegions, size_t NumCodeRegions,
+    const LLVMRustCoverageBranchRegion *BranchRegions, size_t NumBranchRegions,
     const LLVMRustCoverageMCDCBranchRegion *MCDCBranchRegions,
-    unsigned NumMCDCBranchRegions,
+    size_t NumMCDCBranchRegions,
     const LLVMRustCoverageMCDCDecisionRegion *MCDCDecisionRegions,
-    unsigned NumMCDCDecisionRegions, RustStringRef BufferOut) {
+    size_t NumMCDCDecisionRegions, RustStringRef BufferOut) {
   // Convert from FFI representation to LLVM representation.
 
   // Expressions:
@@ -219,34 +222,37 @@ LLVMRustCoverageCreatePGOFuncNameVar(LLVMValueRef F, const char *FuncName,
   return wrap(createPGOFuncNameVar(*cast<Function>(unwrap(F)), FuncNameRef));
 }
 
-extern "C" uint64_t LLVMRustCoverageHashByteArray(const char *Bytes,
-                                                  size_t NumBytes) {
-  auto StrRef = StringRef(Bytes, NumBytes);
-  return IndexedInstrProf::ComputeHash(StrRef);
+extern "C" uint64_t LLVMRustCoverageHashBytes(const char *Bytes,
+                                              size_t NumBytes) {
+  return IndexedInstrProf::ComputeHash(StringRef(Bytes, NumBytes));
 }
 
-static void WriteSectionNameToString(LLVMModuleRef M, InstrProfSectKind SK,
-                                     RustStringRef Str) {
+// Private helper function for getting the covmap and covfun section names.
+static void writeInstrProfSectionNameToString(LLVMModuleRef M,
+                                              InstrProfSectKind SectKind,
+                                              RustStringRef OutStr) {
   auto TargetTriple = Triple(unwrap(M)->getTargetTriple());
-  auto name = getInstrProfSectionName(SK, TargetTriple.getObjectFormat());
-  auto OS = RawRustStringOstream(Str);
+  auto name = getInstrProfSectionName(SectKind, TargetTriple.getObjectFormat());
+  auto OS = RawRustStringOstream(OutStr);
   OS << name;
 }
 
-extern "C" void LLVMRustCoverageWriteMapSectionNameToString(LLVMModuleRef M,
-                                                            RustStringRef Str) {
-  WriteSectionNameToString(M, IPSK_covmap, Str);
+extern "C" void
+LLVMRustCoverageWriteCovmapSectionNameToString(LLVMModuleRef M,
+                                               RustStringRef OutStr) {
+  writeInstrProfSectionNameToString(M, IPSK_covmap, OutStr);
 }
 
 extern "C" void
-LLVMRustCoverageWriteFuncSectionNameToString(LLVMModuleRef M,
-                                             RustStringRef Str) {
-  WriteSectionNameToString(M, IPSK_covfun, Str);
+LLVMRustCoverageWriteCovfunSectionNameToString(LLVMModuleRef M,
+                                               RustStringRef OutStr) {
+  writeInstrProfSectionNameToString(M, IPSK_covfun, OutStr);
 }
 
-extern "C" void LLVMRustCoverageWriteMappingVarNameToString(RustStringRef Str) {
+extern "C" void
+LLVMRustCoverageWriteCovmapVarNameToString(RustStringRef OutStr) {
   auto name = getCoverageMappingVarName();
-  auto OS = RawRustStringOstream(Str);
+  auto OS = RawRustStringOstream(OutStr);
   OS << name;
 }
 
diff --git a/compiler/rustc_llvm/llvm-wrapper/LLVMWrapper.h b/compiler/rustc_llvm/llvm-wrapper/LLVMWrapper.h
index 73bbc9de855..f6598f9faf5 100644
--- a/compiler/rustc_llvm/llvm-wrapper/LLVMWrapper.h
+++ b/compiler/rustc_llvm/llvm-wrapper/LLVMWrapper.h
@@ -1,31 +1,12 @@
+#ifndef INCLUDED_RUSTC_LLVM_LLVMWRAPPER_H
+#define INCLUDED_RUSTC_LLVM_LLVMWRAPPER_H
+
 #include "SuppressLLVMWarnings.h"
 
-#include "llvm-c/BitReader.h"
-#include "llvm-c/Core.h"
-#include "llvm-c/Object.h"
-#include "llvm/ADT/ArrayRef.h"
-#include "llvm/ADT/DenseSet.h"
-#include "llvm/ADT/SmallVector.h"
-#include "llvm/Analysis/Lint.h"
-#include "llvm/Analysis/Passes.h"
-#include "llvm/IR/IRBuilder.h"
-#include "llvm/IR/InlineAsm.h"
-#include "llvm/IR/LLVMContext.h"
-#include "llvm/IR/Module.h"
-#include "llvm/Support/CommandLine.h"
-#include "llvm/Support/Debug.h"
-#include "llvm/Support/DynamicLibrary.h"
-#include "llvm/Support/FormattedStream.h"
-#include "llvm/Support/JSON.h"
-#include "llvm/Support/Memory.h"
-#include "llvm/Support/SourceMgr.h"
-#include "llvm/Support/TargetSelect.h"
-#include "llvm/Support/Timer.h"
-#include "llvm/Support/raw_ostream.h"
-#include "llvm/Target/TargetMachine.h"
-#include "llvm/Target/TargetOptions.h"
-#include "llvm/Transforms/IPO.h"
-#include "llvm/Transforms/Scalar.h"
+#include "llvm/Config/llvm-config.h"  // LLVM_VERSION_MAJOR, LLVM_VERSION_MINOR
+#include "llvm/Support/raw_ostream.h" // llvm::raw_ostream
+#include <cstddef>                    // size_t etc
+#include <cstdint>                    // uint64_t etc
 
 #define LLVM_VERSION_GE(major, minor)                                          \
   (LLVM_VERSION_MAJOR > (major) ||                                             \
@@ -33,79 +14,17 @@
 
 #define LLVM_VERSION_LT(major, minor) (!LLVM_VERSION_GE((major), (minor)))
 
-#if LLVM_VERSION_GE(20, 0)
-#include "llvm/Transforms/Utils/Instrumentation.h"
-#else
-#include "llvm/Transforms/Instrumentation.h"
-#endif
-
-#include "llvm/IR/LegacyPassManager.h"
-
-#include "llvm/Bitcode/BitcodeReader.h"
-#include "llvm/Bitcode/BitcodeWriter.h"
-
-#include "llvm/IR/DIBuilder.h"
-#include "llvm/IR/DebugInfo.h"
-#include "llvm/IR/IRPrintingPasses.h"
-#include "llvm/Linker/Linker.h"
-
-#include "llvm/TargetParser/Triple.h"
-
 extern "C" void LLVMRustSetLastError(const char *);
 
 enum class LLVMRustResult { Success, Failure };
 
-enum LLVMRustAttribute {
-  AlwaysInline = 0,
-  ByVal = 1,
-  Cold = 2,
-  InlineHint = 3,
-  MinSize = 4,
-  Naked = 5,
-  NoAlias = 6,
-  NoCapture = 7,
-  NoInline = 8,
-  NonNull = 9,
-  NoRedZone = 10,
-  NoReturn = 11,
-  NoUnwind = 12,
-  OptimizeForSize = 13,
-  ReadOnly = 14,
-  SExt = 15,
-  StructRet = 16,
-  UWTable = 17,
-  ZExt = 18,
-  InReg = 19,
-  SanitizeThread = 20,
-  SanitizeAddress = 21,
-  SanitizeMemory = 22,
-  NonLazyBind = 23,
-  OptimizeNone = 24,
-  ReadNone = 26,
-  SanitizeHWAddress = 28,
-  WillReturn = 29,
-  StackProtectReq = 30,
-  StackProtectStrong = 31,
-  StackProtect = 32,
-  NoUndef = 33,
-  SanitizeMemTag = 34,
-  NoCfCheck = 35,
-  ShadowCallStack = 36,
-  AllocSize = 37,
-  AllocatedPointer = 38,
-  AllocAlign = 39,
-  SanitizeSafeStack = 40,
-  FnRetThunkExtern = 41,
-  Writable = 42,
-  DeadOnUnwind = 43,
-};
-
 typedef struct OpaqueRustString *RustStringRef;
 typedef struct LLVMOpaqueTwine *LLVMTwineRef;
 typedef struct LLVMOpaqueSMDiagnostic *LLVMSMDiagnosticRef;
 
-extern "C" void LLVMRustStringWriteImpl(RustStringRef Str, const char *Ptr,
-                                        size_t Size);
+extern "C" void LLVMRustStringWriteImpl(RustStringRef buf,
+                                        const char *slice_ptr,
+                                        size_t slice_len);
 
 class RawRustStringOstream : public llvm::raw_ostream {
   RustStringRef Str;
@@ -126,3 +45,5 @@ public:
     flush();
   }
 };
+
+#endif // INCLUDED_RUSTC_LLVM_LLVMWRAPPER_H
diff --git a/compiler/rustc_llvm/llvm-wrapper/Linker.cpp b/compiler/rustc_llvm/llvm-wrapper/Linker.cpp
index f43128ed550..fdf54e2d9b4 100644
--- a/compiler/rustc_llvm/llvm-wrapper/Linker.cpp
+++ b/compiler/rustc_llvm/llvm-wrapper/Linker.cpp
@@ -1,8 +1,10 @@
-#include "llvm/Linker/Linker.h"
-#include "SuppressLLVMWarnings.h"
-
 #include "LLVMWrapper.h"
 
+#include "llvm/Bitcode/BitcodeReader.h"
+#include "llvm/IR/Module.h"
+#include "llvm/Linker/Linker.h"
+#include "llvm/Support/MemoryBuffer.h"
+
 using namespace llvm;
 
 struct RustLinker {
diff --git a/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp
index 3e906f89c15..1ed702ab4cb 100644
--- a/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp
+++ b/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp
@@ -1,25 +1,21 @@
-#include <stdio.h>
-
-#include <cstddef>
-#include <iomanip>
-#include <set>
-#include <vector>
-
 #include "LLVMWrapper.h"
 
-#include "llvm/Analysis/AliasAnalysis.h"
+#include "llvm-c/Core.h"
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/DenseSet.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/Analysis/Lint.h"
 #include "llvm/Analysis/TargetLibraryInfo.h"
-#include "llvm/Analysis/TargetTransformInfo.h"
 #include "llvm/Bitcode/BitcodeWriter.h"
 #include "llvm/CodeGen/CommandFlags.h"
-#include "llvm/CodeGen/TargetSubtargetInfo.h"
 #include "llvm/IR/AssemblyAnnotationWriter.h"
 #include "llvm/IR/AutoUpgrade.h"
-#include "llvm/IR/IntrinsicInst.h"
+#include "llvm/IR/LegacyPassManager.h"
+#include "llvm/IR/PassManager.h"
 #include "llvm/IR/Verifier.h"
 #include "llvm/LTO/LTO.h"
+#include "llvm/MC/MCSubtargetInfo.h"
 #include "llvm/MC/TargetRegistry.h"
-#include "llvm/Object/IRObjectFile.h"
 #include "llvm/Object/ObjectFile.h"
 #include "llvm/Passes/PassBuilder.h"
 #include "llvm/Passes/PassPlugin.h"
@@ -30,26 +26,28 @@
 #include "llvm/Support/VirtualFileSystem.h"
 #include "llvm/Target/TargetMachine.h"
 #include "llvm/TargetParser/Host.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/Instrumentation/AddressSanitizer.h"
 #include "llvm/Transforms/Instrumentation/DataFlowSanitizer.h"
-#include "llvm/Transforms/Utils/AddDiscriminators.h"
-#include "llvm/Transforms/Utils/FunctionImportUtils.h"
-#if LLVM_VERSION_GE(19, 0)
-#include "llvm/Support/PGOOptions.h"
-#endif
-#include "llvm/Transforms/Instrumentation/GCOVProfiler.h"
 #include "llvm/Transforms/Instrumentation/HWAddressSanitizer.h"
 #include "llvm/Transforms/Instrumentation/InstrProfiling.h"
 #include "llvm/Transforms/Instrumentation/MemorySanitizer.h"
 #include "llvm/Transforms/Instrumentation/ThreadSanitizer.h"
-#include "llvm/Transforms/Utils.h"
 #include "llvm/Transforms/Utils/CanonicalizeAliases.h"
+#include "llvm/Transforms/Utils/FunctionImportUtils.h"
 #include "llvm/Transforms/Utils/NameAnonGlobals.h"
+#include <set>
+#include <string>
+#include <vector>
+
+// Conditional includes prevent clang-format from fully sorting the list,
+// so keep them separate.
+#if LLVM_VERSION_GE(19, 0)
+#include "llvm/Support/PGOOptions.h"
+#endif
 
 using namespace llvm;
 
@@ -318,49 +316,17 @@ template <typename KV> static size_t getLongestEntryLength(ArrayRef<KV> Table) {
   return MaxLen;
 }
 
-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 Triple::ArchType HostArch =
-      Triple(sys::getDefaultTargetTriple()).getArch();
-  const Triple::ArchType TargetArch = Target->getTargetTriple().getArch();
-
-  std::ostringstream Buf;
+                                        RustStringRef OutStr) {
+  ArrayRef<SubtargetSubTypeKV> CPUTable =
+      unwrap(TM)->getMCSubtargetInfo()->getAllProcessorDescriptions();
+  auto OS = RawRustStringOstream(OutStr);
 
-  const MCSubtargetInfo *MCInfo = Target->getMCSubtargetInfo();
-  const ArrayRef<SubtargetSubTypeKV> CPUTable =
-      MCInfo->getAllProcessorDescriptions();
-  unsigned MaxCPULen = getLongestEntryLength(CPUTable);
-
-  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();
-    Buf << "    " << std::left << std::setw(MaxCPULen) << "native"
-        << " - Select the CPU of the current host "
-           "(currently "
-        << HostCPU.str() << ").\n";
-  }
+  // Just print a bare list of target CPU names, and let Rust-side code handle
+  // the full formatting of `--print=target-cpus`.
   for (auto &CPU : CPUTable) {
-    // Compare cpu against current target to label the default
-    if (strcmp(CPU.Key, TargetCPU) == 0) {
-      Buf << "    " << std::left << std::setw(MaxCPULen) << CPU.Key
-          << " - This is the default target CPU for the current build target "
-             "(currently "
-          << Target->getTargetTriple().str() << ").";
-    } else {
-      Buf << "    " << CPU.Key;
-    }
-    Buf << "\n";
+    OS << CPU.Key << "\n";
   }
-
-  const auto &BufString = Buf.str();
-  Print(Out, BufString.data(), BufString.size());
 }
 
 extern "C" size_t LLVMRustGetTargetFeaturesCount(LLVMTargetMachineRef TM) {
@@ -383,9 +349,9 @@ extern "C" void LLVMRustGetTargetFeature(LLVMTargetMachineRef TM, size_t Index,
   *Desc = Feat.Desc;
 }
 
-extern "C" const char *LLVMRustGetHostCPUName(size_t *len) {
+extern "C" const char *LLVMRustGetHostCPUName(size_t *OutLen) {
   StringRef Name = sys::getHostCPUName();
-  *len = Name.size();
+  *OutLen = Name.size();
   return Name.data();
 }
 
@@ -714,9 +680,8 @@ extern "C" LLVMRustResult LLVMRustOptimize(
     bool SLPVectorize, bool LoopVectorize, bool DisableSimplifyLibCalls,
     bool EmitLifetimeMarkers, LLVMRustSanitizerOptions *SanitizerOptions,
     const char *PGOGenPath, const char *PGOUsePath, bool InstrumentCoverage,
-    const char *InstrProfileOutput, bool InstrumentGCOV,
-    const char *PGOSampleUsePath, bool DebugInfoForProfiling,
-    void *LlvmSelfProfiler,
+    const char *InstrProfileOutput, const char *PGOSampleUsePath,
+    bool DebugInfoForProfiling, void *LlvmSelfProfiler,
     LLVMRustSelfProfileBeforePassCallback BeforePassCallback,
     LLVMRustSelfProfileAfterPassCallback AfterPassCallback,
     const char *ExtraPasses, size_t ExtraPassesLen, const char *LLVMPlugins,
@@ -779,10 +744,8 @@ extern "C" LLVMRustResult LLVMRustOptimize(
   CGSCCAnalysisManager CGAM;
   ModuleAnalysisManager MAM;
 
-  // FIXME: We may want to expose this as an option.
-  bool DebugPassManager = false;
-
-  StandardInstrumentations SI(TheModule->getContext(), DebugPassManager);
+  StandardInstrumentations SI(TheModule->getContext(),
+                              /*DebugLogging=*/false);
   SI.registerCallbacks(PIC, &MAM);
 
   if (LLVMPluginsLen) {
@@ -820,16 +783,22 @@ extern "C" LLVMRustResult LLVMRustOptimize(
   // the PassBuilder does not create a pipeline.
   std::vector<std::function<void(ModulePassManager &, OptimizationLevel)>>
       PipelineStartEPCallbacks;
+#if LLVM_VERSION_GE(20, 0)
+  std::vector<std::function<void(ModulePassManager &, OptimizationLevel,
+                                 ThinOrFullLTOPhase)>>
+      OptimizerLastEPCallbacks;
+#else
   std::vector<std::function<void(ModulePassManager &, OptimizationLevel)>>
       OptimizerLastEPCallbacks;
+#endif
 
   if (!IsLinkerPluginLTO && SanitizerOptions && SanitizerOptions->SanitizeCFI &&
       !NoPrepopulatePasses) {
     PipelineStartEPCallbacks.push_back(
         [](ModulePassManager &MPM, OptimizationLevel Level) {
-          MPM.addPass(LowerTypeTestsPass(/*ExportSummary=*/nullptr,
-                                         /*ImportSummary=*/nullptr,
-                                         /*DropTypeTests=*/false));
+          MPM.addPass(LowerTypeTestsPass(
+              /*ExportSummary=*/nullptr,
+              /*ImportSummary=*/nullptr));
         });
   }
 
@@ -847,13 +816,6 @@ extern "C" LLVMRustResult LLVMRustOptimize(
         });
   }
 
-  if (InstrumentGCOV) {
-    PipelineStartEPCallbacks.push_back(
-        [](ModulePassManager &MPM, OptimizationLevel Level) {
-          MPM.addPass(GCOVProfilerPass(GCOVOptions::getDefault()));
-        });
-  }
-
   if (InstrumentCoverage) {
     PipelineStartEPCallbacks.push_back(
         [InstrProfileOutput](ModulePassManager &MPM, OptimizationLevel Level) {
@@ -875,7 +837,12 @@ extern "C" LLVMRustResult LLVMRustOptimize(
           SanitizerOptions->SanitizeDataFlowABIList +
               SanitizerOptions->SanitizeDataFlowABIListLen);
       OptimizerLastEPCallbacks.push_back(
+#if LLVM_VERSION_GE(20, 0)
+          [ABIListFiles](ModulePassManager &MPM, OptimizationLevel Level,
+                         ThinOrFullLTOPhase phase) {
+#else
           [ABIListFiles](ModulePassManager &MPM, OptimizationLevel Level) {
+#endif
             MPM.addPass(DataFlowSanitizerPass(ABIListFiles));
           });
     }
@@ -887,23 +854,39 @@ extern "C" LLVMRustResult LLVMRustOptimize(
           /*CompileKernel=*/false,
           /*EagerChecks=*/true);
       OptimizerLastEPCallbacks.push_back(
+#if LLVM_VERSION_GE(20, 0)
+          [Options](ModulePassManager &MPM, OptimizationLevel Level,
+                    ThinOrFullLTOPhase phase) {
+#else
           [Options](ModulePassManager &MPM, OptimizationLevel Level) {
+#endif
             MPM.addPass(MemorySanitizerPass(Options));
           });
     }
 
     if (SanitizerOptions->SanitizeThread) {
-      OptimizerLastEPCallbacks.push_back([](ModulePassManager &MPM,
-                                            OptimizationLevel Level) {
-        MPM.addPass(ModuleThreadSanitizerPass());
-        MPM.addPass(createModuleToFunctionPassAdaptor(ThreadSanitizerPass()));
-      });
+      OptimizerLastEPCallbacks.push_back(
+#if LLVM_VERSION_GE(20, 0)
+          [](ModulePassManager &MPM, OptimizationLevel Level,
+             ThinOrFullLTOPhase phase) {
+#else
+          [](ModulePassManager &MPM, OptimizationLevel Level) {
+#endif
+            MPM.addPass(ModuleThreadSanitizerPass());
+            MPM.addPass(
+                createModuleToFunctionPassAdaptor(ThreadSanitizerPass()));
+          });
     }
 
     if (SanitizerOptions->SanitizeAddress ||
         SanitizerOptions->SanitizeKernelAddress) {
       OptimizerLastEPCallbacks.push_back(
+#if LLVM_VERSION_GE(20, 0)
+          [SanitizerOptions](ModulePassManager &MPM, OptimizationLevel Level,
+                             ThinOrFullLTOPhase phase) {
+#else
           [SanitizerOptions](ModulePassManager &MPM, OptimizationLevel Level) {
+#endif
             auto CompileKernel = SanitizerOptions->SanitizeKernelAddress;
             AddressSanitizerOptions opts = AddressSanitizerOptions{
                 CompileKernel,
@@ -917,7 +900,12 @@ extern "C" LLVMRustResult LLVMRustOptimize(
     }
     if (SanitizerOptions->SanitizeHWAddress) {
       OptimizerLastEPCallbacks.push_back(
+#if LLVM_VERSION_GE(20, 0)
+          [SanitizerOptions](ModulePassManager &MPM, OptimizationLevel Level,
+                             ThinOrFullLTOPhase phase) {
+#else
           [SanitizerOptions](ModulePassManager &MPM, OptimizationLevel Level) {
+#endif
             HWAddressSanitizerOptions opts(
                 /*CompileKernel=*/false,
                 SanitizerOptions->SanitizeHWAddressRecover,
@@ -941,8 +929,9 @@ extern "C" LLVMRustResult LLVMRustOptimize(
       for (const auto &C : OptimizerLastEPCallbacks)
         PB.registerOptimizerLastEPCallback(C);
 
-      // Pass false as we manually schedule ThinLTOBufferPasses below.
-      MPM = PB.buildO0DefaultPipeline(OptLevel, /* PreLinkLTO */ false);
+      // We manually schedule ThinLTOBufferPasses below, so don't pass the value
+      // to enable it here.
+      MPM = PB.buildO0DefaultPipeline(OptLevel);
     } else {
       for (const auto &C : PipelineStartEPCallbacks)
         PB.registerPipelineStartEPCallback(C);
@@ -951,7 +940,7 @@ extern "C" LLVMRustResult LLVMRustOptimize(
 
       switch (OptStage) {
       case LLVMRustOptStage::PreLinkNoLTO:
-        MPM = PB.buildPerModuleDefaultPipeline(OptLevel, DebugPassManager);
+        MPM = PB.buildPerModuleDefaultPipeline(OptLevel);
         break;
       case LLVMRustOptStage::PreLinkThinLTO:
         MPM = PB.buildThinLTOPreLinkDefaultPipeline(OptLevel);
@@ -977,7 +966,11 @@ extern "C" LLVMRustResult LLVMRustOptimize(
     for (const auto &C : PipelineStartEPCallbacks)
       C(MPM, OptLevel);
     for (const auto &C : OptimizerLastEPCallbacks)
+#if LLVM_VERSION_GE(20, 0)
+      C(MPM, OptLevel, ThinOrFullLTOPhase::None);
+#else
       C(MPM, OptLevel);
+#endif
   }
 
   if (ExtraPassesLen) {
@@ -1630,5 +1623,6 @@ extern "C" void LLVMRustComputeLTOCacheKey(RustStringRef KeyOut,
                            CfiFunctionDefs, CfiFunctionDecls);
 #endif
 
-  LLVMRustStringWriteImpl(KeyOut, Key.c_str(), Key.size());
+  auto OS = RawRustStringOstream(KeyOut);
+  OS << Key.str();
 }
diff --git a/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp
index 645b4082be5..cd70c3f2669 100644
--- a/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp
+++ b/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp
@@ -1,28 +1,38 @@
 #include "LLVMWrapper.h"
+
+#include "llvm-c/Core.h"
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/SmallVector.h"
 #include "llvm/ADT/Statistic.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/BinaryFormat/Magic.h"
 #include "llvm/Bitcode/BitcodeWriter.h"
+#include "llvm/IR/DIBuilder.h"
 #include "llvm/IR/DebugInfoMetadata.h"
 #include "llvm/IR/DiagnosticHandler.h"
 #include "llvm/IR/DiagnosticInfo.h"
 #include "llvm/IR/DiagnosticPrinter.h"
 #include "llvm/IR/GlobalVariable.h"
+#include "llvm/IR/IRBuilder.h"
+#include "llvm/IR/InlineAsm.h"
 #include "llvm/IR/Instructions.h"
-#include "llvm/IR/Intrinsics.h"
 #include "llvm/IR/IntrinsicsARM.h"
+#include "llvm/IR/LLVMContext.h"
 #include "llvm/IR/LLVMRemarkStreamer.h"
 #include "llvm/IR/Mangler.h"
+#include "llvm/IR/Module.h"
 #include "llvm/IR/Value.h"
-#include "llvm/Object/Archive.h"
 #include "llvm/Object/COFFImportFile.h"
-#include "llvm/Object/ObjectFile.h"
-#include "llvm/Pass.h"
 #include "llvm/Remarks/RemarkFormat.h"
 #include "llvm/Remarks/RemarkSerializer.h"
 #include "llvm/Remarks/RemarkStreamer.h"
+#include "llvm/Support/Compression.h"
+#include "llvm/Support/FileSystem.h"
+#include "llvm/Support/JSON.h"
 #include "llvm/Support/ModRef.h"
 #include "llvm/Support/Signals.h"
+#include "llvm/Support/Timer.h"
 #include "llvm/Support/ToolOutputFile.h"
-
 #include <iostream>
 
 // for raw `write` in the bad-alloc handler
@@ -140,26 +150,14 @@ extern "C" void LLVMRustSetNormalizedTarget(LLVMModuleRef M,
   unwrap(M)->setTargetTriple(Triple::normalize(Triple));
 }
 
-extern "C" const char *LLVMRustPrintPassTimings(size_t *Len) {
-  std::string buf;
-  auto SS = raw_string_ostream(buf);
-  TimerGroup::printAll(SS);
-  SS.flush();
-  *Len = buf.length();
-  char *CStr = (char *)malloc(*Len);
-  memcpy(CStr, buf.c_str(), *Len);
-  return CStr;
+extern "C" void LLVMRustPrintPassTimings(RustStringRef OutBuf) {
+  auto OS = RawRustStringOstream(OutBuf);
+  TimerGroup::printAll(OS);
 }
 
-extern "C" const char *LLVMRustPrintStatistics(size_t *Len) {
-  std::string buf;
-  auto SS = raw_string_ostream(buf);
-  llvm::PrintStatistics(SS);
-  SS.flush();
-  *Len = buf.length();
-  char *CStr = (char *)malloc(*Len);
-  memcpy(CStr, buf.c_str(), *Len);
-  return CStr;
+extern "C" void LLVMRustPrintStatistics(RustStringRef OutBuf) {
+  auto OS = RawRustStringOstream(OutBuf);
+  llvm::PrintStatistics(OS);
 }
 
 extern "C" LLVMValueRef LLVMRustGetNamedValue(LLVMModuleRef M, const char *Name,
@@ -228,94 +226,140 @@ extern "C" LLVMValueRef LLVMRustInsertPrivateGlobal(LLVMModuleRef M,
                                  GlobalValue::PrivateLinkage, nullptr));
 }
 
-static Attribute::AttrKind fromRust(LLVMRustAttribute Kind) {
+// Must match the layout of `rustc_codegen_llvm::llvm::ffi::AttributeKind`.
+enum class LLVMRustAttributeKind {
+  AlwaysInline = 0,
+  ByVal = 1,
+  Cold = 2,
+  InlineHint = 3,
+  MinSize = 4,
+  Naked = 5,
+  NoAlias = 6,
+  NoCapture = 7,
+  NoInline = 8,
+  NonNull = 9,
+  NoRedZone = 10,
+  NoReturn = 11,
+  NoUnwind = 12,
+  OptimizeForSize = 13,
+  ReadOnly = 14,
+  SExt = 15,
+  StructRet = 16,
+  UWTable = 17,
+  ZExt = 18,
+  InReg = 19,
+  SanitizeThread = 20,
+  SanitizeAddress = 21,
+  SanitizeMemory = 22,
+  NonLazyBind = 23,
+  OptimizeNone = 24,
+  ReadNone = 26,
+  SanitizeHWAddress = 28,
+  WillReturn = 29,
+  StackProtectReq = 30,
+  StackProtectStrong = 31,
+  StackProtect = 32,
+  NoUndef = 33,
+  SanitizeMemTag = 34,
+  NoCfCheck = 35,
+  ShadowCallStack = 36,
+  AllocSize = 37,
+  AllocatedPointer = 38,
+  AllocAlign = 39,
+  SanitizeSafeStack = 40,
+  FnRetThunkExtern = 41,
+  Writable = 42,
+  DeadOnUnwind = 43,
+};
+
+static Attribute::AttrKind fromRust(LLVMRustAttributeKind Kind) {
   switch (Kind) {
-  case AlwaysInline:
+  case LLVMRustAttributeKind::AlwaysInline:
     return Attribute::AlwaysInline;
-  case ByVal:
+  case LLVMRustAttributeKind::ByVal:
     return Attribute::ByVal;
-  case Cold:
+  case LLVMRustAttributeKind::Cold:
     return Attribute::Cold;
-  case InlineHint:
+  case LLVMRustAttributeKind::InlineHint:
     return Attribute::InlineHint;
-  case MinSize:
+  case LLVMRustAttributeKind::MinSize:
     return Attribute::MinSize;
-  case Naked:
+  case LLVMRustAttributeKind::Naked:
     return Attribute::Naked;
-  case NoAlias:
+  case LLVMRustAttributeKind::NoAlias:
     return Attribute::NoAlias;
-  case NoCapture:
+  case LLVMRustAttributeKind::NoCapture:
     return Attribute::NoCapture;
-  case NoCfCheck:
+  case LLVMRustAttributeKind::NoCfCheck:
     return Attribute::NoCfCheck;
-  case NoInline:
+  case LLVMRustAttributeKind::NoInline:
     return Attribute::NoInline;
-  case NonNull:
+  case LLVMRustAttributeKind::NonNull:
     return Attribute::NonNull;
-  case NoRedZone:
+  case LLVMRustAttributeKind::NoRedZone:
     return Attribute::NoRedZone;
-  case NoReturn:
+  case LLVMRustAttributeKind::NoReturn:
     return Attribute::NoReturn;
-  case NoUnwind:
+  case LLVMRustAttributeKind::NoUnwind:
     return Attribute::NoUnwind;
-  case OptimizeForSize:
+  case LLVMRustAttributeKind::OptimizeForSize:
     return Attribute::OptimizeForSize;
-  case ReadOnly:
+  case LLVMRustAttributeKind::ReadOnly:
     return Attribute::ReadOnly;
-  case SExt:
+  case LLVMRustAttributeKind::SExt:
     return Attribute::SExt;
-  case StructRet:
+  case LLVMRustAttributeKind::StructRet:
     return Attribute::StructRet;
-  case UWTable:
+  case LLVMRustAttributeKind::UWTable:
     return Attribute::UWTable;
-  case ZExt:
+  case LLVMRustAttributeKind::ZExt:
     return Attribute::ZExt;
-  case InReg:
+  case LLVMRustAttributeKind::InReg:
     return Attribute::InReg;
-  case SanitizeThread:
+  case LLVMRustAttributeKind::SanitizeThread:
     return Attribute::SanitizeThread;
-  case SanitizeAddress:
+  case LLVMRustAttributeKind::SanitizeAddress:
     return Attribute::SanitizeAddress;
-  case SanitizeMemory:
+  case LLVMRustAttributeKind::SanitizeMemory:
     return Attribute::SanitizeMemory;
-  case NonLazyBind:
+  case LLVMRustAttributeKind::NonLazyBind:
     return Attribute::NonLazyBind;
-  case OptimizeNone:
+  case LLVMRustAttributeKind::OptimizeNone:
     return Attribute::OptimizeNone;
-  case ReadNone:
+  case LLVMRustAttributeKind::ReadNone:
     return Attribute::ReadNone;
-  case SanitizeHWAddress:
+  case LLVMRustAttributeKind::SanitizeHWAddress:
     return Attribute::SanitizeHWAddress;
-  case WillReturn:
+  case LLVMRustAttributeKind::WillReturn:
     return Attribute::WillReturn;
-  case StackProtectReq:
+  case LLVMRustAttributeKind::StackProtectReq:
     return Attribute::StackProtectReq;
-  case StackProtectStrong:
+  case LLVMRustAttributeKind::StackProtectStrong:
     return Attribute::StackProtectStrong;
-  case StackProtect:
+  case LLVMRustAttributeKind::StackProtect:
     return Attribute::StackProtect;
-  case NoUndef:
+  case LLVMRustAttributeKind::NoUndef:
     return Attribute::NoUndef;
-  case SanitizeMemTag:
+  case LLVMRustAttributeKind::SanitizeMemTag:
     return Attribute::SanitizeMemTag;
-  case ShadowCallStack:
+  case LLVMRustAttributeKind::ShadowCallStack:
     return Attribute::ShadowCallStack;
-  case AllocSize:
+  case LLVMRustAttributeKind::AllocSize:
     return Attribute::AllocSize;
-  case AllocatedPointer:
+  case LLVMRustAttributeKind::AllocatedPointer:
     return Attribute::AllocatedPointer;
-  case AllocAlign:
+  case LLVMRustAttributeKind::AllocAlign:
     return Attribute::AllocAlign;
-  case SanitizeSafeStack:
+  case LLVMRustAttributeKind::SanitizeSafeStack:
     return Attribute::SafeStack;
-  case FnRetThunkExtern:
+  case LLVMRustAttributeKind::FnRetThunkExtern:
     return Attribute::FnRetThunkExtern;
-  case Writable:
+  case LLVMRustAttributeKind::Writable:
     return Attribute::Writable;
-  case DeadOnUnwind:
+  case LLVMRustAttributeKind::DeadOnUnwind:
     return Attribute::DeadOnUnwind;
   }
-  report_fatal_error("bad AttributeKind");
+  report_fatal_error("bad LLVMRustAttributeKind");
 }
 
 template <typename T>
@@ -345,7 +389,7 @@ extern "C" void LLVMRustAddCallSiteAttributes(LLVMValueRef Instr,
 }
 
 extern "C" LLVMAttributeRef
-LLVMRustCreateAttrNoValue(LLVMContextRef C, LLVMRustAttribute RustAttr) {
+LLVMRustCreateAttrNoValue(LLVMContextRef C, LLVMRustAttributeKind RustAttr) {
   return wrap(Attribute::get(*unwrap(C), fromRust(RustAttr)));
 }
 
@@ -1261,6 +1305,14 @@ LLVMRustDIBuilderCreateDebugLocation(unsigned Line, unsigned Column,
   return wrap(Loc);
 }
 
+extern "C" LLVMMetadataRef
+LLVMRustDILocationCloneWithBaseDiscriminator(LLVMMetadataRef Location,
+                                             unsigned BD) {
+  DILocation *Loc = unwrapDIPtr<DILocation>(Location);
+  auto NewLoc = Loc->cloneWithBaseDiscriminator(BD);
+  return wrap(NewLoc.has_value() ? NewLoc.value() : nullptr);
+}
+
 extern "C" uint64_t LLVMRustDIBuilderCreateOpDeref() {
   return dwarf::DW_OP_deref;
 }
@@ -1522,8 +1574,8 @@ LLVMRustUnpackSMDiagnostic(LLVMSMDiagnosticRef DRef, RustStringRef MessageOut,
   const SourceMgr &LSM = *D.getSourceMgr();
   const MemoryBuffer *LBuf =
       LSM.getMemoryBuffer(LSM.FindBufferContainingLoc(D.getLoc()));
-  LLVMRustStringWriteImpl(BufferOut, LBuf->getBufferStart(),
-                          LBuf->getBufferSize());
+  auto BufferOS = RawRustStringOstream(BufferOut);
+  BufferOS << LBuf->getBuffer();
 
   *LocOut = D.getLoc().getPointer() - LBuf->getBufferStart();
 
diff --git a/compiler/rustc_llvm/llvm-wrapper/SymbolWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/SymbolWrapper.cpp
index 54ee79dc290..a910e78d489 100644
--- a/compiler/rustc_llvm/llvm-wrapper/SymbolWrapper.cpp
+++ b/compiler/rustc_llvm/llvm-wrapper/SymbolWrapper.cpp
@@ -8,14 +8,14 @@
 // * https://github.com/llvm/llvm-project/blob/ef6d1ec07c693352c4a60dd58db08d2d8558f6ea/llvm/lib/Object/ArchiveWriter.cpp
 
 #include "LLVMWrapper.h"
-#include "SuppressLLVMWarnings.h"
+
 #include "llvm/ADT/SmallString.h"
 #include "llvm/IR/LLVMContext.h"
 #include "llvm/Object/COFF.h"
 #include "llvm/Object/COFFImportFile.h"
 #include "llvm/Object/IRObjectFile.h"
 #include "llvm/Object/ObjectFile.h"
-#include <llvm/Support/raw_ostream.h>
+#include "llvm/Support/raw_ostream.h"
 
 using namespace llvm;
 using namespace llvm::sys;