[lld] r343552 - [ELF] Read the call graph profile from object files.

Michael J. Spencer via llvm-commits llvm-commits at lists.llvm.org
Mon Oct 1 17:17:16 PDT 2018


Author: mspencer
Date: Mon Oct  1 17:17:15 2018
New Revision: 343552

URL: http://llvm.org/viewvc/llvm-project?rev=343552&view=rev
Log:
[ELF] Read the call graph profile from object files.

This uses the call graph profile embedded in the object files to construct the call graph.

This is read from a SHT_LLVM_CALL_GRAPH_PROFILE (0x6fff4c02) section as (uint32_t, uint32_t, uint64_t) tuples as (from symbol index, to symbol index, weight).

Differential Revision: https://reviews.llvm.org/D45850

Added:
    lld/trunk/test/ELF/cgprofile-obj-warn.s
    lld/trunk/test/ELF/cgprofile-obj.s
Modified:
    lld/trunk/ELF/Driver.cpp
    lld/trunk/ELF/InputFiles.cpp
    lld/trunk/ELF/InputFiles.h

Modified: lld/trunk/ELF/Driver.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Driver.cpp?rev=343552&r1=343551&r2=343552&view=diff
==============================================================================
--- lld/trunk/ELF/Driver.cpp (original)
+++ lld/trunk/ELF/Driver.cpp Mon Oct  1 17:17:15 2018
@@ -679,6 +679,27 @@ static void readCallGraph(MemoryBufferRe
   }
 }
 
