Skip to content

Conversation

@mtrofin
Copy link
Member

@mtrofin mtrofin commented Apr 8, 2025

When llvm-extract-ing a function, and the CG Profile flag is present in the original module, we end up with lots of !{null, null, i64 1234} entries for call edges that have disappeared as result of the removed functions.

This patch fixes that by adding a pass to llvm-extract that finds CG Profile edges with one or both operands null and removes them. This results in a cleaner output.

Copy link
Member Author

mtrofin commented Apr 8, 2025

This stack of pull requests is managed by Graphite. Learn more about stacking.

@mtrofin mtrofin changed the title Strip CG Profile [llvm-extract] Delete dead CG Profile edges Apr 8, 2025
@mtrofin mtrofin requested a review from aeubanks April 8, 2025 22:53
@mtrofin mtrofin marked this pull request as ready for review April 8, 2025 22:53
@llvmbot
Copy link
Member

llvmbot commented Apr 8, 2025

@llvm/pr-subscribers-llvm-transforms

Author: Mircea Trofin (mtrofin)

Changes

When llvm-extract-ing a function, and the CG Profile flag is present in the original module, we end up with lots of !{null, null, i64 1234} entries for call edges that have disappeared as result of the removed functions.

This patch fixes that by adding a pass to llvm-extract that finds CG Profile edges with one or both operands null and removes them. This results in a cleaner output.


Full diff: https://github.com/llvm/llvm-project/pull/134940.diff

5 Files Affected:

  • (modified) llvm/include/llvm/Transforms/IPO/StripSymbols.h (+4)
  • (modified) llvm/lib/Passes/PassRegistry.def (+1)
  • (modified) llvm/lib/Transforms/IPO/StripSymbols.cpp (+20)
  • (added) llvm/test/Transforms/StripSymbols/strip-cg-profile.ll (+53)
  • (modified) llvm/tools/llvm-extract/llvm-extract.cpp (+1)
diff --git a/llvm/include/llvm/Transforms/IPO/StripSymbols.h b/llvm/include/llvm/Transforms/IPO/StripSymbols.h
index dd76d481d668c..bd5cdde290dde 100644
--- a/llvm/include/llvm/Transforms/IPO/StripSymbols.h
+++ b/llvm/include/llvm/Transforms/IPO/StripSymbols.h
@@ -42,6 +42,10 @@ struct StripDeadDebugInfoPass : PassInfoMixin<StripDeadDebugInfoPass> {
   PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);
 };
 
+struct StripDeadCGProfilePass : PassInfoMixin<StripDeadCGProfilePass> {
+  PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);
+};
+
 } // end namespace llvm
 
 #endif // LLVM_TRANSFORMS_IPO_STRIPSYMBOLS_H
diff --git a/llvm/lib/Passes/PassRegistry.def b/llvm/lib/Passes/PassRegistry.def
index 0def3304343eb..e7d6511cb9c57 100644
--- a/llvm/lib/Passes/PassRegistry.def
+++ b/llvm/lib/Passes/PassRegistry.def
@@ -153,6 +153,7 @@ MODULE_PASS("strip-dead-prototypes", StripDeadPrototypesPass())
 MODULE_PASS("strip-debug-declare", StripDebugDeclarePass())
 MODULE_PASS("strip-nondebug", StripNonDebugSymbolsPass())
 MODULE_PASS("strip-nonlinetable-debuginfo", StripNonLineTableDebugInfoPass())
+MODULE_PASS("strip-dead-cg-profile", StripDeadCGProfilePass())
 MODULE_PASS("trigger-crash-module", TriggerCrashModulePass())
 MODULE_PASS("trigger-verifier-error", TriggerVerifierErrorPass())
 MODULE_PASS("tsan-module", ModuleThreadSanitizerPass())
diff --git a/llvm/lib/Transforms/IPO/StripSymbols.cpp b/llvm/lib/Transforms/IPO/StripSymbols.cpp
index e7b70308ba7aa..647caaa123cf8 100644
--- a/llvm/lib/Transforms/IPO/StripSymbols.cpp
+++ b/llvm/lib/Transforms/IPO/StripSymbols.cpp
@@ -26,10 +26,12 @@
 #include "llvm/IR/DerivedTypes.h"
 #include "llvm/IR/InstIterator.h"
 #include "llvm/IR/Instructions.h"
+#include "llvm/IR/Metadata.h"
 #include "llvm/IR/Module.h"
 #include "llvm/IR/PassManager.h"
 #include "llvm/IR/TypeFinder.h"
 #include "llvm/IR/ValueSymbolTable.h"
+#include "llvm/Support/Casting.h"
 #include "llvm/Support/CommandLine.h"
 #include "llvm/Transforms/IPO/StripSymbols.h"
 #include "llvm/Transforms/Utils/Local.h"
@@ -297,3 +299,21 @@ PreservedAnalyses StripDeadDebugInfoPass::run(Module &M,
   PA.preserveSet<CFGAnalyses>();
   return PA;
 }
