[Debugify] Skip debugifying on special/immutable passes
authorArthur Eubanks <aeubanks@google.com>
Mon, 16 Nov 2020 19:47:50 +0000 (11:47 -0800)
committerArthur Eubanks <aeubanks@google.com>
Tue, 17 Nov 2020 04:39:46 +0000 (20:39 -0800)
With a function pass manager, it would insert debuginfo metadata before
getting to function passes while processing the pass manager, causing
debugify to skip while running the function passes.

Skip special passes + verifier + printing passes. Compared to the legacy
implementation of -debugify-each, this additionally skips verifier
passes. Probably no need to update the legacy version since it will be
obsolete soon.

This fixes 2 instcombine tests using -debugify-each under NPM.

Reviewed By: MaskRay

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

llvm/lib/IR/PassInstrumentation.cpp
llvm/lib/Transforms/Utils/Debugify.cpp
llvm/test/DebugInfo/debugify-each.ll
llvm/test/DebugInfo/debugify-export.ll
llvm/test/Transforms/InstCombine/call-guard.ll

index d3867de..a0004a8 100644 (file)
@@ -21,9 +21,9 @@ AnalysisKey PassInstrumentationAnalysis::Key;
 
 bool isSpecialPass(StringRef PassID, const std::vector<StringRef> &Specials) {
   size_t Pos = PassID.find('<');
-  if (Pos == StringRef::npos)
-    return false;
-  StringRef Prefix = PassID.substr(0, Pos);
+  StringRef Prefix = PassID;
+  if (Pos != StringRef::npos)
+    Prefix = PassID.substr(0, Pos);
   return any_of(Specials, [Prefix](StringRef S) { return Prefix.endswith(S); });
 }
 
index 526083c..cb6985f 100644 (file)
@@ -20,6 +20,7 @@
 #include "llvm/IR/Instructions.h"
 #include "llvm/IR/IntrinsicInst.h"
 #include "llvm/IR/Module.h"
+#include "llvm/IR/PassInstrumentation.h"
 #include "llvm/Pass.h"
 #include "llvm/Support/CommandLine.h"
 
@@ -530,9 +531,18 @@ PreservedAnalyses NewPMCheckDebugifyPass::run(Module &M,
   return PreservedAnalyses::all();
 }
 
+static bool isIgnoredPass(StringRef PassID) {
+  return isSpecialPass(PassID, {"PassManager", "PassAdaptor",
+                                "AnalysisManagerProxy", "PrintFunctionPass",
+                                "PrintModulePass", "BitcodeWriterPass",
+                                "ThinLTOBitcodeWriterPass", "VerifierPass"});
+}
+
 void DebugifyEachInstrumentation::registerCallbacks(
     PassInstrumentationCallbacks &PIC) {
   PIC.registerBeforeNonSkippedPassCallback([](StringRef P, Any IR) {
+    if (isIgnoredPass(P))
+      return;
     if (any_isa<const Function *>(IR))
       applyDebugify(*const_cast<Function *>(any_cast<const Function *>(IR)));
     else if (any_isa<const Module *>(IR))
@@ -540,6 +550,8 @@ void DebugifyEachInstrumentation::registerCallbacks(
   });
   PIC.registerAfterPassCallback([this](StringRef P, Any IR,
                                        const PreservedAnalyses &PassPA) {
+    if (isIgnoredPass(P))
+      return;
     if (any_isa<const Function *>(IR)) {
       auto &F = *const_cast<Function *>(any_cast<const Function *>(IR));
       Module &M = *F.getParent();
index 74ce1b8..1020b81 100644 (file)
 ; RUN: opt -O1 -debugify-each < %s | llvm-dis -o %t.after
 ; RUN: diff %t.before %t.after
 
+; Check that we only run debugify once per function per function pass.
+; This ensures that we don't run it for pass managers/verifiers/printers.
+; RUN: opt -debugify-each -passes=instsimplify -S -o /dev/null < %s 2> %t
+; RUN: FileCheck %s -input-file=%t -check-prefix=FUNCTION-PASS-ONE
+
+; Check that we only run debugify once per module pass
+; (plus the implicitly added begin/end verifier passes).
+; RUN: opt -debugify-each -passes=globalopt -S -o /dev/null < %s 2> %t
+; RUN: FileCheck %s -input-file=%t -check-prefix=MODULE-PASS-ONE
+
 define void @foo(i32 %arg) {
   call i32 asm "bswap $0", "=r,r"(i32 %arg)
   ret void
@@ -48,3 +58,10 @@ define void @bar() {
 ; FUNCTION-PASS: CheckFunctionDebugify [{{.*}}]
 ; FUNCTION-PASS: CheckFunctionDebugify [{{.*}}]
 ; FUNCTION-PASS: CheckFunctionDebugify [{{.*}}]
+
+; MODULE-PASS-ONE: CheckModuleDebugify [{{.*}}]
+; MODULE-PASS-ONE-NOT: CheckModuleDebugify [{{.*}}]
+
+; FUNCTION-PASS-ONE: CheckFunctionDebugify [{{.*}}]
+; FUNCTION-PASS-ONE: CheckFunctionDebugify [{{.*}}]
+; FUNCTION-PASS-ONE-NOT: CheckFunctionDebugify [{{.*}}]
index 93fb17b..af8865c 100644 (file)
@@ -1,5 +1,5 @@
-; RUN: opt %s -disable-output -debugify-each -debugify-quiet -debugify-export - -enable-new-pm=0 | FileCheck %s
-; RUN: opt %s -disable-output -debugify-each -debugify-quiet -debugify-export - -enable-new-pm=1 | FileCheck %s
+; RUN: opt %s -disable-output -debugify-each -debugify-quiet -debugify-export - -globalopt | FileCheck %s
+; RUN: opt %s -disable-output -debugify-each -debugify-quiet -debugify-export - -passes=globalopt | FileCheck %s
 
 ; CHECK: Pass Name
 ; CHECK-SAME: # of missing debug values
@@ -7,7 +7,7 @@
 ; CHECK-SAME: Missing/Expected value ratio
 ; CHECK-SAME: Missing/Expected location ratio
 
-; CHECK:      {{Module Verifier|VerifierPass}}
+; CHECK:      {{Module Verifier|GlobalOptPass}}
 ; CHECK-SAME: 0,0,0.000000e+00,0.000000e+00
 
 define void @foo() {
index 3d61a5a..e9ff9fa 100644 (file)
@@ -1,5 +1,6 @@
 ; RUN: opt < %s -instcombine -instcombine-infinite-loop-threshold=2 -S | FileCheck %s
 ; RUN: opt < %s -instcombine -S -debugify-each | FileCheck %s
+; RUN: opt < %s -passes=instcombine -S -debugify-each | FileCheck %s
 
 declare void @llvm.experimental.guard(i1, ...)