[llvm] 053dbb9 - Use `-cfg-func-name` value as filter for `-view-cfg`, etc.

Joachim Meyer via llvm-commits llvm-commits at lists.llvm.org
Wed Jun 16 14:51:48 PDT 2021


Author: Joachim Meyer
Date: 2021-06-16T23:54:51+02:00
New Revision: 053dbb939d4a4be5cc7e156441ecedef599a4a6f

URL: https://github.com/llvm/llvm-project/commit/053dbb939d4a4be5cc7e156441ecedef599a4a6f
DIFF: https://github.com/llvm/llvm-project/commit/053dbb939d4a4be5cc7e156441ecedef599a4a6f.diff

LOG: Use `-cfg-func-name` value as filter for `-view-cfg`, etc.

Currently the value is only used when calling `F->viewCFG()` which is missing out on its potential and usefulness.
So I added the check to the printer passes as well.

Reviewed By: MaskRay

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

Added: 
    llvm/test/Other/cfg-printer-filter.ll

Modified: 
    llvm/docs/Passes.rst
    llvm/lib/Analysis/CFGPrinter.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/docs/Passes.rst b/llvm/docs/Passes.rst
index d80dd8d21eab8..14131cba033c8 100644
--- a/llvm/docs/Passes.rst
+++ b/llvm/docs/Passes.rst
@@ -127,6 +127,9 @@ postscript or some other suitable format.
 This pass, only available in ``opt``, prints the control flow graph into a
 ``.dot`` graph.  This graph can then be processed with the :program:`dot` tool
 to convert it to postscript or some other suitable format.
+Additionally the ``-cfg-func-name=<substring>`` option can be used to filter the
+functions that are printed. All functions that contain the specified substring
+will be printed.
 
 ``-dot-cfg-only``: Print CFG of function to "dot" file (with no function bodies)
 --------------------------------------------------------------------------------
@@ -135,6 +138,9 @@ This pass, only available in ``opt``, prints the control flow graph into a
 ``.dot`` graph, omitting the function bodies.  This graph can then be processed
 with the :program:`dot` tool to convert it to postscript or some other suitable
 format.
+Additionally the ``-cfg-func-name=<substring>`` option can be used to filter the
+functions that are printed. All functions that contain the specified substring
+will be printed.
 
 ``-dot-dom``: Print dominance tree of function to "dot" file
 ------------------------------------------------------------
@@ -1192,12 +1198,18 @@ instead just tries to ensure that code is well-formed.
 -----------------------------------
 
 Displays the control flow graph using the GraphViz tool.
+Additionally the ``-cfg-func-name=<substring>`` option can be used to filter the
+functions that are displayed. All functions that contain the specified substring
+will be displayed.
 
 ``-view-cfg-only``: View CFG of function (with no function bodies)
 ------------------------------------------------------------------
 
 Displays the control flow graph using the GraphViz tool, but omitting function
 bodies.
+Additionally the ``-cfg-func-name=<substring>`` option can be used to filter the
+functions that are displayed. All functions that contain the specified substring
+will be displayed.
 
 ``-view-dom``: View dominance tree of function
 ----------------------------------------------

diff  --git a/llvm/lib/Analysis/CFGPrinter.cpp b/llvm/lib/Analysis/CFGPrinter.cpp
index 76f9f7783863a..04ccdc590845a 100644
--- a/llvm/lib/Analysis/CFGPrinter.cpp
+++ b/llvm/lib/Analysis/CFGPrinter.cpp
@@ -100,6 +100,8 @@ struct CFGViewerLegacyPass : public FunctionPass {
   }
 
   bool runOnFunction(Function &F) override {
+    if (!CFGFuncName.empty() && !F.getName().contains(CFGFuncName))
+      return false;
     auto *BPI = &getAnalysis<BranchProbabilityInfoWrapperPass>().getBPI();
     auto *BFI = &getAnalysis<BlockFrequencyInfoWrapperPass>().getBFI();
     viewCFG(F, BFI, BPI, getMaxFreq(F, BFI));
@@ -115,13 +117,15 @@ struct CFGViewerLegacyPass : public FunctionPass {
     AU.setPreservesAll();
   }
 };
