diff options
Diffstat (limited to 'src/rustllvm/PassWrapper.cpp')
| -rw-r--r-- | src/rustllvm/PassWrapper.cpp | 93 |
1 files changed, 57 insertions, 36 deletions
diff --git a/src/rustllvm/PassWrapper.cpp b/src/rustllvm/PassWrapper.cpp index 65071c3ed86..84bde9a52f7 100644 --- a/src/rustllvm/PassWrapper.cpp +++ b/src/rustllvm/PassWrapper.cpp @@ -13,6 +13,8 @@ #include "llvm/IR/AssemblyAnnotationWriter.h" #include "llvm/IR/IntrinsicInst.h" #include "llvm/IR/Verifier.h" +#include "llvm/Object/ObjectFile.h" +#include "llvm/Object/IRObjectFile.h" #include "llvm/Passes/PassBuilder.h" #if LLVM_VERSION_GE(9, 0) #include "llvm/Passes/StandardInstrumentations.h" @@ -33,10 +35,8 @@ #include "llvm/Transforms/Instrumentation/AddressSanitizer.h" #include "llvm/Support/TimeProfiler.h" #endif -#if LLVM_VERSION_GE(8, 0) #include "llvm/Transforms/Instrumentation/ThreadSanitizer.h" #include "llvm/Transforms/Instrumentation/MemorySanitizer.h" -#endif #if LLVM_VERSION_GE(9, 0) #include "llvm/Transforms/Utils/CanonicalizeAliases.h" #endif @@ -67,7 +67,11 @@ extern "C" void LLVMInitializePasses() { } extern "C" void LLVMTimeTraceProfilerInitialize() { -#if LLVM_VERSION_GE(9, 0) +#if LLVM_VERSION_GE(10, 0) + timeTraceProfilerInitialize( + /* TimeTraceGranularity */ 0, + /* ProcName */ "rustc"); +#elif LLVM_VERSION_GE(9, 0) timeTraceProfilerInitialize(); #endif } @@ -134,19 +138,13 @@ extern "C" LLVMPassRef LLVMRustCreateMemorySanitizerPass(int TrackOrigins, bool return wrap(createMemorySanitizerLegacyPassPass( MemorySanitizerOptions{TrackOrigins, Recover, CompileKernel})); -#elif LLVM_VERSION_GE(8, 0) - return wrap(createMemorySanitizerLegacyPassPass(TrackOrigins, Recover)); #else - return wrap(createMemorySanitizerPass(TrackOrigins, Recover)); + return wrap(createMemorySanitizerLegacyPassPass(TrackOrigins, Recover)); #endif } extern "C" LLVMPassRef LLVMRustCreateThreadSanitizerPass() { -#if LLVM_VERSION_GE(8, 0) return wrap(createThreadSanitizerLegacyPassPass()); -#else - return wrap(createThreadSanitizerPass()); -#endif } extern "C" LLVMRustPassKind LLVMRustPassKind(LLVMPassRef RustPass) { @@ -350,8 +348,7 @@ static PassBuilder::OptimizationLevel fromRust(LLVMRustPassBuilderOptLevel Level } } -enum class LLVMRustRelocMode { - Default, +enum class LLVMRustRelocModel { Static, PIC, DynamicNoPic, @@ -360,21 +357,19 @@ enum class LLVMRustRelocMode { ROPIRWPI, }; -static Optional<Reloc::Model> fromRust(LLVMRustRelocMode RustReloc) { +static Reloc::Model fromRust(LLVMRustRelocModel RustReloc) { switch (RustReloc) { - case LLVMRustRelocMode::Default: - return None; - case LLVMRustRelocMode::Static: + case LLVMRustRelocModel::Static: return Reloc::Static; - case LLVMRustRelocMode::PIC: + case LLVMRustRelocModel::PIC: return Reloc::PIC_; - case LLVMRustRelocMode::DynamicNoPic: + case LLVMRustRelocModel::DynamicNoPic: return Reloc::DynamicNoPIC; - case LLVMRustRelocMode::ROPI: + case LLVMRustRelocModel::ROPI: return Reloc::ROPI; - case LLVMRustRelocMode::RWPI: + case LLVMRustRelocModel::RWPI: return Reloc::RWPI; - case LLVMRustRelocMode::ROPIRWPI: + case LLVMRustRelocModel::ROPIRWPI: return Reloc::ROPI_RWPI; } report_fatal_error("Bad RelocModel."); @@ -444,7 +439,7 @@ extern "C" const char* LLVMRustGetHostCPUName(size_t *len) { extern "C" LLVMTargetMachineRef LLVMRustCreateTargetMachine( const char *TripleStr, const char *CPU, const char *Feature, - const char *ABIStr, LLVMRustCodeModel RustCM, LLVMRustRelocMode RustReloc, + const char *ABIStr, LLVMRustCodeModel RustCM, LLVMRustRelocModel RustReloc, LLVMRustCodeGenOptLevel RustOptLevel, bool UseSoftFloat, bool PositionIndependentExecutable, bool FunctionSections, bool DataSections, @@ -452,7 +447,8 @@ extern "C" LLVMTargetMachineRef LLVMRustCreateTargetMachine( bool Singlethread, bool AsmComments, bool EmitStackSizeSection, - bool RelaxELFRelocations) { + bool RelaxELFRelocations, + bool UseInitArray) { auto OptLevel = fromRust(RustOptLevel); auto RM = fromRust(RustReloc); @@ -478,6 +474,7 @@ extern "C" LLVMTargetMachineRef LLVMRustCreateTargetMachine( Options.MCOptions.PreserveAsmComments = AsmComments; Options.MCOptions.ABIName = ABIStr; Options.RelaxELFRelocations = RelaxELFRelocations; + Options.UseInitArray = UseInitArray; if (TrapUnreachable) { // Tell LLVM to codegen `unreachable` into an explicit trap instruction. @@ -868,8 +865,10 @@ LLVMRustOptimizeWithNewPassManager( } else { for (const auto &C : PipelineStartEPCallbacks) PB.registerPipelineStartEPCallback(C); - for (const auto &C : OptimizerLastEPCallbacks) - PB.registerOptimizerLastEPCallback(C); + if (OptStage != LLVMRustOptStage::PreLinkThinLTO) { + for (const auto &C : OptimizerLastEPCallbacks) + PB.registerOptimizerLastEPCallback(C); + } switch (OptStage) { case LLVMRustOptStage::PreLinkNoLTO: @@ -877,6 +876,12 @@ LLVMRustOptimizeWithNewPassManager( break; case LLVMRustOptStage::PreLinkThinLTO: MPM = PB.buildThinLTOPreLinkDefaultPipeline(OptLevel, DebugPassManager); + if (!OptimizerLastEPCallbacks.empty()) { + FunctionPassManager FPM(DebugPassManager); + for (const auto &C : OptimizerLastEPCallbacks) + C(FPM, OptLevel); + MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM))); + } break; case LLVMRustOptStage::PreLinkFatLTO: MPM = PB.buildLTOPreLinkDefaultPipeline(OptLevel, DebugPassManager); @@ -1224,15 +1229,11 @@ LLVMRustCreateThinLTOData(LLVMRustThinLTOModule *modules, auto deadIsPrevailing = [&](GlobalValue::GUID G) { return PrevailingType::Unknown; }; -#if LLVM_VERSION_GE(8, 0) // We don't have a complete picture in our use of ThinLTO, just our immediate // crate, so we need `ImportEnabled = false` to limit internalization. // Otherwise, we sometimes lose `static` values -- see #60184. computeDeadSymbolsWithConstProp(Ret->Index, Ret->GUIDPreservedSymbols, deadIsPrevailing, /* ImportEnabled = */ false); -#else - computeDeadSymbols(Ret->Index, Ret->GUIDPreservedSymbols, deadIsPrevailing); -#endif ComputeCrossModuleImport( Ret->Index, Ret->ModuleToDefinedGVSummaries, @@ -1265,10 +1266,8 @@ LLVMRustCreateThinLTOData(LLVMRustThinLTOModule *modules, #if LLVM_VERSION_GE(9, 0) thinLTOResolvePrevailingInIndex(Ret->Index, isPrevailing, recordNewLinkage, Ret->GUIDPreservedSymbols); -#elif LLVM_VERSION_GE(8, 0) - thinLTOResolvePrevailingInIndex(Ret->Index, isPrevailing, recordNewLinkage); #else - thinLTOResolveWeakForLinkerInIndex(Ret->Index, isPrevailing, recordNewLinkage); + thinLTOResolvePrevailingInIndex(Ret->Index, isPrevailing, recordNewLinkage); #endif // Here we calculate an `ExportedGUIDs` set for use in the `isExported` @@ -1334,11 +1333,7 @@ extern "C" bool LLVMRustPrepareThinLTOResolveWeak(const LLVMRustThinLTOData *Data, LLVMModuleRef M) { Module &Mod = *unwrap(M); const auto &DefinedGlobals = Data->ModuleToDefinedGVSummaries.lookup(Mod.getModuleIdentifier()); -#if LLVM_VERSION_GE(8, 0) thinLTOResolvePrevailingInModule(Mod, DefinedGlobals); -#else - thinLTOResolveWeakForLinkerModule(Mod, DefinedGlobals); -#endif return true; } @@ -1484,6 +1479,32 @@ LLVMRustParseBitcodeForLTO(LLVMContextRef Context, return wrap(std::move(*SrcOrError).release()); } +// Find the bitcode section in the object file data and return it as a slice. +// Fail if the bitcode section is present but empty. +// +// On success, the return value is the pointer to the start of the slice and +// `out_len` is filled with the (non-zero) length. On failure, the return value +// is `nullptr` and `out_len` is set to zero. +extern "C" const char* +LLVMRustGetBitcodeSliceFromObjectData(const char *data, + size_t len, + size_t *out_len) { + *out_len = 0; + + StringRef Data(data, len); + MemoryBufferRef Buffer(Data, ""); // The id is unused. + + Expected<MemoryBufferRef> BitcodeOrError = + object::IRObjectFile::findBitcodeInMemBuffer(Buffer); + if (!BitcodeOrError) { + LLVMRustSetLastError(toString(BitcodeOrError.takeError()).c_str()); + return nullptr; + } + + *out_len = BitcodeOrError->getBufferSize(); + 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 |
