Skip to content

Commit 6d4d017

Browse files
authored
[llvm-extract] Delete dead CG Profile edges (#134940)
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.
1 parent c8d49e9 commit 6d4d017

File tree

5 files changed

+79
-0
lines changed

5 files changed

+79
-0
lines changed

llvm/include/llvm/Transforms/IPO/StripSymbols.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,10 @@ struct StripDeadDebugInfoPass : PassInfoMixin<StripDeadDebugInfoPass> {
4242
PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);
4343
};
4444

45+
struct StripDeadCGProfilePass : PassInfoMixin<StripDeadCGProfilePass> {
46+
PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);
47+
};
48+
4549
} // end namespace llvm
4650

4751
#endif // LLVM_TRANSFORMS_IPO_STRIPSYMBOLS_H

llvm/lib/Passes/PassRegistry.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,7 @@ MODULE_PASS("strip-dead-prototypes", StripDeadPrototypesPass())
155155
MODULE_PASS("strip-debug-declare", StripDebugDeclarePass())
156156
MODULE_PASS("strip-nondebug", StripNonDebugSymbolsPass())
157157
MODULE_PASS("strip-nonlinetable-debuginfo", StripNonLineTableDebugInfoPass())
158+
MODULE_PASS("strip-dead-cg-profile", StripDeadCGProfilePass())
158159
MODULE_PASS("trigger-crash-module", TriggerCrashModulePass())
159160
MODULE_PASS("trigger-verifier-error", TriggerVerifierErrorPass())
160161
MODULE_PASS("tsan-module", ModuleThreadSanitizerPass())

llvm/lib/Transforms/IPO/StripSymbols.cpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,10 +26,12 @@
2626
#include "llvm/IR/DerivedTypes.h"
2727
#include "llvm/IR/InstIterator.h"
2828
#include "llvm/IR/Instructions.h"
29+
#include "llvm/IR/Metadata.h"
2930
#include "llvm/IR/Module.h"
3031
#include "llvm/IR/PassManager.h"
3132
#include "llvm/IR/TypeFinder.h"
3233
#include "llvm/IR/ValueSymbolTable.h"
34+
#include "llvm/Support/Casting.h"
3335
#include "llvm/Support/CommandLine.h"
3436
#include "llvm/Transforms/IPO/StripSymbols.h"
3537
#include "llvm/Transforms/Utils/Local.h"
@@ -297,3 +299,21 @@ PreservedAnalyses StripDeadDebugInfoPass::run(Module &M,
297299
PA.preserveSet<CFGAnalyses>();
298300
return PA;
299301
}
302+
303+
PreservedAnalyses StripDeadCGProfilePass::run(Module &M,
304+
ModuleAnalysisManager &AM) {
305+
auto *CGProf = dyn_cast_or_null<MDTuple>(M.getModuleFlag("CG Profile"));
306+
if (!CGProf)
307+
return PreservedAnalyses::all();
308+
309+
SmallVector<Metadata *, 16> ValidCGEdges;
310+
for (Metadata *Edge : CGProf->operands()) {
311+
if (auto *EdgeAsNode = dyn_cast_or_null<MDNode>(Edge))
312+
if (llvm::all_of(EdgeAsNode->operands(),
313+
[](const Metadata *V) { return V != nullptr; }))
314+
ValidCGEdges.push_back(Edge);
315+
}
316+
M.setModuleFlag(Module::Append, "CG Profile",
317+
MDTuple::getDistinct(M.getContext(), ValidCGEdges));
318+
return PreservedAnalyses::none();
319+
}
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
; RUN: opt -passes=strip-dead-cg-profile %s -S -o - | FileCheck %s --check-prefix=NOOP
2+
; RUN: llvm-extract %s -func=a -S -o - | FileCheck %s --check-prefix=EXTRACT-A
3+
; RUN: llvm-extract %s -func=a --func=b -S -o - | FileCheck %s --check-prefix=EXTRACT-AB
4+
; RUN: llvm-extract %s -func=solo -S -o - | FileCheck %s --check-prefix=NOTHING-LEFT
5+
6+
define void @a() {
7+
call void @b()
8+
ret void
9+
}
10+
11+
define void @b() {
12+
call void @c()
13+
ret void
14+
}
15+
16+
define void @c() {
17+
call void @d()
18+
ret void
19+
}
20+
21+
define void @d() {
22+
ret void
23+
}
24+
25+
define void @solo() {
26+
ret void
27+
}
28+
29+
!llvm.module.flags = !{!0}
30+
31+
!0 = !{i32 5, !"CG Profile", !1}
32+
!1 = !{!2, !3, !4}
33+
!2 = !{ptr @a, ptr @b, i64 42}
34+
!3 = !{ptr @b, ptr @c, i64 20}
35+
!4 = !{ptr @c, ptr @d, i64 101}
36+
37+
; NOOP: !0 = !{i32 5, !"CG Profile", !1}
38+
; NOOP-NEXT: !1 = distinct !{!2, !3, !4}
39+
; NOOP-NEXT: !2 = !{ptr @a, ptr @b, i64 42}
40+
; NOOP-NEXT: !3 = !{ptr @b, ptr @c, i64 20}
41+
; NOOP-NEXT: !4 = !{ptr @c, ptr @d, i64 101}
42+
43+
; EXTRACT-A: !0 = !{i32 5, !"CG Profile", !1}
44+
; EXTRACT-A-NEXT: !1 = distinct !{!2}
45+
; EXTRACT-A-NEXT: !2 = !{ptr @a, ptr @b, i64 42}
46+
47+
; EXTRACT-AB: !0 = !{i32 5, !"CG Profile", !1}
48+
; EXTRACT-AB-NEXT: !1 = distinct !{!2, !3}
49+
; EXTRACT-AB-NEXT: !2 = !{ptr @a, ptr @b, i64 42}
50+
; EXTRACT-AB-NEXT: !3 = !{ptr @b, ptr @c, i64 20}
51+
52+
; NOTHING-LEFT: !0 = !{i32 5, !"CG Profile", !1}
53+
; NOTHING-LEFT-NEXT: !1 = distinct !{}

llvm/tools/llvm-extract/llvm-extract.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -408,6 +408,7 @@ int main(int argc, char **argv) {
408408
PM.addPass(GlobalDCEPass());
409409
PM.addPass(StripDeadDebugInfoPass());
410410
PM.addPass(StripDeadPrototypesPass());
411+
PM.addPass(StripDeadCGProfilePass());
411412

412413
std::error_code EC;
413414
ToolOutputFile Out(OutputFilename, EC, sys::fs::OF_None);

0 commit comments

Comments
 (0)