llvm / llvm-project

The LLVM Project is a collection of modular and reusable compiler and toolchain technologies.
http://llvm.org
Other
27.22k stars 11.15k forks source link

-print-after-all banner not printed following r292442 #31555

Closed llvmbot closed 7 years ago

llvmbot commented 7 years ago
Bugzilla Link 32207
Resolution FIXED
Resolved on Jun 11, 2017 19:18
Version trunk
OS All
Reporter LLVM Bugzilla Contributor
CC @joker-eph

Extended Description

$ cat a.cpp void foo() {} $ clang -c -O a.cpp -mllvm -print-after-all |& grep unused IR Dump After Remove unused exception handling info $ clang -c -O a.cpp -mllvm -print-after-all |& grep inlining $ clang -v clang version 5.0.0 (trunk 294982)

the problem is static bool BannerPrinted is shared across all PrintCallGraphPass passes so only the first pass (Remove unused exception handling info) prints its banner.

To achieve one BannerPrinted per non-empty SCC, it should be non static local to runOnSCC:

bool runOnSCC(CallGraphSCC &SCC) override {
  bool BannerPrinted = false;
  auto PrintBannerOnce = [&] () {
    if (BannerPrinted)
      return;
    Out << Banner;
    BannerPrinted = true;
    };
  for (CallGraphNode *CGN : SCC) {
    if (CGN->getFunction()) {
      if (isFunctionInPrintList(CGN->getFunction()->getName())) {
        PrintBannerOnce();
        CGN->getFunction()->print(Out);
      }
    } else if (llvm::isFunctionInPrintList("*")) {
      PrintBannerOnce();
      Out << "\nPrinting <null> Function\n";
    }
  }
  return false;
}
llvmbot commented 7 years ago

https://reviews.llvm.org/rL305179

llvmbot commented 7 years ago

https://reviews.llvm.org/D34086

joker-eph commented 7 years ago

Can you submit a patch?

llvmbot commented 7 years ago

ping...

llvmbot commented 7 years ago

Ping?

llvmbot commented 7 years ago

skipping declaration prints better:

bool runOnSCC(CallGraphSCC &SCC) override {
  bool BannerPrinted = false;
  auto PrintBannerOnce = [&] () {
    if (BannerPrinted)
      return;
    Out << Banner;
    BannerPrinted = true;
    };
  for (CallGraphNode *CGN : SCC) {
    if (Function *F = CGN->getFunction()) {
      if (!F->isDeclaration() && isFunctionInPrintList(F->getName())) {
        PrintBannerOnce();
        F->print(Out);
      }
    } else if (llvm::isFunctionInPrintList("*")) {
      PrintBannerOnce();
      Out << "\nPrinting <null> Function\n";
    }
  }
  return false;
}
llvmbot commented 7 years ago

scc (and the text output) are interleaved, all scc passes on scc1, all scc passes on scc2 etc. for example the output with this patch for two unrelated functions maind and foo is:

IR Dump After Remove unused exception handling info ; Function Attrs: norecurse nounwind uwtable define i32 @​main() #​0 !dbg !​7 { entry: ret i32 0, !dbg !​11 } IR Dump After Function Integration/Inlining ; Function Attrs: norecurse nounwind uwtable define i32 @​main() #​0 !dbg !​7 { entry: ret i32 0, !dbg !​11 }

...

IR Dump After Function Integration/Inlining ; Function Attrs: noreturn nounwind uwtable define i32 @​_Z3foov() #​1 !dbg !​7 { entry: unreachable, !dbg !​11 } IR Dump After Deduce function attributes ; Function Attrs: norecurse noreturn nounwind readnone uwtable define i32 @​_Z3foov() #​1 !dbg !​7 { entry: unreachable, !dbg !​11 } ...

runs are disjointed, can't merge the banners between scc prints.

joker-eph commented 7 years ago

Yep, that was a terrible patch I wrote there ;)

The issue is that the fix you suggest does not provide the feature I am looking for, which is have each PrintCallGraphPass print only once.

You change will make it print once per SCC. What do you think about making it a member variable of the CallGraphSCC class instead?