+
+PreservedAnalyses StripDeadCGProfilePass::run(Module &M,
+                                              ModuleAnalysisManager &AM) {
+  auto *CGProf = dyn_cast_or_null<MDTuple>(M.getModuleFlag("CG Profile"));
+  if (!CGProf)
+    return PreservedAnalyses::all();
+
+  SmallVector<Metadata *, 16> ValidCGEdges;
+  for (Metadata *Edge : CGProf->operands()) {
+    if (auto *EdgeAsNode = dyn_cast_or_null<MDNode>(Edge))
+      if (llvm::all_of(EdgeAsNode->operands(),
+                       [](const Metadata *V) { return V != nullptr; }))
+        ValidCGEdges.push_back(Edge);
+  }
+  M.setModuleFlag(Module::Append, "CG Profile",
+                  MDTuple::getDistinct(M.getContext(), ValidCGEdges));
+  return PreservedAnalyses::none();
+}
\ No newline at end of file
diff --git a/llvm/test/Transforms/StripSymbols/strip-cg-profile.ll b/llvm/test/Transforms/StripSymbols/strip-cg-profile.ll
new file mode 100644
index 0000000000000..679deec10615a
--- /dev/null
+++ b/llvm/test/Transforms/StripSymbols/strip-cg-profile.ll
@@ -0,0 +1,53 @@
+; RUN: opt -passes=strip-cg-profile %s -S -o - | FileCheck %s --check-prefix=NOOP
+; RUN: llvm-extract -func=a -S -o - | FileCheck %s --check-prefix=EXTRACT-A
+; RUN: llvm-extract -func=a --func=b -S -o - | FileCheck %s --check-prefix=EXTRACT-AB
+; RUN: llvm-extract -func=solo -S -o - | FileCheck %s --check-prefix=NOTHING-LEFT
+
+define void @a() {
+  call void @b()
+  ret void
+}
+
+define void @b() {
+  call void @c()
+  ret void
+}
+
+define void @c() {
+  call void @d()
+  ret void
+}
+
+define void @d() {
+  ret void
+}
+
+define void @solo() {
+  ret void
+}
+
+!llvm.module.flags = !{!0}
+
+!0 = !{i32 5, !"CG Profile", !1}
+!1 = !{!2, !3, !4}
+!2 = !{ptr @a, ptr @b, i64 42}
+!3 = !{ptr @b, ptr @c, i64 20}
+!4 = !{ptr @c, ptr @d, i64 101}
+
+; NOOP:       !0 = !{i32 5, !"CG Profile", !1}
+; NOOP-NEXT:  !1 = !{!2, !3, !4}
+; NOOP-NEXT:  !2 = !{ptr @a, ptr @b, i64 42}
+; NOOP-NEXT:  !3 = !{ptr @b, ptr @c, i64 20}
+; NOOP-NEXT:  !4 = !{ptr @c, ptr @d, i64 101}
+
+; EXTRACT-A:      !0 = !{i32 5, !"CG Profile", !1}
+; EXTRACT-A-NEXT: !1 = distinct !{!2}
+; EXTRACT-A-NEXT: !2 = !{ptr @a, ptr @b, i64 42}
+
+; EXTRACT-AB:      !0 = !{i32 5, !"CG Profile", !1}
+; EXTRACT-AB-NEXT: !1 = distinct !{!2, !3}
+; EXTRACT-AB-NEXT: !2 = !{ptr @a, ptr @b, i64 42}
+; EXTRACT-AB-NEXT: !3 = !{ptr @b, ptr @c, i64 20}
+
+; NOTHING-LEFT:      !0 = !{i32 5, !"CG Profile", !1}
+; NOTHING-LEFT-NEXT: !1 = distinct !{}
\ No newline at end of file
diff --git a/llvm/tools/llvm-extract/llvm-extract.cpp b/llvm/tools/llvm-extract/llvm-extract.cpp
index 169cd0c2e4cbf..648060acb392c 100644
--- a/llvm/tools/llvm-extract/llvm-extract.cpp
+++ b/llvm/tools/llvm-extract/llvm-extract.cpp
@@ -408,6 +408,7 @@ int main(int argc, char **argv) {
     PM.addPass(GlobalDCEPass());
   PM.addPass(StripDeadDebugInfoPass());
   PM.addPass(StripDeadPrototypesPass());
+  PM.addPass(StripDeadCGProfilePass());
 
   std::error_code EC;
   ToolOutputFile Out(OutputFilename, EC, sys::fs::OF_None);

@mtrofin mtrofin requested a review from Bigcheese April 8, 2025 22:54
Copy link
Contributor

@hstk30-hw hstk30-hw left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@mtrofin mtrofin force-pushed the users/mtrofin/04-08-strip_cg_profile branch from ae1727c to 7bdd0a1 Compare April 9, 2025 14:40
Copy link
Member Author

mtrofin commented Apr 9, 2025

Merge activity

  • Apr 9, 1:34 PM EDT: A user started a stack merge that includes this pull request via Graphite.
  • Apr 9, 1:36 PM EDT: A user merged this pull request with Graphite.

@mtrofin mtrofin merged commit 6d4d017 into main Apr 9, 2025
11 checks passed
@mtrofin mtrofin deleted the users/mtrofin/04-08-strip_cg_profile branch April 9, 2025 17:36
AllinLeeYL pushed a commit to AllinLeeYL/llvm-project that referenced this pull request Apr 10, 2025
When `llvm-extract`-ing a function, and the `CG Profile` flag is present in the original module, we end up with lots of `!{null, null, i64 1234}` entries for call edges that have disappeared as result of the removed functions.

This patch fixes that by adding a pass to `llvm-extract` that finds `CG Profile` edges with one or both operands `null` and removes them. This results in a cleaner output.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants