[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