-}
+} // namespace
 
 char CFGViewerLegacyPass::ID = 0;
 INITIALIZE_PASS(CFGViewerLegacyPass, "view-cfg", "View CFG of function", false,
                 true)
 
 PreservedAnalyses CFGViewerPass::run(Function &F, FunctionAnalysisManager &AM) {
+  if (!CFGFuncName.empty() && !F.getName().contains(CFGFuncName))
+    return PreservedAnalyses::all();
   auto *BFI = &AM.getResult<BlockFrequencyAnalysis>(F);
   auto *BPI = &AM.getResult<BranchProbabilityAnalysis>(F);
   viewCFG(F, BFI, BPI, getMaxFreq(F, BFI));
@@ -136,6 +140,8 @@ struct CFGOnlyViewerLegacyPass : public FunctionPass {
   }
 
   bool runOnFunction(Function &F) override {
+    if (!CFGFuncName.empty() && !F.getName().contains(CFGFuncName))
+      return false;
     auto *BPI = &getAnalysis<BranchProbabilityInfoWrapperPass>().getBPI();
     auto *BFI = &getAnalysis<BlockFrequencyInfoWrapperPass>().getBFI();
     viewCFG(F, BFI, BPI, getMaxFreq(F, BFI), /*CFGOnly=*/true);
@@ -151,7 +157,7 @@ struct CFGOnlyViewerLegacyPass : public FunctionPass {
     AU.setPreservesAll();
   }
 };
-}
+} // namespace
 
 char CFGOnlyViewerLegacyPass::ID = 0;
 INITIALIZE_PASS(CFGOnlyViewerLegacyPass, "view-cfg-only",
@@ -159,6 +165,8 @@ INITIALIZE_PASS(CFGOnlyViewerLegacyPass, "view-cfg-only",
 
 PreservedAnalyses CFGOnlyViewerPass::run(Function &F,
                                          FunctionAnalysisManager &AM) {
+  if (!CFGFuncName.empty() && !F.getName().contains(CFGFuncName))
+    return PreservedAnalyses::all();
   auto *BFI = &AM.getResult<BlockFrequencyAnalysis>(F);
   auto *BPI = &AM.getResult<BranchProbabilityAnalysis>(F);
   viewCFG(F, BFI, BPI, getMaxFreq(F, BFI), /*CFGOnly=*/true);
@@ -173,6 +181,8 @@ struct CFGPrinterLegacyPass : public FunctionPass {
   }
 
   bool runOnFunction(Function &F) override {
+    if (!CFGFuncName.empty() && !F.getName().contains(CFGFuncName))
+      return false;
     auto *BPI = &getAnalysis<BranchProbabilityInfoWrapperPass>().getBPI();
     auto *BFI = &getAnalysis<BlockFrequencyInfoWrapperPass>().getBFI();
     writeCFGToDotFile(F, BFI, BPI, getMaxFreq(F, BFI));
@@ -188,7 +198,7 @@ struct CFGPrinterLegacyPass : public FunctionPass {
     AU.setPreservesAll();
   }
 };
-}
+} // namespace
 
 char CFGPrinterLegacyPass::ID = 0;
 INITIALIZE_PASS(CFGPrinterLegacyPass, "dot-cfg",
@@ -196,6 +206,8 @@ INITIALIZE_PASS(CFGPrinterLegacyPass, "dot-cfg",
 
 PreservedAnalyses CFGPrinterPass::run(Function &F,
                                       FunctionAnalysisManager &AM) {
+  if (!CFGFuncName.empty() && !F.getName().contains(CFGFuncName))
+    return PreservedAnalyses::all();
   auto *BFI = &AM.getResult<BlockFrequencyAnalysis>(F);
   auto *BPI = &AM.getResult<BranchProbabilityAnalysis>(F);
   writeCFGToDotFile(F, BFI, BPI, getMaxFreq(F, BFI));
@@ -210,6 +222,8 @@ struct CFGOnlyPrinterLegacyPass : public FunctionPass {
   }
 
   bool runOnFunction(Function &F) override {
+    if (!CFGFuncName.empty() && !F.getName().contains(CFGFuncName))
+      return false;
     auto *BPI = &getAnalysis<BranchProbabilityInfoWrapperPass>().getBPI();
     auto *BFI = &getAnalysis<BlockFrequencyInfoWrapperPass>().getBFI();
     writeCFGToDotFile(F, BFI, BPI, getMaxFreq(F, BFI), /*CFGOnly=*/true);
@@ -224,7 +238,7 @@ struct CFGOnlyPrinterLegacyPass : public FunctionPass {
     AU.setPreservesAll();
   }
 };
-}
+} // namespace
 
 char CFGOnlyPrinterLegacyPass::ID = 0;
 INITIALIZE_PASS(CFGOnlyPrinterLegacyPass, "dot-cfg-only",
@@ -233,6 +247,8 @@ INITIALIZE_PASS(CFGOnlyPrinterLegacyPass, "dot-cfg-only",
 
 PreservedAnalyses CFGOnlyPrinterPass::run(Function &F,
                                           FunctionAnalysisManager &AM) {
+  if (!CFGFuncName.empty() && !F.getName().contains(CFGFuncName))
+    return PreservedAnalyses::all();
   auto *BFI = &AM.getResult<BlockFrequencyAnalysis>(F);
   auto *BPI = &AM.getResult<BranchProbabilityAnalysis>(F);
   writeCFGToDotFile(F, BFI, BPI, getMaxFreq(F, BFI), /*CFGOnly=*/true);

diff  --git a/llvm/test/Other/cfg-printer-filter.ll b/llvm/test/Other/cfg-printer-filter.ll
new file mode 100644
index 0000000000000..0d3bf3df5f531
--- /dev/null
+++ b/llvm/test/Other/cfg-printer-filter.ll
@@ -0,0 +1,40 @@
+; RUN: rm -f %t.other.dot %t-only.other.dot
+
+;; Both f and func are dumped because their names contain the pattern 'f' as a substring.
+; RUN: opt < %s -dot-cfg -cfg-dot-filename-prefix=%t -cfg-func-name=f 2>/dev/null
+; RUN: FileCheck %s -input-file=%t.f.dot -check-prefix=F
+; RUN: FileCheck %s -input-file=%t.func.dot -check-prefix=Func
+; RUN: not test -f %t.other.dot
+
+; RUN: opt < %s -dot-cfg-only -cfg-dot-filename-prefix=%t-only -cfg-func-name=f 2>/dev/null
+; RUN: FileCheck %s -input-file=%t-only.f.dot -check-prefix=F
+; RUN: FileCheck %s -input-file=%t-only.func.dot -check-prefix=Func
+; RUN: not test -f %t-only.other.dot
+
+; F: digraph "CFG for 'f' function"
+define void @f(i32) {
+entry:
+  %check = icmp sgt i32 %0, 0
+  br i1 %check, label %if, label %exit
+if:                     ; preds = %entry
+  br label %exit
+exit:                   ; preds = %entry, %if
+  ret void
+}
+
+; Func: digraph "CFG for 'func' function"
+define void @func(i32) {
+entry:
+  %check = icmp sgt i32 %0, 0
+  br label %exit
+exit:                   ; preds = %entry
+  ret void
+}
+
+define void @other(i32) {
+entry:
+  %check = icmp sgt i32 %0, 0
+  br label %exit
+exit:                   ; preds = %entry
+  ret void
+}


        


More information about the llvm-commits mailing list