From 4c307de6557ecf5fe7cf12fa22fb2ee0f49e104c Mon Sep 17 00:00:00 2001 From: "A. Wilcox" Date: Fri, 26 Apr 2019 04:16:14 +0000 Subject: user/rust: Add LLVM 8 compatibility patch, and use LLVM 8 --- user/rust/0050-LLVM-8.0-compatibility.patch | 310 ++++++++++++++++++++++++++++ 1 file changed, 310 insertions(+) create mode 100644 user/rust/0050-LLVM-8.0-compatibility.patch (limited to 'user/rust/0050-LLVM-8.0-compatibility.patch') diff --git a/user/rust/0050-LLVM-8.0-compatibility.patch b/user/rust/0050-LLVM-8.0-compatibility.patch new file mode 100644 index 000000000..a8bffb2b9 --- /dev/null +++ b/user/rust/0050-LLVM-8.0-compatibility.patch @@ -0,0 +1,310 @@ +From 78ff5598497c95a696ca669f88a93d127aa24c8d Mon Sep 17 00:00:00 2001 +From: Josh Stone +Date: Wed, 16 Jan 2019 09:59:03 -0800 +Subject: [PATCH 08/15] LLVM 8.0 compatibility + +Backported from commit df0466d upstream. +--- + src/librustc_codegen_llvm/debuginfo/mod.rs | 15 ++-- + src/librustc_codegen_llvm/llvm/ffi.rs | 22 +++-- + src/rustllvm/PassWrapper.cpp | 7 +- + src/rustllvm/RustWrapper.cpp | 93 ++++++++++++++++++++-- + src/test/codegen/enum-debug-clike.rs | 5 +- + 5 files changed, 123 insertions(+), 19 deletions(-) + +diff --git a/src/librustc_codegen_llvm/debuginfo/mod.rs b/src/librustc_codegen_llvm/debuginfo/mod.rs +index 2eab626ae8..7aca63caa4 100644 +--- a/src/librustc_codegen_llvm/debuginfo/mod.rs ++++ b/src/librustc_codegen_llvm/debuginfo/mod.rs +@@ -12,7 +12,7 @@ use self::source_loc::InternalDebugLocation::{self, UnknownLocation}; + + use llvm; + use llvm::debuginfo::{DIFile, DIType, DIScope, DIBuilder, DISubprogram, DIArray, DIFlags, +- DILexicalBlock}; ++ DISPFlags, DILexicalBlock}; + use rustc::hir::CodegenFnAttrFlags; + use rustc::hir::def_id::{DefId, CrateNum}; + use rustc::ty::subst::{Substs, UnpackedKind}; +@@ -283,7 +283,6 @@ impl DebugInfoMethods<'tcx> for CodegenCx<'ll, 'tcx> { + let linkage_name = mangled_name_of_instance(self, instance); + + let scope_line = span_start(self, span).line; +- let is_local_to_unit = is_node_local_to_unit(self, def_id); + + let function_name = CString::new(name).unwrap(); + let linkage_name = SmallCStr::new(&linkage_name.as_str()); +@@ -301,6 +300,14 @@ impl DebugInfoMethods<'tcx> for CodegenCx<'ll, 'tcx> { + flags |= DIFlags::FlagNoReturn; + } + ++ let mut spflags = DISPFlags::SPFlagDefinition; ++ if is_node_local_to_unit(self, def_id) { ++ spflags |= DISPFlags::SPFlagLocalToUnit; ++ } ++ if self.sess().opts.optimize != config::OptLevel::No { ++ spflags |= DISPFlags::SPFlagOptimized; ++ } ++ + let fn_metadata = unsafe { + llvm::LLVMRustDIBuilderCreateFunction( + DIB(self), +@@ -310,11 +317,9 @@ impl DebugInfoMethods<'tcx> for CodegenCx<'ll, 'tcx> { + file_metadata, + loc.line as c_uint, + function_type_metadata, +- is_local_to_unit, +- true, + scope_line as c_uint, + flags, +- self.sess().opts.optimize != config::OptLevel::No, ++ spflags, + llfn, + template_parameters, + None) +diff --git a/src/librustc_codegen_llvm/llvm/ffi.rs b/src/librustc_codegen_llvm/llvm/ffi.rs +index 11e34f600c..853c1ff004 100644 +--- a/src/librustc_codegen_llvm/llvm/ffi.rs ++++ b/src/librustc_codegen_llvm/llvm/ffi.rs +@@ -2,7 +2,7 @@ use super::debuginfo::{ + DIBuilder, DIDescriptor, DIFile, DILexicalBlock, DISubprogram, DIType, + DIBasicType, DIDerivedType, DICompositeType, DIScope, DIVariable, + DIGlobalVariableExpression, DIArray, DISubrange, DITemplateTypeParameter, DIEnumerator, +- DINameSpace, DIFlags, ++ DINameSpace, DIFlags, DISPFlags, + }; + + use libc::{c_uint, c_int, size_t, c_char}; +@@ -591,6 +591,20 @@ pub mod debuginfo { + const FlagMainSubprogram = (1 << 21); + } + } ++ ++ // These values **must** match with LLVMRustDISPFlags!! ++ bitflags! { ++ #[repr(C)] ++ #[derive(Default)] ++ pub struct DISPFlags: ::libc::uint32_t { ++ const SPFlagZero = 0; ++ const SPFlagVirtual = 1; ++ const SPFlagPureVirtual = 2; ++ const SPFlagLocalToUnit = (1 << 2); ++ const SPFlagDefinition = (1 << 3); ++ const SPFlagOptimized = (1 << 4); ++ } ++ } + } + + extern { pub type ModuleBuffer; } +@@ -1387,11 +1401,9 @@ extern "C" { + File: &'a DIFile, + LineNo: c_uint, + Ty: &'a DIType, +- isLocalToUnit: bool, +- isDefinition: bool, + ScopeLine: c_uint, + Flags: DIFlags, +- isOptimized: bool, ++ SPFlags: DISPFlags, + Fn: &'a Value, + TParam: &'a DIArray, + Decl: Option<&'a DIDescriptor>) +@@ -1529,7 +1541,7 @@ extern "C" { + AlignInBits: u32, + Elements: &'a DIArray, + ClassType: &'a DIType, +- IsFixed: bool) ++ IsScoped: bool) + -> &'a DIType; + + pub fn LLVMRustDIBuilderCreateUnionType(Builder: &DIBuilder<'a>, +diff --git a/src/rustllvm/PassWrapper.cpp b/src/rustllvm/PassWrapper.cpp +index df7a81643b..18d277be21 100644 +--- a/src/rustllvm/PassWrapper.cpp ++++ b/src/rustllvm/PassWrapper.cpp +@@ -789,7 +789,7 @@ struct LLVMRustThinLTOData { + StringMap ModuleToDefinedGVSummaries; + + #if LLVM_VERSION_GE(7, 0) +- LLVMRustThinLTOData() : Index(/* isPerformingAnalysis = */ false) {} ++ LLVMRustThinLTOData() : Index(/* HaveGVs = */ false) {} + #endif + }; + +@@ -865,7 +865,12 @@ LLVMRustCreateThinLTOData(LLVMRustThinLTOModule *modules, + auto deadIsPrevailing = [&](GlobalValue::GUID G) { + return PrevailingType::Unknown; + }; ++#if LLVM_VERSION_GE(8, 0) ++ computeDeadSymbolsWithConstProp(Ret->Index, Ret->GUIDPreservedSymbols, ++ deadIsPrevailing, /* ImportEnabled = */ true); ++#else + computeDeadSymbols(Ret->Index, Ret->GUIDPreservedSymbols, deadIsPrevailing); ++#endif + #else + computeDeadSymbols(Ret->Index, Ret->GUIDPreservedSymbols); + #endif +diff --git a/src/rustllvm/RustWrapper.cpp b/src/rustllvm/RustWrapper.cpp +index 9d3e6f93b0..7905e9f0f2 100644 +--- a/src/rustllvm/RustWrapper.cpp ++++ b/src/rustllvm/RustWrapper.cpp +@@ -294,7 +294,7 @@ extern "C" void LLVMRustSetHasUnsafeAlgebra(LLVMValueRef V) { + extern "C" LLVMValueRef + LLVMRustBuildAtomicLoad(LLVMBuilderRef B, LLVMValueRef Source, const char *Name, + LLVMAtomicOrdering Order) { +- LoadInst *LI = new LoadInst(unwrap(Source), 0); ++ LoadInst *LI = new LoadInst(unwrap(Source)); + LI->setAtomic(fromRust(Order)); + return wrap(unwrap(B)->Insert(LI, Name)); + } +@@ -511,6 +511,71 @@ static DINode::DIFlags fromRust(LLVMRustDIFlags Flags) { + return Result; + } + ++// These values **must** match debuginfo::DISPFlags! They also *happen* ++// to match LLVM, but that isn't required as we do giant sets of ++// matching below. The value shouldn't be directly passed to LLVM. ++enum class LLVMRustDISPFlags : uint32_t { ++ SPFlagZero = 0, ++ SPFlagVirtual = 1, ++ SPFlagPureVirtual = 2, ++ SPFlagLocalToUnit = (1 << 2), ++ SPFlagDefinition = (1 << 3), ++ SPFlagOptimized = (1 << 4), ++ // Do not add values that are not supported by the minimum LLVM ++ // version we support! see llvm/include/llvm/IR/DebugInfoFlags.def ++ // (In LLVM < 8, createFunction supported these as separate bool arguments.) ++}; ++ ++inline LLVMRustDISPFlags operator&(LLVMRustDISPFlags A, LLVMRustDISPFlags B) { ++ return static_cast(static_cast(A) & ++ static_cast(B)); ++} ++ ++inline LLVMRustDISPFlags operator|(LLVMRustDISPFlags A, LLVMRustDISPFlags B) { ++ return static_cast(static_cast(A) | ++ static_cast(B)); ++} ++ ++inline LLVMRustDISPFlags &operator|=(LLVMRustDISPFlags &A, LLVMRustDISPFlags B) { ++ return A = A | B; ++} ++ ++inline bool isSet(LLVMRustDISPFlags F) { return F != LLVMRustDISPFlags::SPFlagZero; } ++ ++inline LLVMRustDISPFlags virtuality(LLVMRustDISPFlags F) { ++ return static_cast(static_cast(F) & 0x3); ++} ++ ++#if LLVM_VERSION_GE(8, 0) ++static DISubprogram::DISPFlags fromRust(LLVMRustDISPFlags SPFlags) { ++ DISubprogram::DISPFlags Result = DISubprogram::DISPFlags::SPFlagZero; ++ ++ switch (virtuality(SPFlags)) { ++ case LLVMRustDISPFlags::SPFlagVirtual: ++ Result |= DISubprogram::DISPFlags::SPFlagVirtual; ++ break; ++ case LLVMRustDISPFlags::SPFlagPureVirtual: ++ Result |= DISubprogram::DISPFlags::SPFlagPureVirtual; ++ break; ++ default: ++ // The rest are handled below ++ break; ++ } ++ ++ if (isSet(SPFlags & LLVMRustDISPFlags::SPFlagLocalToUnit)) { ++ Result |= DISubprogram::DISPFlags::SPFlagLocalToUnit; ++ } ++ if (isSet(SPFlags & LLVMRustDISPFlags::SPFlagDefinition)) { ++ Result |= DISubprogram::DISPFlags::SPFlagDefinition; ++ } ++ if (isSet(SPFlags & LLVMRustDISPFlags::SPFlagOptimized)) { ++ Result |= DISubprogram::DISPFlags::SPFlagOptimized; ++ } ++ ++ return Result; ++} ++#endif ++ + extern "C" uint32_t LLVMRustDebugMetadataVersion() { + return DEBUG_METADATA_VERSION; + } +@@ -575,16 +640,26 @@ LLVMRustDIBuilderCreateSubroutineType(LLVMRustDIBuilderRef Builder, + extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateFunction( + LLVMRustDIBuilderRef Builder, LLVMMetadataRef Scope, const char *Name, + const char *LinkageName, LLVMMetadataRef File, unsigned LineNo, +- LLVMMetadataRef Ty, bool IsLocalToUnit, bool IsDefinition, +- unsigned ScopeLine, LLVMRustDIFlags Flags, bool IsOptimized, +- LLVMValueRef Fn, LLVMMetadataRef TParam, LLVMMetadataRef Decl) { ++ LLVMMetadataRef Ty, unsigned ScopeLine, LLVMRustDIFlags Flags, ++ LLVMRustDISPFlags SPFlags, LLVMValueRef Fn, LLVMMetadataRef TParam, ++ LLVMMetadataRef Decl) { + DITemplateParameterArray TParams = + DITemplateParameterArray(unwrap(TParam)); ++#if LLVM_VERSION_GE(8, 0) ++ DISubprogram *Sub = Builder->createFunction( ++ unwrapDI(Scope), Name, LinkageName, unwrapDI(File), ++ LineNo, unwrapDI(Ty), ScopeLine, fromRust(Flags), ++ fromRust(SPFlags), TParams, unwrapDIPtr(Decl)); ++#else ++ bool IsLocalToUnit = isSet(SPFlags & LLVMRustDISPFlags::SPFlagLocalToUnit); ++ bool IsDefinition = isSet(SPFlags & LLVMRustDISPFlags::SPFlagDefinition); ++ bool IsOptimized = isSet(SPFlags & LLVMRustDISPFlags::SPFlagOptimized); + DISubprogram *Sub = Builder->createFunction( + unwrapDI(Scope), Name, LinkageName, unwrapDI(File), + LineNo, unwrapDI(Ty), IsLocalToUnit, IsDefinition, + ScopeLine, fromRust(Flags), IsOptimized, TParams, + unwrapDIPtr(Decl)); ++#endif + unwrap(Fn)->setSubprogram(Sub); + return wrap(Sub); + } +@@ -773,14 +848,14 @@ extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateEnumerationType( + LLVMRustDIBuilderRef Builder, LLVMMetadataRef Scope, const char *Name, + LLVMMetadataRef File, unsigned LineNumber, uint64_t SizeInBits, + uint32_t AlignInBits, LLVMMetadataRef Elements, +- LLVMMetadataRef ClassTy, bool IsFixed) { ++ LLVMMetadataRef ClassTy, bool IsScoped) { + #if LLVM_VERSION_GE(7, 0) + return wrap(Builder->createEnumerationType( + unwrapDI(Scope), Name, unwrapDI(File), LineNumber, + SizeInBits, AlignInBits, DINodeArray(unwrapDI(Elements)), +- unwrapDI(ClassTy), "", IsFixed)); ++ unwrapDI(ClassTy), "", IsScoped)); + #else +- // Ignore IsFixed on older LLVM. ++ // Ignore IsScoped on older LLVM. + return wrap(Builder->createEnumerationType( + unwrapDI(Scope), Name, unwrapDI(File), LineNumber, + SizeInBits, AlignInBits, DINodeArray(unwrapDI(Elements)), +@@ -920,7 +995,11 @@ extern "C" void LLVMRustUnpackOptimizationDiagnostic( + if (loc.isValid()) { + *Line = loc.getLine(); + *Column = loc.getColumn(); ++#if LLVM_VERSION_GE(8, 0) ++ FilenameOS << loc.getAbsolutePath(); ++#else + FilenameOS << loc.getFilename(); ++#endif + } + + RawRustStringOstream MessageOS(MessageOut); +diff --git a/src/test/codegen/enum-debug-clike.rs b/src/test/codegen/enum-debug-clike.rs +index 98f07505f7..62cfef5a84 100644 +--- a/src/test/codegen/enum-debug-clike.rs ++++ b/src/test/codegen/enum-debug-clike.rs +@@ -8,8 +8,11 @@ + + // compile-flags: -g -C no-prepopulate-passes + ++// DIFlagFixedEnum was deprecated in 8.0, renamed to DIFlagEnumClass. ++// We match either for compatibility. ++ + // CHECK-LABEL: @main +-// CHECK: {{.*}}DICompositeType{{.*}}tag: DW_TAG_enumeration_type,{{.*}}name: "E",{{.*}}flags: DIFlagFixedEnum,{{.*}} ++// CHECK: {{.*}}DICompositeType{{.*}}tag: DW_TAG_enumeration_type,{{.*}}name: "E",{{.*}}flags: {{(DIFlagEnumClass|DIFlagFixedEnum)}},{{.*}} + // CHECK: {{.*}}DIEnumerator{{.*}}name: "A",{{.*}}value: {{[0-9].*}} + // CHECK: {{.*}}DIEnumerator{{.*}}name: "B",{{.*}}value: {{[0-9].*}} + // CHECK: {{.*}}DIEnumerator{{.*}}name: "C",{{.*}}value: {{[0-9].*}} +-- +2.19.2 + -- cgit v1.2.3-60-g2f50