[llvm] 06926e0 - Port print-must-be-executed-contexts and print-mustexecute to NPM
Arthur Eubanks via llvm-commits
llvm-commits at lists.llvm.org
Tue Nov 3 21:06:57 PST 2020
Author: Arthur Eubanks
Date: 2020-11-03T21:06:46-08:00
New Revision: 06926e0f012cbfb2e05c3ab4b9db6b0d057b6d0d
URL: https://github.com/llvm/llvm-project/commit/06926e0f012cbfb2e05c3ab4b9db6b0d057b6d0d
DIFF: https://github.com/llvm/llvm-project/commit/06926e0f012cbfb2e05c3ab4b9db6b0d057b6d0d.diff
LOG: Port print-must-be-executed-contexts and print-mustexecute to NPM
Reviewed By: asbirlea
Differential Revision: https://reviews.llvm.org/D90207
Added:
Modified:
llvm/include/llvm/Analysis/MustExecute.h
llvm/lib/Analysis/MustExecute.cpp
llvm/lib/Passes/PassBuilder.cpp
llvm/lib/Passes/PassRegistry.def
llvm/test/Analysis/MustExecute/const-cond.ll
llvm/test/Analysis/MustExecute/must_be_executed_context.ll
Removed:
################################################################################
diff --git a/llvm/include/llvm/Analysis/MustExecute.h b/llvm/include/llvm/Analysis/MustExecute.h
index a3b7bee97808..df489aaa534d 100644
--- a/llvm/include/llvm/Analysis/MustExecute.h
+++ b/llvm/include/llvm/Analysis/MustExecute.h
@@ -27,6 +27,8 @@
#include "llvm/ADT/DenseSet.h"
#include "llvm/Analysis/EHPersonalities.h"
#include "llvm/Analysis/InstructionPrecedenceTracking.h"
+#include "llvm/IR/PassManager.h"
+#include "llvm/Support/raw_ostream.h"
namespace llvm {
@@ -541,6 +543,23 @@ struct MustBeExecutedContextExplorer {
MustBeExecutedIterator EndIterator;
};
+class MustExecutePrinterPass : public PassInfoMixin<MustExecutePrinterPass> {
+ raw_ostream &OS;
+
+public:
+ MustExecutePrinterPass(raw_ostream &OS) : OS(OS) {}
+ PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
+};
+
+class MustBeExecutedContextPrinterPass
+ : public PassInfoMixin<MustBeExecutedContextPrinterPass> {
+ raw_ostream &OS;
+
+public:
+ MustBeExecutedContextPrinterPass(raw_ostream &OS) : OS(OS) {}
+ PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);
+};
+
} // namespace llvm
#endif
diff --git a/llvm/lib/Analysis/MustExecute.cpp b/llvm/lib/Analysis/MustExecute.cpp
index 6e3ff67bdddb..cb77a87bd1af 100644
--- a/llvm/lib/Analysis/MustExecute.cpp
+++ b/llvm/lib/Analysis/MustExecute.cpp
@@ -16,9 +16,11 @@
#include "llvm/Analysis/ValueTracking.h"
#include "llvm/IR/AssemblyAnnotationWriter.h"
#include "llvm/IR/DataLayout.h"
+#include "llvm/IR/Dominators.h"
#include "llvm/IR/InstIterator.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Module.h"
+#include "llvm/IR/PassManager.h"
#include "llvm/InitializePasses.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/FormattedStream.h"
@@ -300,30 +302,31 @@ bool ICFLoopSafetyInfo::doesNotWriteMemoryBefore(const Instruction &I,
}
namespace {
- struct MustExecutePrinter : public FunctionPass {
+struct MustExecutePrinter : public FunctionPass {
- static char ID; // Pass identification, replacement for typeid
- MustExecutePrinter() : FunctionPass(ID) {
- initializeMustExecutePrinterPass(*PassRegistry::getPassRegistry());
- }
- void getAnalysisUsage(AnalysisUsage &AU) const override {
- AU.setPreservesAll();
- AU.addRequired<DominatorTreeWrapperPass>();
- AU.addRequired<LoopInfoWrapperPass>();
- }
- bool runOnFunction(Function &F) override;
- };
- struct MustBeExecutedContextPrinter : public ModulePass {
- static char ID;
+ static char ID; // Pass identification, replacement for typeid
+ MustExecutePrinter() : FunctionPass(ID) {
+ initializeMustExecutePrinterPass(*PassRegistry::getPassRegistry());
+ }
+ void getAnalysisUsage(AnalysisUsage &AU) const override {
+ AU.setPreservesAll();
+ AU.addRequired<DominatorTreeWrapperPass>();
+ AU.addRequired<LoopInfoWrapperPass>();
+ }
+ bool runOnFunction(Function &F) override;
+};
+struct MustBeExecutedContextPrinter : public ModulePass {
+ static char ID;
- MustBeExecutedContextPrinter() : ModulePass(ID) {
- initializeMustBeExecutedContextPrinterPass(*PassRegistry::getPassRegistry());
- }
- void getAnalysisUsage(AnalysisUsage &AU) const override {
- AU.setPreservesAll();
- }
- bool runOnModule(Module &M) override;
- };
+ MustBeExecutedContextPrinter() : ModulePass(ID) {
+ initializeMustBeExecutedContextPrinterPass(
+ *PassRegistry::getPassRegistry());
+ }
+ void getAnalysisUsage(AnalysisUsage &AU) const override {
+ AU.setPreservesAll();
+ }
+ bool runOnModule(Module &M) override;
+};
}
char MustExecutePrinter::ID = 0;
@@ -339,15 +342,16 @@ FunctionPass *llvm::createMustExecutePrinter() {
}
char MustBeExecutedContextPrinter::ID = 0;
-INITIALIZE_PASS_BEGIN(
- MustBeExecutedContextPrinter, "print-must-be-executed-contexts",
- "print the must-be-executed-contexed for all instructions", false, true)
+INITIALIZE_PASS_BEGIN(MustBeExecutedContextPrinter,
+ "print-must-be-executed-contexts",
+ "print the must-be-executed-context for all instructions",
+ false, true)
INITIALIZE_PASS_DEPENDENCY(PostDominatorTreeWrapperPass)
INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
INITIALIZE_PASS_DEPENDENCY(LoopInfoWrapperPass)
INITIALIZE_PASS_END(MustBeExecutedContextPrinter,
"print-must-be-executed-contexts",
- "print the must-be-executed-contexed for all instructions",
+ "print the must-be-executed-context for all instructions",
false, true)
ModulePass *llvm::createMustBeExecutedContextPrinter() {
@@ -835,3 +839,42 @@ const Instruction *MustBeExecutedIterator::advance() {
Tail = nullptr;
return nullptr;
}
+
+PreservedAnalyses MustExecutePrinterPass::run(Function &F,
+ FunctionAnalysisManager &AM) {
+ auto &LI = AM.getResult<LoopAnalysis>(F);
+ auto &DT = AM.getResult<DominatorTreeAnalysis>(F);
+
+ MustExecuteAnnotatedWriter Writer(F, DT, LI);
+ F.print(OS, &Writer);
+ return PreservedAnalyses::all();
+}
+
+PreservedAnalyses
+MustBeExecutedContextPrinterPass::run(Module &M, ModuleAnalysisManager &AM) {
+ FunctionAnalysisManager &FAM =
+ AM.getResult<FunctionAnalysisManagerModuleProxy>(M).getManager();
+ GetterTy<const LoopInfo> LIGetter = [&](const Function &F) {
+ return &FAM.getResult<LoopAnalysis>(const_cast<Function &>(F));
+ };
+ GetterTy<const DominatorTree> DTGetter = [&](const Function &F) {
+ return &FAM.getResult<DominatorTreeAnalysis>(const_cast<Function &>(F));
+ };
+ GetterTy<const PostDominatorTree> PDTGetter = [&](const Function &F) {
+ return &FAM.getResult<PostDominatorTreeAnalysis>(const_cast<Function &>(F));
+ };
+
+ MustBeExecutedContextExplorer Explorer(
+ /* ExploreInterBlock */ true,
+ /* ExploreCFGForward */ true,
+ /* ExploreCFGBackward */ true, LIGetter, DTGetter, PDTGetter);
+
+ for (Function &F : M) {
+ for (Instruction &I : instructions(F)) {
+ OS << "-- Explore context of: " << I << "\n";
+ for (const Instruction *CI : Explorer.range(&I))
+ OS << " [F: " << CI->getFunction()->getName() << "] " << *CI << "\n";
+ }
+ }
+ return PreservedAnalyses::all();
+}
diff --git a/llvm/lib/Passes/PassBuilder.cpp b/llvm/lib/Passes/PassBuilder.cpp
index 719ad83d04f7..fd16bedc70aa 100644
--- a/llvm/lib/Passes/PassBuilder.cpp
+++ b/llvm/lib/Passes/PassBuilder.cpp
@@ -51,6 +51,7 @@
#include "llvm/Analysis/MemorySSA.h"
#include "llvm/Analysis/ModuleDebugInfoPrinter.h"
#include "llvm/Analysis/ModuleSummaryAnalysis.h"
+#include "llvm/Analysis/MustExecute.h"
#include "llvm/Analysis/ObjCARCAliasAnalysis.h"
#include "llvm/Analysis/OptimizationRemarkEmitter.h"
#include "llvm/Analysis/PhiValues.h"
diff --git a/llvm/lib/Passes/PassRegistry.def b/llvm/lib/Passes/PassRegistry.def
index fb313480902a..dd004c7b9adc 100644
--- a/llvm/lib/Passes/PassRegistry.def
+++ b/llvm/lib/Passes/PassRegistry.def
@@ -86,6 +86,7 @@ MODULE_PASS("print-callgraph", CallGraphPrinterPass(dbgs()))
MODULE_PASS("print", PrintModulePass(dbgs()))
MODULE_PASS("print-lcg", LazyCallGraphPrinterPass(dbgs()))
MODULE_PASS("print-lcg-dot", LazyCallGraphDOTPrinterPass(dbgs()))
+MODULE_PASS("print-must-be-executed-contexts", MustBeExecutedContextPrinterPass(dbgs()))
MODULE_PASS("print-stack-safety", StackSafetyGlobalPrinterPass(dbgs()))
MODULE_PASS("print<module-debuginfo>", ModuleDebugInfoPrinterPass(dbgs()))
MODULE_PASS("rewrite-statepoints-for-gc", RewriteStatepointsForGC())
@@ -276,9 +277,10 @@ FUNCTION_PASS("print<phi-values>", PhiValuesPrinterPass(dbgs()))
FUNCTION_PASS("print<regions>", RegionInfoPrinterPass(dbgs()))
FUNCTION_PASS("print<scalar-evolution>", ScalarEvolutionPrinterPass(dbgs()))
FUNCTION_PASS("print<stack-safety-local>", StackSafetyPrinterPass(dbgs()))
-// TODO: rename to print<alias-sets> after NPM switch
+// TODO: rename to print<foo> after NPM switch
FUNCTION_PASS("print-alias-sets", AliasSetsPrinterPass(dbgs()))
FUNCTION_PASS("print-predicateinfo", PredicateInfoPrinterPass(dbgs()))
+FUNCTION_PASS("print-mustexecute", MustExecutePrinterPass(dbgs()))
FUNCTION_PASS("reassociate", ReassociatePass())
FUNCTION_PASS("scalarizer", ScalarizerPass())
FUNCTION_PASS("sccp", SCCPPass())
diff --git a/llvm/test/Analysis/MustExecute/const-cond.ll b/llvm/test/Analysis/MustExecute/const-cond.ll
index 73651ce71e31..36ef73180cd0 100644
--- a/llvm/test/Analysis/MustExecute/const-cond.ll
+++ b/llvm/test/Analysis/MustExecute/const-cond.ll
@@ -1,46 +1,47 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
-; RUN: opt -disable-output -print-mustexecute %s 2>&1 | FileCheck %s
-
-; In general the CFG below is easily simplified but this is useful for
-; pass ordering issue elimination.
-define i1 @const_cond(i32 %high) {
-; CHECK-LABEL: @const_cond(
-; CHECK-NEXT: entry:
-; CHECK-NEXT: br label [[LOOP:%.*]]
-; CHECK: loop:
-; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[BACKEDGE:%.*]] ] ; (mustexec in: loop)
-; CHECK-NEXT: br i1 true, label [[NEXT:%.*]], label [[NEVER1:%.*]] ; (mustexec in: loop)
-; CHECK: next:
-; CHECK-NEXT: br i1 false, label [[NEVER2:%.*]], label [[BACKEDGE]] ; (mustexec in: loop)
-; CHECK: backedge:
-; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1 ; (mustexec in: loop)
-; CHECK-NEXT: [[EXIT_TEST:%.*]] = icmp slt i32 [[IV]], [[HIGH:%.*]] ; (mustexec in: loop)
-; CHECK-NEXT: br i1 [[EXIT_TEST]], label [[LOOP]], label [[EXIT:%.*]] ; (mustexec in: loop)
-; CHECK: exit:
-; CHECK-NEXT: ret i1 false
-; CHECK: never1:
-; CHECK-NEXT: unreachable
-; CHECK: never2:
-; CHECK-NEXT: unreachable
-;
-entry:
- br label %loop
-
-loop:
- %iv = phi i32 [0, %entry], [%iv.next, %backedge]
- br i1 true, label %next, label %never1
-next:
- br i1 false, label %never2, label %backedge
-backedge:
- %iv.next = add nsw nuw i32 %iv, 1
- %exit.test = icmp slt i32 %iv, %high
- br i1 %exit.test, label %loop, label %exit
-
-exit:
- ret i1 false
-never1:
- unreachable
-never2:
- unreachable
-}
-
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
+; RUN: opt -disable-output -print-mustexecute %s 2>&1 | FileCheck %s
+; RUN: opt -disable-output -passes=print-mustexecute %s 2>&1 | FileCheck %s
+
+; In general the CFG below is easily simplified but this is useful for
+; pass ordering issue elimination.
+define i1 @const_cond(i32 %high) {
+; CHECK-LABEL: @const_cond(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: br label [[LOOP:%.*]]
+; CHECK: loop:
+; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[BACKEDGE:%.*]] ] ; (mustexec in: loop)
+; CHECK-NEXT: br i1 true, label [[NEXT:%.*]], label [[NEVER1:%.*]] ; (mustexec in: loop)
+; CHECK: next:
+; CHECK-NEXT: br i1 false, label [[NEVER2:%.*]], label [[BACKEDGE]] ; (mustexec in: loop)
+; CHECK: backedge:
+; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1 ; (mustexec in: loop)
+; CHECK-NEXT: [[EXIT_TEST:%.*]] = icmp slt i32 [[IV]], [[HIGH:%.*]] ; (mustexec in: loop)
+; CHECK-NEXT: br i1 [[EXIT_TEST]], label [[LOOP]], label [[EXIT:%.*]] ; (mustexec in: loop)
+; CHECK: exit:
+; CHECK-NEXT: ret i1 false
+; CHECK: never1:
+; CHECK-NEXT: unreachable
+; CHECK: never2:
+; CHECK-NEXT: unreachable
+;
+entry:
+ br label %loop
+
+loop:
+ %iv = phi i32 [0, %entry], [%iv.next, %backedge]
+ br i1 true, label %next, label %never1
+next:
+ br i1 false, label %never2, label %backedge
+backedge:
+ %iv.next = add nsw nuw i32 %iv, 1
+ %exit.test = icmp slt i32 %iv, %high
+ br i1 %exit.test, label %loop, label %exit
+
+exit:
+ ret i1 false
+never1:
+ unreachable
+never2:
+ unreachable
+}
+
diff --git a/llvm/test/Analysis/MustExecute/must_be_executed_context.ll b/llvm/test/Analysis/MustExecute/must_be_executed_context.ll
index d65e08e6ff3f..7471a6559ab7 100644
--- a/llvm/test/Analysis/MustExecute/must_be_executed_context.ll
+++ b/llvm/test/Analysis/MustExecute/must_be_executed_context.ll
@@ -1,6 +1,7 @@
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
-; RUN: opt < %s -print-mustexecute -analyze 2>&1 | FileCheck %s --check-prefix=ME
-; RUN: opt < %s -print-must-be-executed-contexts -analyze 2>&1 | FileCheck %s --check-prefix=MBEC
+; RUN: opt < %s -print-mustexecute -disable-output 2>&1 | FileCheck %s --check-prefix=ME
+; RUN: opt < %s -print-must-be-executed-contexts -disable-output 2>&1 | FileCheck %s --check-prefix=MBEC
+; RUN: opt < %s -passes=print-must-be-executed-contexts -disable-output 2>&1 | FileCheck %s --check-prefix=MBEC
;
; void simple_conditional(int c) {
; A();
More information about the llvm-commits
mailing list