diff options
Diffstat (limited to 'compiler/rustc_llvm/llvm-wrapper')
| -rw-r--r-- | compiler/rustc_llvm/llvm-wrapper/LLVMWrapper.h | 1 | ||||
| -rw-r--r-- | compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp | 277 | ||||
| -rw-r--r-- | compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp | 134 | ||||
| -rw-r--r-- | compiler/rustc_llvm/llvm-wrapper/SymbolWrapper.cpp | 96 |
4 files changed, 196 insertions, 312 deletions
diff --git a/compiler/rustc_llvm/llvm-wrapper/LLVMWrapper.h b/compiler/rustc_llvm/llvm-wrapper/LLVMWrapper.h index 015c1c52bef..727cfc4416e 100644 --- a/compiler/rustc_llvm/llvm-wrapper/LLVMWrapper.h +++ b/compiler/rustc_llvm/llvm-wrapper/LLVMWrapper.h @@ -76,7 +76,6 @@ enum LLVMRustAttribute { OptimizeNone = 24, ReturnsTwice = 25, ReadNone = 26, - InaccessibleMemOnly = 27, SanitizeHWAddress = 28, WillReturn = 29, StackProtectReq = 30, diff --git a/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp index 24e18826048..1a3d458c300 100644 --- a/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp +++ b/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp @@ -31,13 +31,12 @@ #include "llvm/Transforms/IPO/PassManagerBuilder.h" #include "llvm/Transforms/IPO/AlwaysInliner.h" #include "llvm/Transforms/IPO/FunctionImport.h" -#if LLVM_VERSION_GE(15, 0) +#include "llvm/Transforms/IPO/Internalize.h" #include "llvm/Transforms/IPO/ThinLTOBitcodeWriter.h" -#endif #include "llvm/Transforms/Utils/AddDiscriminators.h" #include "llvm/Transforms/Utils/FunctionImportUtils.h" #include "llvm/LTO/LTO.h" -#include "llvm/Bitcode/BitcodeWriterPass.h" +#include "llvm/Bitcode/BitcodeWriter.h" #include "llvm-c/Transforms/PassManagerBuilder.h" #include "llvm/Transforms/Instrumentation.h" @@ -70,7 +69,9 @@ extern "C" void LLVMInitializePasses() { initializeAnalysis(Registry); initializeTransformUtils(Registry); initializeInstCombine(Registry); +#if LLVM_VERSION_LT(16, 0) initializeInstrumentation(Registry); +#endif initializeTarget(Registry); } @@ -93,172 +94,6 @@ extern "C" void LLVMTimeTraceProfilerFinish(const char* FileName) { timeTraceProfilerCleanup(); } -extern "C" LLVMPassRef LLVMRustFindAndCreatePass(const char *PassName) { -#if LLVM_VERSION_LT(15, 0) - StringRef SR(PassName); - PassRegistry *PR = PassRegistry::getPassRegistry(); - - const PassInfo *PI = PR->getPassInfo(SR); - if (PI) { - return wrap(PI->createPass()); - } - return nullptr; -#else - report_fatal_error("Legacy PM not supported with LLVM 15"); -#endif -} - -extern "C" LLVMPassRef LLVMRustCreateAddressSanitizerFunctionPass(bool Recover) { -#if LLVM_VERSION_LT(15, 0) - const bool CompileKernel = false; - const bool UseAfterScope = true; - - return wrap(createAddressSanitizerFunctionPass(CompileKernel, Recover, UseAfterScope)); -#else - report_fatal_error("Legacy PM not supported with LLVM 15"); -#endif -} - -extern "C" LLVMPassRef LLVMRustCreateModuleAddressSanitizerPass(bool Recover) { -#if LLVM_VERSION_LT(15, 0) - const bool CompileKernel = false; - - return wrap(createModuleAddressSanitizerLegacyPassPass(CompileKernel, Recover)); -#else - report_fatal_error("Legacy PM not supported with LLVM 15"); -#endif -} - -extern "C" LLVMPassRef LLVMRustCreateMemorySanitizerPass(int TrackOrigins, bool Recover) { -#if LLVM_VERSION_LT(15, 0) - const bool CompileKernel = false; - - return wrap(createMemorySanitizerLegacyPassPass( -#if LLVM_VERSION_GE(14, 0) - MemorySanitizerOptions{TrackOrigins, Recover, CompileKernel, /*EagerChecks=*/true} -#else - MemorySanitizerOptions{TrackOrigins, Recover, CompileKernel} -#endif - )); -#else - report_fatal_error("Legacy PM not supported with LLVM 15"); -#endif -} - -extern "C" LLVMPassRef LLVMRustCreateThreadSanitizerPass() { -#if LLVM_VERSION_LT(15, 0) - return wrap(createThreadSanitizerLegacyPassPass()); -#else - report_fatal_error("Legacy PM not supported with LLVM 15"); -#endif -} - -extern "C" LLVMPassRef LLVMRustCreateHWAddressSanitizerPass(bool Recover) { -#if LLVM_VERSION_LT(15, 0) - const bool CompileKernel = false; - - return wrap(createHWAddressSanitizerLegacyPassPass(CompileKernel, Recover)); -#else - report_fatal_error("Legacy PM not supported with LLVM 15"); -#endif -} - -extern "C" void LLVMRustAddPass(LLVMPassManagerRef PMR, LLVMPassRef RustPass) { -#if LLVM_VERSION_LT(15, 0) - assert(RustPass); - Pass *Pass = unwrap(RustPass); - PassManagerBase *PMB = unwrap(PMR); - PMB->add(Pass); -#else - report_fatal_error("Legacy PM not supported with LLVM 15"); -#endif -} - -extern "C" LLVMPassManagerBuilderRef LLVMRustPassManagerBuilderCreate() { -#if LLVM_VERSION_LT(15, 0) - return LLVMPassManagerBuilderCreate(); -#else - report_fatal_error("Legacy PM not supported with LLVM 15"); -#endif -} - -extern "C" void LLVMRustPassManagerBuilderDispose(LLVMPassManagerBuilderRef PMB) { -#if LLVM_VERSION_LT(15, 0) - LLVMPassManagerBuilderDispose(PMB); -#else - report_fatal_error("Legacy PM not supported with LLVM 15"); -#endif -} - -extern "C" void LLVMRustPassManagerBuilderPopulateFunctionPassManager( - LLVMPassManagerBuilderRef PMB, LLVMPassManagerRef PM) { -#if LLVM_VERSION_LT(15, 0) - LLVMPassManagerBuilderPopulateFunctionPassManager(PMB, PM); -#else - report_fatal_error("Legacy PM not supported with LLVM 15"); -#endif -} - -extern "C" void LLVMRustPassManagerBuilderPopulateModulePassManager( - LLVMPassManagerBuilderRef PMB, LLVMPassManagerRef PM) { -#if LLVM_VERSION_LT(15, 0) - LLVMPassManagerBuilderPopulateModulePassManager(PMB, PM); -#else - report_fatal_error("Legacy PM not supported with LLVM 15"); -#endif -} - -extern "C" void LLVMRustPassManagerBuilderPopulateLTOPassManager( - LLVMPassManagerBuilderRef PMB, LLVMPassManagerRef PM, bool Internalize, bool RunInliner) { -#if LLVM_VERSION_LT(15, 0) - LLVMPassManagerBuilderPopulateLTOPassManager(PMB, PM, Internalize, RunInliner); -#else - report_fatal_error("Legacy PM not supported with LLVM 15"); -#endif -} - -extern "C" -void LLVMRustPassManagerBuilderPopulateThinLTOPassManager( - LLVMPassManagerBuilderRef PMBR, - LLVMPassManagerRef PMR -) { -#if LLVM_VERSION_LT(15, 0) - unwrap(PMBR)->populateThinLTOPassManager(*unwrap(PMR)); -#else - report_fatal_error("Legacy PM not supported with LLVM 15"); -#endif -} - -extern "C" void LLVMRustPassManagerBuilderUseInlinerWithThreshold( - LLVMPassManagerBuilderRef PMB, unsigned Threshold) { -#if LLVM_VERSION_LT(15, 0) - LLVMPassManagerBuilderUseInlinerWithThreshold(PMB, Threshold); -#else - report_fatal_error("Legacy PM not supported with LLVM 15"); -#endif -} - -extern "C" -void LLVMRustAddLastExtensionPasses( - LLVMPassManagerBuilderRef PMBR, LLVMPassRef *Passes, size_t NumPasses) { -#if LLVM_VERSION_LT(15, 0) - auto AddExtensionPasses = [Passes, NumPasses]( - const PassManagerBuilder &Builder, PassManagerBase &PM) { - for (size_t I = 0; I < NumPasses; I++) { - PM.add(unwrap(Passes[I])); - } - }; - // Add the passes to both of the pre-finalization extension points, - // so they are run for optimized and non-optimized builds. - unwrap(PMBR)->addExtension(PassManagerBuilder::EP_OptimizerLast, - AddExtensionPasses); - unwrap(PMBR)->addExtension(PassManagerBuilder::EP_EnabledOnOptLevel0, - AddExtensionPasses); -#else - report_fatal_error("Legacy PM not supported with LLVM 15"); -#endif -} - #ifdef LLVM_COMPONENT_X86 #define SUBTARGET_X86 SUBTARGET(X86) #else @@ -370,7 +205,12 @@ enum class LLVMRustCodeModel { None, }; -static Optional<CodeModel::Model> fromRust(LLVMRustCodeModel Model) { +#if LLVM_VERSION_LT(16, 0) +static Optional<CodeModel::Model> +#else +static std::optional<CodeModel::Model> +#endif +fromRust(LLVMRustCodeModel Model) { switch (Model) { case LLVMRustCodeModel::Tiny: return CodeModel::Tiny; @@ -604,47 +444,6 @@ extern "C" void LLVMRustDisposeTargetMachine(LLVMTargetMachineRef TM) { delete unwrap(TM); } -extern "C" void LLVMRustConfigurePassManagerBuilder( - LLVMPassManagerBuilderRef PMBR, LLVMRustCodeGenOptLevel OptLevel, - bool MergeFunctions, bool SLPVectorize, bool LoopVectorize, bool PrepareForThinLTO, - const char* PGOGenPath, const char* PGOUsePath, const char* PGOSampleUsePath, - int SizeLevel) { -#if LLVM_VERSION_LT(15, 0) - unwrap(PMBR)->MergeFunctions = MergeFunctions; - unwrap(PMBR)->SLPVectorize = SLPVectorize; - unwrap(PMBR)->OptLevel = fromRust(OptLevel); - unwrap(PMBR)->LoopVectorize = LoopVectorize; - unwrap(PMBR)->PrepareForThinLTO = PrepareForThinLTO; - unwrap(PMBR)->SizeLevel = SizeLevel; - unwrap(PMBR)->DisableUnrollLoops = SizeLevel != 0; - - if (PGOGenPath) { - assert(!PGOUsePath && !PGOSampleUsePath); - unwrap(PMBR)->EnablePGOInstrGen = true; - unwrap(PMBR)->PGOInstrGen = PGOGenPath; - } else if (PGOUsePath) { - assert(!PGOSampleUsePath); - unwrap(PMBR)->PGOInstrUse = PGOUsePath; - } else if (PGOSampleUsePath) { - unwrap(PMBR)->PGOSampleUse = PGOSampleUsePath; - } -#else - report_fatal_error("Legacy PM not supported with LLVM 15"); -#endif -} - -// Unfortunately, the LLVM C API doesn't provide a way to set the `LibraryInfo` -// field of a PassManagerBuilder, we expose our own method of doing so. -extern "C" void LLVMRustAddBuilderLibraryInfo(LLVMPassManagerBuilderRef PMBR, - LLVMModuleRef M, - bool DisableSimplifyLibCalls) { - Triple TargetTriple(unwrap(M)->getTargetTriple()); - TargetLibraryInfoImpl *TLI = new TargetLibraryInfoImpl(TargetTriple); - if (DisableSimplifyLibCalls) - TLI->disableAllFunctions(); - unwrap(PMBR)->LibraryInfo = TLI; -} - // Unfortunately, the LLVM C API doesn't provide a way to create the // TargetLibraryInfo pass, so we use this method to do so. extern "C" void LLVMRustAddLibraryInfo(LLVMPassManagerRef PMR, LLVMModuleRef M, @@ -656,27 +455,6 @@ extern "C" void LLVMRustAddLibraryInfo(LLVMPassManagerRef PMR, LLVMModuleRef M, unwrap(PMR)->add(new TargetLibraryInfoWrapperPass(TLII)); } -// Unfortunately, the LLVM C API doesn't provide an easy way of iterating over -// all the functions in a module, so we do that manually here. You'll find -// similar code in clang's BackendUtil.cpp file. -extern "C" void LLVMRustRunFunctionPassManager(LLVMPassManagerRef PMR, - LLVMModuleRef M) { - llvm::legacy::FunctionPassManager *P = - unwrap<llvm::legacy::FunctionPassManager>(PMR); - P->doInitialization(); - - // Upgrade all calls to old intrinsics first. - for (Module::iterator I = unwrap(M)->begin(), E = unwrap(M)->end(); I != E;) - UpgradeCallsToIntrinsic(&*I++); // must be post-increment, as we remove - - for (Module::iterator I = unwrap(M)->begin(), E = unwrap(M)->end(); I != E; - ++I) - if (!I->isDeclaration()) - P->run(*I); - - P->doFinalization(); -} - extern "C" void LLVMRustSetLLVMOptions(int Argc, char **Argv) { // Initializing the command-line options more than once is not allowed. So, // check if they've already been initialized. (This could happen if we're @@ -820,7 +598,7 @@ struct LLVMRustSanitizerOptions { }; extern "C" LLVMRustResult -LLVMRustOptimizeWithNewPassManager( +LLVMRustOptimize( LLVMModuleRef ModuleRef, LLVMTargetMachineRef TMRef, LLVMRustPassBuilderOptLevel OptLevelRust, @@ -854,14 +632,22 @@ LLVMRustOptimizeWithNewPassManager( bool DebugPassManager = false; PassInstrumentationCallbacks PIC; +#if LLVM_VERSION_LT(16, 0) StandardInstrumentations SI(DebugPassManager); +#else + StandardInstrumentations SI(TheModule->getContext(), DebugPassManager); +#endif SI.registerCallbacks(PIC); if (LlvmSelfProfiler){ LLVMSelfProfileInitializeCallbacks(PIC,LlvmSelfProfiler,BeforePassCallback,AfterPassCallback); } +#if LLVM_VERSION_LT(16, 0) Optional<PGOOptions> PGOOpt; +#else + std::optional<PGOOptions> PGOOpt; +#endif if (PGOGenPath) { assert(!PGOUsePath && !PGOSampleUsePath); PGOOpt = PGOOptions(PGOGenPath, "", "", PGOOptions::IRInstr, @@ -1027,7 +813,7 @@ LLVMRustOptimizeWithNewPassManager( auto Plugin = PassPlugin::Load(PluginPath.str()); if (!Plugin) { LLVMRustSetLastError(("Failed to load pass plugin" + PluginPath.str()).c_str()); - continue; + return LLVMRustResult::Failure; } Plugin->registerPassBuilderCallbacks(PB); } @@ -1241,15 +1027,8 @@ extern "C" void LLVMRustPrintPasses() { PR->enumerateWith(&Listener); } -extern "C" void LLVMRustAddAlwaysInlinePass(LLVMPassManagerBuilderRef PMBR, - bool AddLifetimes) { - unwrap(PMBR)->Inliner = llvm::createAlwaysInlinerLegacyPass(AddLifetimes); -} - extern "C" void LLVMRustRunRestrictionPass(LLVMModuleRef M, char **Symbols, size_t Len) { - llvm::legacy::PassManager passes; - auto PreserveFunctions = [=](const GlobalValue &GV) { for (size_t I = 0; I < Len; I++) { if (GV.getName() == Symbols[I]) { @@ -1259,9 +1038,7 @@ extern "C" void LLVMRustRunRestrictionPass(LLVMModuleRef M, char **Symbols, return false; }; - passes.add(llvm::createInternalizePass(PreserveFunctions)); - - passes.run(*unwrap(M)); + internalizeModule(*unwrap(M), PreserveFunctions); } extern "C" void @@ -1282,7 +1059,7 @@ extern "C" void LLVMRustSetModulePIELevel(LLVMModuleRef M) { extern "C" void LLVMRustSetModuleCodeModel(LLVMModuleRef M, LLVMRustCodeModel Model) { auto CM = fromRust(Model); - if (!CM.hasValue()) + if (!CM) return; unwrap(M)->setCodeModel(*CM); } @@ -1610,11 +1387,6 @@ LLVMRustThinLTOBufferCreate(LLVMModuleRef M, bool is_thin) { raw_string_ostream OS(Ret->data); { if (is_thin) { -#if LLVM_VERSION_LT(15, 0) - legacy::PassManager PM; - PM.add(createWriteThinLTOBitcodePass(OS)); - PM.run(*unwrap(M)); -#else PassBuilder PB; LoopAnalysisManager LAM; FunctionAnalysisManager FAM; @@ -1628,11 +1400,8 @@ LLVMRustThinLTOBufferCreate(LLVMModuleRef M, bool is_thin) { ModulePassManager MPM; MPM.addPass(ThinLTOBitcodeWriterPass(OS, nullptr)); MPM.run(*unwrap(M), MAM); -#endif } else { - legacy::PassManager PM; - PM.add(createBitcodeWriterPass(OS)); - PM.run(*unwrap(M)); + WriteBitcodeToFile(*unwrap(M), OS); } } } diff --git a/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp index 6ee3c7d6821..5831d4693f1 100644 --- a/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp +++ b/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp @@ -8,13 +8,18 @@ #include "llvm/IR/Intrinsics.h" #include "llvm/IR/IntrinsicsARM.h" #include "llvm/IR/Mangler.h" +#if LLVM_VERSION_GE(16, 0) +#include "llvm/Support/ModRef.h" +#endif #include "llvm/Object/Archive.h" #include "llvm/Object/COFFImportFile.h" #include "llvm/Object/ObjectFile.h" #include "llvm/Pass.h" -#include "llvm/Bitcode/BitcodeWriterPass.h" +#include "llvm/Bitcode/BitcodeWriter.h" #include "llvm/Support/Signals.h" +#if LLVM_VERSION_LT(16, 0) #include "llvm/ADT/Optional.h" +#endif #include <iostream> @@ -213,8 +218,6 @@ static Attribute::AttrKind fromRust(LLVMRustAttribute Kind) { return Attribute::ReturnsTwice; case ReadNone: return Attribute::ReadNone; - case InaccessibleMemOnly: - return Attribute::InaccessibleMemOnly; case SanitizeHWAddress: return Attribute::SanitizeHWAddress; case WillReturn: @@ -379,6 +382,43 @@ extern "C" LLVMAttributeRef LLVMRustCreateAllocKindAttr(LLVMContextRef C, uint64 #endif } +// Simplified representation of `MemoryEffects` across the FFI boundary. +// +// Each variant corresponds to one of the static factory methods on `MemoryEffects`. +enum class LLVMRustMemoryEffects { + None, + ReadOnly, + InaccessibleMemOnly, +}; + +extern "C" LLVMAttributeRef LLVMRustCreateMemoryEffectsAttr(LLVMContextRef C, + LLVMRustMemoryEffects Effects) { +#if LLVM_VERSION_GE(16, 0) + switch (Effects) { + case LLVMRustMemoryEffects::None: + return wrap(Attribute::getWithMemoryEffects(*unwrap(C), MemoryEffects::none())); + case LLVMRustMemoryEffects::ReadOnly: + return wrap(Attribute::getWithMemoryEffects(*unwrap(C), MemoryEffects::readOnly())); + case LLVMRustMemoryEffects::InaccessibleMemOnly: + return wrap(Attribute::getWithMemoryEffects(*unwrap(C), + MemoryEffects::inaccessibleMemOnly())); + default: + report_fatal_error("bad MemoryEffects."); + } +#else + switch (Effects) { + case LLVMRustMemoryEffects::None: + return wrap(Attribute::get(*unwrap(C), Attribute::ReadNone)); + case LLVMRustMemoryEffects::ReadOnly: + return wrap(Attribute::get(*unwrap(C), Attribute::ReadOnly)); + case LLVMRustMemoryEffects::InaccessibleMemOnly: + return wrap(Attribute::get(*unwrap(C), Attribute::InaccessibleMemOnly)); + default: + report_fatal_error("bad MemoryEffects."); + } +#endif +} + // Enable a fast-math flag // // https://llvm.org/docs/LangRef.html#fast-math-flags @@ -406,45 +446,6 @@ extern "C" LLVMValueRef LLVMRustBuildAtomicStore(LLVMBuilderRef B, return wrap(SI); } -// FIXME: Use the C-API LLVMBuildAtomicCmpXchg and LLVMSetWeak -// once we raise our minimum support to LLVM 10. -extern "C" LLVMValueRef -LLVMRustBuildAtomicCmpXchg(LLVMBuilderRef B, LLVMValueRef Target, - LLVMValueRef Old, LLVMValueRef Source, - LLVMAtomicOrdering Order, - LLVMAtomicOrdering FailureOrder, LLVMBool Weak) { - // Rust probably knows the alignment of the target value and should be able to - // specify something more precise than MaybeAlign here. See also - // https://reviews.llvm.org/D97224 which may be a useful reference. - AtomicCmpXchgInst *ACXI = unwrap(B)->CreateAtomicCmpXchg( - unwrap(Target), unwrap(Old), unwrap(Source), llvm::MaybeAlign(), fromRust(Order), - fromRust(FailureOrder)); - ACXI->setWeak(Weak); - return wrap(ACXI); -} - -enum class LLVMRustSynchronizationScope { - SingleThread, - CrossThread, -}; - -static SyncScope::ID fromRust(LLVMRustSynchronizationScope Scope) { - switch (Scope) { - case LLVMRustSynchronizationScope::SingleThread: - return SyncScope::SingleThread; - case LLVMRustSynchronizationScope::CrossThread: - return SyncScope::System; - default: - report_fatal_error("bad SynchronizationScope."); - } -} - -extern "C" LLVMValueRef -LLVMRustBuildAtomicFence(LLVMBuilderRef B, LLVMAtomicOrdering Order, - LLVMRustSynchronizationScope Scope) { - return wrap(unwrap(B)->CreateFence(fromRust(Order), fromRust(Scope))); -} - enum class LLVMRustAsmDialect { Att, Intel, @@ -709,7 +710,11 @@ enum class LLVMRustChecksumKind { SHA256, }; +#if LLVM_VERSION_LT(16, 0) static Optional<DIFile::ChecksumKind> fromRust(LLVMRustChecksumKind Kind) { +#else +static std::optional<DIFile::ChecksumKind> fromRust(LLVMRustChecksumKind Kind) { +#endif switch (Kind) { case LLVMRustChecksumKind::None: return None; @@ -788,8 +793,18 @@ extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateFile( const char *Filename, size_t FilenameLen, const char *Directory, size_t DirectoryLen, LLVMRustChecksumKind CSKind, const char *Checksum, size_t ChecksumLen) { + +#if LLVM_VERSION_LT(16, 0) Optional<DIFile::ChecksumKind> llvmCSKind = fromRust(CSKind); +#else + std::optional<DIFile::ChecksumKind> llvmCSKind = fromRust(CSKind); +#endif + +#if LLVM_VERSION_LT(16, 0) Optional<DIFile::ChecksumInfo<StringRef>> CSInfo{}; +#else + std::optional<DIFile::ChecksumInfo<StringRef>> CSInfo{}; +#endif if (llvmCSKind) CSInfo.emplace(*llvmCSKind, StringRef{Checksum, ChecksumLen}); return wrap(Builder->createFile(StringRef(Filename, FilenameLen), @@ -1037,8 +1052,9 @@ extern "C" LLVMValueRef LLVMRustDIBuilderInsertDeclareAtEnd( extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateEnumerator( LLVMRustDIBuilderRef Builder, const char *Name, size_t NameLen, - int64_t Value, bool IsUnsigned) { - return wrap(Builder->createEnumerator(StringRef(Name, NameLen), Value, IsUnsigned)); + const uint64_t Value[2], unsigned SizeInBits, bool IsUnsigned) { + return wrap(Builder->createEnumerator(StringRef(Name, NameLen), + APSInt(APInt(SizeInBits, makeArrayRef(Value, 2)), IsUnsigned))); } extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateEnumerationType( @@ -1112,6 +1128,10 @@ extern "C" uint64_t LLVMRustDIBuilderCreateOpPlusUconst() { return dwarf::DW_OP_plus_uconst; } +extern "C" int64_t LLVMRustDIBuilderCreateOpLLVMFragment() { + return dwarf::DW_OP_LLVM_fragment; +} + extern "C" void LLVMRustWriteTypeToString(LLVMTypeRef Ty, RustStringRef Str) { RawRustStringOstream OS(Str); unwrap<llvm::Type>(Ty)->print(OS); @@ -1456,13 +1476,13 @@ extern "C" void LLVMRustFreeOperandBundleDef(OperandBundleDef *Bundle) { extern "C" LLVMValueRef LLVMRustBuildCall(LLVMBuilderRef B, LLVMTypeRef Ty, LLVMValueRef Fn, LLVMValueRef *Args, unsigned NumArgs, - OperandBundleDef *Bundle) { + OperandBundleDef **OpBundles, + unsigned NumOpBundles) { Value *Callee = unwrap(Fn); FunctionType *FTy = unwrap<FunctionType>(Ty); - unsigned Len = Bundle ? 1 : 0; - ArrayRef<OperandBundleDef> Bundles = makeArrayRef(Bundle, Len); return wrap(unwrap(B)->CreateCall( - FTy, Callee, makeArrayRef(unwrap(Args), NumArgs), Bundles)); + FTy, Callee, makeArrayRef(unwrap(Args), NumArgs), + makeArrayRef(*OpBundles, NumOpBundles))); } extern "C" LLVMValueRef LLVMRustGetInstrProfIncrementIntrinsic(LLVMModuleRef M) { @@ -1502,14 +1522,14 @@ extern "C" LLVMValueRef LLVMRustBuildInvoke(LLVMBuilderRef B, LLVMTypeRef Ty, LLVMValueRef Fn, LLVMValueRef *Args, unsigned NumArgs, LLVMBasicBlockRef Then, LLVMBasicBlockRef Catch, - OperandBundleDef *Bundle, const char *Name) { + OperandBundleDef **OpBundles, unsigned NumOpBundles, + const char *Name) { Value *Callee = unwrap(Fn); FunctionType *FTy = unwrap<FunctionType>(Ty); - unsigned Len = Bundle ? 1 : 0; - ArrayRef<OperandBundleDef> Bundles = makeArrayRef(Bundle, Len); return wrap(unwrap(B)->CreateInvoke(FTy, Callee, unwrap(Then), unwrap(Catch), makeArrayRef(unwrap(Args), NumArgs), - Bundles, Name)); + makeArrayRef(*OpBundles, NumOpBundles), + Name)); } extern "C" void LLVMRustPositionBuilderAtStart(LLVMBuilderRef B, @@ -1709,11 +1729,7 @@ LLVMRustModuleBufferCreate(LLVMModuleRef M) { auto Ret = std::make_unique<LLVMRustModuleBuffer>(); { raw_string_ostream OS(Ret->data); - { - legacy::PassManager PM; - PM.add(createBitcodeWriterPass(OS)); - PM.run(*unwrap(M)); - } + WriteBitcodeToFile(*unwrap(M), OS); } return Ret.release(); } @@ -1967,3 +1983,7 @@ extern "C" int32_t LLVMRustGetElementTypeArgIndex(LLVMValueRef CallSite) { #endif return -1; } + +extern "C" bool LLVMRustIsBitcode(char *ptr, size_t len) { + return identify_magic(StringRef(ptr, len)) == file_magic::bitcode; +} diff --git a/compiler/rustc_llvm/llvm-wrapper/SymbolWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/SymbolWrapper.cpp new file mode 100644 index 00000000000..974207e918c --- /dev/null +++ b/compiler/rustc_llvm/llvm-wrapper/SymbolWrapper.cpp @@ -0,0 +1,96 @@ +// Derived from code in LLVM, which is: +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +// Derived from: +// * 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/IR/LLVMContext.h" +#include "llvm/Object/ObjectFile.h" +#include "llvm/ADT/Optional.h" + +using namespace llvm; +using namespace llvm::sys; +using namespace llvm::object; + +static bool isArchiveSymbol(const object::BasicSymbolRef &S) { + Expected<uint32_t> SymFlagsOrErr = S.getFlags(); + if (!SymFlagsOrErr) + // FIXME: Actually report errors helpfully. + report_fatal_error(SymFlagsOrErr.takeError()); + if (*SymFlagsOrErr & object::SymbolRef::SF_FormatSpecific) + return false; + if (!(*SymFlagsOrErr & object::SymbolRef::SF_Global)) + return false; + if (*SymFlagsOrErr & object::SymbolRef::SF_Undefined) + return false; + return true; +} + +typedef void *(*LLVMRustGetSymbolsCallback)(void *, const char *); +typedef void *(*LLVMRustGetSymbolsErrorCallback)(const char *); + +// Note: This is implemented in C++ instead of using the C api from Rust as IRObjectFile doesn't +// implement getSymbolName, only printSymbolName, which is inaccessible from the C api. +extern "C" void *LLVMRustGetSymbols( + char *BufPtr, size_t BufLen, void *State, LLVMRustGetSymbolsCallback Callback, + LLVMRustGetSymbolsErrorCallback ErrorCallback) { + std::unique_ptr<MemoryBuffer> Buf = + MemoryBuffer::getMemBuffer(StringRef(BufPtr, BufLen), StringRef("LLVMRustGetSymbolsObject"), + false); + SmallString<0> SymNameBuf; + raw_svector_ostream SymName(SymNameBuf); + + // In the scenario when LLVMContext is populated SymbolicFile will contain a + // reference to it, thus SymbolicFile should be destroyed first. + LLVMContext Context; + std::unique_ptr<object::SymbolicFile> Obj; + + const file_magic Type = identify_magic(Buf->getBuffer()); + if (!object::SymbolicFile::isSymbolicFile(Type, &Context)) { + return 0; + } + + if (Type == file_magic::bitcode) { + auto ObjOrErr = object::SymbolicFile::createSymbolicFile( + Buf->getMemBufferRef(), file_magic::bitcode, &Context); + if (!ObjOrErr) { + Error E = ObjOrErr.takeError(); + SmallString<0> ErrorBuf; + raw_svector_ostream Error(ErrorBuf); + Error << E << '\0'; + return ErrorCallback(Error.str().data()); + } + Obj = std::move(*ObjOrErr); + } else { + auto ObjOrErr = object::SymbolicFile::createSymbolicFile(Buf->getMemBufferRef()); + if (!ObjOrErr) { + Error E = ObjOrErr.takeError(); + SmallString<0> ErrorBuf; + raw_svector_ostream Error(ErrorBuf); + Error << E << '\0'; + return ErrorCallback(Error.str().data()); + } + Obj = std::move(*ObjOrErr); + } + + + for (const object::BasicSymbolRef &S : Obj->symbols()) { + if (!isArchiveSymbol(S)) + continue; + if (Error E = S.printName(SymName)) { + SmallString<0> ErrorBuf; + raw_svector_ostream Error(ErrorBuf); + Error << E << '\0'; + return ErrorCallback(Error.str().data()); + } + SymName << '\0'; + if (void *E = Callback(State, SymNameBuf.str().data())) { + return E; + } + SymNameBuf.clear(); + } + return 0; +} |
