49#ifndef LLVM_ANALYSIS_IRSIMILARITYIDENTIFIER_H
50#define LLVM_ANALYSIS_IRSIMILARITYIDENTIFIER_H
62namespace IRSimilarity {
116 :
ilist_node<IRInstructionData, ilist_sentinel_tracking<true>> {
267 if (isa<CmpInst>(
ID.Inst))
285 if (isa<CallInst>(
ID.Inst)) {
286 std::string FunctionName = *
ID.CalleeName;
303 :
simple_ilist<IRInstructionData, ilist_sentinel_tracking<true>> {};
324 assert(
E &&
"IRInstructionData is a nullptr?");
334 assert(
LHS &&
RHS &&
"nullptr should have been caught by getEmptyKey?");
465 unsigned BBNumber = 0;
479 std::vector<IRInstructionData *> &InstrList,
480 std::vector<unsigned> &IntegerMapping);
491 std::vector<unsigned> &IntegerMappingForBB,
492 std::vector<IRInstructionData *> &InstrListForBB);
505 std::vector<IRInstructionData *> &InstrListForBB,
bool End =
false);
513 "DenseMapInfo<unsigned>'s empty key isn't -1!");
515 static_cast<unsigned>(-2) &&
516 "DenseMapInfo<unsigned>'s tombstone key isn't -2!");
525 :
public InstVisitor<InstructionClassification, InstrType> {
555 if (
II.isAssumeLikeIntrinsic())
566 if (!
F && !IsIndirectCall)
656 unsigned StartIdx = 0;
784 const unsigned InstValA,
const unsigned &InstValB,
910 if (BBSet.
insert(BB).second)
933 unsigned getEndIdx()
const {
return StartIdx + Len - 1; }
958 assert(V !=
nullptr &&
"Value is a nullptr?");
960 if (VNIt == ValueToNumber.
end())
969 std::optional<Value *>
fromGVN(
unsigned Num) {
971 if (VNIt == NumberToValue.
end())
973 assert(VNIt->second !=
nullptr &&
"Found value is a nullptr!");
985 if (NCIt == NumberToCanonNum.
end())
998 if (CNIt == CanonNumToNumber.
end())
1000 return CNIt->second;
1047 bool MatchIndirectCalls =
true,
1048 bool MatchCallsWithName =
false,
1049 bool MatchIntrinsics =
true,
1050 bool MatchMustTailCalls =
true)
1051 : Mapper(&InstDataAllocator, &InstDataListAllocator),
1052 EnableBranches(MatchBranches), EnableIndirectCalls(MatchIndirectCalls),
1053 EnableMatchingCallsByName(MatchCallsWithName),
1054 EnableIntrinsics(MatchIntrinsics),
1055 EnableMustTailCalls(MatchMustTailCalls) {}
1064 void populateMapper(
Module &M, std::vector<IRInstructionData *> &InstrList,
1065 std::vector<unsigned> &IntegerMapping);
1073 void populateMapper(
ArrayRef<std::unique_ptr<Module>> &Modules,
1074 std::vector<IRInstructionData *> &InstrList,
1075 std::vector<unsigned> &IntegerMapping);
1083 void findCandidates(std::vector<IRInstructionData *> &InstrList,
1084 std::vector<unsigned> &IntegerMapping);
1108 if (SimilarityCandidates)
1109 SimilarityCandidates->clear();
1117 return SimilarityCandidates;
1133 bool EnableBranches =
true;
1137 bool EnableIndirectCalls =
true;
1142 bool EnableMatchingCallsByName =
true;
1146 bool EnableIntrinsics =
true;
1150 bool EnableMustTailCalls =
false;
1154 std::optional<SimilarityGroupList> SimilarityCandidates;
1162 std::unique_ptr<IRSimilarity::IRSimilarityIdentifier> IRSI;
1171 bool doInitialization(
Module &M)
override;
1172 bool doFinalization(
Module &M)
override;
1173 bool runOnModule(
Module &M)
override;
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
This file defines the BumpPtrAllocator interface.
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
This header defines various interfaces for pass management in LLVM.
uint64_t IntrinsicInst * II
an instruction to allocate memory on the stack
A container for analyses that lazily runs them and caches their results.
Represent the analysis usage information of a pass.
void setPreservesAll()
Set by analyses that do not transform their input at all.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
LLVM Basic Block Representation.
const Function * getParent() const
Return the enclosing method, or null if none.
InstListType::iterator iterator
Instruction iterators...
Conditional or Unconditional Branch instruction.
Function * getCalledFunction() const
Returns the function called, or null if this is an indirect function invocation or the function signa...
CallingConv::ID getCallingConv() const
LLVM_ABI bool isIndirectCall() const
Return true if the callsite is an indirect call.
CallBr instruction, tracking function calls that may not return control but instead transfer it to a ...
This class represents a function call, abstracting a target machine's calling convention.
bool isMustTailCall() const
This class is the base class for the comparison instructions.
Predicate
This enumeration lists the possible predicates for CmpInst subclasses.
iterator find(const_arg_type_t< KeyT > Val)
Implements a dense probed hash-table based set.
Printer pass that uses IRSimilarityAnalysis.
LLVM_ABI PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM)
IRSimilarityAnalysisPrinterPass(raw_ostream &OS)
An analysis pass that runs and returns the IRSimilarityIdentifier run on the Module.
IRSimilarity::IRSimilarityIdentifier Result
LLVM_ABI Result run(Module &M, ModuleAnalysisManager &)
An analysis pass based on legacy pass manager that runs and returns IRSimilarityIdentifier run on the...
IRSimilarityIdentifierWrapperPass()
IRSimilarity::IRSimilarityIdentifier & getIRSI()
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - This function should be overriden by passes that need analysis information to do t...
const IRSimilarity::IRSimilarityIdentifier & getIRSI() const
This is a class that wraps a range of IRInstructionData from one point to another in the vector of IR...
Instruction * backInstruction()
LLVM_ABI void createCanonicalRelationFrom(IRSimilarityCandidate &SourceCand, DenseMap< unsigned, DenseSet< unsigned > > &ToSourceMapping, DenseMap< unsigned, DenseSet< unsigned > > &FromSourceMapping)
Create a mapping for the value numbering of the calling IRSimilarityCandidate, to a different separat...
static LLVM_ABI bool isSimilar(const IRSimilarityCandidate &A, const IRSimilarityCandidate &B)
LLVM_ABI void createCanonicalRelationFrom(IRSimilarityCandidate &SourceCand, DenseMap< unsigned, unsigned > &OneToOne, DenseMap< unsigned, DenseSet< unsigned > > &ToSourceMapping, DenseMap< unsigned, DenseSet< unsigned > > &FromSourceMapping)
Create a mapping for the value numbering of the calling IRSimilarityCandidate, to a different separat...
std::optional< unsigned > getGVN(Value *V)
Finds the positive number associated with V if it has been mapped.
unsigned getLength() const
void getBasicBlocks(DenseSet< BasicBlock * > &BBSet, SmallVector< BasicBlock * > &BBList) const
unsigned getEndIdx() const
static LLVM_ABI bool compareAssignmentMapping(const unsigned InstValA, const unsigned &InstValB, DenseMap< unsigned, DenseSet< unsigned > > &ValueNumberMappingA, DenseMap< unsigned, DenseSet< unsigned > > &ValueNumberMappingB)
Compare the GVN of the assignment value in corresponding instructions in IRSimilarityCandidates A and...
IRInstructionData * back() const
void getBasicBlocks(DenseSet< BasicBlock * > &BBSet) const
bool operator<(const IRSimilarityCandidate &RHS) const
std::optional< Value * > fromGVN(unsigned Num)
Finds the Value associate with Num if it exists.
IRInstructionDataList::iterator iterator
Instruction * frontInstruction()
static LLVM_ABI bool checkRelativeLocations(RelativeLocMapping A, RelativeLocMapping B)
Compare the relative locations in A and B and check that the distances match if both locations are co...
static LLVM_ABI bool compareStructure(const IRSimilarityCandidate &A, const IRSimilarityCandidate &B)
static LLVM_ABI void createCanonicalMappingFor(IRSimilarityCandidate &CurrCand)
Create a mapping from the value numbering to a different separate set of numbers.
static LLVM_ABI bool overlap(const IRSimilarityCandidate &A, const IRSimilarityCandidate &B)
Compare the start and end indices of the two IRSimilarityCandidates for whether they overlap.
unsigned getStartIdx() const
BasicBlock * getStartBB()
std::optional< unsigned > getCanonicalNum(unsigned N)
Find the canonical number from the global value number N stored in the candidate.
std::optional< unsigned > fromCanonicalNum(unsigned N)
Find the global value number from the canonical number N stored in the candidate.
IRInstructionData * front() const
static LLVM_ABI bool compareNonCommutativeOperandMapping(OperandMapping A, OperandMapping B)
Compare the operands in A and B and check that the current mapping of global value numbers from A to ...
static LLVM_ABI bool compareCommutativeOperandMapping(OperandMapping A, OperandMapping B)
Compare the operands in A and B and check that the current mapping of global value numbers from A to ...
This class puts all the pieces of the IRInstructionData, IRInstructionMapper, IRSimilarityCandidate t...
IRSimilarityIdentifier(bool MatchBranches=true, bool MatchIndirectCalls=true, bool MatchCallsWithName=false, bool MatchIntrinsics=true, bool MatchMustTailCalls=true)
void resetSimilarityCandidates()
LLVM_ABI SimilarityGroupList & findSimilarity(ArrayRef< std::unique_ptr< Module > > Modules)
std::optional< SimilarityGroupList > & getSimilarity()
Base class for instruction visitors.
A wrapper class for inspecting calls to intrinsic functions.
The landingpad instruction holds all of the information necessary to generate correct exception handl...
ModulePass class - This class is used to implement unstructured interprocedural optimizations and ana...
A Module instance is used to store all the information related to an LLVM module.
A set of analyses that are preserved following a run of a transformation pass.
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
A BumpPtrAllocator that allows only elements of a specific type to be allocated.
StringRef - Represent a constant reference to a string, i.e.
This class represents the va_arg llvm instruction, which returns an argument of the specified type gi...
LLVM Value Representation.
std::pair< iterator, bool > insert(const ValueT &V)
An opaque object representing a hash code.
const ParentTy * getParent() const
This class implements an extremely fast bulk output stream that can only output to a stream.
A simple intrusive list implementation.
typename ilist_select_iterator_type< OptionsT::has_iterator_bits, OptionsT, false, false >::type iterator
@ Tail
Attemps to make calls as fast as possible while guaranteeing that tail call optimization can always b...
@ SwiftTail
This follows the Swift calling convention in how arguments are passed but guarantees tail calls will ...
std::vector< SimilarityGroup > SimilarityGroupList
std::vector< IRSimilarityCandidate > SimilarityGroup
DenseMap< IRSimilarityCandidate *, DenseMap< unsigned, DenseSet< unsigned > > > CandidateGVNMapping
LLVM_ABI bool isClose(const IRInstructionData &A, const IRInstructionData &B)
Compare one IRInstructionData class to another IRInstructionData class for whether they are performin...
InstrType
This represents what is and is not supported when finding similarity in Instructions.
This is an optimization pass for GlobalISel generic memory operations.
hash_code hash_value(const FixedPointSemantics &Val)
hash_code hash_combine(const Ts &...args)
Combine values into a single hash_code.
hash_code hash_combine_range(InputIteratorT first, InputIteratorT last)
Compute a hash_code for a sequence of values.
A CRTP mix-in that provides informational APIs needed for analysis passes.
A special type used by analysis passes to provide an address that identifies that particular analysis...
An information struct used to provide DenseMap with the various necessary components for a given valu...
static IRInstructionData * getEmptyKey()
static unsigned getHashValue(const IRInstructionData *E)
static bool isEqual(const IRInstructionData *LHS, const IRInstructionData *RHS)
static IRInstructionData * getTombstoneKey()
This provides the utilities for hashing an Instruction to an unsigned integer.
LLVM_ABI StringRef getCalleeName() const
Get the callee name that the call instruction is using for hashing the instruction.
LLVM_ABI void initializeInstruction()
Fills data stuctures for IRInstructionData when it is constructed from a.
SmallVector< int, 4 > RelativeBlockLocations
This structure holds the distances of how far "ahead of" or "behind" the target blocks of a branch,...
std::optional< std::string > CalleeName
This is only relevant if we are wrapping a CallInst.
LLVM_ABI ArrayRef< Value * > getBlockOperVals()
Get the BasicBlock based operands for PHINodes and BranchInsts.
Instruction * Inst
The source Instruction that is being wrapped.
IRInstructionDataList * IDL
static LLVM_ABI CmpInst::Predicate predicateForConsistency(CmpInst *CI)
A function that swaps the predicates to their less than form if they are in a greater than form.
LLVM_ABI void setPHIPredecessors(DenseMap< BasicBlock *, unsigned > &BasicBlockToInteger)
For an IRInstructionData containing a PHINode, finds the relative distances from the incoming basic b...
SmallVector< Value *, 4 > OperVals
The values of the operands in the Instruction.
friend hash_code hash_value(const IRInstructionData &ID)
Hashes Value based on its opcode, types, and operand types.
LLVM_ABI void setBranchSuccessors(DenseMap< BasicBlock *, unsigned > &BasicBlockToInteger)
For an IRInstructionData containing a branch, finds the relative distances from the source basic bloc...
bool Legal
The legality of the wrapped instruction.
LLVM_ABI void setCalleeName(bool MatchByName=true)
For an IRInstructionData containing a CallInst, set the function name appropriately.
LLVM_ABI CmpInst::Predicate getPredicate() const
Get the predicate that the compare instruction is using for hashing the instruction.
std::optional< CmpInst::Predicate > RevisedPredicate
This is only relevant if we are wrapping a CmpInst where we needed to change the predicate of a compa...
Custom InstVisitor to classify different instructions for whether it can be analyzed for similarity.
InstrType visitInvokeInst(InvokeInst &II)
InstrType visitLandingPadInst(LandingPadInst &LPI)
InstrType visitFuncletPadInst(FuncletPadInst &FPI)
InstrType visitCallInst(CallInst &CI)
InstrType visitAllocaInst(AllocaInst &AI)
InstrType visitCallBrInst(CallBrInst &CBI)
InstructionClassification()=default
InstrType visitBranchInst(BranchInst &BI)
InstrType visitIntrinsicInst(IntrinsicInst &II)
InstrType visitInstruction(Instruction &I)
InstrType visitPHINode(PHINode &PN)
InstrType visitTerminator(Instruction &I)
InstrType visitVAArgInst(VAArgInst &VI)
Helper struct for converting the Instructions in a Module into a vector of unsigned integers.
DenseMap< IRInstructionData *, unsigned, IRInstructionDataTraits > InstructionIntegerMap
Correspondence from IRInstructionData to unsigned integers.
SpecificBumpPtrAllocator< IRInstructionDataList > * IDLAllocator
This allocator pointer is in charge of creating the IRInstructionDataList so it is not deallocated un...
SpecificBumpPtrAllocator< IRInstructionData > * InstDataAllocator
This allocator pointer is in charge of holding on to the IRInstructionData so it is not deallocated u...
bool EnableMatchCallsByName
Marks whether we should use exact function names, as well as types to find similarity between calls.
unsigned LegalInstrNumber
The next available integer to assign to a legal Instruction to.
unsigned IllegalInstrNumber
The starting illegal instruction number to map to.
InstructionClassification InstClassifier
Maps an Instruction to a member of InstrType.
void initializeForBBs(Function &F, unsigned &BBNumber)
Assigns values to all the basic blocks in function F starting from integer BBNumber.
bool HaveLegalRange
Marks whether we have found a set of instructions that is long enough to be considered for similarity...
void initializeForBBs(Module &M)
Assigns values to all the basic blocks in Module M.
LLVM_ABI IRInstructionData * allocateIRInstructionData(Instruction &I, bool Legality, IRInstructionDataList &IDL)
Get an allocated IRInstructionData struct using the InstDataAllocator.
IRInstructionMapper(SpecificBumpPtrAllocator< IRInstructionData > *IDA, SpecificBumpPtrAllocator< IRInstructionDataList > *IDLA)
bool CanCombineWithPrevInstr
Marks whether we found a illegal instruction in the previous step.
IRInstructionDataList * IDL
DenseMap< BasicBlock *, unsigned > BasicBlockToInteger
A mapping for a basic block in a module to its assigned number/location in the module.
LLVM_ABI IRInstructionDataList * allocateIRInstructionDataList()
Get an allocated IRInstructionDataList object using the IDLAllocator.
LLVM_ABI unsigned mapToLegalUnsigned(BasicBlock::iterator &It, std::vector< unsigned > &IntegerMappingForBB, std::vector< IRInstructionData * > &InstrListForBB)
Maps an Instruction to a legal integer.
LLVM_ABI void convertToUnsignedVec(BasicBlock &BB, std::vector< IRInstructionData * > &InstrList, std::vector< unsigned > &IntegerMapping)
Maps the Instructions in a BasicBlock BB to legal or illegal integers determined by InstrType.
bool AddedIllegalLastTime
Set if we added an illegal number in the previous step.
LLVM_ABI unsigned mapToIllegalUnsigned(BasicBlock::iterator &It, std::vector< unsigned > &IntegerMappingForBB, std::vector< IRInstructionData * > &InstrListForBB, bool End=false)
Maps an Instruction to an illegal integer.
DenseMap< unsigned, DenseSet< unsigned > > & ValueNumberMapping
The current mapping of global value numbers from one IRSimilarityCandidate to another IRSimilarityCan...
const IRSimilarityCandidate & IRSC
The IRSimilarityCandidate that holds the instruction the OperVals were pulled from.
ArrayRef< Value * > & OperVals
The operand values to be analyzed.
A helper struct to hold the candidate, for a branch instruction, the relative location of a label,...
const IRSimilarityCandidate & IRSC
The IRSimilarityCandidate that holds the instruction the relative location was pulled from.
int RelativeLocation
The relative location to be analyzed.
Value * OperVal
The corresponding value.
A CRTP mix-in to automatically provide informational APIs needed for passes.