[llvm] f02c4c8 - [IRSim] Adding wrapper pass for IRSimilarityIdentfier
Andrew Litteken via llvm-commits
llvm-commits at lists.llvm.org
Thu Sep 24 12:59:51 PDT 2020
Author: Andrew Litteken
Date: 2020-09-24T14:59:41-05:00
New Revision: f02c4c87b46c8203d7368cadc62607707d6f66b8
URL: https://github.com/llvm/llvm-project/commit/f02c4c87b46c8203d7368cadc62607707d6f66b8
DIFF: https://github.com/llvm/llvm-project/commit/f02c4c87b46c8203d7368cadc62607707d6f66b8.diff
LOG: [IRSim] Adding wrapper pass for IRSimilarityIdentfier
This introduces an analysis pass that wraps IRSimilarityIdentifier,
and adds a printer pass to examine in what function similarities are
being found.
Test for what the printer pass can find are in
test/Analysis/IRSimilarityIdentifier.
Reviewed by: paquette, jroelofs
Differential Revision: https://reviews.llvm.org/D86973
Added:
llvm/test/Analysis/IRSimilarityIdentifier/basic.ll
llvm/test/Analysis/IRSimilarityIdentifier/different.ll
llvm/test/Analysis/IRSimilarityIdentifier/nothing.ll
Modified:
llvm/include/llvm/Analysis/IRSimilarityIdentifier.h
llvm/include/llvm/InitializePasses.h
llvm/lib/Analysis/Analysis.cpp
llvm/lib/Analysis/IRSimilarityIdentifier.cpp
llvm/lib/Passes/PassBuilder.cpp
llvm/lib/Passes/PassRegistry.def
Removed:
################################################################################
diff --git a/llvm/include/llvm/Analysis/IRSimilarityIdentifier.h b/llvm/include/llvm/Analysis/IRSimilarityIdentifier.h
index dceb531285a7..764b2f5f7441 100644
--- a/llvm/include/llvm/Analysis/IRSimilarityIdentifier.h
+++ b/llvm/include/llvm/Analysis/IRSimilarityIdentifier.h
@@ -52,6 +52,8 @@
#include "llvm/IR/InstVisitor.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/Module.h"
+#include "llvm/IR/PassManager.h"
+#include "llvm/Pass.h"
#include "llvm/Support/Allocator.h"
namespace llvm {
@@ -695,6 +697,50 @@ class IRSimilarityIdentifier {
};
} // end namespace IRSimilarity
+
+/// An analysis pass based on legacy pass manager that runs and returns
+/// IRSimilarityIdentifier run on the Module.
+class IRSimilarityIdentifierWrapperPass : public ModulePass {
+ std::unique_ptr<IRSimilarity::IRSimilarityIdentifier> IRSI;
+
+public:
+ static char ID;
+ IRSimilarityIdentifierWrapperPass();
+
+ IRSimilarity::IRSimilarityIdentifier &getIRSI() { return *IRSI; }
+ const IRSimilarity::IRSimilarityIdentifier &getIRSI() const { return *IRSI; }
+
+ bool doInitialization(Module &M) override;
+ bool doFinalization(Module &M) override;
+ bool runOnModule(Module &M) override;
+ void getAnalysisUsage(AnalysisUsage &AU) const override {
+ AU.setPreservesAll();
+ }
+};
+
+/// An analysis pass that runs and returns the IRSimilarityIdentifier run on the
+/// Module.
+class IRSimilarityAnalysis : public AnalysisInfoMixin<IRSimilarityAnalysis> {
+public:
+ typedef IRSimilarity::IRSimilarityIdentifier Result;
+
+ Result run(Module &M, ModuleAnalysisManager &);
+
+private:
+ friend AnalysisInfoMixin<IRSimilarityAnalysis>;
+ static AnalysisKey Key;
+};
+
+/// Printer pass that uses \c IRSimilarityAnalysis.
+class IRSimilarityAnalysisPrinterPass
+ : public PassInfoMixin<IRSimilarityAnalysisPrinterPass> {
+ raw_ostream &OS;
+
+public:
+ explicit IRSimilarityAnalysisPrinterPass(raw_ostream &OS) : OS(OS) {}
+ PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);
+};
+
} // end namespace llvm
#endif // LLVM_ANALYSIS_IRSIMILARITYIDENTIFIER_H
diff --git a/llvm/include/llvm/InitializePasses.h b/llvm/include/llvm/InitializePasses.h
index 62b49906ab3f..7e21649a54ed 100644
--- a/llvm/include/llvm/InitializePasses.h
+++ b/llvm/include/llvm/InitializePasses.h
@@ -181,6 +181,7 @@ void initializeHotColdSplittingLegacyPassPass(PassRegistry&);
void initializeHWAddressSanitizerLegacyPassPass(PassRegistry &);
void initializeIPSCCPLegacyPassPass(PassRegistry&);
void initializeIRCELegacyPassPass(PassRegistry&);
+void initializeIRSimilarityIdentifierWrapperPassPass(PassRegistry&);
void initializeIRTranslatorPass(PassRegistry&);
void initializeIVUsersWrapperPassPass(PassRegistry&);
void initializeIfConverterPass(PassRegistry&);
diff --git a/llvm/lib/Analysis/Analysis.cpp b/llvm/lib/Analysis/Analysis.cpp
index 0496e23195d5..fdd5c9fc4669 100644
--- a/llvm/lib/Analysis/Analysis.cpp
+++ b/llvm/lib/Analysis/Analysis.cpp
@@ -52,6 +52,7 @@ void llvm::initializeAnalysis(PassRegistry &Registry) {
initializeIVUsersWrapperPassPass(Registry);
initializeInstCountLegacyPassPass(Registry);
initializeIntervalPartitionPass(Registry);
+ initializeIRSimilarityIdentifierWrapperPassPass(Registry);
initializeLazyBranchProbabilityInfoPassPass(Registry);
initializeLazyBlockFrequencyInfoPassPass(Registry);
initializeLazyValueInfoWrapperPassPass(Registry);
diff --git a/llvm/lib/Analysis/IRSimilarityIdentifier.cpp b/llvm/lib/Analysis/IRSimilarityIdentifier.cpp
index 579074f5de08..dc8385ff87e6 100644
--- a/llvm/lib/Analysis/IRSimilarityIdentifier.cpp
+++ b/llvm/lib/Analysis/IRSimilarityIdentifier.cpp
@@ -16,6 +16,7 @@
#include "llvm/ADT/DenseMap.h"
#include "llvm/IR/Intrinsics.h"
#include "llvm/IR/User.h"
+#include "llvm/InitializePasses.h"
#include "llvm/Support/SuffixTree.h"
using namespace llvm;
@@ -639,3 +640,58 @@ SimilarityGroupList &IRSimilarityIdentifier::findSimilarity(Module &M) {
return SimilarityCandidates.getValue();
}
+
+INITIALIZE_PASS(IRSimilarityIdentifierWrapperPass, "ir-similarity-identifier",
+ "ir-similarity-identifier", false, true)
+
+IRSimilarityIdentifierWrapperPass::IRSimilarityIdentifierWrapperPass()
+ : ModulePass(ID) {
+ initializeIRSimilarityIdentifierWrapperPassPass(
+ *PassRegistry::getPassRegistry());
+}
+
+bool IRSimilarityIdentifierWrapperPass::doInitialization(Module &M) {
+ IRSI.reset(new IRSimilarityIdentifier(M));
+ return false;
+}
+
+bool IRSimilarityIdentifierWrapperPass::doFinalization(Module &M) {
+ IRSI.reset();
+ return false;
+}
+
+bool IRSimilarityIdentifierWrapperPass::runOnModule(Module &M) {
+ // All the real work is done in the constructor for the pass.
+ IRSI.reset(new IRSimilarityIdentifier(M));
+ return false;
+}
+
+AnalysisKey IRSimilarityAnalysis::Key;
+IRSimilarityIdentifier IRSimilarityAnalysis::run(Module &M,
+ ModuleAnalysisManager &) {
+
+ return IRSimilarityIdentifier(M);
+}
+
+PreservedAnalyses
+IRSimilarityAnalysisPrinterPass::run(Module &M, ModuleAnalysisManager &AM) {
+ IRSimilarityIdentifier &IRSI = AM.getResult<IRSimilarityAnalysis>(M);
+ Optional<SimilarityGroupList> &SimilarityCandidatesOpt = IRSI.getSimilarity();
+
+ for (std::vector<IRSimilarityCandidate> &CandVec : *SimilarityCandidatesOpt) {
+ OS << CandVec.size() << " candidates of length "
+ << CandVec.begin()->getLength() << ". Found in: \n";
+ for (IRSimilarityCandidate &Cand : CandVec) {
+ OS << " Function: " << Cand.front()->Inst->getFunction()->getName().str()
+ << ", Basic Block: ";
+ if (Cand.front()->Inst->getParent()->getName().str() == "")
+ OS << "(unnamed)\n";
+ else
+ OS << Cand.front()->Inst->getParent()->getName().str() << "\n";
+ }
+ }
+
+ return PreservedAnalyses::all();
+}
+
+char IRSimilarityIdentifierWrapperPass::ID = 0;
diff --git a/llvm/lib/Passes/PassBuilder.cpp b/llvm/lib/Passes/PassBuilder.cpp
index 8dfeb158bf12..a19d2935994a 100644
--- a/llvm/lib/Passes/PassBuilder.cpp
+++ b/llvm/lib/Passes/PassBuilder.cpp
@@ -35,6 +35,7 @@
#include "llvm/Analysis/DominanceFrontier.h"
#include "llvm/Analysis/FunctionPropertiesAnalysis.h"
#include "llvm/Analysis/GlobalsModRef.h"
+#include "llvm/Analysis/IRSimilarityIdentifier.h"
#include "llvm/Analysis/IVUsers.h"
#include "llvm/Analysis/InlineAdvisor.h"
#include "llvm/Analysis/InlineSizeEstimatorAnalysis.h"
diff --git a/llvm/lib/Passes/PassRegistry.def b/llvm/lib/Passes/PassRegistry.def
index 803bd80424cb..bf50698b6d74 100644
--- a/llvm/lib/Passes/PassRegistry.def
+++ b/llvm/lib/Passes/PassRegistry.def
@@ -28,6 +28,7 @@ MODULE_ANALYSIS("verify", VerifierAnalysis())
MODULE_ANALYSIS("pass-instrumentation", PassInstrumentationAnalysis(PIC))
MODULE_ANALYSIS("asan-globals-md", ASanGlobalsMetadataAnalysis())
MODULE_ANALYSIS("inline-advisor", InlineAdvisorAnalysis())
+MODULE_ANALYSIS("ir-similarity", IRSimilarityAnalysis())
#ifndef MODULE_ALIAS_ANALYSIS
#define MODULE_ALIAS_ANALYSIS(NAME, CREATE_PASS) \
@@ -65,6 +66,7 @@ MODULE_PASS("instrprof", InstrProfiling())
MODULE_PASS("internalize", InternalizePass())
MODULE_PASS("invalidate<all>", InvalidateAllAnalysesPass())
MODULE_PASS("ipsccp", IPSCCPPass())
+MODULE_PASS("print-ir-similarity", IRSimilarityAnalysisPrinterPass(dbgs()))
MODULE_PASS("lowertypetests", LowerTypeTestsPass(nullptr, nullptr))
MODULE_PASS("mergefunc", MergeFunctionsPass())
MODULE_PASS("name-anon-globals", NameAnonGlobalPass())
diff --git a/llvm/test/Analysis/IRSimilarityIdentifier/basic.ll b/llvm/test/Analysis/IRSimilarityIdentifier/basic.ll
new file mode 100644
index 000000000000..36d53c939a73
--- /dev/null
+++ b/llvm/test/Analysis/IRSimilarityIdentifier/basic.ll
@@ -0,0 +1,97 @@
+; RUN: opt -disable-output -S -passes=print-ir-similarity < %s 2>&1 | FileCheck %s
+
+; This is a simple test to make sure the IRSimilarityIdentifier and
+; IRSimilarityPrinterPass is working.
+
+; CHECK: 4 candidates of length 2. Found in:
+; CHECK-NEXT: Function: cat, Basic Block: entry
+; CHECK-NEXT: Function: fish, Basic Block: entry
+; CHECK-NEXT: Function: dog, Basic Block: entry
+; CHECK-NEXT: Function: turtle, Basic Block: (unnamed)
+; CHECK-NEXT: 4 candidates of length 3. Found in:
+; CHECK-NEXT: Function: cat, Basic Block: entry
+; CHECK-NEXT: Function: fish, Basic Block: entry
+; CHECK-NEXT: Function: dog, Basic Block: entry
+; CHECK-NEXT: Function: turtle, Basic Block: (unnamed)
+; CHECK-NEXT: 4 candidates of length 4. Found in:
+; CHECK-NEXT: Function: cat, Basic Block: entry
+; CHECK-NEXT: Function: fish, Basic Block: entry
+; CHECK-NEXT: Function: dog, Basic Block: entry
+; CHECK-NEXT: Function: turtle, Basic Block: (unnamed)
+; CHECK-NEXT: 4 candidates of length 5. Found in:
+; CHECK-NEXT: Function: cat, Basic Block: entry
+; CHECK-NEXT: Function: fish, Basic Block: entry
+; CHECK-NEXT: Function: dog, Basic Block: entry
+; CHECK-NEXT: Function: turtle, Basic Block: (unnamed)
+; CHECK-NEXT: 4 candidates of length 6. Found in:
+; CHECK-NEXT: Function: cat, Basic Block: entry
+; CHECK-NEXT: Function: fish, Basic Block: entry
+; CHECK-NEXT: Function: dog, Basic Block: entry
+; CHECK-NEXT: Function: turtle, Basic Block: (unnamed)
+
+define linkonce_odr void @fish() {
+entry:
+ %0 = alloca i32, align 4
+ %1 = alloca i32, align 4
+ %2 = alloca i32, align 4
+ %3 = alloca i32, align 4
+ %4 = alloca i32, align 4
+ %5 = alloca i32, align 4
+ store i32 6, i32* %0, align 4
+ store i32 1, i32* %1, align 4
+ store i32 2, i32* %2, align 4
+ store i32 3, i32* %3, align 4
+ store i32 4, i32* %4, align 4
+ store i32 5, i32* %5, align 4
+ ret void
+}
+
+define void @turtle() {
+ %1 = alloca i32, align 4
+ %2 = alloca i32, align 4
+ %3 = alloca i32, align 4
+ %4 = alloca i32, align 4
+ %5 = alloca i32, align 4
+ %6 = alloca i32, align 4
+ store i32 1, i32* %1, align 4
+ store i32 2, i32* %2, align 4
+ store i32 3, i32* %3, align 4
+ store i32 4, i32* %4, align 4
+ store i32 5, i32* %5, align 4
+ store i32 6, i32* %6, align 4
+ ret void
+}
+
+define void @cat() {
+entry:
+ %0 = alloca i32, align 4
+ %1 = alloca i32, align 4
+ %2 = alloca i32, align 4
+ %3 = alloca i32, align 4
+ %4 = alloca i32, align 4
+ %5 = alloca i32, align 4
+ store i32 6, i32* %0, align 4
+ store i32 1, i32* %1, align 4
+ store i32 2, i32* %2, align 4
+ store i32 3, i32* %3, align 4
+ store i32 4, i32* %4, align 4
+ store i32 5, i32* %5, align 4
+ ret void
+}
+
+define void @dog() {
+entry:
+ %0 = alloca i32, align 4
+ %1 = alloca i32, align 4
+ %2 = alloca i32, align 4
+ %3 = alloca i32, align 4
+ %4 = alloca i32, align 4
+ %5 = alloca i32, align 4
+ store i32 6, i32* %0, align 4
+ store i32 1, i32* %1, align 4
+ store i32 2, i32* %2, align 4
+ store i32 3, i32* %3, align 4
+ store i32 4, i32* %4, align 4
+ store i32 5, i32* %5, align 4
+ ret void
+}
diff --git a/llvm/test/Analysis/IRSimilarityIdentifier/
diff erent.ll b/llvm/test/Analysis/IRSimilarityIdentifier/
diff erent.ll
new file mode 100644
index 000000000000..ab79f00d04ec
--- /dev/null
+++ b/llvm/test/Analysis/IRSimilarityIdentifier/
diff erent.ll
@@ -0,0 +1,37 @@
+; RUN: opt -disable-output -S -passes=print-ir-similarity < %s 2>&1 | FileCheck --allow-empty %s
+
+; Check to make sure that the IRSimilarityIdentifier and IRSimilarityPrinterPass
+; return items only within the same function when there are
diff erent sets of
+; instructions in functions.
+
+; CHECK: 2 candidates of length 3. Found in:
+; CHECK-NEXT: Function: turtle, Basic Block: (unnamed)
+; CHECK-NEXT: Function: turtle, Basic Block: (unnamed)
+; CHECK-NEXT: 2 candidates of length 5. Found in:
+; CHECK-NEXT: Function: fish, Basic Block: entry
+; CHECK-NEXT: Function: fish, Basic Block: entry
+
+define linkonce_odr void @fish() {
+entry:
+ %0 = alloca i32, align 4
+ %1 = alloca i32, align 4
+ %2 = alloca i32, align 4
+ %3 = alloca i32, align 4
+ %4 = alloca i32, align 4
+ %5 = alloca i32, align 4
+ store i32 6, i32* %0, align 4
+ store i32 1, i32* %1, align 4
+ store i32 2, i32* %2, align 4
+ store i32 3, i32* %3, align 4
+ store i32 4, i32* %4, align 4
+ store i32 5, i32* %5, align 4
+ ret void
+}
+
+define void @turtle(i32* %0, i32* %1, i32* %2, i32* %3) {
+ %a = load i32, i32* %0
+ %b = load i32, i32* %1
+ %c = load i32, i32* %2
+ %d = load i32, i32* %3
+ ret void
+}
diff --git a/llvm/test/Analysis/IRSimilarityIdentifier/nothing.ll b/llvm/test/Analysis/IRSimilarityIdentifier/nothing.ll
new file mode 100644
index 000000000000..e956a418aeef
--- /dev/null
+++ b/llvm/test/Analysis/IRSimilarityIdentifier/nothing.ll
@@ -0,0 +1,11 @@
+; RUN: opt -disable-output -S -passes=print-ir-similarity < %s 2>&1 | FileCheck --allow-empty %s
+
+; This is a simple test to make sure the IRSimilarityPrinterPass returns
+; nothing when there is nothing to analyze.
+
+; CHECK-NOT: Found in
+
+define linkonce_odr void @fish() {
+entry:
+ ret void
+}
More information about the llvm-commits
mailing list