53 #define DEBUG_TYPE "functioncomparator" 62 if ((
int)L < (
int)R)
return -1;
63 if ((
int)L > (
int)R)
return 1;
70 if (L.
ugt(R))
return 1;
71 if (R.
ugt(L))
return -1;
114 for (; LI !=
LE && RI != RE; ++LI, ++RI) {
130 int FunctionComparator::cmpRangeMetadata(
const MDNode *L,
157 int FunctionComparator::cmpOperandBundlesSchema(
const Instruction *L,
162 assert(LCS && RCS &&
"Must be calls or invokes!");
173 if (
int Res = OBL.getTagName().compare(OBR.getTagName()))
176 if (
int Res =
cmpNumbers(OBL.Inputs.size(), OBR.Inputs.size()))
214 unsigned TyLWidth = 0;
215 unsigned TyRWidth = 0;
217 if (
auto *VecTyL = dyn_cast<VectorType>(TyL))
218 TyLWidth = VecTyL->getBitWidth();
219 if (
auto *VecTyR = dyn_cast<VectorType>(TyR))
220 TyRWidth = VecTyR->getBitWidth();
222 if (TyLWidth != TyRWidth)
231 unsigned AddrSpaceR = PTyR->getAddressSpace();
232 if (
int Res =
cmpNumbers(AddrSpaceL, AddrSpaceR))
257 if (GlobalValueL && GlobalValueR) {
264 if (
const auto *SeqL = dyn_cast<ConstantDataSequential>(L)) {
265 const auto *SeqR = cast<ConstantDataSequential>(R);
271 return cmpMem(SeqL->getRawDataValues(), SeqR->getRawDataValues());
275 case Value::UndefValueVal:
276 case Value::ConstantTokenNoneVal:
278 case Value::ConstantIntVal: {
279 const APInt &LInt = cast<ConstantInt>(L)->getValue();
280 const APInt &RInt = cast<ConstantInt>(R)->getValue();
283 case Value::ConstantFPVal: {
284 const APFloat &LAPF = cast<ConstantFP>(L)->getValueAPF();
285 const APFloat &RAPF = cast<ConstantFP>(R)->getValueAPF();
288 case Value::ConstantArrayVal: {
291 uint64_t NumElementsL = cast<ArrayType>(TyL)->getNumElements();
292 uint64_t NumElementsR = cast<ArrayType>(TyR)->getNumElements();
293 if (
int Res =
cmpNumbers(NumElementsL, NumElementsR))
295 for (uint64_t i = 0; i < NumElementsL; ++i) {
297 cast<Constant>(RA->getOperand(i))))
302 case Value::ConstantStructVal: {
305 unsigned NumElementsL = cast<StructType>(TyL)->getNumElements();
306 unsigned NumElementsR = cast<StructType>(TyR)->getNumElements();
307 if (
int Res =
cmpNumbers(NumElementsL, NumElementsR))
309 for (
unsigned i = 0; i != NumElementsL; ++i) {
311 cast<Constant>(RS->getOperand(i))))
316 case Value::ConstantVectorVal: {
319 unsigned NumElementsL = cast<VectorType>(TyL)->getNumElements();
320 unsigned NumElementsR = cast<VectorType>(TyR)->getNumElements();
321 if (
int Res =
cmpNumbers(NumElementsL, NumElementsR))
323 for (uint64_t i = 0; i < NumElementsL; ++i) {
325 cast<Constant>(RV->getOperand(i))))
330 case Value::ConstantExprVal: {
334 unsigned NumOperandsR = RE->getNumOperands();
335 if (
int Res =
cmpNumbers(NumOperandsL, NumOperandsR))
337 for (
unsigned i = 0; i < NumOperandsL; ++i) {
339 cast<Constant>(RE->getOperand(i))))
344 case Value::BlockAddressVal: {
386 uint64_t LNumber = GlobalNumbers->
getNumber(L);
387 uint64_t RNumber = GlobalNumbers->
getNumber(R);
400 TyL = DL.getIntPtrType(TyL);
401 if (PTyR && PTyR->getAddressSpace() == 0)
402 TyR = DL.getIntPtrType(TyR);
429 assert(PTyL && PTyR &&
"Both types must be pointers here.");
438 if (STyL->
isPacked() != STyR->isPacked())
454 if (FTyL->
isVarArg() != FTyR->isVarArg())
460 for (
unsigned i = 0, e = FTyL->
getNumParams(); i != e; ++i) {
469 auto *STyL = cast<SequentialType>(TyL);
470 auto *STyR = cast<SequentialType>(TyR);
471 if (STyL->getNumElements() != STyR->getNumElements())
472 return cmpNumbers(STyL->getNumElements(), STyR->getNumElements());
473 return cmpTypes(STyL->getElementType(), STyR->getElementType());
484 bool &needToCmpOperands)
const {
485 needToCmpOperands =
true;
497 needToCmpOperands =
false;
502 return cmpGEPs(GEPL, GEPR);
524 if (
const AllocaInst *AI = dyn_cast<AllocaInst>(L)) {
525 if (
int Res =
cmpTypes(AI->getAllocatedType(),
526 cast<AllocaInst>(R)->getAllocatedType()))
530 if (
const LoadInst *LI = dyn_cast<LoadInst>(L)) {
537 cmpOrderings(LI->getOrdering(), cast<LoadInst>(R)->getOrdering()))
539 if (
int Res =
cmpNumbers(LI->getSyncScopeID(),
540 cast<LoadInst>(R)->getSyncScopeID()))
545 if (
const StoreInst *
SI = dyn_cast<StoreInst>(L)) {
553 cmpOrderings(
SI->getOrdering(), cast<StoreInst>(R)->getOrdering()))
556 cast<StoreInst>(R)->getSyncScopeID());
558 if (
const CmpInst *CI = dyn_cast<CmpInst>(L))
560 if (
const CallInst *CI = dyn_cast<CallInst>(L)) {
561 if (
int Res =
cmpNumbers(CI->getCallingConv(),
562 cast<CallInst>(R)->getCallingConv()))
565 cmpAttrs(CI->getAttributes(), cast<CallInst>(R)->
getAttributes()))
567 if (
int Res = cmpOperandBundlesSchema(CI, R))
569 return cmpRangeMetadata(
573 if (
const InvokeInst *II = dyn_cast<InvokeInst>(L)) {
574 if (
int Res =
cmpNumbers(II->getCallingConv(),
575 cast<InvokeInst>(R)->getCallingConv()))
578 cmpAttrs(II->getAttributes(), cast<InvokeInst>(R)->
getAttributes()))
580 if (
int Res = cmpOperandBundlesSchema(II, R))
582 return cmpRangeMetadata(
591 for (
size_t i = 0, e = LIndices.
size(); i != e; ++i) {
592 if (
int Res =
cmpNumbers(LIndices[i], RIndices[i]))
602 for (
size_t i = 0, e = LIndices.
size(); i != e; ++i) {
603 if (
int Res =
cmpNumbers(LIndices[i], RIndices[i]))
607 if (
const FenceInst *FI = dyn_cast<FenceInst>(L)) {
609 cmpOrderings(FI->getOrdering(), cast<FenceInst>(R)->getOrdering()))
612 cast<FenceInst>(R)->getSyncScopeID());
619 cast<AtomicCmpXchgInst>(R)->
isWeak()))
622 cmpOrderings(CXI->getSuccessOrdering(),
623 cast<AtomicCmpXchgInst>(R)->getSuccessOrdering()))
626 cmpOrderings(CXI->getFailureOrdering(),
627 cast<AtomicCmpXchgInst>(R)->getFailureOrdering()))
630 cast<AtomicCmpXchgInst>(R)->getSyncScopeID());
632 if (
const AtomicRMWInst *RMWI = dyn_cast<AtomicRMWInst>(L)) {
633 if (
int Res =
cmpNumbers(RMWI->getOperation(),
634 cast<AtomicRMWInst>(R)->getOperation()))
639 if (
int Res = cmpOrderings(RMWI->getOrdering(),
640 cast<AtomicRMWInst>(R)->getOrdering()))
643 cast<AtomicRMWInst>(R)->getSyncScopeID());
645 if (
const PHINode *PNL = dyn_cast<PHINode>(L)) {
646 const PHINode *PNR = cast<PHINode>(R);
650 for (
unsigned i = 0, e = PNL->getNumIncomingValues(); i != e; ++i) {
661 int FunctionComparator::cmpGEPs(
const GEPOperator *GEPL,
673 APInt OffsetL(BitWidth, 0), OffsetR(BitWidth, 0);
692 int FunctionComparator::cmpInlineAsm(
const InlineAsm *L,
733 if (ConstL && ConstR) {
747 if (InlineAsmL && InlineAsmR)
748 return cmpInlineAsm(InlineAsmL, InlineAsmR);
754 auto LeftSN = sn_mapL.insert(std::make_pair(L, sn_mapL.size())),
755 RightSN = sn_mapR.insert(std::make_pair(R, sn_mapR.size()));
757 return cmpNumbers(LeftSN.first->second, RightSN.first->second);
767 bool needToCmpOperands =
true;
768 if (
int Res =
cmpOperations(&*InstL, &*InstR, needToCmpOperands))
770 if (needToCmpOperands) {
771 assert(InstL->getNumOperands() == InstR->getNumOperands());
773 for (
unsigned i = 0, e = InstL->getNumOperands(); i != e; ++i) {
774 Value *OpL = InstL->getOperand(i);
775 Value *OpR = InstR->getOperand(i);
785 }
while (InstL != InstLE && InstR != InstRE);
787 if (InstL != InstLE && InstR == InstRE)
789 if (InstL == InstLE && InstR != InstRE)
826 "Identically typed functions have different numbers of args!");
833 ArgLI != ArgLE; ++ArgLI, ++ArgRI) {
857 VisitedBBs.
insert(FnLBBs[0]);
858 while (!FnLBBs.
empty()) {
892 class HashAccumulator64 {
897 HashAccumulator64() { Hash = 0x6acaa36bef8325c5ULL; }
899 void add(uint64_t V) {
904 uint64_t getHash() {
return Hash; }
930 VisitedBBs.
insert(BBs[0]);
931 while (!BBs.
empty()) {
936 for (
auto &Inst : *BB) {
937 H.add(Inst.getOpcode());
static unsigned getBitWidth(Type *Ty, const DataLayout &DL)
Returns the bitwidth of the given scalar or pointer type.
const Function & getFunction() const
bool isVarArg() const
isVarArg - Return true if this function takes a variable number of arguments.
int cmpGlobalValues(GlobalValue *L, GlobalValue *R) const
Compares two global values by number.
StringRef getSection() const
Get the custom section of this global if it has one.
A parsed version of the target data layout string in and methods for querying it. ...
Value * getPointerOperand()
This class is the base class for the comparison instructions.
This class represents an incoming formal argument to a Function.
unsigned getValueID() const
Return an ID for the concrete type of this object.
int cmpBasicBlocks(const BasicBlock *BBL, const BasicBlock *BBR) const
Test whether two basic blocks have equivalent behaviour.
This class represents lattice values for constants.
Type * getParamType(unsigned i) const
Parameter type accessors.
Type * getElementType(unsigned N) const
int compareSignature() const
Compares the signature and other general attributes of the two functions.
2: 32-bit floating point type
BasicBlock * getSuccessor(unsigned Idx) const
Return the specified successor. This instruction must be a terminator.
An instruction for ordering other memory operations.
an instruction that atomically checks whether a specified value is in a memory location, and, if it is, stores a new value there.
unsigned getNumElements() const
Random access to the elements.
void push_back(const T &Elt)
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE size_t size() const
size - Get the string size.
This class represents a function call, abstracting a target machine's calling convention.
const std::string & getAsmString() const
unsigned getPointerAddressSpace() const
Method to return the address space of the pointer operand.
unsigned getPointerSizeInBits(unsigned AS=0) const
Layout pointer size, in bits FIXME: The defaults need to be removed once all of the backends/clients ...
4: 80-bit floating point type (X87)
int cmpAPInts(const APInt &L, const APInt &R) const
const MDOperand & getOperand(unsigned I) const
const fltSemantics & getSemantics() const
An instruction for reading from memory.
an instruction that atomically reads a memory location, combines it with another value, and then stores the result back.
const Instruction * getTerminator() const LLVM_READONLY
Returns the terminator instruction if the block is well formed or null if the block is not well forme...
unsigned index_end() const
unsigned getBitWidth() const
Return the number of bits in the APInt.
bool accumulateConstantOffset(const DataLayout &DL, APInt &Offset) const
Accumulate the constant address offset of this GEP if possible.
iterator begin()
Instruction iterator methods.
bool hasSideEffects() const
Function * getFunction() const
int cmpAPFloats(const APFloat &L, const APFloat &R) const
SI optimize exec mask operations pre RA
The address of a basic block.
static uint32_t getAlignment(const MCSectionCOFF &Sec)
uint64_t FunctionHash
Hash a function.
const DataLayout & getDataLayout() const
Get the data layout for the module's target platform.
TypeID getTypeID() const
Return the type id for the type.
Class to represent struct types.
This file contains the simple types necessary to represent the attributes associated with functions a...
static ExponentType semanticsMaxExponent(const fltSemantics &)
This file implements a class to represent arbitrary precision integral constant values and operations...
AtomicOrdering
Atomic ordering for LLVM's memory model.
AttributeList getAttributes(LLVMContext &C, ID id)
Return the attributes for an intrinsic.
void beginCompare()
Start the comparison.
bool isNullValue() const
Return true if this is the value that would be returned by getNullValue.
Class to represent function types.
A constant value that is initialized with an expression using other constant values.
Type * getType() const
All values are typed, get the type of this value.
bool isFirstClassType() const
Return true if the type is "first class", meaning it is a valid type for a Value. ...
static unsigned int semanticsSizeInBits(const fltSemantics &)
int cmpOperations(const Instruction *L, const Instruction *R, bool &needToCmpOperands) const
Compare two Instructions for equivalence, similar to Instruction::isSameOperationAs.
const APInt & getValue() const
Return the constant as an APInt value reference.
unsigned getOpcode() const
Returns a member of one of the enums like Instruction::Add.
BasicBlock * getBasicBlock() const
const std::string & getGC() const
uint64_t hash_16_bytes(uint64_t low, uint64_t high)
AttributeList getAttributes() const
Return the attribute list for this Function.
An instruction for storing to memory.
uint64_t getNumber(GlobalValue *Global)
static ExponentType semanticsMinExponent(const fltSemantics &)
unsigned getNumSuccessors() const
Return the number of successors that this instruction has.
Value * getOperand(unsigned i) const
Class to represent pointers.
bool isCall() const
Return true if a CallInst is enclosed.
static FunctionHash functionHash(Function &)
AttributeSet getAttributes(unsigned Index) const
The attributes for the specified index are returned.
unsigned getRawSubclassOptionalData() const
Return the raw optional flags value contained in this value.
11: Arbitrary bit width integers
const BasicBlock & getEntryBlock() const
an instruction for type-safe pointer arithmetic to access elements of arrays and structs ...
LLVM Basic Block Representation.
The instances of the Type class are immutable: once they are created, they are never changed...
size_t size() const
size - Get the array size.
This is an important base class in LLVM.
This file contains the declarations for the subclasses of Constant, which represent the different fla...
unsigned getNumParams() const
Return the number of fixed parameters this function type requires.
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
This file declares a class to represent arbitrary precision floating point values and provide a varie...
6: 128-bit floating point type (two 64-bits, PowerPC)
unsigned getAddressSpace() const
Return the address space of the Pointer type.
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE int compare(StringRef RHS) const
compare - Compare two strings; the result is -1, 0, or 1 if this string is lexicographically less tha...
Constant Vector Declarations.
int cmpMem(StringRef L, StringRef R) const
bool isAlignStack() const
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
const std::string & getConstraintString() const
Predicate getPredicate(unsigned Condition, unsigned Hint)
Return predicate consisting of specified condition and hint bits.
Iterator for intrusive lists based on ilist_node.
unsigned getNumOperands() const
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements...
This is the shared class of boolean and integer constants.
16: SIMD 'packed' format, or other vector type
OperandBundleUse getOperandBundleAt(unsigned Index) const
CallingConv::ID getCallingConv() const
getCallingConv()/setCallingConv(CC) - These method get and set the calling convention of this functio...
bool hasSection() const
Check if this global has a custom object file section.
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small...
Module.h This file contains the declarations for the Module class.
Type * getReturnType() const
LLVM_NODISCARD T pop_back_val()
static unsigned int semanticsPrecision(const fltSemantics &)
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
FunctionType * getFunctionType() const
Returns the FunctionType for me.
ConstantArray - Constant Array Declarations.
Class for arbitrary precision integers.
unsigned getNumAttrSets() const
static bool isWeak(const MCSymbolELF &Sym)
int compare()
Test whether the two functions have equivalent behaviour.
int cmpTypes(Type *TyL, Type *TyR) const
cmpType - compares two types, defines total ordering among the types set.
bool ugt(const APInt &RHS) const
Unsigned greather than comparison.
bool hasGC() const
hasGC/getGC/setGC/clearGC - The name of the garbage collection algorithm to use during code generatio...
unsigned getNumOperandBundles() const
LLVM_NODISCARD bool empty() const
Establish a view to a call site for examination.
BasicBlock * getIncomingBlock(unsigned i) const
Return incoming basic block number i.
LLVM_NODISCARD std::enable_if<!is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type >::type dyn_cast(const Y &Val)
const BasicBlockListType & getBasicBlockList() const
Get the underlying elements of the Function...
FunctionType * getFunctionType() const
getFunctionType - InlineAsm's are always pointers to functions.
AsmDialect getDialect() const
3: 64-bit floating point type
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
Module * getParent()
Get the module that this global value is contained inside of...
LLVM Value Representation.
int cmpValues(const Value *L, const Value *R) const
Assign or look up previously assigned numbers for the two values, and return whether the numbers are ...
StringRef - Represent a constant reference to a string, i.e.
int cmpConstants(const Constant *L, const Constant *R) const
Constants comparison.
Type * getSourceElementType() const
APInt bitcastToAPInt() const
static bool isVolatile(Instruction *Inst)
unsigned getNumOperands() const
Return number of MDNode operands.
unsigned index_begin() const
Use these to iterate over the valid attribute indices.
an instruction to allocate memory on the stack
This instruction inserts a struct field of array element value into an aggregate value.
5: 128-bit floating point type (112-bit mantissa)
int cmpNumbers(uint64_t L, uint64_t R) const