[flang-commits] [flang] [Flang][Driver] Emit module summary for Full LTO (PR #164302)

Anchu Rajendran S via flang-commits flang-commits at lists.llvm.org
Wed Oct 22 10:36:33 PDT 2025


https://github.com/anchuraj updated https://github.com/llvm/llvm-project/pull/164302

>From 330989345ab5acfd6854a0ac196dec82a0a582a6 Mon Sep 17 00:00:00 2001
From: Anchu Rajendran <asudhaku at amd.com>
Date: Fri, 17 Oct 2025 17:37:12 -0500
Subject: [PATCH 1/5] [Flang][Driver] Emit module summary for LTO

---
 flang/lib/Frontend/FrontendActions.cpp | 18 ++++++++-----
 flang/test/CMakeLists.txt              |  1 +
 flang/test/Driver/lto-bc.f90           | 36 ++++++++++++++++++--------
 3 files changed, 38 insertions(+), 17 deletions(-)

diff --git a/flang/lib/Frontend/FrontendActions.cpp b/flang/lib/Frontend/FrontendActions.cpp
index 0c630d2ba876d..c773a96bcd2a8 100644
--- a/flang/lib/Frontend/FrontendActions.cpp
+++ b/flang/lib/Frontend/FrontendActions.cpp
@@ -1019,11 +1019,15 @@ void CodeGenAction::runOptimizationPipeline(llvm::raw_pwrite_stream &os) {
 
   // Create the pass manager.
   llvm::ModulePassManager mpm;
+  // The module summary should be emitted by default for regular LTO
+  // except for ld64 targets.
+  bool emitSummary = (opts.PrepareForThinLTO || opts.PrepareForFullLTO) &&
+                     (triple.getVendor() != llvm::Triple::Apple);
+
+  if (emitSummary && !opts.PrepareForThinLTO)
+    llvmModule->addModuleFlag(llvm::Module::Error, "ThinLTO", uint32_t(0));
+
   if (opts.PrepareForFatLTO) {
-    // The module summary should be emitted by default for regular LTO
-    // except for ld64 targets.
-    bool emitSummary = opts.PrepareForThinLTO || opts.PrepareForFullLTO ||
-                       triple.getVendor() != llvm::Triple::Apple;
     mpm = pb.buildFatLTODefaultPipeline(level, opts.PrepareForThinLTO,
                                         emitSummary);
   } else if (opts.PrepareForFullLTO)
@@ -1034,9 +1038,11 @@ void CodeGenAction::runOptimizationPipeline(llvm::raw_pwrite_stream &os) {
     mpm = pb.buildPerModuleDefaultPipeline(level);
 
   if (action == BackendActionTy::Backend_EmitBC)
-    mpm.addPass(llvm::BitcodeWriterPass(os));
+    mpm.addPass(llvm::BitcodeWriterPass(
+        os, /*ShouldPreserveUseListOrder=*/false, emitSummary));
   else if (action == BackendActionTy::Backend_EmitLL)
-    mpm.addPass(llvm::PrintModulePass(os));
+    mpm.addPass(llvm::PrintModulePass(
+        os, /*Banner=*/"", /*ShouldPreserveUseListOrder=*/false, emitSummary));
 
   // FIXME: This should eventually be replaced by a first-class driver option.
   // This should be done for both flang and clang simultaneously.
diff --git a/flang/test/CMakeLists.txt b/flang/test/CMakeLists.txt
index da557f9ec3443..8c8e92faa787a 100644
--- a/flang/test/CMakeLists.txt
+++ b/flang/test/CMakeLists.txt
@@ -72,6 +72,7 @@ if (NOT FLANG_STANDALONE_BUILD)
     FileCheck
     count
     not
+    llvm-bcanalyzer
     llvm-dis
     llvm-objcopy
     llvm-objdump
diff --git a/flang/test/Driver/lto-bc.f90 b/flang/test/Driver/lto-bc.f90
index 5e34cdb87c5b1..fbf964b849eb7 100644
--- a/flang/test/Driver/lto-bc.f90
+++ b/flang/test/Driver/lto-bc.f90
@@ -1,21 +1,35 @@
 ! Test that the output is LLVM bitcode for LTO and not a native objectfile by
-! disassembling it to LLVM IR.
-! Right now there is nothing special about it and it is similar to non-lto IR,
-! more work is needed to add things like module summaries.
+! disassembling it to LLVM IR. Also tests module summaries are emitted for LTO
 
 ! RUN: %flang %s -c -o - | not llvm-dis -o %t
 ! RUN: %flang_fc1 %s -emit-llvm-bc -o - | llvm-dis -o - | FileCheck %s
-
-! RUN: %flang -flto %s -c -o - | llvm-dis -o - | FileCheck %s
-! RUN: %flang -flto=thin %s -c -o - | llvm-dis -o - | FileCheck %s
-
 ! CHECK: define void @_QQmain()
 ! CHECK-NEXT:  ret void
 ! CHECK-NEXT: }
+! CHECK-NOT: !{{.*}} = !{i32 1, !"ThinLTO", i32 0}
+! CHECK-NOT: ^{{.*}} = module:
+! CHECK-NOT: ^{{.*}} = gv: (name:
+! CHECK-NOT: ^{{.*}} = blockcount:
+
+! RUN: %flang -flto %s -c -o - | llvm-dis -o - | FileCheck %s --check-prefix=FULL
+! THIN: define void @_QQmain()
+! THIN-NEXT:  ret void
+! THIN-NEXT: }
+! THIN-NOT: !{{.*}} = !{i32 1, !"ThinLTO", i32 0}
+! THIN: ^{{.*}} = module:
+! THIN: ^{{.*}} = gv: (name:
+! THIN: ^{{.*}} = blockcount:
 
-! CHECK-NOT: ^0 = module:
-! CHECK-NOT: ^1 = gv: (name:
-! CHECK-NOT: ^2 = flags:
-! CHECK-NOT: ^3 = blockcount:
+! RUN: %flang -flto=thin %s -c -o - | llvm-dis -o - | FileCheck %s --check-prefix=THIN
+! FULL: define void @_QQmain()
+! FULL-NEXT:  ret void
+! FULL-NEXT: }
+! FULL: !{{.*}} = !{i32 1, !"ThinLTO", i32 0}
+! FULL: ^{{.*}} = module:
+! FULL: ^{{.*}} = gv: (name:
+! FULL: ^{{.*}} = blockcount:
 
+! RUN: %flang_fc1 -flto -emit-llvm-bc %s -o - | llvm-bcanalyzer -dump| FileCheck --check-prefix=MOD-SUMM %s
+! MOD-SUMM: FULL_LTO_GLOBALVAL_SUMMARY_BLOCK
+program main
 end program

>From 1ecbeb9e5900b485fb199739721516b1b1850dfd Mon Sep 17 00:00:00 2001
From: Anchu Rajendran <asudhaku at amd.com>
Date: Tue, 21 Oct 2025 12:18:58 -0500
Subject: [PATCH 2/5] R2: Addressing review comments

---
 flang/lib/Frontend/FrontendActions.cpp | 4 ++--
 flang/test/Driver/lto-bc.f90           | 6 +++---
 2 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/flang/lib/Frontend/FrontendActions.cpp b/flang/lib/Frontend/FrontendActions.cpp
index c773a96bcd2a8..54353310aac6e 100644
--- a/flang/lib/Frontend/FrontendActions.cpp
+++ b/flang/lib/Frontend/FrontendActions.cpp
@@ -1027,10 +1027,10 @@ void CodeGenAction::runOptimizationPipeline(llvm::raw_pwrite_stream &os) {
   if (emitSummary && !opts.PrepareForThinLTO)
     llvmModule->addModuleFlag(llvm::Module::Error, "ThinLTO", uint32_t(0));
 
-  if (opts.PrepareForFatLTO) {
+  if (opts.PrepareForFatLTO)
     mpm = pb.buildFatLTODefaultPipeline(level, opts.PrepareForThinLTO,
                                         emitSummary);
-  } else if (opts.PrepareForFullLTO)
+  else if (opts.PrepareForFullLTO)
     mpm = pb.buildLTOPreLinkDefaultPipeline(level);
   else if (opts.PrepareForThinLTO)
     mpm = pb.buildThinLTOPreLinkDefaultPipeline(level);
diff --git a/flang/test/Driver/lto-bc.f90 b/flang/test/Driver/lto-bc.f90
index fbf964b849eb7..57b81aa8d2809 100644
--- a/flang/test/Driver/lto-bc.f90
+++ b/flang/test/Driver/lto-bc.f90
@@ -1,5 +1,5 @@
 ! Test that the output is LLVM bitcode for LTO and not a native objectfile by
-! disassembling it to LLVM IR. Also tests module summaries are emitted for LTO
+! disassembling it to LLVM IR. Also tests that module summaries are emitted for LTO
 
 ! RUN: %flang %s -c -o - | not llvm-dis -o %t
 ! RUN: %flang_fc1 %s -emit-llvm-bc -o - | llvm-dis -o - | FileCheck %s
@@ -11,7 +11,7 @@
 ! CHECK-NOT: ^{{.*}} = gv: (name:
 ! CHECK-NOT: ^{{.*}} = blockcount:
 
-! RUN: %flang -flto %s -c -o - | llvm-dis -o - | FileCheck %s --check-prefix=FULL
+! RUN: %flang -flto=thin %s -c -o - | llvm-dis -o - | FileCheck %s --check-prefix=THIN
 ! THIN: define void @_QQmain()
 ! THIN-NEXT:  ret void
 ! THIN-NEXT: }
@@ -20,7 +20,7 @@
 ! THIN: ^{{.*}} = gv: (name:
 ! THIN: ^{{.*}} = blockcount:
 
-! RUN: %flang -flto=thin %s -c -o - | llvm-dis -o - | FileCheck %s --check-prefix=THIN
+! RUN: %flang -flto %s -c -o - | llvm-dis -o - | FileCheck %s --check-prefix=FULL
 ! FULL: define void @_QQmain()
 ! FULL-NEXT:  ret void
 ! FULL-NEXT: }

>From 51e02c1bb88a4cb39635ffd09e09f76e9f01b7ab Mon Sep 17 00:00:00 2001
From: Anchu Rajendran <asudhaku at amd.com>
Date: Tue, 21 Oct 2025 13:50:52 -0500
Subject: [PATCH 3/5] Removing the changes from ThinLTO

---
 flang/lib/Frontend/FrontendActions.cpp | 30 +++++++++++++++++---------
 flang/test/Driver/lto-bc.f90           |  6 ------
 2 files changed, 20 insertions(+), 16 deletions(-)

diff --git a/flang/lib/Frontend/FrontendActions.cpp b/flang/lib/Frontend/FrontendActions.cpp
index 54353310aac6e..c691577c634d3 100644
--- a/flang/lib/Frontend/FrontendActions.cpp
+++ b/flang/lib/Frontend/FrontendActions.cpp
@@ -1023,10 +1023,6 @@ void CodeGenAction::runOptimizationPipeline(llvm::raw_pwrite_stream &os) {
   // except for ld64 targets.
   bool emitSummary = (opts.PrepareForThinLTO || opts.PrepareForFullLTO) &&
                      (triple.getVendor() != llvm::Triple::Apple);
-
-  if (emitSummary && !opts.PrepareForThinLTO)
-    llvmModule->addModuleFlag(llvm::Module::Error, "ThinLTO", uint32_t(0));
-
   if (opts.PrepareForFatLTO)
     mpm = pb.buildFatLTODefaultPipeline(level, opts.PrepareForThinLTO,
                                         emitSummary);
@@ -1037,12 +1033,26 @@ void CodeGenAction::runOptimizationPipeline(llvm::raw_pwrite_stream &os) {
   else
     mpm = pb.buildPerModuleDefaultPipeline(level);
 
-  if (action == BackendActionTy::Backend_EmitBC)
-    mpm.addPass(llvm::BitcodeWriterPass(
-        os, /*ShouldPreserveUseListOrder=*/false, emitSummary));
-  else if (action == BackendActionTy::Backend_EmitLL)
-    mpm.addPass(llvm::PrintModulePass(
-        os, /*Banner=*/"", /*ShouldPreserveUseListOrder=*/false, emitSummary));
+  if (action == BackendActionTy::Backend_EmitBC ||
+      action == BackendActionTy::Backend_EmitLL || opts.PrepareForFatLTO) {
+    if (opts.PrepareForThinLTO) {
+      // TODO: ThinLTO module summary support is yet to be enabled.
+      if (action == BackendActionTy::Backend_EmitBC)
+        mpm.addPass(llvm::BitcodeWriterPass(os));
+      else if (action == BackendActionTy::Backend_EmitLL)
+        mpm.addPass(llvm::PrintModulePass(os));
+    } else {
+      if (emitSummary && !llvmModule->getModuleFlag("ThinLTO"))
+        llvmModule->addModuleFlag(llvm::Module::Error, "ThinLTO", uint32_t(0));
+      if (action == BackendActionTy::Backend_EmitBC)
+        mpm.addPass(llvm::BitcodeWriterPass(
+            os, /*ShouldPreserveUseListOrder=*/false, emitSummary));
+      else if (action == BackendActionTy::Backend_EmitLL)
+        mpm.addPass(llvm::PrintModulePass(os, /*Banner=*/"",
+                                          /*ShouldPreserveUseListOrder=*/false,
+                                          emitSummary));
+    }
+  }
 
   // FIXME: This should eventually be replaced by a first-class driver option.
   // This should be done for both flang and clang simultaneously.
diff --git a/flang/test/Driver/lto-bc.f90 b/flang/test/Driver/lto-bc.f90
index 57b81aa8d2809..b85021331902c 100644
--- a/flang/test/Driver/lto-bc.f90
+++ b/flang/test/Driver/lto-bc.f90
@@ -12,13 +12,7 @@
 ! CHECK-NOT: ^{{.*}} = blockcount:
 
 ! RUN: %flang -flto=thin %s -c -o - | llvm-dis -o - | FileCheck %s --check-prefix=THIN
-! THIN: define void @_QQmain()
-! THIN-NEXT:  ret void
-! THIN-NEXT: }
 ! THIN-NOT: !{{.*}} = !{i32 1, !"ThinLTO", i32 0}
-! THIN: ^{{.*}} = module:
-! THIN: ^{{.*}} = gv: (name:
-! THIN: ^{{.*}} = blockcount:
 
 ! RUN: %flang -flto %s -c -o - | llvm-dis -o - | FileCheck %s --check-prefix=FULL
 ! FULL: define void @_QQmain()

>From c050671c5f9c8c96c0bb452e2079b6a5e375ef3b Mon Sep 17 00:00:00 2001
From: Anchu Rajendran <asudhaku at amd.com>
Date: Wed, 22 Oct 2025 12:20:41 -0500
Subject: [PATCH 4/5] R3: Addressing review comments

---
 flang/lib/Frontend/FrontendActions.cpp | 3 +--
 flang/test/Driver/lto-bc.f90           | 3 +++
 2 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/flang/lib/Frontend/FrontendActions.cpp b/flang/lib/Frontend/FrontendActions.cpp
index c691577c634d3..5dbdc799f1611 100644
--- a/flang/lib/Frontend/FrontendActions.cpp
+++ b/flang/lib/Frontend/FrontendActions.cpp
@@ -1021,8 +1021,7 @@ void CodeGenAction::runOptimizationPipeline(llvm::raw_pwrite_stream &os) {
   llvm::ModulePassManager mpm;
   // The module summary should be emitted by default for regular LTO
   // except for ld64 targets.
-  bool emitSummary = (opts.PrepareForThinLTO || opts.PrepareForFullLTO) &&
-                     (triple.getVendor() != llvm::Triple::Apple);
+  bool emitSummary = opts.PrepareForFullLTO && (triple.getVendor() != llvm::Triple::Apple);
   if (opts.PrepareForFatLTO)
     mpm = pb.buildFatLTODefaultPipeline(level, opts.PrepareForThinLTO,
                                         emitSummary);
diff --git a/flang/test/Driver/lto-bc.f90 b/flang/test/Driver/lto-bc.f90
index b85021331902c..01fdcacb6d783 100644
--- a/flang/test/Driver/lto-bc.f90
+++ b/flang/test/Driver/lto-bc.f90
@@ -13,6 +13,9 @@
 
 ! RUN: %flang -flto=thin %s -c -o - | llvm-dis -o - | FileCheck %s --check-prefix=THIN
 ! THIN-NOT: !{{.*}} = !{i32 1, !"ThinLTO", i32 0}
+! THIN-NOT: ^{{.*}} = module:
+! THIN-NOT: ^{{.*}} = gv: (name:
+! THIN-NOT: ^{{.*}} = blockcount:
 
 ! RUN: %flang -flto %s -c -o - | llvm-dis -o - | FileCheck %s --check-prefix=FULL
 ! FULL: define void @_QQmain()

>From a6dd62b3f6d066a58d4e8f2103d52991e7e8c24a Mon Sep 17 00:00:00 2001
From: Anchu Rajendran <asudhaku at amd.com>
Date: Wed, 22 Oct 2025 12:34:49 -0500
Subject: [PATCH 5/5] R4: Addressing review comments

---
 flang/test/Driver/lto-bc.f90 | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/flang/test/Driver/lto-bc.f90 b/flang/test/Driver/lto-bc.f90
index 01fdcacb6d783..5705fe0cbb929 100644
--- a/flang/test/Driver/lto-bc.f90
+++ b/flang/test/Driver/lto-bc.f90
@@ -12,6 +12,9 @@
 ! CHECK-NOT: ^{{.*}} = blockcount:
 
 ! RUN: %flang -flto=thin %s -c -o - | llvm-dis -o - | FileCheck %s --check-prefix=THIN
+! THIN: define void @_QQmain()
+! THIN-NEXT:  ret void
+! THIN-NEXT: }
 ! THIN-NOT: !{{.*}} = !{i32 1, !"ThinLTO", i32 0}
 ! THIN-NOT: ^{{.*}} = module:
 ! THIN-NOT: ^{{.*}} = gv: (name:



More information about the flang-commits mailing list