mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-26 12:43:36 +01: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:
parent
d92e22a706
commit
c432043c07
@ -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
|
||||
|
@ -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&);
|
||||
|
@ -52,6 +52,7 @@ void llvm::initializeAnalysis(PassRegistry &Registry) {
|
||||
initializeIVUsersWrapperPassPass(Registry);
|
||||
initializeInstCountLegacyPassPass(Registry);
|
||||
initializeIntervalPartitionPass(Registry);
|
||||
initializeIRSimilarityIdentifierWrapperPassPass(Registry);
|
||||
initializeLazyBranchProbabilityInfoPassPass(Registry);
|
||||
initializeLazyBlockFrequencyInfoPassPass(Registry);
|
||||
initializeLazyValueInfoWrapperPassPass(Registry);
|
||||
|
@ -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;
|
||||
|
@ -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"
|
||||
|
@ -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())
|
||||
|
97
test/Analysis/IRSimilarityIdentifier/basic.ll
Normal file
97
test/Analysis/IRSimilarityIdentifier/basic.ll
Normal 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
|
||||
}
|
37
test/Analysis/IRSimilarityIdentifier/different.ll
Normal file
37
test/Analysis/IRSimilarityIdentifier/different.ll
Normal 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
|
||||
}
|
11
test/Analysis/IRSimilarityIdentifier/nothing.ll
Normal file
11
test/Analysis/IRSimilarityIdentifier/nothing.ll
Normal 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
|
||||
}
|
Loading…
Reference in New Issue
Block a user