mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-01-31 12:41:49 +01:00
Preserve the lexical order for global variables during llvm-link merge
The order of global variables is generated in the order of recursively materializing variables if the global variable has the attribute of hasLocalLinkage or hasLinkOnceLinkage during the module merging. In practice, it is often the exact reverse of source order. This new order may cause performance regression. The change is to preserve the original lexical order for global variables. Reviewed By: jdoerfert, dexonsmith Differential Revision: https://reviews.llvm.org/D94202
This commit is contained in:
parent
6b1be183c5
commit
673715d427
@ -1509,6 +1509,20 @@ Error IRLinker::run() {
|
||||
});
|
||||
}
|
||||
|
||||
// Reorder the globals just added to the destination module to match their
|
||||
// original order in the source module.
|
||||
Module::GlobalListType &Globals = DstM.getGlobalList();
|
||||
for (GlobalVariable &GV : SrcM->globals()) {
|
||||
if (GV.hasAppendingLinkage())
|
||||
continue;
|
||||
Value *NewValue = Mapper.mapValue(GV);
|
||||
if (NewValue) {
|
||||
auto *NewGV = dyn_cast<GlobalVariable>(NewValue->stripPointerCasts());
|
||||
if (NewGV)
|
||||
Globals.splice(Globals.end(), Globals, NewGV->getIterator());
|
||||
}
|
||||
}
|
||||
|
||||
// Merge the module flags into the DstM module.
|
||||
return linkModuleFlagsMetadata();
|
||||
}
|
||||
|
14
test/Linker/Inputs/globalorder-2.ll
Normal file
14
test/Linker/Inputs/globalorder-2.ll
Normal file
@ -0,0 +1,14 @@
|
||||
@var5 = internal global i32 0, align 4
|
||||
@var6 = internal global i32 0, align 4
|
||||
@var7 = global i32* @var5, align 4
|
||||
@var8 = global i32* @var6, align 4
|
||||
|
||||
define i32 @foo2() {
|
||||
entry:
|
||||
%0 = load i32*, i32** @var7, align 4
|
||||
%1 = load i32, i32* %0, align 4
|
||||
%2 = load i32*, i32** @var8, align 4
|
||||
%3 = load i32, i32* %2, align 4
|
||||
%add = add nsw i32 %3, %1
|
||||
ret i32 %add
|
||||
}
|
@ -23,9 +23,9 @@ $any = comdat any
|
||||
; CHECK: $foo = comdat largest
|
||||
; CHECK: $any = comdat any
|
||||
|
||||
; CHECK: @foo = global i64 43, comdat{{$}}
|
||||
; CHECK: @qux = global i64 12, comdat{{$}}
|
||||
; CHECK: @any = global i64 6, comdat{{$}}
|
||||
; CHECK: @foo = global i64 43, comdat{{$}}
|
||||
; CHECK-NOT: @in_unselected_group = global i32 13, comdat $qux
|
||||
|
||||
; CHECK: define i32 @baz() comdat($qux)
|
||||
|
@ -5,5 +5,5 @@ $c = comdat any
|
||||
@v = global i32 0, comdat ($c)
|
||||
|
||||
; CHECK: @v = global i32 0, comdat($c)
|
||||
; CHECK: @v2 = external dllexport global i32
|
||||
; CHECK: @v3 = external global i32
|
||||
; CHECK: @v2 = external dllexport global i32
|
||||
|
@ -6,12 +6,12 @@
|
||||
; Test the bitcode writer too. It used to crash.
|
||||
; RUN: llvm-link %s %p/Inputs/ctors.ll -o %t.bc
|
||||
|
||||
; ALL: @llvm.global_ctors = appending global [1 x { i32, void ()*, i8* }] [{ i32, void ()*, i8* } { i32 65535, void ()* @f, i8* @v }]
|
||||
@v = weak global i8 0
|
||||
; CHECK1: @v = weak global i8 0
|
||||
; CHECK2: @v = weak global i8 1
|
||||
|
||||
@llvm.global_ctors = appending global [1 x { i32, void ()*, i8* }] [{ i32, void ()*, i8* } { i32 65535, void ()* @f, i8* @v }]
|
||||
; ALL: @llvm.global_ctors = appending global [1 x { i32, void ()*, i8* }] [{ i32, void ()*, i8* } { i32 65535, void ()* @f, i8* @v }]
|
||||
|
||||
define weak void @f() {
|
||||
ret void
|
||||
|
@ -3,5 +3,5 @@
|
||||
$foo = comdat any
|
||||
@foo = global i8 0, comdat
|
||||
|
||||
; CHECK: @foo = global i8 0, comdat
|
||||
; CHECK: @llvm.global_ctors = appending global [0 x { i32, void ()*, i8* }] zeroinitializer
|
||||
; CHECK: @foo = global i8 0, comdat
|
||||
|
@ -4,5 +4,5 @@ $foo = comdat any
|
||||
%t = type { i8 }
|
||||
@foo = global %t zeroinitializer, comdat
|
||||
|
||||
; CHECK: @foo = global %t zeroinitializer, comdat
|
||||
; CHECK: @llvm.global_ctors = appending global [0 x { i32, void ()*, i8* }] zeroinitializer
|
||||
; CHECK: @foo = global %t zeroinitializer, comdat
|
||||
|
27
test/Linker/globalorder.ll
Normal file
27
test/Linker/globalorder.ll
Normal file
@ -0,0 +1,27 @@
|
||||
; Test the order of global variables during llvm-link
|
||||
|
||||
; RUN: llvm-link %s %S/Inputs/globalorder-2.ll -o %t.bc
|
||||
; RUN: llvm-dis -o - %t.bc | FileCheck %s
|
||||
|
||||
@var1 = internal global i32 0, align 4
|
||||
@var2 = internal global i32 0, align 4
|
||||
@var3 = global i32* @var1, align 4
|
||||
@var4 = global i32* @var2, align 4
|
||||
|
||||
define i32 @foo() {
|
||||
entry:
|
||||
%0 = load i32*, i32** @var3, align 4
|
||||
%1 = load i32, i32* %0, align 4
|
||||
%2 = load i32*, i32** @var4, align 4
|
||||
%3 = load i32, i32* %2, align 4
|
||||
%add = add nsw i32 %3, %1
|
||||
ret i32 %add
|
||||
}
|
||||
; CHECK: @var1 =
|
||||
; CHECK-NEXT: @var2 =
|
||||
; CHECK-NEXT: @var3 =
|
||||
; CHECK-NEXT: @var4 =
|
||||
; CHECK-NEXT: @var5 =
|
||||
; CHECK-NEXT: @var6 =
|
||||
; CHECK-NEXT: @var7 =
|
||||
; CHECK-NEXT: @var8 =
|
@ -9,8 +9,8 @@ CI-LABEL: @X = internal global i32 5
|
||||
CU-LABEL:@U = global i32 6
|
||||
CI-LABEL:@U = internal global i32 6
|
||||
CN-NOT:@U
|
||||
DI-LABEL: @Y = global i8 42
|
||||
DI-LABEL: @llvm.used = appending global [2 x i8*] [i8* @Y, i8* bitcast (i64 ()* @foo to i8*)], section "llvm.metadata"
|
||||
DI-LABEL: @Y = global i8 42
|
||||
|
||||
B-LABEL: define void @bar() {
|
||||
|
||||
|
@ -6,17 +6,17 @@
|
||||
; CHECK-LINKED1: @g1 = global i32 0, !attach !0{{$}}
|
||||
@g1 = global i32 0, !attach !0
|
||||
|
||||
; CHECK: @g3 = weak global i32 1, !attach !0{{$}}
|
||||
; CHECK: @g2 = external global i32, !attach !0{{$}}
|
||||
; CHECK: @g3 = weak global i32 1, !attach !0{{$}}
|
||||
; CHECK-LINKED1: @g2 = global i32 1, !attach !1{{$}}
|
||||
@g2 = external global i32, !attach !0
|
||||
|
||||
; CHECK-LINKED1: @g3 = global i32 2, !attach !1{{$}}
|
||||
@g3 = weak global i32 1, !attach !0
|
||||
|
||||
; CHECK-LINKED2: @g2 = global i32 1, !attach !0{{$}}
|
||||
; CHECK-LINKED2: @g3 = global i32 2, !attach !0{{$}}
|
||||
; CHECK-LINKED2: @g1 = global i32 0, !attach !1{{$}}
|
||||
; CHECK-LINKED2: @g1 = global i32 0, !attach !0{{$}}
|
||||
; CHECK-LINKED2: @g2 = global i32 1, !attach !1{{$}}
|
||||
; CHECK-LINKED2: @g3 = global i32 2, !attach !1{{$}}
|
||||
|
||||
; CHECK: define void @f1() !attach !0 {
|
||||
; CHECK-LINKED1: define void @f1() !attach !0 {
|
||||
@ -36,14 +36,14 @@ define weak void @f3() !attach !0 {
|
||||
ret void
|
||||
}
|
||||
|
||||
; CHECK-LINKED2: define void @f2() !attach !0 {
|
||||
; CHECK-LINKED2: define void @f3() !attach !0 {
|
||||
; CHECK-LINKED2: define void @f1() !attach !1 {
|
||||
; CHECK-LINKED2: define void @f2() !attach !1 {
|
||||
; CHECK-LINKED2: define void @f3() !attach !1 {
|
||||
; CHECK-LINKED2: define void @f1() !attach !0 {
|
||||
|
||||
; CHECK-LINKED1: !0 = !{i32 0}
|
||||
; CHECK-LINKED1: !1 = !{i32 1}
|
||||
|
||||
; CHECK-LINKED2: !0 = !{i32 1}
|
||||
; CHECK-LINKED2: !1 = !{i32 0}
|
||||
; CHECK-LINKED2: !0 = !{i32 0}
|
||||
; CHECK-LINKED2: !1 = !{i32 1}
|
||||
|
||||
!0 = !{i32 0}
|
||||
|
@ -1,7 +1,7 @@
|
||||
; RUN: llvm-link %s %S/Inputs/testlink.ll -S | FileCheck %s
|
||||
|
||||
; CHECK: %Ty2 = type { %Ty1* }
|
||||
; CHECK: %Ty1 = type { %Ty2* }
|
||||
; CHECK: %Ty2 = type { %Ty1* }
|
||||
%Ty1 = type opaque
|
||||
%Ty2 = type { %Ty1* }
|
||||
|
||||
|
@ -28,9 +28,9 @@
|
||||
; PROMOTE: @_ZL3Obj.llvm.{{.*}} = hidden constant %struct.S { i32 4, i32 8, i32* @val }
|
||||
|
||||
; @outer is a write-only variable, so it's been converted to zeroinitializer.
|
||||
; IMPORT: @outer = internal local_unnamed_addr global %struct.Q zeroinitializer
|
||||
; IMPORT: @val = available_externally global i32 42
|
||||
; IMPORT-NEXT: @_ZL3Obj.llvm.{{.*}} = available_externally hidden constant %struct.S { i32 4, i32 8, i32* @val }
|
||||
; IMPORT-NEXT: @val = available_externally global i32 42
|
||||
; IMPORT-NEXT: @outer = internal local_unnamed_addr global %struct.Q zeroinitializer
|
||||
|
||||
; OPT: @outer = internal unnamed_addr global %struct.Q zeroinitializer
|
||||
|
||||
@ -39,8 +39,8 @@
|
||||
; OPT-NEXT: store %struct.S* null, %struct.S** getelementptr inbounds (%struct.Q, %struct.Q* @outer, i64 0, i32 0)
|
||||
; OPT-NEXT: ret i32 12
|
||||
|
||||
; NOREFS: @outer = internal local_unnamed_addr global %struct.Q zeroinitializer
|
||||
; NOREFS-NEXT: @_ZL3Obj.llvm.{{.*}} = external hidden constant %struct.S
|
||||
; NOREFS: @_ZL3Obj.llvm.{{.*}} = external hidden constant %struct.S
|
||||
; NOREFS-NEXT: @outer = internal local_unnamed_addr global %struct.Q zeroinitializer
|
||||
|
||||
target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
|
||||
target triple = "x86_64-unknown-linux-gnu"
|
||||
|
@ -19,14 +19,14 @@
|
||||
; RUN: llvm-lto -thinlto-action=import -exported-symbol main -exported-symbol gBar %t1.bc -thinlto-index=%t3.index.bc -o %t1.imported2.bc
|
||||
; RUN: llvm-dis %t1.imported2.bc -o - | FileCheck %s --check-prefix=IMPORT2
|
||||
|
||||
; IMPORT: @gFoo.llvm.0 = internal unnamed_addr global i32 1, align 4, !dbg !0
|
||||
; IMPORT-NEXT: @gBar = internal local_unnamed_addr global i32 2, align 4, !dbg !5
|
||||
; IMPORT: @gBar = internal local_unnamed_addr global i32 2, align 4, !dbg !0
|
||||
; IMPORT-NEXT: @gFoo.llvm.0 = internal unnamed_addr global i32 1, align 4, !dbg !5
|
||||
; IMPORT: !DICompileUnit({{.*}})
|
||||
|
||||
; OPTIMIZE: define i32 @main
|
||||
; OPTIMIZE-NEXT: ret i32 3
|
||||
|
||||
; IMPORT2: @gBar = available_externally local_unnamed_addr global i32 2, align 4, !dbg !5
|
||||
; IMPORT2: @gBar = available_externally local_unnamed_addr global i32 2, align 4, !dbg !0
|
||||
|
||||
target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
|
||||
target triple = "x86_64-pc-linux-gnu"
|
||||
|
@ -57,13 +57,13 @@
|
||||
; with corresponsing stores
|
||||
; RUN: llvm-dis %t5.2.5.precodegen.bc -o - | FileCheck %s --check-prefix=CODEGEN2-SRC
|
||||
|
||||
; IMPORT: @gFoo.llvm.0 = internal unnamed_addr global i32 1, align 4
|
||||
; IMPORT-NEXT: @gBar = internal local_unnamed_addr global i32 2, align 4
|
||||
; IMPORT: @gBar = internal local_unnamed_addr global i32 2, align 4
|
||||
; IMPORT-NEXT: @gFoo.llvm.0 = internal unnamed_addr global i32 1, align 4
|
||||
; IMPORT: !DICompileUnit({{.*}})
|
||||
|
||||
; Write only variables are imported with a zero initializer.
|
||||
; IMPORT-WRITEONLY: @gFoo.llvm.0 = internal unnamed_addr global i32 0
|
||||
; IMPORT-WRITEONLY: @gBar = internal local_unnamed_addr global i32 0
|
||||
; IMPORT-WRITEONLY: @gFoo.llvm.0 = internal unnamed_addr global i32 0
|
||||
|
||||
; CODEGEN: i32 @main()
|
||||
; CODEGEN-NEXT: ret i32 3
|
||||
|
@ -11,8 +11,8 @@
|
||||
; RUN: llvm-dis %t1.imported.bc -o - | FileCheck %s --check-prefix=IMPORT
|
||||
; RUN: llvm-lto -thinlto-action=optimize %t1.imported.bc -o - | llvm-dis - -o - | FileCheck %s --check-prefix=OPTIMIZE
|
||||
|
||||
; IMPORT: @gFoo.llvm.0 = internal unnamed_addr global i32 0, align 4, !dbg !0
|
||||
; IMPORT-NEXT: @gBar = internal local_unnamed_addr global i32 0, align 4, !dbg !5
|
||||
; IMPORT: @gBar = internal local_unnamed_addr global i32 0, align 4, !dbg !0
|
||||
; IMPORT-NEXT: @gFoo.llvm.0 = internal unnamed_addr global i32 0, align 4, !dbg !5
|
||||
; IMPORT: !DICompileUnit({{.*}})
|
||||
|
||||
; STATS: 2 module-summary-index - Number of live global variables marked write only
|
||||
@ -29,8 +29,8 @@
|
||||
; RUN: llvm-lto -propagate-attrs=false -thinlto-action=import -exported-symbol=main %t1.bc -thinlto-index=%t3.index.bc -o %t1.imported.bc -stats 2>&1 | FileCheck %s --check-prefix=STATS-NOPROP
|
||||
; RUN: llvm-dis %t1.imported.bc -o - | FileCheck %s --check-prefix=IMPORT-NOPROP
|
||||
; STATS-NOPROP-NOT: Number of live global variables marked write only
|
||||
; IMPORT-NOPROP: @gFoo.llvm.0 = available_externally
|
||||
; IMPORT-NOPROP-NEXT: @gBar = available_externally
|
||||
; IMPORT-NOPROP: @gBar = available_externally
|
||||
; IMPORT-NOPROP-NEXT: @gFoo.llvm.0 = available_externally
|
||||
|
||||
target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
|
||||
target triple = "x86_64-pc-linux-gnu"
|
||||
|
@ -19,8 +19,8 @@
|
||||
; with corresponsing stores
|
||||
; RUN: llvm-dis %t3.2.5.precodegen.bc -o - | FileCheck %s --check-prefix=CODEGEN-SRC
|
||||
|
||||
; IMPORT: @gFoo.llvm.0 = internal unnamed_addr global i32 0, align 4
|
||||
; IMPORT-NEXT: @gBar = internal local_unnamed_addr global i32 0, align 4
|
||||
; IMPORT: @gBar = internal local_unnamed_addr global i32 0, align 4
|
||||
; IMPORT-NEXT: @gFoo.llvm.0 = internal unnamed_addr global i32 0, align 4
|
||||
; IMPORT: !DICompileUnit({{.*}})
|
||||
|
||||
; CODEGEN-NOT: gFoo
|
||||
|
Loading…
x
Reference in New Issue
Block a user