1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-10-18 10:32:48 +02:00

[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
This commit is contained in:
Andrew Litteken 2020-09-17 16:29:43 -05:00
parent d92e22a706
commit c432043c07
9 changed files with 252 additions and 0 deletions

View File

@ -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 @@ private:
};
} // 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

View File

@ -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&);

View File

@ -52,6 +52,7 @@ void llvm::initializeAnalysis(PassRegistry &Registry) {
initializeIVUsersWrapperPassPass(Registry);
initializeInstCountLegacyPassPass(Registry);
initializeIntervalPartitionPass(Registry);
initializeIRSimilarityIdentifierWrapperPassPass(Registry);
initializeLazyBranchProbabilityInfoPassPass(Registry);
initializeLazyBlockFrequencyInfoPassPass(Registry);
initializeLazyValueInfoWrapperPassPass(Registry);

View File

@ -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;

View File

@ -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"

View File

@ -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())

View File

@ -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
}

View File

@ -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 different 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
}

View File

@ -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
}