https://github.com/mikolaj-pirog updated https://github.com/llvm/llvm-project/pull/114260
From f903e7e2effbd9675d0977dc1fd176ce97f11778 Mon Sep 17 00:00:00 2001 From: "Pirog, Mikolaj Maciej" <mikolaj.maciej.pi...@intel.com> Date: Wed, 30 Oct 2024 16:30:39 +0100 Subject: [PATCH 1/5] Correct test --- clang/test/CodeGen/debug-dir-win-pe-pgi-string.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 clang/test/CodeGen/debug-dir-win-pe-pgi-string.c diff --git a/clang/test/CodeGen/debug-dir-win-pe-pgi-string.c b/clang/test/CodeGen/debug-dir-win-pe-pgi-string.c new file mode 100644 index 00000000000000..7f1e9e35aaf120 --- /dev/null +++ b/clang/test/CodeGen/debug-dir-win-pe-pgi-string.c @@ -0,0 +1,14 @@ +// This test checks if Windows PE file compiled with +// -fprofile-generate has magic string "PGI" to indicate so. + + +// REQUIRES: system-windows + +// RUN: %clang --target=x86_64-pc-windows-msvc -fprofile-generate -fuse-ld=lld %s -o %t.exe +// RUN: dumpbin /HEADERS %t.exe | FileCheck --check-prefix=CHECK2 %s +// CHECK2: {{.*}}PGI{{.*}} + +int main(void) { + + return 0; +} From 9dfc603efb9d826c782a5b2919f910bbb6b0d4ff Mon Sep 17 00:00:00 2001 From: "Pirog, Mikolaj Maciej" <mikolaj.maciej.pi...@intel.com> Date: Wed, 30 Oct 2024 16:42:07 +0100 Subject: [PATCH 2/5] Add emitting of Windows PE PGO/LTO strings --- clang/lib/CodeGen/BackendUtil.cpp | 3 + .../CodeGen/debug-dir-win-pe-ltcg-string.c | 13 +++++ .../CodeGen/debug-dir-win-pe-pgu-string.c | 18 ++++++ lld/COFF/Writer.cpp | 56 ++++++++++++++++++- ...debug_dir_magic_strings_from_section_pgi.s | 18 ++++++ ...debug_dir_magic_strings_from_section_pgu.s | 17 ++++++ llvm/include/llvm/MC/MCTargetOptions.h | 3 +- llvm/lib/MC/WinCOFFObjectWriter.cpp | 13 +++++ 8 files changed, 139 insertions(+), 2 deletions(-) create mode 100644 clang/test/CodeGen/debug-dir-win-pe-ltcg-string.c create mode 100644 clang/test/CodeGen/debug-dir-win-pe-pgu-string.c create mode 100644 lld/test/COFF/debug_dir_magic_strings_from_section_pgi.s create mode 100644 lld/test/COFF/debug_dir_magic_strings_from_section_pgu.s diff --git a/clang/lib/CodeGen/BackendUtil.cpp b/clang/lib/CodeGen/BackendUtil.cpp index f018130807519d..fcf3dc25d95fc0 100644 --- a/clang/lib/CodeGen/BackendUtil.cpp +++ b/clang/lib/CodeGen/BackendUtil.cpp @@ -525,6 +525,9 @@ static bool initTargetOptions(DiagnosticsEngine &Diags, Options.MCOptions.PPCUseFullRegisterNames = CodeGenOpts.PPCUseFullRegisterNames; Options.MisExpect = CodeGenOpts.MisExpect; + Options.MCOptions.PgoInstrumentation = CodeGenOpts.getProfileInstr() > 0; + Options.MCOptions.PgoUse = + CodeGenOpts.getProfileUse() > 0 || !CodeGenOpts.SampleProfileFile.empty(); return true; } diff --git a/clang/test/CodeGen/debug-dir-win-pe-ltcg-string.c b/clang/test/CodeGen/debug-dir-win-pe-ltcg-string.c new file mode 100644 index 00000000000000..a121ab8c9acc45 --- /dev/null +++ b/clang/test/CodeGen/debug-dir-win-pe-ltcg-string.c @@ -0,0 +1,13 @@ +// This test checks if Window PE file compiled with -flto option contains a magic +// string "LTCG" to indicate LTO compilation. + +// REQUIRES: system-windows + +// RUN: %clang --target=x86_64-pc-windows-msvc -flto -fuse-ld=lld %s -o %t.exe +// RUN: dumpbin /HEADERS %t.exe | FileCheck %s +// CHECK: {{.*}}LTCG{{.*}} + +int main(void) { + + return 0; +} diff --git a/clang/test/CodeGen/debug-dir-win-pe-pgu-string.c b/clang/test/CodeGen/debug-dir-win-pe-pgu-string.c new file mode 100644 index 00000000000000..12c63425aee0f5 --- /dev/null +++ b/clang/test/CodeGen/debug-dir-win-pe-pgu-string.c @@ -0,0 +1,18 @@ +// This test checks if Windows PE file contains a "PGU" string to indicate that +// it was compiled using profiling data. + +// REQUIRES: system-windows + +// RUN: %clang --target=x86_64-pc-windows-msvc -fprofile-instr-generate="%profdata" -fuse-ld=lld %s -o %t.exe +// RUN: %t.exe +// RUN: llvm-profdata merge -output=%code.profdata %profdata +// RUN: %clang --target=x86_64-pc-windows-msvc -fprofile-use=%code.profdata -fuse-ld=lld %s -o %t.exe +// RUN: dumpbin /HEADERS %t.exe | FileCheck %s + +// CHECK: {{.*}}PGU{{.*}} + +int main(void) { + + return 0; +} + diff --git a/lld/COFF/Writer.cpp b/lld/COFF/Writer.cpp index 71ee5ce4685553..0ce62ad21c4634 100644 --- a/lld/COFF/Writer.cpp +++ b/lld/COFF/Writer.cpp @@ -77,6 +77,12 @@ static unsigned char dosProgram[] = { static_assert(sizeof(dosProgram) % 8 == 0, "DOSProgram size must be multiple of 8"); +static char ltcg[] = "LTCG"; +static char pgi[] = "PGI"; +static char pgu[] = "PGU"; +static char pgiSectionName[] = ".pgi"; +static char pguSectionName[] = ".pgu"; + static const int dosStubSize = sizeof(dos_header) + sizeof(dosProgram); static_assert(dosStubSize % 8 == 0, "DOSStub size must be multiple of 8"); @@ -179,6 +185,23 @@ class ExtendedDllCharacteristicsChunk : public NonSectionChunk { uint32_t characteristics = 0; }; +class DebugDirStringChunk : public NonSectionChunk { +public: + DebugDirStringChunk(std::string str) : str(str.begin(), str.end()) { + while (this->str.size() % 4 != 0) + this->str.push_back(0); + } + size_t getSize() const override { return str.size(); } + + void writeTo(uint8_t *b) const override { + char *p = reinterpret_cast<char *>(b); + auto strReverse = str; + std::reverse(strReverse.begin(), strReverse.end()); + memcpy(p, strReverse.data(), strReverse.size()); + } + std::vector<char> str; +}; + // PartialSection represents a group of chunks that contribute to an // OutputSection. Collating a collection of PartialSections of same name and // characteristics constitutes the OutputSection. @@ -1165,6 +1188,23 @@ void Writer::createMiscChunks() { llvm::TimeTraceScope timeScope("Misc chunks"); Configuration *config = &ctx.config; + auto searchForPgoMagicSection = [this](char sectionName[]) { + for (auto *obj : ctx.objFileInstances) { + for (auto &chunk : obj->getChunks()) { + if (chunk->kind() == Chunk::SectionKind && + chunk->getSectionName() == sectionName) { + return true; + } + } + } + return false; + }; + + bool writePgi = searchForPgoMagicSection(pgiSectionName); + bool writePgu = !writePgi && searchForPgoMagicSection(pguSectionName); + bool writeLTO = ctx.bitcodeFileInstances.size(); + + for (MergeChunk *p : ctx.mergeChunkInstances) { if (p) { p->finalizeContents(); @@ -1181,7 +1221,7 @@ void Writer::createMiscChunks() { // Create Debug Information Chunks debugInfoSec = config->mingw ? buildidSec : rdataSec; if (config->buildIDHash != BuildIDHash::None || config->debug || - config->repro || config->cetCompat) { + config->repro || config->cetCompat || writePgi || writePgu || writeLTO) { debugDirectory = make<DebugDirectoryChunk>(ctx, debugRecords, config->repro); debugDirectory->setAlignment(4); @@ -1206,6 +1246,20 @@ void Writer::createMiscChunks() { IMAGE_DLL_CHARACTERISTICS_EX_CET_COMPAT)); } + + if (writeLTO) { + debugRecords.emplace_back(COFF::IMAGE_DEBUG_TYPE_POGO, + make<DebugDirStringChunk>(ltcg)); + } + + if (writePgi) { + debugRecords.emplace_back(COFF::IMAGE_DEBUG_TYPE_POGO, + make<DebugDirStringChunk>(pgi)); + } else if (writePgu) { + debugRecords.emplace_back(COFF::IMAGE_DEBUG_TYPE_POGO, + make<DebugDirStringChunk>(pgu)); + } + // Align and add each chunk referenced by the debug data directory. for (std::pair<COFF::DebugType, Chunk *> r : debugRecords) { r.second->setAlignment(4); diff --git a/lld/test/COFF/debug_dir_magic_strings_from_section_pgi.s b/lld/test/COFF/debug_dir_magic_strings_from_section_pgi.s new file mode 100644 index 00000000000000..e59bc5f19b7a55 --- /dev/null +++ b/lld/test/COFF/debug_dir_magic_strings_from_section_pgi.s @@ -0,0 +1,18 @@ +// This test checks if lld puts magic string "PGI" reversed when an object files contains +// .pgi section. + +// REQUIRES: system-windows + + +// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-windows-msvc %s -o %t.main.obj + +// RUN: lld-link -out:%t.exe %t.main.obj -entry:entry -subsystem:console -debug:symtab +// RUN: dumpbin /HEADERS %t.exe +// CHECK: PGI + +#--- main.s +.section .pgi +.global entry +entry: + movl %edx, %edx + diff --git a/lld/test/COFF/debug_dir_magic_strings_from_section_pgu.s b/lld/test/COFF/debug_dir_magic_strings_from_section_pgu.s new file mode 100644 index 00000000000000..59ace661f7c2e5 --- /dev/null +++ b/lld/test/COFF/debug_dir_magic_strings_from_section_pgu.s @@ -0,0 +1,17 @@ +// This test checks if lld puts magic string "PGU" reversed when an object files contains +// .pgu section. + +// REQUIRES: system-windows + +// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-windows-msvc %s -o %t.main.obj + +// RUN: lld-link -out:%t.exe %t.main.obj -entry:entry -subsystem:console -debug:symtab +// RUN: dumpbin /HEADERS %t.exe +// CHECK: PGU + +#--- main.s +.section .pgu +.global entry +entry: + movl %edx, %edx + diff --git a/llvm/include/llvm/MC/MCTargetOptions.h b/llvm/include/llvm/MC/MCTargetOptions.h index 7b0d81faf73d2d..5e6a58a36615b1 100644 --- a/llvm/include/llvm/MC/MCTargetOptions.h +++ b/llvm/include/llvm/MC/MCTargetOptions.h @@ -1,5 +1,4 @@ //===- MCTargetOptions.h - MC Target Options --------------------*- C++ -*-===// -// // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception @@ -112,6 +111,8 @@ class MCTargetOptions { // Whether or not to use full register names on PowerPC. bool PPCUseFullRegisterNames : 1; + bool PgoInstrumentation = false; + bool PgoUse = false; MCTargetOptions(); /// getABIName - If this returns a non-empty string this represents the diff --git a/llvm/lib/MC/WinCOFFObjectWriter.cpp b/llvm/lib/MC/WinCOFFObjectWriter.cpp index 62f53423126ea9..e413a2d3e48b9e 100644 --- a/llvm/lib/MC/WinCOFFObjectWriter.cpp +++ b/llvm/lib/MC/WinCOFFObjectWriter.cpp @@ -28,6 +28,7 @@ #include "llvm/MC/MCSectionCOFF.h" #include "llvm/MC/MCSymbol.h" #include "llvm/MC/MCSymbolCOFF.h" +#include "llvm/MC/MCTargetOptions.h" #include "llvm/MC/MCValue.h" #include "llvm/MC/MCWinCOFFObjectWriter.h" #include "llvm/MC/StringTableBuilder.h" @@ -981,6 +982,18 @@ static std::time_t getTime() { uint64_t WinCOFFWriter::writeObject(MCAssembler &Asm) { uint64_t StartOffset = W.OS.tell(); + const auto *Options = Asm.getContext().getTargetOptions(); + + if (Options && Options->PgoInstrumentation) { + auto *Section = Asm.getContext().getCOFFSection(".pgi", 0); + defineSection(Asm, *Section); + } + + if (Options && Options->PgoUse) { + auto *Section = Asm.getContext().getCOFFSection(".pgu", 0); + defineSection(Asm, *Section); + } + if (Sections.size() > INT32_MAX) report_fatal_error( "PE COFF object files can't have more than 2147483647 sections"); From aff0c9021299b3e3ce66fa865dc28ebdc01abd9d Mon Sep 17 00:00:00 2001 From: "Pirog, Mikolaj Maciej" <mikolaj.maciej.pi...@intel.com> Date: Wed, 30 Oct 2024 16:45:31 +0100 Subject: [PATCH 3/5] Correct test description --- lld/test/COFF/debug_dir_magic_strings_from_section_pgi.s | 3 +-- lld/test/COFF/debug_dir_magic_strings_from_section_pgu.s | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/lld/test/COFF/debug_dir_magic_strings_from_section_pgi.s b/lld/test/COFF/debug_dir_magic_strings_from_section_pgi.s index e59bc5f19b7a55..b1782dade39042 100644 --- a/lld/test/COFF/debug_dir_magic_strings_from_section_pgi.s +++ b/lld/test/COFF/debug_dir_magic_strings_from_section_pgi.s @@ -1,9 +1,8 @@ -// This test checks if lld puts magic string "PGI" reversed when an object files contains +// This test checks if lld puts magic string "PGI" when an object files contains // .pgi section. // REQUIRES: system-windows - // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-windows-msvc %s -o %t.main.obj // RUN: lld-link -out:%t.exe %t.main.obj -entry:entry -subsystem:console -debug:symtab diff --git a/lld/test/COFF/debug_dir_magic_strings_from_section_pgu.s b/lld/test/COFF/debug_dir_magic_strings_from_section_pgu.s index 59ace661f7c2e5..341f88d25bbaad 100644 --- a/lld/test/COFF/debug_dir_magic_strings_from_section_pgu.s +++ b/lld/test/COFF/debug_dir_magic_strings_from_section_pgu.s @@ -1,4 +1,4 @@ -// This test checks if lld puts magic string "PGU" reversed when an object files contains +// This test checks if lld puts magic string "PGU" when an object files contains // .pgu section. // REQUIRES: system-windows From 5cb0237d1b6fd1d3ee973faf41a8e6f9012da9f1 Mon Sep 17 00:00:00 2001 From: "Pirog, Mikolaj Maciej" <mikolaj.maciej.pi...@intel.com> Date: Mon, 4 Nov 2024 12:31:20 +0100 Subject: [PATCH 4/5] Don't write to DwoOnly files --- llvm/lib/MC/WinCOFFObjectWriter.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/llvm/lib/MC/WinCOFFObjectWriter.cpp b/llvm/lib/MC/WinCOFFObjectWriter.cpp index e413a2d3e48b9e..6e6685008d16ec 100644 --- a/llvm/lib/MC/WinCOFFObjectWriter.cpp +++ b/llvm/lib/MC/WinCOFFObjectWriter.cpp @@ -984,12 +984,12 @@ uint64_t WinCOFFWriter::writeObject(MCAssembler &Asm) { const auto *Options = Asm.getContext().getTargetOptions(); - if (Options && Options->PgoInstrumentation) { + if (Mode != DwoOnly && Options && Options->PgoInstrumentation) { auto *Section = Asm.getContext().getCOFFSection(".pgi", 0); defineSection(Asm, *Section); } - if (Options && Options->PgoUse) { + if (Mode != DwoOnly && Options && Options->PgoUse) { auto *Section = Asm.getContext().getCOFFSection(".pgu", 0); defineSection(Asm, *Section); } From 0e3749fa3dfaab658f8f877d55864c378beedd7e Mon Sep 17 00:00:00 2001 From: "Pirog, Mikolaj Maciej" <mikolaj.maciej.pi...@intel.com> Date: Mon, 4 Nov 2024 21:33:19 +0100 Subject: [PATCH 5/5] Apply reviewers' suggestions to testing --- clang/test/CodeGen/debug-dir-win-pe-pgi-string.c | 14 +++++++------- clang/test/CodeGen/debug-dir-win-pe-pgu-string.c | 4 ++-- .../debug_dir_magic_strings_from_section_pgi.s | 15 +++++++-------- .../debug_dir_magic_strings_from_section_pgu.s | 15 +++++++-------- 4 files changed, 23 insertions(+), 25 deletions(-) diff --git a/clang/test/CodeGen/debug-dir-win-pe-pgi-string.c b/clang/test/CodeGen/debug-dir-win-pe-pgi-string.c index 7f1e9e35aaf120..60c9c745fd4d8c 100644 --- a/clang/test/CodeGen/debug-dir-win-pe-pgi-string.c +++ b/clang/test/CodeGen/debug-dir-win-pe-pgi-string.c @@ -1,12 +1,12 @@ -// This test checks if Windows PE file compiled with -// -fprofile-generate has magic string "PGI" to indicate so. +// This test checks if COFF file compiled with +// -fprofile-generate has magic section ".pgi" to indicate so. +// RUN: %clang --target=x86_64-pc-windows-msvc -fprofile-generate %s -c -o %t_x86 +// RUN: llvm-objdump -h %t_x86 | FileCheck --check-prefix=CHECK_PGI %s +// RUN: %clang --target=aarch64-pc-windows-msvc -fprofile-generate %s -c -o %t_aarch +// RUN: llvm-objdump -h %t_aarch | FileCheck --check-prefix=CHECK_PGI %s -// REQUIRES: system-windows - -// RUN: %clang --target=x86_64-pc-windows-msvc -fprofile-generate -fuse-ld=lld %s -o %t.exe -// RUN: dumpbin /HEADERS %t.exe | FileCheck --check-prefix=CHECK2 %s -// CHECK2: {{.*}}PGI{{.*}} +// CHECK_PGI: {{.*}}.pgi{{.*}} int main(void) { diff --git a/clang/test/CodeGen/debug-dir-win-pe-pgu-string.c b/clang/test/CodeGen/debug-dir-win-pe-pgu-string.c index 12c63425aee0f5..a934f12940a5bf 100644 --- a/clang/test/CodeGen/debug-dir-win-pe-pgu-string.c +++ b/clang/test/CodeGen/debug-dir-win-pe-pgu-string.c @@ -7,9 +7,9 @@ // RUN: %t.exe // RUN: llvm-profdata merge -output=%code.profdata %profdata // RUN: %clang --target=x86_64-pc-windows-msvc -fprofile-use=%code.profdata -fuse-ld=lld %s -o %t.exe -// RUN: dumpbin /HEADERS %t.exe | FileCheck %s +// RUN: llvm-readobj --coff-debug-directory %t.exe | FileCheck %s -// CHECK: {{.*}}PGU{{.*}} +// CHECK: {{.*}}ugp{{.*}} int main(void) { diff --git a/lld/test/COFF/debug_dir_magic_strings_from_section_pgi.s b/lld/test/COFF/debug_dir_magic_strings_from_section_pgi.s index b1782dade39042..1f8ea7d0dae582 100644 --- a/lld/test/COFF/debug_dir_magic_strings_from_section_pgi.s +++ b/lld/test/COFF/debug_dir_magic_strings_from_section_pgi.s @@ -1,17 +1,16 @@ // This test checks if lld puts magic string "PGI" when an object files contains // .pgi section. -// REQUIRES: system-windows +// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-windows-msvc %s -o %t.main_x86.obj +// RUN: llvm-mc -filetype=obj -triple=aarch64-pc-windows-msvc %s -o %t.main_aarch.obj -// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-windows-msvc %s -o %t.main.obj - -// RUN: lld-link -out:%t.exe %t.main.obj -entry:entry -subsystem:console -debug:symtab -// RUN: dumpbin /HEADERS %t.exe -// CHECK: PGI +// RUN: lld-link -out:%t_x86.exe %t.main_x86.obj -entry:entry -subsystem:console -debug:symtab +// RUN: lld-link -out:%t_aarch.exe %t.main_aarch.obj -entry:entry -subsystem:console -debug:symtab +// RUN: llvm-readobj --coff-debug-directory %t_x86.exe | FileCheck --check-prefix=CHECK_PGI %s +// RUN: llvm-readobj --coff-debug-directory %t_aarch.exe | FileCheck --check-prefix=CHECK_PGI %s +// CHECK_PGI: {{.*}}IGP{{.*}} #--- main.s .section .pgi .global entry entry: - movl %edx, %edx - diff --git a/lld/test/COFF/debug_dir_magic_strings_from_section_pgu.s b/lld/test/COFF/debug_dir_magic_strings_from_section_pgu.s index 341f88d25bbaad..bca1345eac3337 100644 --- a/lld/test/COFF/debug_dir_magic_strings_from_section_pgu.s +++ b/lld/test/COFF/debug_dir_magic_strings_from_section_pgu.s @@ -1,17 +1,16 @@ // This test checks if lld puts magic string "PGU" when an object files contains // .pgu section. -// REQUIRES: system-windows +// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-windows-msvc %s -o %t.main_x86.obj +// RUN: llvm-mc -filetype=obj -triple=aarch64-pc-windows-msvc %s -o %t.main_aarch.obj -// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-windows-msvc %s -o %t.main.obj - -// RUN: lld-link -out:%t.exe %t.main.obj -entry:entry -subsystem:console -debug:symtab -// RUN: dumpbin /HEADERS %t.exe -// CHECK: PGU +// RUN: lld-link -out:%t_x86.exe %t.main_x86.obj -entry:entry -subsystem:console -debug:symtab +// RUN: lld-link -out:%t_aarch.exe %t.main_aarch.obj -entry:entry -subsystem:console -debug:symtab +// RUN: llvm-readobj --coff-debug-directory %t_x86.exe | FileCheck --check-prefix=CHECK_PGU %s +// RUN: llvm-readobj --coff-debug-directory %t_aarch.exe | FileCheck --check-prefix=CHECK_PGU %s +// CHECK_PGU: {{.*}}UGP{{.*}} #--- main.s .section .pgu .global entry entry: - movl %edx, %edx - _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits