diff options
Diffstat (limited to 'compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp')
| -rw-r--r-- | compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp | 230 |
1 files changed, 98 insertions, 132 deletions
diff --git a/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp index 0a42265a6ba..71df17c9ce7 100644 --- a/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp +++ b/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp @@ -1,5 +1,6 @@ #include <stdio.h> +#include <iomanip> #include <vector> #include <set> @@ -9,7 +10,6 @@ #include "llvm/Analysis/TargetLibraryInfo.h" #include "llvm/Analysis/TargetTransformInfo.h" #include "llvm/CodeGen/TargetSubtargetInfo.h" -#include "llvm/InitializePasses.h" #include "llvm/IR/AutoUpgrade.h" #include "llvm/IR/AssemblyAnnotationWriter.h" #include "llvm/IR/IntrinsicInst.h" @@ -27,7 +27,6 @@ #endif #include "llvm/Support/Host.h" #include "llvm/Target/TargetMachine.h" -#include "llvm/Transforms/IPO/PassManagerBuilder.h" #include "llvm/Transforms/IPO/AlwaysInliner.h" #include "llvm/Transforms/IPO/FunctionImport.h" #include "llvm/Transforms/IPO/Internalize.h" @@ -36,7 +35,6 @@ #include "llvm/Transforms/Utils/FunctionImportUtils.h" #include "llvm/LTO/LTO.h" #include "llvm/Bitcode/BitcodeWriter.h" -#include "llvm-c/Transforms/PassManagerBuilder.h" #include "llvm/Transforms/Instrumentation.h" #include "llvm/Transforms/Instrumentation/AddressSanitizer.h" @@ -58,22 +56,6 @@ typedef struct LLVMOpaqueTargetMachine *LLVMTargetMachineRef; DEFINE_STDCXX_CONVERSION_FUNCTIONS(Pass, LLVMPassRef) DEFINE_STDCXX_CONVERSION_FUNCTIONS(TargetMachine, LLVMTargetMachineRef) -extern "C" void LLVMInitializePasses() { - PassRegistry &Registry = *PassRegistry::getPassRegistry(); - initializeCore(Registry); - initializeCodeGen(Registry); - initializeScalarOpts(Registry); - initializeVectorization(Registry); - initializeIPO(Registry); - initializeAnalysis(Registry); - initializeTransformUtils(Registry); - initializeInstCombine(Registry); -#if LLVM_VERSION_LT(16, 0) - initializeInstrumentation(Registry); -#endif - initializeTarget(Registry); -} - extern "C" void LLVMTimeTraceProfilerInitialize() { timeTraceProfilerInitialize( /* TimeTraceGranularity */ 0, @@ -165,6 +147,12 @@ extern "C" void LLVMTimeTraceProfilerFinish(const char* FileName) { #define SUBTARGET_HEXAGON #endif +#ifdef LLVM_COMPONENT_LOONGARCH +#define SUBTARGET_LOONGARCH SUBTARGET(LoongArch) +#else +#define SUBTARGET_LOONGARCH +#endif + #define GEN_SUBTARGETS \ SUBTARGET_X86 \ SUBTARGET_ARM \ @@ -178,6 +166,7 @@ extern "C" void LLVMTimeTraceProfilerFinish(const char* FileName) { SUBTARGET_SPARC \ SUBTARGET_HEXAGON \ SUBTARGET_RISCV \ + SUBTARGET_LOONGARCH \ #define SUBTARGET(x) \ namespace llvm { \ @@ -309,7 +298,6 @@ static Reloc::Model fromRust(LLVMRustRelocModel RustReloc) { report_fatal_error("Bad RelocModel."); } -#ifdef LLVM_RUSTLLVM /// getLongestEntryLength - Return the length of the longest entry in the table. template<typename KV> static size_t getLongestEntryLength(ArrayRef<KV> Table) { @@ -319,54 +307,79 @@ static size_t getLongestEntryLength(ArrayRef<KV> Table) { return MaxLen; } -extern "C" void LLVMRustPrintTargetCPUs(LLVMTargetMachineRef TM) { +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::getProcessTriple()).getArch(); + 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<SubtargetSubTypeKV> CPUTable = MCInfo->getAllProcessorDescriptions(); +#elif defined(LLVM_RUSTLLVM) const ArrayRef<SubtargetSubTypeKV> CPUTable = MCInfo->getCPUTable(); +#else + 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) - printf(" %-*s\n", MaxCPULen, CPU.Key); - printf("\n"); + 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"; + } + + const auto &BufString = Buf.str(); + Print(Out, BufString.data(), BufString.size()); } extern "C" size_t LLVMRustGetTargetFeaturesCount(LLVMTargetMachineRef TM) { +#ifdef LLVM_RUSTLLVM const TargetMachine *Target = unwrap(TM); const MCSubtargetInfo *MCInfo = Target->getMCSubtargetInfo(); const ArrayRef<SubtargetFeatureKV> FeatTable = MCInfo->getFeatureTable(); return FeatTable.size(); +#else + return 0; +#endif } extern "C" void LLVMRustGetTargetFeature(LLVMTargetMachineRef TM, size_t Index, const char** Feature, const char** Desc) { +#ifdef LLVM_RUSTLLVM const TargetMachine *Target = unwrap(TM); const MCSubtargetInfo *MCInfo = Target->getMCSubtargetInfo(); const ArrayRef<SubtargetFeatureKV> FeatTable = MCInfo->getFeatureTable(); const SubtargetFeatureKV Feat = FeatTable[Index]; *Feature = Feat.Key; *Desc = Feat.Desc; -} - -#else - -extern "C" void LLVMRustPrintTargetCPUs(LLVMTargetMachineRef) { - printf("Target CPU help is not supported by this LLVM version.\n\n"); -} - -extern "C" size_t LLVMRustGetTargetFeaturesCount(LLVMTargetMachineRef) { - return 0; -} - -extern "C" void LLVMRustGetTargetFeature(LLVMTargetMachineRef, const char**, const char**) {} #endif +} extern "C" const char* LLVMRustGetHostCPUName(size_t *len) { StringRef Name = sys::getHostCPUName(); @@ -387,7 +400,8 @@ extern "C" LLVMTargetMachineRef LLVMRustCreateTargetMachine( bool EmitStackSizeSection, bool RelaxELFRelocations, bool UseInitArray, - const char *SplitDwarfFile) { + const char *SplitDwarfFile, + bool ForceEmulatedTls) { auto OptLevel = fromRust(RustOptLevel); auto RM = fromRust(RustReloc); @@ -420,6 +434,15 @@ extern "C" LLVMTargetMachineRef LLVMRustCreateTargetMachine( Options.RelaxELFRelocations = RelaxELFRelocations; Options.UseInitArray = UseInitArray; +#if LLVM_VERSION_LT(17, 0) + if (ForceEmulatedTls) { + Options.ExplicitEmulatedTLS = true; + Options.EmulatedTLS = true; + } +#else + Options.EmulatedTLS = ForceEmulatedTls || Trip.hasDefaultEmulatedTLS(); +#endif + if (TrapUnreachable) { // Tell LLVM to codegen `unreachable` into an explicit trap instruction. // This limits the extent of possible undefined behavior in some cases, as @@ -530,14 +553,14 @@ extern "C" typedef void (*LLVMRustSelfProfileBeforePassCallback)(void*, // LlvmS extern "C" typedef void (*LLVMRustSelfProfileAfterPassCallback)(void*); // LlvmSelfProfiler std::string LLVMRustwrappedIrGetName(const llvm::Any &WrappedIr) { - if (any_isa<const Module *>(WrappedIr)) - return any_cast<const Module *>(WrappedIr)->getName().str(); - if (any_isa<const Function *>(WrappedIr)) - return any_cast<const Function *>(WrappedIr)->getName().str(); - if (any_isa<const Loop *>(WrappedIr)) - return any_cast<const Loop *>(WrappedIr)->getName().str(); - if (any_isa<const LazyCallGraph::SCC *>(WrappedIr)) - return any_cast<const LazyCallGraph::SCC *>(WrappedIr)->getName(); + if (const auto *Cast = any_cast<const Module *>(&WrappedIr)) + return (*Cast)->getName().str(); + if (const auto *Cast = any_cast<const Function *>(&WrappedIr)) + return (*Cast)->getName().str(); + if (const auto *Cast = any_cast<const Loop *>(&WrappedIr)) + return (*Cast)->getName().str(); + if (const auto *Cast = any_cast<const LazyCallGraph::SCC *>(&WrappedIr)) + return (*Cast)->getName(); return "<UNKNOWN>"; } @@ -656,6 +679,7 @@ LLVMRustOptimize( assert(!PGOUsePath && !PGOSampleUsePath); PGOOpt = PGOOptions(PGOGenPath, "", "", #if LLVM_VERSION_GE(17, 0) + "", FS, #endif PGOOptions::IRInstr, PGOOptions::NoCSAction, @@ -664,6 +688,7 @@ LLVMRustOptimize( assert(!PGOSampleUsePath); PGOOpt = PGOOptions(PGOUsePath, "", "", #if LLVM_VERSION_GE(17, 0) + "", FS, #endif PGOOptions::IRUse, PGOOptions::NoCSAction, @@ -671,6 +696,7 @@ LLVMRustOptimize( } else if (PGOSampleUsePath) { PGOOpt = PGOOptions(PGOSampleUsePath, "", "", #if LLVM_VERSION_GE(17, 0) + "", FS, #endif PGOOptions::SampleUse, PGOOptions::NoCSAction, @@ -678,6 +704,7 @@ LLVMRustOptimize( } else if (DebugInfoForProfiling) { PGOOpt = PGOOptions("", "", "", #if LLVM_VERSION_GE(17, 0) + "", FS, #endif PGOOptions::NoAction, PGOOptions::NoCSAction, @@ -734,6 +761,9 @@ LLVMRustOptimize( if (InstrProfileOutput) { Options.InstrProfileOutput = InstrProfileOutput; } + // cargo run tests in multhreading mode by default + // so use atomics for coverage counters + Options.Atomic = true; MPM.addPass(InstrProfiling(Options, false)); } ); @@ -818,7 +848,7 @@ LLVMRustOptimize( ModulePassManager MPM; bool NeedThinLTOBufferPasses = UseThinLTOBuffers; if (!NoPrepopulatePasses) { - // The pre-link pipelines don't support O0 and require using budilO0DefaultPipeline() instead. + // The pre-link pipelines don't support O0 and require using buildO0DefaultPipeline() instead. // At the same time, the LTO pipelines do support O0 and using them is required. bool IsLTO = OptStage == LLVMRustOptStage::ThinLTO || OptStage == LLVMRustOptStage::FatLTO; if (OptLevel == OptimizationLevel::O0 && !IsLTO) { @@ -1004,23 +1034,8 @@ LLVMRustPrintModule(LLVMModuleRef M, const char *Path, DemangleFn Demangle) { } extern "C" void LLVMRustPrintPasses() { - LLVMInitializePasses(); - struct MyListener : PassRegistrationListener { - void passEnumerate(const PassInfo *Info) { - StringRef PassArg = Info->getPassArgument(); - StringRef PassName = Info->getPassName(); - if (!PassArg.empty()) { - // These unsigned->signed casts could theoretically overflow, but - // realistically never will (and even if, the result is implementation - // defined rather plain UB). - printf("%15.*s - %.*s\n", (int)PassArg.size(), PassArg.data(), - (int)PassName.size(), PassName.data()); - } - } - } Listener; - - PassRegistry *PR = PassRegistry::getPassRegistry(); - PR->enumerateWith(&Listener); + PassBuilder PB; + PB.printPassNames(outs()); } extern "C" void LLVMRustRunRestrictionPass(LLVMModuleRef M, char **Symbols, @@ -1192,13 +1207,6 @@ LLVMRustCreateThinLTOData(LLVMRustThinLTOModule *modules, // Otherwise, we sometimes lose `static` values -- see #60184. computeDeadSymbolsWithConstProp(Ret->Index, Ret->GUIDPreservedSymbols, deadIsPrevailing, /* ImportEnabled = */ false); - ComputeCrossModuleImport( - Ret->Index, - Ret->ModuleToDefinedGVSummaries, - Ret->ImportLists, - Ret->ExportLists - ); - // Resolve LinkOnce/Weak symbols, this has to be computed early be cause it // impacts the caching. // @@ -1215,6 +1223,16 @@ LLVMRustCreateThinLTOData(LLVMRustThinLTOModule *modules, return true; return Prevailing->second == S; }; + ComputeCrossModuleImport( + Ret->Index, + Ret->ModuleToDefinedGVSummaries, +#if LLVM_VERSION_GE(17, 0) + isPrevailing, +#endif + Ret->ImportLists, + Ret->ExportLists + ); + auto recordNewLinkage = [&](StringRef ModuleIdentifier, GlobalValue::GUID GUID, GlobalValue::LinkageTypes NewLinkage) { @@ -1348,6 +1366,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); @@ -1461,63 +1484,6 @@ LLVMRustGetBitcodeSliceFromObjectData(const char *data, return BitcodeOrError->getBufferStart(); } -// Rewrite all `DICompileUnit` pointers to the `DICompileUnit` specified. See -// the comment in `back/lto.rs` for why this exists. -extern "C" void -LLVMRustThinLTOGetDICompileUnit(LLVMModuleRef Mod, - DICompileUnit **A, - DICompileUnit **B) { - Module *M = unwrap(Mod); - DICompileUnit **Cur = A; - DICompileUnit **Next = B; - for (DICompileUnit *CU : M->debug_compile_units()) { - *Cur = CU; - Cur = Next; - Next = nullptr; - if (Cur == nullptr) - break; - } -} - -// Rewrite all `DICompileUnit` pointers to the `DICompileUnit` specified. See -// the comment in `back/lto.rs` for why this exists. -extern "C" void -LLVMRustThinLTOPatchDICompileUnit(LLVMModuleRef Mod, DICompileUnit *Unit) { - Module *M = unwrap(Mod); - - // If the original source module didn't have a `DICompileUnit` then try to - // merge all the existing compile units. If there aren't actually any though - // then there's not much for us to do so return. - if (Unit == nullptr) { - for (DICompileUnit *CU : M->debug_compile_units()) { - Unit = CU; - break; - } - if (Unit == nullptr) - return; - } - - // Use LLVM's built-in `DebugInfoFinder` to find a bunch of debuginfo and - // process it recursively. Note that we used to specifically iterate over - // instructions to ensure we feed everything into it, but `processModule` - // started doing this the same way in LLVM 7 (commit d769eb36ab2b8). - DebugInfoFinder Finder; - Finder.processModule(*M); - - // After we've found all our debuginfo, rewrite all subprograms to point to - // the same `DICompileUnit`. - for (auto &F : Finder.subprograms()) { - F->replaceUnit(Unit); - } - - // Erase any other references to other `DICompileUnit` instances, the verifier - // will later ensure that we don't actually have any other stale references to - // worry about. - auto *MD = M->getNamedMetadata("llvm.dbg.cu"); - MD->clearOperands(); - MD->addOperand(Unit); -} - // 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 |
