mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-01-31 12:41:49 +01:00
Port print-must-be-executed-contexts and print-mustexecute to NPM
Reviewed By: asbirlea Differential Revision: https://reviews.llvm.org/D90207
This commit is contained in:
parent
de70f3e87f
commit
e22b9f13f5
@ -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 @@ private:
|
||||
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
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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"
|
||||
|
@ -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())
|
||||
|
@ -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
|
||||
}
|
||||
|
||||
|
@ -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();
|
||||
|
Loading…
x
Reference in New Issue
Block a user