1
0
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:
Jin Lin 2021-04-23 22:37:08 -07:00
parent 6b1be183c5
commit 673715d427
16 changed files with 87 additions and 32 deletions

View File

@ -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();
}

View 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
}

View File

@ -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)

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View 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 =

View File

@ -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() {

View File

@ -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}

View File

@ -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* }

View File

@ -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"

View File

@ -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"

View File

@ -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

View File

@ -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"

View File

@ -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