+template <class ELFT> static void readCallGraphsFromObjectFiles() {
+  auto FindSection = [&](const Symbol *Sym) -> const InputSectionBase * {
+    warnUnorderableSymbol(Sym);
+    if (const auto *SymD = dyn_cast<Defined>(Sym))
+      return dyn_cast_or_null<InputSectionBase>(SymD->Section);
+    return nullptr;
+  };
+
+  for (auto File : ObjectFiles) {
+    auto *Obj = cast<ObjFile<ELFT>>(File);
+    for (const Elf_CGProfile_Impl<ELFT> &CGPE : Obj->CGProfile) {
+      const InputSectionBase *FromSB =
+          FindSection(&Obj->getSymbol(CGPE.cgp_from));
+      const InputSectionBase *ToSB = FindSection(&Obj->getSymbol(CGPE.cgp_to));
+      if (!FromSB || !ToSB)
+        continue;
+      Config->CallGraphProfile[{FromSB, ToSB}] += CGPE.cgp_weight;
+    }
+  }
+}
+
 static bool getCompressDebugSections(opt::InputArgList &Args) {
   StringRef S = Args.getLastArgValue(OPT_compress_debug_sections, "none");
   if (S == "none")
@@ -1598,6 +1619,7 @@ template <class ELFT> void LinkerDriver:
   if (auto *Arg = Args.getLastArg(OPT_call_graph_ordering_file))
     if (Optional<MemoryBufferRef> Buffer = readFile(Arg->getValue()))
       readCallGraph(*Buffer);
+  readCallGraphsFromObjectFiles<ELFT>();
 
   // Write the result to the file.
   writeResult<ELFT>();

Modified: lld/trunk/ELF/InputFiles.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/InputFiles.cpp?rev=343552&r1=343551&r2=343552&view=diff
==============================================================================
--- lld/trunk/ELF/InputFiles.cpp (original)
+++ lld/trunk/ELF/InputFiles.cpp Mon Oct  1 17:17:15 2018
@@ -412,6 +412,11 @@ void ObjFile<ELFT>::initializeSections(
       continue;
     const Elf_Shdr &Sec = ObjSections[I];
 
+    if (Sec.sh_type == ELF::SHT_LLVM_CALL_GRAPH_PROFILE)
+      CGProfile = check(
+          this->getObj().template getSectionContentsAsArray<Elf_CGProfile>(
+              &Sec));
+
     // SHF_EXCLUDE'ed sections are discarded by the linker. However,
     // if -r is given, we'll let the final link discard such sections.
     // This is compatible with GNU.

Modified: lld/trunk/ELF/InputFiles.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/InputFiles.h?rev=343552&r1=343551&r2=343552&view=diff
==============================================================================
--- lld/trunk/ELF/InputFiles.h (original)
+++ lld/trunk/ELF/InputFiles.h Mon Oct  1 17:17:15 2018
@@ -171,6 +171,7 @@ template <class ELFT> class ObjFile : pu
   typedef typename ELFT::Sym Elf_Sym;
   typedef typename ELFT::Shdr Elf_Shdr;
   typedef typename ELFT::Word Elf_Word;
+  typedef typename ELFT::CGProfile Elf_CGProfile;
 
   StringRef getShtGroupSignature(ArrayRef<Elf_Shdr> Sections,
                                  const Elf_Shdr &Sec);
@@ -220,6 +221,9 @@ public:
   // Pointer to this input file's .llvm_addrsig section, if it has one.
   const Elf_Shdr *AddrsigSec = nullptr;
 
+  // SHT_LLVM_CALL_GRAPH_PROFILE table
+  ArrayRef<Elf_CGProfile> CGProfile;
+
 private:
   void
   initializeSections(llvm::DenseSet<llvm::CachedHashStringRef> &ComdatGroups);

Added: lld/trunk/test/ELF/cgprofile-obj-warn.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/cgprofile-obj-warn.s?rev=343552&view=auto
==============================================================================
--- lld/trunk/test/ELF/cgprofile-obj-warn.s (added)
+++ lld/trunk/test/ELF/cgprofile-obj-warn.s Mon Oct  1 17:17:15 2018
@@ -0,0 +1,37 @@
+# REQUIRES: x86
+
+# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
+
+# RUN: ld.lld -e A %t -o /dev/null \
+# RUN:   -noinhibit-exec -icf=all 2>&1 | FileCheck %s
+
+    .section    .text.C,"ax", at progbits
+    .globl  C
+C:
+    mov poppy, %rax
+    retq
+
+B = 0x1234
+
+    .section    .text.A,"ax", at progbits
+    .globl  A
+A:
+    mov poppy, %rax
+    retq
+
+    .cg_profile A, B, 100
+    .cg_profile A, C, 40
+    .cg_profile B, C, 30
+    .cg_profile adena1, A, 30
+    .cg_profile A, adena2, 30
+    .cg_profile poppy, A, 30
+
+# CHECK: unable to order absolute symbol: B
+# CHECK: unable to order undefined symbol: adena1
+# CHECK: unable to order undefined symbol: adena2
+# CHECK: unable to order undefined symbol: poppy
+
+# RUN: ld.lld %t -o /dev/null \
+# RUN:   -noinhibit-exec -icf=all --no-warn-symbol-ordering 2>&1 \
+# RUN:   | FileCheck %s --check-prefix=NOWARN
+# NOWARN-NOT: unable to order

Added: lld/trunk/test/ELF/cgprofile-obj.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/cgprofile-obj.s?rev=343552&view=auto
==============================================================================
--- lld/trunk/test/ELF/cgprofile-obj.s (added)
+++ lld/trunk/test/ELF/cgprofile-obj.s Mon Oct  1 17:17:15 2018
@@ -0,0 +1,41 @@
+# REQUIRES: x86
+
+# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
+# RUN: ld.lld -e A %t -o %t2
+# RUN: llvm-readobj -symbols %t2 | FileCheck %s
+
+    .section    .text.D,"ax", at progbits
+D:
+    retq
+
+    .section    .text.C,"ax", at progbits
+    .globl  C
+C:
+    retq
+
+    .section    .text.B,"ax", at progbits
+    .globl  B
+B:
+    retq
+
+    .section    .text.A,"ax", at progbits
+    .globl  A
+A:
+Aa:
+    retq
+
+    .cg_profile A, B, 10
+    .cg_profile A, B, 10
+    .cg_profile Aa, B, 80
+    .cg_profile A, C, 40
+    .cg_profile B, C, 30
+    .cg_profile C, D, 90
+
+# CHECK:          Name: D
+# CHECK-NEXT:     Value: 0x201003
+# CHECK:          Name: A
+# CHECK-NEXT:     Value: 0x201000
+# CHECK:          Name: B
+# CHECK-NEXT:     Value: 0x201001
+# CHECK:          Name: C
+# CHECK-NEXT:     Value: 0x201002




More information about the llvm-commits mailing list