[llvm] cedfa38 - Preserve the lexical order for global variables during llvm-link merge

Jin Lin via llvm-commits llvm-commits at lists.llvm.org
Mon Apr 26 10:11:41 PDT 2021


Author: Jin Lin
Date: 2021-04-26T10:11:34-07:00
New Revision: cedfa38fc46d7531c44ea230b767d8286767f350

URL: https://github.com/llvm/llvm-project/commit/cedfa38fc46d7531c44ea230b767d8286767f350
DIFF: https://github.com/llvm/llvm-project/commit/cedfa38fc46d7531c44ea230b767d8286767f350.diff

LOG: 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

Added: 
    llvm/test/Linker/Inputs/globalorder-2.ll
    llvm/test/Linker/globalorder.ll

Modified: 
    llvm/lib/Linker/IRMover.cpp
    llvm/test/Linker/comdat.ll
    llvm/test/Linker/comdat14.ll
    llvm/test/Linker/ctors.ll
    llvm/test/Linker/ctors2.ll
    llvm/test/Linker/ctors3.ll
    llvm/test/Linker/link-flags.ll
    llvm/test/Linker/metadata-attach.ll
    llvm/test/Linker/testlink.ll
    llvm/test/ThinLTO/X86/import-constant.ll
    llvm/test/ThinLTO/X86/index-const-prop.ll
    llvm/test/ThinLTO/X86/index-const-prop2.ll
    llvm/test/ThinLTO/X86/writeonly.ll
    llvm/test/ThinLTO/X86/writeonly2.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Linker/IRMover.cpp b/llvm/lib/Linker/IRMover.cpp
index 1433d074595b..9489f9655469 100644
--- a/llvm/lib/Linker/IRMover.cpp
+++ b/llvm/lib/Linker/IRMover.cpp
@@ -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();
 }

diff  --git a/llvm/test/Linker/Inputs/globalorder-2.ll b/llvm/test/Linker/Inputs/globalorder-2.ll
new file mode 100644
index 000000000000..a984ebf78a6a
--- /dev/null
+++ b/llvm/test/Linker/Inputs/globalorder-2.ll
@@ -0,0 +1,14 @@
+ at var5 = internal global i32 0, align 4
+ at var6 = internal global i32 0, align 4
+ at var7 = global i32* @var5, align 4
+ at 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
+}

diff  --git a/llvm/test/Linker/comdat.ll b/llvm/test/Linker/comdat.ll
index 2a2ec3bbb6b2..e3bb1ea39260 100644
--- a/llvm/test/Linker/comdat.ll
+++ b/llvm/test/Linker/comdat.ll
@@ -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)

diff  --git a/llvm/test/Linker/comdat14.ll b/llvm/test/Linker/comdat14.ll
index 9c6eb7c4cc1d..1a1ba47aa017 100644
--- a/llvm/test/Linker/comdat14.ll
+++ b/llvm/test/Linker/comdat14.ll
@@ -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

diff  --git a/llvm/test/Linker/ctors.ll b/llvm/test/Linker/ctors.ll
index 37dba23d4c91..f68ca3e54762 100644
--- a/llvm/test/Linker/ctors.ll
+++ b/llvm/test/Linker/ctors.ll
@@ -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

diff  --git a/llvm/test/Linker/ctors2.ll b/llvm/test/Linker/ctors2.ll
index 9b7a70eb7cd1..c02973faf4d0 100644
--- a/llvm/test/Linker/ctors2.ll
+++ b/llvm/test/Linker/ctors2.ll
@@ -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

diff  --git a/llvm/test/Linker/ctors3.ll b/llvm/test/Linker/ctors3.ll
index e62b92dca0b4..d522df58e891 100644
--- a/llvm/test/Linker/ctors3.ll
+++ b/llvm/test/Linker/ctors3.ll
@@ -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

diff  --git a/llvm/test/Linker/globalorder.ll b/llvm/test/Linker/globalorder.ll
new file mode 100644
index 000000000000..caab97a6ba86
--- /dev/null
+++ b/llvm/test/Linker/globalorder.ll
@@ -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
+
+ at var1 = internal global i32 0, align 4
+ at var2 = internal global i32 0, align 4
+ at var3 = global i32* @var1, align 4
+ at 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 =

diff  --git a/llvm/test/Linker/link-flags.ll b/llvm/test/Linker/link-flags.ll
index 1a57e8aa4d28..4e8eaa62dd78 100644
--- a/llvm/test/Linker/link-flags.ll
+++ b/llvm/test/Linker/link-flags.ll
@@ -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() {
 

diff  --git a/llvm/test/Linker/metadata-attach.ll b/llvm/test/Linker/metadata-attach.ll
index 368c72a9c5f8..6b6c8dd9ed35 100644
--- a/llvm/test/Linker/metadata-attach.ll
+++ b/llvm/test/Linker/metadata-attach.ll
@@ -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}

diff  --git a/llvm/test/Linker/testlink.ll b/llvm/test/Linker/testlink.ll
index 6a316a3bf846..69870b50413c 100644
--- a/llvm/test/Linker/testlink.ll
+++ b/llvm/test/Linker/testlink.ll
@@ -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* }
 

diff  --git a/llvm/test/ThinLTO/X86/import-constant.ll b/llvm/test/ThinLTO/X86/import-constant.ll
index 1bc2a1c2f7a4..e5254948f591 100644
--- a/llvm/test/ThinLTO/X86/import-constant.ll
+++ b/llvm/test/ThinLTO/X86/import-constant.ll
@@ -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"

diff  --git a/llvm/test/ThinLTO/X86/index-const-prop.ll b/llvm/test/ThinLTO/X86/index-const-prop.ll
index 9718aec8a944..b8028d65fa58 100644
--- a/llvm/test/ThinLTO/X86/index-const-prop.ll
+++ b/llvm/test/ThinLTO/X86/index-const-prop.ll
@@ -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"

diff  --git a/llvm/test/ThinLTO/X86/index-const-prop2.ll b/llvm/test/ThinLTO/X86/index-const-prop2.ll
index 5bf40fc688d5..68fe058a8637 100644
--- a/llvm/test/ThinLTO/X86/index-const-prop2.ll
+++ b/llvm/test/ThinLTO/X86/index-const-prop2.ll
@@ -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

diff  --git a/llvm/test/ThinLTO/X86/writeonly.ll b/llvm/test/ThinLTO/X86/writeonly.ll
index 7616f192fbfc..65c93a79afa9 100644
--- a/llvm/test/ThinLTO/X86/writeonly.ll
+++ b/llvm/test/ThinLTO/X86/writeonly.ll
@@ -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"

diff  --git a/llvm/test/ThinLTO/X86/writeonly2.ll b/llvm/test/ThinLTO/X86/writeonly2.ll
index 2648727f0997..f31f9b35a253 100644
--- a/llvm/test/ThinLTO/X86/writeonly2.ll
+++ b/llvm/test/ThinLTO/X86/writeonly2.ll
@@ -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


        


More information about the llvm-commits mailing list