50#define DEBUG_TYPE "functioncomparator"
61 if (L.value() < R.value())
63 if (L.value() > R.value())
77 if (
int Res =
cmpNumbers(L.getBitWidth(), R.getBitWidth()))
88 if (
int Res =
cmpAPInts(L.getLower(), R.getLower()))
90 return cmpAPInts(L.getUpper(), R.getUpper());
96 const fltSemantics &SL = L.getSemantics(), &SR = R.getSemantics();
109 return cmpAPInts(L.bitcastToAPInt(), R.bitcastToAPInt());
119 return std::clamp(L.compare(R), -1, 1);
122int FunctionComparator::cmpAttrs(
const AttributeList L,
123 const AttributeList R)
const {
124 if (
int Res =
cmpNumbers(L.getNumAttrSets(), R.getNumAttrSets()))
127 for (
unsigned i : L.indexes()) {
132 for (; LI != LE && RI != RE; ++LI, ++RI) {
140 Type *TyR =
RA.getValueAsType();
153 RA.isConstantRangeAttribute()) {
161 RA.isConstantRangeListAttribute()) {
170 for (
const auto &[L, R] :
zip(CRL, CRR))
188int FunctionComparator::cmpMetadata(
const Metadata *L,
198 if (MDStringL && MDStringR) {
199 if (MDStringL == MDStringR)
201 return MDStringL->getString().compare(MDStringR->getString());
219int FunctionComparator::cmpMDNode(
const MDNode *L,
const MDNode *R)
const {
232 if (
int Res =
cmpNumbers(
L->getNumOperands(),
R->getNumOperands()))
234 for (
size_t I = 0;
I <
L->getNumOperands(); ++
I)
235 if (
int Res = cmpMetadata(
L->getOperand(
I),
R->getOperand(
I)))
240int FunctionComparator::cmpInstMetadata(
Instruction const *L,
246 L->getAllMetadataOtherThanDebugLoc(MDL);
247 R->getAllMetadataOtherThanDebugLoc(MDR);
252 for (
size_t I = 0,
N = MDL.
size();
I <
N; ++
I) {
253 auto const [KeyL,
ML] = MDL[
I];
254 auto const [KeyR, MR] = MDR[
I];
257 if (
int Res = cmpMDNode(
ML, MR))
263int FunctionComparator::cmpOperandBundlesSchema(
const CallBase &LCS,
275 if (
int Res = OBL.getTagName().compare(OBR.getTagName()))
278 if (
int Res =
cmpNumbers(OBL.Inputs.size(), OBR.Inputs.size()))
292 Type *TyL = L->getType();
293 Type *TyR = R->getType();
316 unsigned TyLWidth = 0;
317 unsigned TyRWidth = 0;
320 TyLWidth = VecTyL->getPrimitiveSizeInBits().getFixedValue();
322 TyRWidth = VecTyR->getPrimitiveSizeInBits().getFixedValue();
324 if (TyLWidth != TyRWidth)
334 if (
int Res =
cmpNumbers(AddrSpaceL, AddrSpaceR))
350 if (L->isNullValue() && R->isNullValue())
352 if (L->isNullValue() && !R->isNullValue())
354 if (!L->isNullValue() && R->isNullValue())
359 if (GlobalValueL && GlobalValueR) {
363 if (
int Res =
cmpNumbers(L->getValueID(), R->getValueID()))
373 return cmpMem(SeqL->getRawDataValues(), SeqR->getRawDataValues());
376 switch (L->getValueID()) {
377 case Value::UndefValueVal:
378 case Value::PoisonValueVal:
379 case Value::ConstantTokenNoneVal:
381 case Value::ConstantIntVal: {
386 case Value::ConstantFPVal: {
391 case Value::ConstantArrayVal: {
396 if (
int Res =
cmpNumbers(NumElementsL, NumElementsR))
398 for (
uint64_t i = 0; i < NumElementsL; ++i) {
405 case Value::ConstantStructVal: {
410 if (
int Res =
cmpNumbers(NumElementsL, NumElementsR))
412 for (
unsigned i = 0; i != NumElementsL; ++i) {
419 case Value::ConstantVectorVal: {
424 if (
int Res =
cmpNumbers(NumElementsL, NumElementsR))
426 for (
uint64_t i = 0; i < NumElementsL; ++i) {
433 case Value::ConstantExprVal: {
438 unsigned NumOperandsL = LE->getNumOperands();
440 if (
int Res =
cmpNumbers(NumOperandsL, NumOperandsR))
442 for (
unsigned i = 0; i < NumOperandsL; ++i) {
449 if (
int Res =
cmpTypes(GEPL->getSourceElementType(),
450 GEPR->getSourceElementType()))
452 if (
int Res =
cmpNumbers(GEPL->getNoWrapFlags().getRaw(),
453 GEPR->getNoWrapFlags().getRaw()))
456 std::optional<ConstantRange> InRangeL = GEPL->getInRange();
457 std::optional<ConstantRange> InRangeR = GEPR->getInRange();
463 }
else if (InRangeR) {
478 case Value::BlockAddressVal: {
512 case Value::DSOLocalEquivalentVal: {
519 return cmpGlobalValues(LEquiv->getGlobalValue(), REquiv->getGlobalValue());
521 case Value::ConstantPtrAuthVal: {
536 LLVM_DEBUG(
dbgs() <<
"Looking at valueID " << L->getValueID() <<
"\n");
543 uint64_t LNumber = GlobalNumbers->getNumber(L);
544 uint64_t RNumber = GlobalNumbers->getNumber(R);
557 TyL =
DL.getIntPtrType(TyL);
559 TyR =
DL.getIntPtrType(TyR);
586 assert(PTyL && PTyR &&
"Both types must be pointers here.");
617 for (
unsigned i = 0, e = FTyL->
getNumParams(); i != e; ++i) {
627 if (STyL->getNumElements() != STyR->getNumElements())
628 return cmpNumbers(STyL->getNumElements(), STyR->getNumElements());
629 return cmpTypes(STyL->getElementType(), STyR->getElementType());
635 if (STyL->getElementCount().isScalable() !=
636 STyR->getElementCount().isScalable())
637 return cmpNumbers(STyL->getElementCount().isScalable(),
638 STyR->getElementCount().isScalable());
639 if (STyL->getElementCount() != STyR->getElementCount())
640 return cmpNumbers(STyL->getElementCount().getKnownMinValue(),
641 STyR->getElementCount().getKnownMinValue());
642 return cmpTypes(STyL->getElementType(), STyR->getElementType());
653 bool &needToCmpOperands)
const {
654 needToCmpOperands =
true;
662 if (
int Res =
cmpNumbers(L->getOpcode(), R->getOpcode()))
666 needToCmpOperands =
false;
671 return cmpGEPs(GEPL, GEPR);
674 if (
int Res =
cmpNumbers(L->getNumOperands(), R->getNumOperands()))
677 if (
int Res =
cmpTypes(L->getType(), R->getType()))
680 if (
int Res =
cmpNumbers(L->getRawSubclassOptionalData(),
681 R->getRawSubclassOptionalData()))
686 for (
unsigned i = 0, e = L->getNumOperands(); i != e; ++i) {
688 cmpTypes(L->getOperand(i)->getType(), R->getOperand(i)->getType()))
694 if (
int Res =
cmpTypes(AI->getAllocatedType(),
705 cmpOrderings(LI->getOrdering(),
cast<LoadInst>(R)->getOrdering()))
707 if (
int Res =
cmpNumbers(LI->getSyncScopeID(),
710 return cmpInstMetadata(L, R);
728 if (
int Res =
cmpNumbers(CBL->getCallingConv(), CBR->getCallingConv()))
730 if (
int Res = cmpAttrs(CBL->getAttributes(), CBR->getAttributes()))
732 if (
int Res = cmpOperandBundlesSchema(*CBL, *CBR))
735 if (
int Res =
cmpNumbers(CI->getTailCallKind(),
738 return cmpMDNode(L->getMetadata(LLVMContext::MD_range),
739 R->getMetadata(LLVMContext::MD_range));
743 if (
int Res =
cmpConstants(LCase.getCaseValue(), RCase.getCaseValue()))
752 for (
size_t i = 0, e = LIndices.
size(); i != e; ++i) {
753 if (
int Res =
cmpNumbers(LIndices[i], RIndices[i]))
763 for (
size_t i = 0, e = LIndices.
size(); i != e; ++i) {
764 if (
int Res =
cmpNumbers(LIndices[i], RIndices[i]))
783 cmpOrderings(CXI->getSuccessOrdering(),
787 cmpOrderings(CXI->getFailureOrdering(),
794 if (
int Res =
cmpNumbers(RMWI->getOperation(),
800 if (
int Res = cmpOrderings(RMWI->getOrdering(),
811 for (
size_t i = 0, e = LMask.
size(); i != e; ++i) {
821 for (
unsigned i = 0, e = PNL->getNumIncomingValues(); i != e; ++i) {
832int FunctionComparator::cmpGEPs(
const GEPOperator *GEPL,
843 unsigned OffsetBitWidth =
DL.getIndexSizeInBits(ASL);
844 APInt OffsetL(OffsetBitWidth, 0), OffsetR(OffsetBitWidth, 0);
863int FunctionComparator::cmpInlineAsm(
const InlineAsm *L,
869 if (
int Res =
cmpTypes(
L->getFunctionType(),
R->getFunctionType()))
871 if (
int Res =
cmpMem(
L->getAsmString(),
R->getAsmString()))
873 if (
int Res =
cmpMem(
L->getConstraintString(),
R->getConstraintString()))
875 if (
int Res =
cmpNumbers(
L->hasSideEffects(),
R->hasSideEffects()))
877 if (
int Res =
cmpNumbers(
L->isAlignStack(),
R->isAlignStack()))
879 if (
int Res =
cmpNumbers(
L->getDialect(),
R->getDialect()))
881 assert(
L->getFunctionType() !=
R->getFunctionType());
904 if (ConstL && ConstR) {
917 if (MetadataValueL && MetadataValueR) {
918 if (MetadataValueL == MetadataValueR)
933 if (InlineAsmL && InlineAsmR)
934 return cmpInlineAsm(InlineAsmL, InlineAsmR);
940 auto LeftSN = sn_mapL.insert(std::make_pair(L, sn_mapL.size())),
941 RightSN = sn_mapR.insert(std::make_pair(R, sn_mapR.size()));
943 return cmpNumbers(LeftSN.first->second, RightSN.first->second);
953 bool needToCmpOperands =
true;
954 if (
int Res =
cmpOperations(&*InstL, &*InstR, needToCmpOperands))
956 if (needToCmpOperands) {
957 assert(InstL->getNumOperands() == InstR->getNumOperands());
959 for (
unsigned i = 0, e = InstL->getNumOperands(); i != e; ++i) {
960 Value *OpL = InstL->getOperand(i);
961 Value *OpR = InstR->getOperand(i);
971 }
while (InstL != InstLE && InstR != InstRE);
973 if (InstL != InstLE && InstR == InstRE)
975 if (InstL == InstLE && InstR != InstRE)
981 if (
int Res = cmpAttrs(
FnL->getAttributes(),
FnR->getAttributes()))
995 if (
FnL->hasSection()) {
996 if (
int Res =
cmpMem(
FnL->getSection(),
FnR->getSection()))
1008 if (
int Res =
cmpTypes(
FnL->getFunctionType(),
FnR->getFunctionType()))
1012 "Identically typed functions have different numbers of args!");
1017 ArgRI =
FnR->arg_begin(),
1018 ArgLE =
FnL->arg_end();
1019 ArgLI != ArgLE; ++ArgLI, ++ArgRI) {
1043 VisitedBBs.
insert(FnLBBs[0]);
1044 while (!FnLBBs.
empty()) {
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
This file declares a class to represent arbitrary precision floating point values and provide a varie...
This file implements a class to represent arbitrary precision integral constant values and operations...
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
This file contains the simple types necessary to represent the attributes associated with functions a...
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
This file contains the declarations for the subclasses of Constant, which represent the different fla...
Module.h This file contains the declarations for the Module class.
SI optimize exec mask operations pre RA
This file defines the SmallPtrSet class.
This file defines the SmallVector class.
static unsigned getBitWidth(Type *Ty, const DataLayout &DL)
Returns the bitwidth of the given scalar or pointer type.
static LLVM_ABI ExponentType semanticsMinExponent(const fltSemantics &)
static LLVM_ABI unsigned int semanticsSizeInBits(const fltSemantics &)
static LLVM_ABI ExponentType semanticsMaxExponent(const fltSemantics &)
static LLVM_ABI unsigned int semanticsPrecision(const fltSemantics &)
Class for arbitrary precision integers.
an instruction to allocate memory on the stack
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
size_t size() const
size - Get the array size.
An instruction that atomically checks whether a specified value is in a memory location,...
an instruction that atomically reads a memory location, combines it with another value,...
This class holds the attributes for a particular argument, parameter, function, or return value.
const Attribute * iterator
LLVM_ABI iterator begin() const
LLVM_ABI iterator end() const
Functions, function parameters, and return types can have attributes to indicate how they should be t...
LLVM_ABI const ConstantRange & getRange() const
Returns the value of the range attribute.
LLVM_ABI bool isConstantRangeAttribute() const
Return true if the attribute is a ConstantRange attribute.
LLVM_ABI Attribute::AttrKind getKindAsEnum() const
Return the attribute's kind as an enum (Attribute::AttrKind).
LLVM_ABI ArrayRef< ConstantRange > getValueAsConstantRangeList() const
Return the attribute's value as a ConstantRange array.
LLVM_ABI bool isTypeAttribute() const
Return true if the attribute is a type attribute.
LLVM_ABI bool isConstantRangeListAttribute() const
Return true if the attribute is a ConstantRangeList attribute.
LLVM_ABI Type * getValueAsType() const
Return the attribute's value as a Type.
LLVM Basic Block Representation.
iterator begin()
Instruction iterator methods.
InstListType::const_iterator const_iterator
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...
The address of a basic block.
Function * getFunction() const
BasicBlock * getBasicBlock() const
Base class for all callable instructions (InvokeInst and CallInst) Holds everything related to callin...
OperandBundleUse getOperandBundleAt(unsigned Index) const
Return the operand bundle at a specific index.
unsigned getNumOperandBundles() const
Return the number of operand bundles associated with this User.
This class represents a function call, abstracting a target machine's calling convention.
This class is the base class for the comparison instructions.
ConstantArray - Constant Array Declarations.
A constant value that is initialized with an expression using other constant values.
unsigned getOpcode() const
Return the opcode at the root of this constant expression.
A signed pointer, in the ptrauth sense.
Constant * getAddrDiscriminator() const
The address discriminator if any, or the null constant.
Constant * getPointer() const
The pointer that is signed in this ptrauth signed pointer.
ConstantInt * getKey() const
The Key ID, an i32 constant.
ConstantInt * getDiscriminator() const
The integer discriminator, an i64 constant, or 0.
This class represents a range of values.
Constant Vector Declarations.
This is an important base class in LLVM.
A parsed version of the target data layout string in and methods for querying it.
An instruction for ordering other memory operations.
LLVM_ABI int cmpBasicBlocks(const BasicBlock *BBL, const BasicBlock *BBR) const
Test whether two basic blocks have equivalent behaviour.
LLVM_ABI int cmpConstantRanges(const ConstantRange &L, const ConstantRange &R) const
LLVM_ABI int compareSignature() const
Compares the signature and other general attributes of the two functions.
LLVM_ABI int cmpMem(StringRef L, StringRef R) const
LLVM_ABI int compare()
Test whether the two functions have equivalent behaviour.
LLVM_ABI int cmpAPFloats(const APFloat &L, const APFloat &R) const
LLVM_ABI int cmpTypes(Type *TyL, Type *TyR) const
cmpType - compares two types, defines total ordering among the types set.
LLVM_ABI int cmpOperations(const Instruction *L, const Instruction *R, bool &needToCmpOperands) const
Compare two Instructions for equivalence, similar to Instruction::isSameOperationAs.
LLVM_ABI int cmpNumbers(uint64_t L, uint64_t R) const
LLVM_ABI int cmpAligns(Align L, Align R) const
void beginCompare()
Start the comparison.
LLVM_ABI 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 ...
LLVM_ABI int cmpGlobalValues(GlobalValue *L, GlobalValue *R) const
Compares two global values by number.
LLVM_ABI int cmpConstants(const Constant *L, const Constant *R) const
Constants comparison.
LLVM_ABI int cmpAPInts(const APInt &L, const APInt &R) const
Class to represent function types.
unsigned getNumParams() const
Return the number of fixed parameters this function type requires.
Type * getParamType(unsigned i) const
Parameter type accessors.
Type * getReturnType() const
const DataLayout & getDataLayout() const
Get the data layout of the module this function belongs to.
const Argument * const_arg_iterator
LLVM_ABI Type * getSourceElementType() const
LLVM_ABI bool accumulateConstantOffset(const DataLayout &DL, APInt &Offset, function_ref< bool(Value &, APInt &)> ExternalAnalysis=nullptr) const
Accumulate the constant address offset of this GEP if possible.
unsigned getPointerAddressSpace() const
Method to return the address space of the pointer operand.
an instruction for type-safe pointer arithmetic to access elements of arrays and structs
Value * getPointerOperand()
This instruction inserts a struct field of array element value into an aggregate value.
LLVM_ABI unsigned getNumSuccessors() const LLVM_READONLY
Return the number of successors that this instruction has.
LLVM_ABI BasicBlock * getSuccessor(unsigned Idx) const LLVM_READONLY
Return the specified successor. This instruction must be a terminator.
unsigned getOpcode() const
Returns a member of one of the enums like Instruction::Add.
An instruction for reading from memory.
BasicBlock * getIncomingBlock(unsigned i) const
Return incoming basic block number i.
Class to represent pointers.
unsigned getAddressSpace() const
Return the address space of the Pointer type.
This instruction constructs a fixed permutation of two input vectors.
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
An instruction for storing to memory.
StringRef - Represent a constant reference to a string, i.e.
Class to represent struct types.
unsigned getNumElements() const
Random access to the elements.
Type * getElementType(unsigned N) const
The instances of the Type class are immutable: once they are created, they are never changed.
@ VoidTyID
type with no size
@ ScalableVectorTyID
Scalable SIMD vector type.
@ FloatTyID
32-bit floating point type
@ IntegerTyID
Arbitrary bit width integers.
@ FixedVectorTyID
Fixed width SIMD vector type.
@ DoubleTyID
64-bit floating point type
@ X86_FP80TyID
80-bit floating point type (X87)
@ PPC_FP128TyID
128-bit floating point type (two 64-bits, PowerPC)
@ FP128TyID
128-bit floating point type (112-bit significand)
LLVM_ABI bool isFirstClassType() const
Return true if the type is "first class", meaning it is a valid type for a Value.
TypeID getTypeID() const
Return the type id for the type.
Value * getOperand(unsigned i) const
unsigned getNumOperands() const
LLVM Value Representation.
Type * getType() const
All values are typed, get the type of this value.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
This is an optimization pass for GlobalISel generic memory operations.
detail::zippy< detail::zip_shortest, T, U, Args... > zip(T &&t, U &&u, Args &&...args)
zip iterator for two or more iteratable types.
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
AtomicOrdering
Atomic ordering for LLVM's memory model.
ArrayRef(const T &OneElt) -> ArrayRef< T >
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
This struct is a compact representation of a valid (non-zero power of two) alignment.