52 #define DEBUG_TYPE "functioncomparator" 61 if ((
int)L < (
int)R)
return -1;
62 if ((
int)L > (
int)R)
return 1;
69 if (L.
ugt(R))
return 1;
70 if (R.
ugt(L))
return -1;
113 for (; LI !=
LE && RI != RE; ++LI, ++RI) {
127 return cmpNumbers((uint64_t)TyL, (uint64_t)TyR);
142 int FunctionComparator::cmpRangeMetadata(
const MDNode *L,
169 int FunctionComparator::cmpOperandBundlesSchema(
const Instruction *L,
174 assert(LCS && RCS &&
"Must be calls or invokes!");
185 if (
int Res = OBL.getTagName().compare(OBR.getTagName()))
188 if (
int Res =
cmpNumbers(OBL.Inputs.size(), OBR.Inputs.size()))
226 unsigned TyLWidth = 0;
227 unsigned TyRWidth = 0;
229 if (
auto *VecTyL = dyn_cast<VectorType>(TyL))
230 TyLWidth = VecTyL->getBitWidth();
231 if (
auto *VecTyR = dyn_cast<VectorType>(TyR))
232 TyRWidth = VecTyR->getBitWidth();
234 if (TyLWidth != TyRWidth)
243 unsigned AddrSpaceR = PTyR->getAddressSpace();
244 if (
int Res =
cmpNumbers(AddrSpaceL, AddrSpaceR))
269 if (GlobalValueL && GlobalValueR) {
276 if (
const auto *SeqL = dyn_cast<ConstantDataSequential>(L)) {
277 const auto *SeqR = cast<ConstantDataSequential>(R);
283 return cmpMem(SeqL->getRawDataValues(), SeqR->getRawDataValues());
287 case Value::UndefValueVal:
288 case Value::ConstantTokenNoneVal:
290 case Value::ConstantIntVal: {
291 const APInt &LInt = cast<ConstantInt>(L)->getValue();
292 const APInt &RInt = cast<ConstantInt>(R)->getValue();
295 case Value::ConstantFPVal: {
296 const APFloat &LAPF = cast<ConstantFP>(L)->getValueAPF();
297 const APFloat &RAPF = cast<ConstantFP>(R)->getValueAPF();
300 case Value::ConstantArrayVal: {
303 uint64_t NumElementsL = cast<ArrayType>(TyL)->getNumElements();
304 uint64_t NumElementsR = cast<ArrayType>(TyR)->getNumElements();
305 if (
int Res =
cmpNumbers(NumElementsL, NumElementsR))
307 for (uint64_t i = 0; i < NumElementsL; ++i) {
309 cast<Constant>(RA->getOperand(i))))
314 case Value::ConstantStructVal: {
317 unsigned NumElementsL = cast<StructType>(TyL)->getNumElements();
318 unsigned NumElementsR = cast<StructType>(TyR)->getNumElements();
319 if (
int Res =
cmpNumbers(NumElementsL, NumElementsR))
321 for (
unsigned i = 0; i != NumElementsL; ++i) {
323 cast<Constant>(RS->getOperand(i))))
328 case Value::ConstantVectorVal: {
331 unsigned NumElementsL = cast<VectorType>(TyL)->getNumElements();
332 unsigned NumElementsR = cast<VectorType>(TyR)->getNumElements();
333 if (
int Res =
cmpNumbers(NumElementsL, NumElementsR))
335 for (uint64_t i = 0; i < NumElementsL; ++i) {
337 cast<Constant>(RV->getOperand(i))))
342 case Value::ConstantExprVal: {
346 unsigned NumOperandsR = RE->getNumOperands();
347 if (
int Res =
cmpNumbers(NumOperandsL, NumOperandsR))
349 for (
unsigned i = 0; i < NumOperandsL; ++i) {
351 cast<Constant>(RE->getOperand(i))))
356 case Value::BlockAddressVal: {
398 uint64_t LNumber = GlobalNumbers->
getNumber(L);
399 uint64_t RNumber = GlobalNumbers->
getNumber(R);
412 TyL = DL.getIntPtrType(TyL);
413 if (PTyR && PTyR->getAddressSpace() == 0)
414 TyR = DL.getIntPtrType(TyR);
441 assert(PTyL && PTyR &&
"Both types must be pointers here.");
450 if (STyL->
isPacked() != STyR->isPacked())
466 if (FTyL->
isVarArg() != FTyR->isVarArg())
481 auto *STyL = cast<SequentialType>(TyL);
482 auto *STyR = cast<SequentialType>(TyR);
483 if (STyL->getNumElements() != STyR->getNumElements())
484 return cmpNumbers(STyL->getNumElements(), STyR->getNumElements());
485 return cmpTypes(STyL->getElementType(), STyR->getElementType());
496 bool &needToCmpOperands)
const {
497 needToCmpOperands =
true;
509 needToCmpOperands =
false;
514 return cmpGEPs(GEPL, GEPR);
536 if (
const AllocaInst *AI = dyn_cast<AllocaInst>(L)) {
537 if (
int Res =
cmpTypes(AI->getAllocatedType(),
538 cast<AllocaInst>(R)->getAllocatedType()))
542 if (
const LoadInst *LI = dyn_cast<LoadInst>(L)) {
549 cmpOrderings(LI->getOrdering(), cast<LoadInst>(R)->getOrdering()))
551 if (
int Res =
cmpNumbers(LI->getSyncScopeID(),
552 cast<LoadInst>(R)->getSyncScopeID()))
554 return cmpRangeMetadata(LI->getMetadata(LLVMContext::MD_range),
555 cast<LoadInst>(R)->getMetadata(LLVMContext::MD_range));
557 if (
const StoreInst *
SI = dyn_cast<StoreInst>(L)) {
565 cmpOrderings(
SI->getOrdering(), cast<StoreInst>(R)->getOrdering()))
568 cast<StoreInst>(R)->getSyncScopeID());
570 if (
const CmpInst *CI = dyn_cast<CmpInst>(L))
572 if (
auto CSL =
CallSite(const_cast<Instruction *>(L))) {
573 auto CSR =
CallSite(const_cast<Instruction *>(R));
574 if (
int Res =
cmpNumbers(CSL.getCallingConv(), CSR.getCallingConv()))
576 if (
int Res = cmpAttrs(CSL.getAttributes(), CSR.getAttributes()))
578 if (
int Res = cmpOperandBundlesSchema(L, R))
580 if (
const CallInst *CI = dyn_cast<CallInst>(L))
581 if (
int Res =
cmpNumbers(CI->getTailCallKind(),
582 cast<CallInst>(R)->getTailCallKind()))
584 return cmpRangeMetadata(L->
getMetadata(LLVMContext::MD_range),
592 for (
size_t i = 0,
e = LIndices.
size(); i !=
e; ++i) {
593 if (
int Res =
cmpNumbers(LIndices[i], RIndices[i]))
603 for (
size_t i = 0,
e = LIndices.
size(); i !=
e; ++i) {
604 if (
int Res =
cmpNumbers(LIndices[i], RIndices[i]))
608 if (
const FenceInst *FI = dyn_cast<FenceInst>(L)) {
610 cmpOrderings(FI->getOrdering(), cast<FenceInst>(R)->getOrdering()))
613 cast<FenceInst>(R)->getSyncScopeID());
620 cast<AtomicCmpXchgInst>(R)->
isWeak()))
623 cmpOrderings(CXI->getSuccessOrdering(),
624 cast<AtomicCmpXchgInst>(R)->getSuccessOrdering()))
627 cmpOrderings(CXI->getFailureOrdering(),
628 cast<AtomicCmpXchgInst>(R)->getFailureOrdering()))
631 cast<AtomicCmpXchgInst>(R)->getSyncScopeID());
633 if (
const AtomicRMWInst *RMWI = dyn_cast<AtomicRMWInst>(L)) {
634 if (
int Res =
cmpNumbers(RMWI->getOperation(),
635 cast<AtomicRMWInst>(R)->getOperation()))
640 if (
int Res = cmpOrderings(RMWI->getOrdering(),
641 cast<AtomicRMWInst>(R)->getOrdering()))
644 cast<AtomicRMWInst>(R)->getSyncScopeID());
646 if (
const PHINode *PNL = dyn_cast<PHINode>(L)) {
647 const PHINode *PNR = cast<PHINode>(R);
651 for (
unsigned i = 0,
e = PNL->getNumIncomingValues(); i !=
e; ++i) {
662 int FunctionComparator::cmpGEPs(
const GEPOperator *GEPL,
674 APInt OffsetL(BitWidth, 0), OffsetR(BitWidth, 0);
693 int FunctionComparator::cmpInlineAsm(
const InlineAsm *L,
734 if (ConstL && ConstR) {
748 if (InlineAsmL && InlineAsmR)
749 return cmpInlineAsm(InlineAsmL, InlineAsmR);
755 auto LeftSN = sn_mapL.insert(std::make_pair(L, sn_mapL.size())),
756 RightSN = sn_mapR.insert(std::make_pair(R, sn_mapR.size()));
758 return cmpNumbers(LeftSN.first->second, RightSN.first->second);
768 bool needToCmpOperands =
true;
769 if (
int Res =
cmpOperations(&*InstL, &*InstR, needToCmpOperands))
771 if (needToCmpOperands) {
772 assert(InstL->getNumOperands() == InstR->getNumOperands());
774 for (
unsigned i = 0,
e = InstL->getNumOperands(); i !=
e; ++i) {
775 Value *OpL = InstL->getOperand(i);
776 Value *OpR = InstR->getOperand(i);
786 }
while (InstL != InstLE && InstR != InstRE);
788 if (InstL != InstLE && InstR == InstRE)
790 if (InstL == InstLE && InstR != InstRE)
827 "Identically typed functions have different numbers of args!");
834 ArgLI != ArgLE; ++ArgLI, ++ArgRI) {
858 VisitedBBs.
insert(FnLBBs[0]);
859 while (!FnLBBs.
empty()) {
893 class HashAccumulator64 {
898 HashAccumulator64() { Hash = 0x6acaa36bef8325c5ULL; }
900 void add(uint64_t V) {
905 uint64_t getHash() {
return Hash; }
931 VisitedBBs.
insert(BBs[0]);
932 while (!BBs.
empty()) {
937 for (
auto &Inst : *BB) {
938 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 int compare(StringRef RHS) const
compare - Compare two strings; the result is -1, 0, or 1 if this string is lexicographically less tha...
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.
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.
Type * getValueAsType() const
Return the attribute's value as a Type.
MDNode * getMetadata(unsigned KindID) const
Get the metadata of given kind attached to this Instruction.
LLVM_NODISCARD size_t size() const
size - Get the string size.
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.
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...
Attribute::AttrKind getKindAsEnum() const
Return the attribute's kind as an enum (Attribute::AttrKind).
6: 128-bit floating point type (two 64-bits, PowerPC)
unsigned getAddressSpace() const
Return the address space of the Pointer type.
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
CallingConv::ID getCallingConv() const
getCallingConv()/setCallingConv(CC) - These method get and set the calling convention of this functio...
static uint64_t add(uint64_t LeftOp, uint64_t RightOp)
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.
unsigned getNumOperandBundles() const
Type * getReturnType() const
LLVM_NODISCARD T pop_back_val()
bool isTypeAttribute() const
Return true if the attribute is a type attribute.
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...
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
bool isCall() const
Return true if a CallInst is enclosed.
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
OperandBundleUse getOperandBundleAt(unsigned Index) 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