Go to the documentation of this file.
51 #define DEBUG_TYPE "functioncomparator"
62 if (L.
value() < R.value())
64 if (L.
value() > R.value())
126 for (; LI !=
LE && RI != RE; ++LI, ++RI) {
134 Type *TyR =
RA.getValueAsType();
160 int FunctionComparator::cmpRangeMetadata(
const MDNode *L,
180 ConstantInt *RLow = mdconst::extract<ConstantInt>(
R->getOperand(
I));
187 int FunctionComparator::cmpOperandBundlesSchema(
const CallBase &LCS,
199 if (
int Res = OBL.getTagName().compare(OBR.getTagName()))
202 if (
int Res =
cmpNumbers(OBL.Inputs.size(), OBR.Inputs.size()))
217 Type *TyR = R->getType();
240 unsigned TyLWidth = 0;
241 unsigned TyRWidth = 0;
243 if (
auto *VecTyL = dyn_cast<VectorType>(TyL))
244 TyLWidth = VecTyL->getPrimitiveSizeInBits().getFixedSize();
245 if (
auto *VecTyR = dyn_cast<VectorType>(TyR))
246 TyRWidth = VecTyR->getPrimitiveSizeInBits().getFixedSize();
248 if (TyLWidth != TyRWidth)
258 if (
int Res =
cmpNumbers(AddrSpaceL, AddrSpaceR))
281 auto GlobalValueL =
const_cast<GlobalValue *
>(dyn_cast<GlobalValue>(L));
282 auto GlobalValueR =
const_cast<GlobalValue *
>(dyn_cast<GlobalValue>(R));
283 if (GlobalValueL && GlobalValueR) {
290 if (
const auto *SeqL = dyn_cast<ConstantDataSequential>(L)) {
291 const auto *SeqR = cast<ConstantDataSequential>(R);
297 return cmpMem(SeqL->getRawDataValues(), SeqR->getRawDataValues());
301 case Value::UndefValueVal:
302 case Value::PoisonValueVal:
303 case Value::ConstantTokenNoneVal:
305 case Value::ConstantIntVal: {
306 const APInt &LInt = cast<ConstantInt>(L)->getValue();
307 const APInt &RInt = cast<ConstantInt>(R)->getValue();
310 case Value::ConstantFPVal: {
311 const APFloat &LAPF = cast<ConstantFP>(L)->getValueAPF();
312 const APFloat &RAPF = cast<ConstantFP>(R)->getValueAPF();
315 case Value::ConstantArrayVal: {
318 uint64_t NumElementsL = cast<ArrayType>(TyL)->getNumElements();
319 uint64_t NumElementsR = cast<ArrayType>(TyR)->getNumElements();
320 if (
int Res =
cmpNumbers(NumElementsL, NumElementsR))
324 cast<Constant>(
RA->getOperand(
i))))
329 case Value::ConstantStructVal: {
332 unsigned NumElementsL = cast<StructType>(TyL)->getNumElements();
333 unsigned NumElementsR = cast<StructType>(TyR)->getNumElements();
334 if (
int Res =
cmpNumbers(NumElementsL, NumElementsR))
336 for (
unsigned i = 0;
i != NumElementsL; ++
i) {
343 case Value::ConstantVectorVal: {
346 unsigned NumElementsL = cast<FixedVectorType>(TyL)->getNumElements();
347 unsigned NumElementsR = cast<FixedVectorType>(TyR)->getNumElements();
348 if (
int Res =
cmpNumbers(NumElementsL, NumElementsR))
357 case Value::ConstantExprVal: {
360 unsigned NumOperandsL =
LE->getNumOperands();
362 if (
int Res =
cmpNumbers(NumOperandsL, NumOperandsR))
364 for (
unsigned i = 0;
i < NumOperandsL; ++
i) {
371 case Value::BlockAddressVal: {
427 TyL =
DL.getIntPtrType(TyL);
429 TyR =
DL.getIntPtrType(TyR);
456 assert(PTyL && PTyR &&
"Both types must be pointers here.");
495 auto *STyL = cast<ArrayType>(TyL);
496 auto *STyR = cast<ArrayType>(TyR);
497 if (STyL->getNumElements() != STyR->getNumElements())
498 return cmpNumbers(STyL->getNumElements(), STyR->getNumElements());
499 return cmpTypes(STyL->getElementType(), STyR->getElementType());
503 auto *STyL = cast<VectorType>(TyL);
504 auto *STyR = cast<VectorType>(TyR);
505 if (STyL->getElementCount().isScalable() !=
506 STyR->getElementCount().isScalable())
507 return cmpNumbers(STyL->getElementCount().isScalable(),
508 STyR->getElementCount().isScalable());
509 if (STyL->getElementCount() != STyR->getElementCount())
510 return cmpNumbers(STyL->getElementCount().getKnownMinValue(),
511 STyR->getElementCount().getKnownMinValue());
512 return cmpTypes(STyL->getElementType(), STyR->getElementType());
523 bool &needToCmpOperands)
const {
524 needToCmpOperands =
true;
536 needToCmpOperands =
false;
541 return cmpGEPs(GEPL, GEPR);
551 R->getRawSubclassOptionalData()))
563 if (
const AllocaInst *AI = dyn_cast<AllocaInst>(L)) {
564 if (
int Res =
cmpTypes(AI->getAllocatedType(),
565 cast<AllocaInst>(R)->getAllocatedType()))
567 return cmpAligns(AI->getAlign(), cast<AllocaInst>(R)->getAlign());
569 if (
const LoadInst *LI = dyn_cast<LoadInst>(L)) {
570 if (
int Res =
cmpNumbers(LI->isVolatile(), cast<LoadInst>(R)->isVolatile()))
572 if (
int Res =
cmpAligns(LI->getAlign(), cast<LoadInst>(R)->getAlign()))
575 cmpOrderings(LI->getOrdering(), cast<LoadInst>(R)->getOrdering()))
577 if (
int Res =
cmpNumbers(LI->getSyncScopeID(),
578 cast<LoadInst>(R)->getSyncScopeID()))
580 return cmpRangeMetadata(
581 LI->getMetadata(LLVMContext::MD_range),
582 cast<LoadInst>(R)->getMetadata(LLVMContext::MD_range));
584 if (
const StoreInst *
SI = dyn_cast<StoreInst>(L)) {
586 cmpNumbers(
SI->isVolatile(), cast<StoreInst>(R)->isVolatile()))
588 if (
int Res =
cmpAligns(
SI->getAlign(), cast<StoreInst>(R)->getAlign()))
591 cmpOrderings(
SI->getOrdering(), cast<StoreInst>(R)->getOrdering()))
594 cast<StoreInst>(R)->getSyncScopeID());
596 if (
const CmpInst *CI = dyn_cast<CmpInst>(L))
597 return cmpNumbers(CI->getPredicate(), cast<CmpInst>(R)->getPredicate());
598 if (
auto *CBL = dyn_cast<CallBase>(L)) {
599 auto *CBR = cast<CallBase>(R);
600 if (
int Res =
cmpNumbers(CBL->getCallingConv(), CBR->getCallingConv()))
602 if (
int Res = cmpAttrs(CBL->getAttributes(), CBR->getAttributes()))
604 if (
int Res = cmpOperandBundlesSchema(*CBL, *CBR))
606 if (
const CallInst *CI = dyn_cast<CallInst>(L))
607 if (
int Res =
cmpNumbers(CI->getTailCallKind(),
608 cast<CallInst>(R)->getTailCallKind()))
610 return cmpRangeMetadata(L->
getMetadata(LLVMContext::MD_range),
611 R->getMetadata(LLVMContext::MD_range));
618 for (
size_t i = 0,
e = LIndices.
size();
i !=
e; ++
i) {
629 for (
size_t i = 0,
e = LIndices.
size();
i !=
e; ++
i) {
634 if (
const FenceInst *FI = dyn_cast<FenceInst>(L)) {
636 cmpOrderings(FI->getOrdering(), cast<FenceInst>(R)->getOrdering()))
639 cast<FenceInst>(R)->getSyncScopeID());
643 cast<AtomicCmpXchgInst>(R)->isVolatile()))
646 cmpNumbers(CXI->isWeak(), cast<AtomicCmpXchgInst>(R)->isWeak()))
649 cmpOrderings(CXI->getSuccessOrdering(),
650 cast<AtomicCmpXchgInst>(R)->getSuccessOrdering()))
653 cmpOrderings(CXI->getFailureOrdering(),
654 cast<AtomicCmpXchgInst>(R)->getFailureOrdering()))
657 cast<AtomicCmpXchgInst>(R)->getSyncScopeID());
659 if (
const AtomicRMWInst *RMWI = dyn_cast<AtomicRMWInst>(L)) {
660 if (
int Res =
cmpNumbers(RMWI->getOperation(),
661 cast<AtomicRMWInst>(R)->getOperation()))
664 cast<AtomicRMWInst>(R)->isVolatile()))
666 if (
int Res = cmpOrderings(RMWI->getOrdering(),
667 cast<AtomicRMWInst>(R)->getOrdering()))
670 cast<AtomicRMWInst>(R)->getSyncScopeID());
674 ArrayRef<int> RMask = cast<ShuffleVectorInst>(R)->getShuffleMask();
677 for (
size_t i = 0,
e = LMask.
size();
i !=
e; ++
i) {
682 if (
const PHINode *PNL = dyn_cast<PHINode>(L)) {
683 const PHINode *PNR = cast<PHINode>(R);
687 for (
unsigned i = 0,
e = PNL->getNumIncomingValues();
i !=
e; ++
i) {
698 int FunctionComparator::cmpGEPs(
const GEPOperator *GEPL,
709 unsigned BitWidth =
DL.getPointerSizeInBits(ASL);
729 int FunctionComparator::cmpInlineAsm(
const InlineAsm *L,
768 const Constant *ConstL = dyn_cast<Constant>(L);
769 const Constant *ConstR = dyn_cast<Constant>(R);
770 if (ConstL && ConstR) {
781 const InlineAsm *InlineAsmL = dyn_cast<InlineAsm>(L);
782 const InlineAsm *InlineAsmR = dyn_cast<InlineAsm>(R);
784 if (InlineAsmL && InlineAsmR)
785 return cmpInlineAsm(InlineAsmL, InlineAsmR);
791 auto LeftSN = sn_mapL.insert(std::make_pair(L, sn_mapL.size())),
792 RightSN = sn_mapR.insert(std::make_pair(R, sn_mapR.size()));
794 return cmpNumbers(LeftSN.first->second, RightSN.first->second);
804 bool needToCmpOperands =
true;
805 if (
int Res =
cmpOperations(&*InstL, &*InstR, needToCmpOperands))
807 if (needToCmpOperands) {
808 assert(InstL->getNumOperands() == InstR->getNumOperands());
810 for (
unsigned i = 0,
e = InstL->getNumOperands();
i !=
e; ++
i) {
811 Value *OpL = InstL->getOperand(
i);
812 Value *OpR = InstR->getOperand(
i);
822 }
while (InstL != InstLE && InstR != InstRE);
824 if (InstL != InstLE && InstR == InstRE)
826 if (InstL == InstLE && InstR != InstRE)
863 "Identically typed functions have different numbers of args!");
870 ArgLI != ArgLE; ++ArgLI, ++ArgRI) {
894 VisitedBBs.
insert(FnLBBs[0]);
895 while (!FnLBBs.empty()) {
929 class HashAccumulator64 {
934 HashAccumulator64() { Hash = 0x6acaa36bef8325c5ULL; }
964 BBs.push_back(&
F.getEntryBlock());
965 VisitedBBs.
insert(BBs[0]);
966 while (!BBs.empty()) {
971 for (
auto &Inst : *
BB) {
972 H.add(Inst.getOpcode());
975 for (
unsigned i = 0,
e =
Term->getNumSuccessors();
i !=
e; ++
i) {
976 if (!VisitedBBs.
insert(
Term->getSuccessor(
i)).second)
978 BBs.push_back(
Term->getSuccessor(
i));
unsigned getNumOperandBundles() const
Return the number of operand bundles associated with this User.
This class represents an incoming formal argument to a Function.
@ FloatTyID
32-bit floating point type
static unsigned int semanticsSizeInBits(const fltSemantics &)
@ DoubleTyID
64-bit floating point type
This is an optimization pass for GlobalISel generic memory operations.
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 ...
A parsed version of the target data layout string in and methods for querying it.
int cmpBasicBlocks(const BasicBlock *BBL, const BasicBlock *BBR) const
Test whether two basic blocks have equivalent behaviour.
const std::string & getAsmString() const
@ VoidTyID
type with no size
bool isAlignStack() const
StringRef getSection() const
Get the custom section of this global if it has one.
bool isTypeAttribute() const
Return true if the attribute is a type attribute.
const APInt & getValue() const
Return the constant as an APInt value reference.
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
int compareSignature() const
Compares the signature and other general attributes of the two functions.
const BasicBlock & getEntryBlock() const
unsigned getAddressSpace() const
Return the address space of the Pointer type.
BasicBlock * getBasicBlock() const
TypeID getTypeID() const
Return the type id for the type.
The instances of the Type class are immutable: once they are created, they are never changed.
unsigned getBitWidth() const
Return the number of bits in the APInt.
void beginCompare()
Start the comparison.
bool ugt(const APInt &RHS) const
Unsigned greater than comparison.
An instruction for ordering other memory operations.
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
FunctionType * getFunctionType() const
getFunctionType - InlineAsm's are always pointers to functions.
static unsigned getBitWidth(Type *Ty, const DataLayout &DL)
Returns the bitwidth of the given scalar or pointer type.
unsigned getNumParams() const
Return the number of fixed parameters this function type requires.
LLVM_NODISCARD T pop_back_val()
const fltSemantics & getSemantics() const
int cmpConstants(const Constant *L, const Constant *R) const
Constants comparison.
LLVM Basic Block Representation.
unsigned getNumOperands() const
Return number of MDNode operands.
static FunctionHash functionHash(Function &)
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
This is the shared class of boolean and integer constants.
unsigned getNumSuccessors() const
Return the number of successors that this instruction has.
unsigned getOpcode() const
Returns a member of one of the enums like Instruction::Add.
bool isNullValue() const
Return true if this is the value that would be returned by getNullValue.
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
int cmpMem(StringRef L, StringRef R) const
bool hasSideEffects() const
iterator begin()
Instruction iterator methods.
unsigned getValueID() const
Return an ID for the concrete type of this object.
ConstantArray - Constant Array Declarations.
AttributeSet getAttributes(unsigned Index) const
The attributes for the specified index are returned.
int cmpAPInts(const APInt &L, const APInt &R) const
BasicBlock * getSuccessor(unsigned Idx) const
Return the specified successor. This instruction must be a terminator.
uint64_t hash_16_bytes(uint64_t low, uint64_t high)
APInt bitcastToAPInt() const
AsmDialect getDialect() const
This struct is a compact representation of a valid (non-zero power of two) alignment.
MDNode * getMetadata(unsigned KindID) const
Get the metadata of given kind attached to this Instruction.
AttributeList getAttributes() const
Return the attribute list for this Function.
This class is the base class for the comparison instructions.
const std::string & getGC() const
const MDOperand & getOperand(unsigned I) const
AtomicOrdering
Atomic ordering for LLVM's memory model.
bool hasSection() const
Check if this global has a custom object file section.
int compare()
Test whether the two functions have equivalent behaviour.
An instruction for storing to memory.
This is an important base class in LLVM.
CallingConv::ID getCallingConv() const
getCallingConv()/setCallingConv(CC) - These method get and set the calling convention of this functio...
Module * getParent()
Get the module that this global value is contained inside of...
bool hasGC() const
hasGC/getGC/setGC/clearGC - The name of the garbage collection algorithm to use during code generatio...
Attribute::AttrKind getKindAsEnum() const
Return the attribute's kind as an enum (Attribute::AttrKind).
int cmpAligns(Align L, Align R) const
Type * getParamType(unsigned i) const
Parameter type accessors.
an instruction for type-safe pointer arithmetic to access elements of arrays and structs
Class to represent pointers.
Constant Vector Declarations.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
StandardInstrumentations SI(Debug, VerifyEach)
int cmpAPFloats(const APFloat &L, const APFloat &R) const
SI optimize exec mask operations pre RA
Class for arbitrary precision integers.
@ FP128TyID
128-bit floating point type (112-bit significand)
const std::string & getConstraintString() const
uint64_t getNumber(GlobalValue *Global)
The address of a basic block.
Class to represent struct types.
@ PPC_FP128TyID
128-bit floating point type (two 64-bits, PowerPC)
StringRef - Represent a constant reference to a string, i.e.
OperandBundleUse getOperandBundleAt(unsigned Index) const
Return the operand bundle at a specific index.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Type * getType() const
All values are typed, get the type of this value.
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
int cmpOperations(const Instruction *L, const Instruction *R, bool &needToCmpOperands) const
Compare two Instructions for equivalence, similar to Instruction::isSameOperationAs.
unsigned getRawSubclassOptionalData() const
Return the raw optional flags value contained in this value.
An instruction for reading from memory.
unsigned getNumElements() const
Random access to the elements.
an instruction that atomically reads a memory location, combines it with another value,...
@ IntegerTyID
Arbitrary bit width integers.
unsigned getPointerAddressSpace() const
Method to return the address space of the pointer operand.
constexpr LLVM_NODISCARD size_t size() const
size - Get the string size.
Function * getFunction() const
A constant value that is initialized with an expression using other constant values.
int cmpTypes(Type *TyL, Type *TyR) const
cmpType - compares two types, defines total ordering among the types set.
uint64_t value() const
This is a hole in the type system and should not be abused.
@ FixedVectorTyID
Fixed width SIMD vector type.
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.
Type * getValueAsType() const
Return the attribute's value as a Type.
constexpr unsigned BitWidth
unsigned getNumAttrSets() const
FunctionType * getFunctionType() const
Returns the FunctionType for me.
bool isVarArg() const
isVarArg - Return true if this function takes a variable number of arguments.
This instruction constructs a fixed permutation of two input vectors.
Type * getSourceElementType() const
unsigned getNumOperands() const
int cmpNumbers(uint64_t L, uint64_t R) const
static unsigned int semanticsPrecision(const fltSemantics &)
BasicBlock * getIncomingBlock(unsigned i) const
Return incoming basic block number i.
size_t size() const
size - Get the array size.
index_iterator indexes() const
Use this to iterate over the valid attribute indexes.
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...
Type * getElementType(unsigned N) const
Base class for all callable instructions (InvokeInst and CallInst) Holds everything related to callin...
@ ScalableVectorTyID
Scalable SIMD vector type.
const DataLayout & getDataLayout() const
Get the data layout for the module's target platform.
This class represents a function call, abstracting a target machine's calling convention.
Common register allocation spilling lr str ldr sxth r3 ldr mla r4 can lr mov lr str ldr sxth r3 mla r4 and then merge mul and lr str ldr sxth r3 mla r4 It also increase the likelihood the store may become dead bb27 Successors according to LLVM BB
an instruction to allocate memory on the stack
Value * getOperand(unsigned i) const
This instruction inserts a struct field of array element value into an aggregate value.
Value * getPointerOperand()
Type * getReturnType() const
LLVM Value Representation.
An instruction that atomically checks whether a specified value is in a memory location,...
int cmpGlobalValues(GlobalValue *L, GlobalValue *R) const
Compares two global values by number.
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...
@ X86_FP80TyID
80-bit floating point type (X87)
static ExponentType semanticsMaxExponent(const fltSemantics &)
InstListType::const_iterator const_iterator
bool isFirstClassType() const
Return true if the type is "first class", meaning it is a valid type for a Value.
Class to represent function types.
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
static ExponentType semanticsMinExponent(const fltSemantics &)