summaryrefslogtreecommitdiff
path: root/user/rust/0050-LLVM-8.0-compatibility.patch
diff options
context:
space:
mode:
Diffstat (limited to 'user/rust/0050-LLVM-8.0-compatibility.patch')
-rw-r--r--user/rust/0050-LLVM-8.0-compatibility.patch310
1 files changed, 310 insertions, 0 deletions
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 <jistone@redhat.com>
+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<GVSummaryMapTy> 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<LLVMRustDISPFlags>(static_cast<uint32_t>(A) &
++ static_cast<uint32_t>(B));
++}
++
++inline LLVMRustDISPFlags operator|(LLVMRustDISPFlags A, LLVMRustDISPFlags B) {
++ return static_cast<LLVMRustDISPFlags>(static_cast<uint32_t>(A) |
++ static_cast<uint32_t>(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<LLVMRustDISPFlags>(static_cast<uint32_t>(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<MDTuple>(TParam));
++#if LLVM_VERSION_GE(8, 0)
++ DISubprogram *Sub = Builder->createFunction(
++ unwrapDI<DIScope>(Scope), Name, LinkageName, unwrapDI<DIFile>(File),
++ LineNo, unwrapDI<DISubroutineType>(Ty), ScopeLine, fromRust(Flags),
++ fromRust(SPFlags), TParams, unwrapDIPtr<DISubprogram>(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<DIScope>(Scope), Name, LinkageName, unwrapDI<DIFile>(File),
+ LineNo, unwrapDI<DISubroutineType>(Ty), IsLocalToUnit, IsDefinition,
+ ScopeLine, fromRust(Flags), IsOptimized, TParams,
+ unwrapDIPtr<DISubprogram>(Decl));
++#endif
+ unwrap<Function>(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<DIDescriptor>(Scope), Name, unwrapDI<DIFile>(File), LineNumber,
+ SizeInBits, AlignInBits, DINodeArray(unwrapDI<MDTuple>(Elements)),
+- unwrapDI<DIType>(ClassTy), "", IsFixed));
++ unwrapDI<DIType>(ClassTy), "", IsScoped));
+ #else
+- // Ignore IsFixed on older LLVM.
++ // Ignore IsScoped on older LLVM.
+ return wrap(Builder->createEnumerationType(
+ unwrapDI<DIDescriptor>(Scope), Name, unwrapDI<DIFile>(File), LineNumber,
+ SizeInBits, AlignInBits, DINodeArray(unwrapDI<MDTuple>(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
+