10b57cec5SDimitry Andric //===- FunctionComparator.h - Function Comparator -------------------------===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric //
90b57cec5SDimitry Andric // This file implements the FunctionComparator and GlobalNumberState classes
100b57cec5SDimitry Andric // which are used by the MergeFunctions pass for comparing functions.
110b57cec5SDimitry Andric //
120b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
130b57cec5SDimitry Andric
140b57cec5SDimitry Andric #include "llvm/Transforms/Utils/FunctionComparator.h"
150b57cec5SDimitry Andric #include "llvm/ADT/APFloat.h"
160b57cec5SDimitry Andric #include "llvm/ADT/APInt.h"
170b57cec5SDimitry Andric #include "llvm/ADT/ArrayRef.h"
180b57cec5SDimitry Andric #include "llvm/ADT/Hashing.h"
190b57cec5SDimitry Andric #include "llvm/ADT/SmallPtrSet.h"
200b57cec5SDimitry Andric #include "llvm/ADT/SmallVector.h"
210b57cec5SDimitry Andric #include "llvm/IR/Attributes.h"
220b57cec5SDimitry Andric #include "llvm/IR/BasicBlock.h"
230b57cec5SDimitry Andric #include "llvm/IR/Constant.h"
240b57cec5SDimitry Andric #include "llvm/IR/Constants.h"
250b57cec5SDimitry Andric #include "llvm/IR/DataLayout.h"
260b57cec5SDimitry Andric #include "llvm/IR/DerivedTypes.h"
270b57cec5SDimitry Andric #include "llvm/IR/Function.h"
280b57cec5SDimitry Andric #include "llvm/IR/GlobalValue.h"
290b57cec5SDimitry Andric #include "llvm/IR/InlineAsm.h"
300b57cec5SDimitry Andric #include "llvm/IR/InstrTypes.h"
310b57cec5SDimitry Andric #include "llvm/IR/Instruction.h"
320b57cec5SDimitry Andric #include "llvm/IR/Instructions.h"
330b57cec5SDimitry Andric #include "llvm/IR/LLVMContext.h"
340b57cec5SDimitry Andric #include "llvm/IR/Metadata.h"
350b57cec5SDimitry Andric #include "llvm/IR/Module.h"
360b57cec5SDimitry Andric #include "llvm/IR/Operator.h"
370b57cec5SDimitry Andric #include "llvm/IR/Type.h"
380b57cec5SDimitry Andric #include "llvm/IR/Value.h"
390b57cec5SDimitry Andric #include "llvm/Support/Casting.h"
400b57cec5SDimitry Andric #include "llvm/Support/Compiler.h"
410b57cec5SDimitry Andric #include "llvm/Support/Debug.h"
420b57cec5SDimitry Andric #include "llvm/Support/ErrorHandling.h"
430b57cec5SDimitry Andric #include "llvm/Support/raw_ostream.h"
440b57cec5SDimitry Andric #include <cassert>
450b57cec5SDimitry Andric #include <cstddef>
460b57cec5SDimitry Andric #include <cstdint>
470b57cec5SDimitry Andric #include <utility>
480b57cec5SDimitry Andric
490b57cec5SDimitry Andric using namespace llvm;
500b57cec5SDimitry Andric
510b57cec5SDimitry Andric #define DEBUG_TYPE "functioncomparator"
520b57cec5SDimitry Andric
cmpNumbers(uint64_t L,uint64_t R) const530b57cec5SDimitry Andric int FunctionComparator::cmpNumbers(uint64_t L, uint64_t R) const {
545ffd83dbSDimitry Andric if (L < R)
555ffd83dbSDimitry Andric return -1;
565ffd83dbSDimitry Andric if (L > R)
575ffd83dbSDimitry Andric return 1;
580b57cec5SDimitry Andric return 0;
590b57cec5SDimitry Andric }
600b57cec5SDimitry Andric
cmpAligns(Align L,Align R) const610eae32dcSDimitry Andric int FunctionComparator::cmpAligns(Align L, Align R) const {
620eae32dcSDimitry Andric if (L.value() < R.value())
630eae32dcSDimitry Andric return -1;
640eae32dcSDimitry Andric if (L.value() > R.value())
650eae32dcSDimitry Andric return 1;
660eae32dcSDimitry Andric return 0;
670eae32dcSDimitry Andric }
680eae32dcSDimitry Andric
cmpOrderings(AtomicOrdering L,AtomicOrdering R) const690b57cec5SDimitry Andric int FunctionComparator::cmpOrderings(AtomicOrdering L, AtomicOrdering R) const {
705ffd83dbSDimitry Andric if ((int)L < (int)R)
715ffd83dbSDimitry Andric return -1;
725ffd83dbSDimitry Andric if ((int)L > (int)R)
735ffd83dbSDimitry Andric return 1;
740b57cec5SDimitry Andric return 0;
750b57cec5SDimitry Andric }
760b57cec5SDimitry Andric
cmpAPInts(const APInt & L,const APInt & R) const770b57cec5SDimitry Andric int FunctionComparator::cmpAPInts(const APInt &L, const APInt &R) const {
780b57cec5SDimitry Andric if (int Res = cmpNumbers(L.getBitWidth(), R.getBitWidth()))
790b57cec5SDimitry Andric return Res;
805ffd83dbSDimitry Andric if (L.ugt(R))
815ffd83dbSDimitry Andric return 1;
825ffd83dbSDimitry Andric if (R.ugt(L))
835ffd83dbSDimitry Andric return -1;
840b57cec5SDimitry Andric return 0;
850b57cec5SDimitry Andric }
860b57cec5SDimitry Andric
cmpAPFloats(const APFloat & L,const APFloat & R) const870b57cec5SDimitry Andric int FunctionComparator::cmpAPFloats(const APFloat &L, const APFloat &R) const {
880b57cec5SDimitry Andric // Floats are ordered first by semantics (i.e. float, double, half, etc.),
890b57cec5SDimitry Andric // then by value interpreted as a bitstring (aka APInt).
900b57cec5SDimitry Andric const fltSemantics &SL = L.getSemantics(), &SR = R.getSemantics();
910b57cec5SDimitry Andric if (int Res = cmpNumbers(APFloat::semanticsPrecision(SL),
920b57cec5SDimitry Andric APFloat::semanticsPrecision(SR)))
930b57cec5SDimitry Andric return Res;
940b57cec5SDimitry Andric if (int Res = cmpNumbers(APFloat::semanticsMaxExponent(SL),
950b57cec5SDimitry Andric APFloat::semanticsMaxExponent(SR)))
960b57cec5SDimitry Andric return Res;
970b57cec5SDimitry Andric if (int Res = cmpNumbers(APFloat::semanticsMinExponent(SL),
980b57cec5SDimitry Andric APFloat::semanticsMinExponent(SR)))
990b57cec5SDimitry Andric return Res;
1000b57cec5SDimitry Andric if (int Res = cmpNumbers(APFloat::semanticsSizeInBits(SL),
1010b57cec5SDimitry Andric APFloat::semanticsSizeInBits(SR)))
1020b57cec5SDimitry Andric return Res;
1030b57cec5SDimitry Andric return cmpAPInts(L.bitcastToAPInt(), R.bitcastToAPInt());
1040b57cec5SDimitry Andric }
1050b57cec5SDimitry Andric
cmpMem(StringRef L,StringRef R) const1060b57cec5SDimitry Andric int FunctionComparator::cmpMem(StringRef L, StringRef R) const {
1070b57cec5SDimitry Andric // Prevent heavy comparison, compare sizes first.
1080b57cec5SDimitry Andric if (int Res = cmpNumbers(L.size(), R.size()))
1090b57cec5SDimitry Andric return Res;
1100b57cec5SDimitry Andric
1110b57cec5SDimitry Andric // Compare strings lexicographically only when it is necessary: only when
1120b57cec5SDimitry Andric // strings are equal in size.
113bdd1243dSDimitry Andric return std::clamp(L.compare(R), -1, 1);
1140b57cec5SDimitry Andric }
1150b57cec5SDimitry Andric
cmpAttrs(const AttributeList L,const AttributeList R) const1160b57cec5SDimitry Andric int FunctionComparator::cmpAttrs(const AttributeList L,
1170b57cec5SDimitry Andric const AttributeList R) const {
1180b57cec5SDimitry Andric if (int Res = cmpNumbers(L.getNumAttrSets(), R.getNumAttrSets()))
1190b57cec5SDimitry Andric return Res;
1200b57cec5SDimitry Andric
121349cc55cSDimitry Andric for (unsigned i : L.indexes()) {
1220b57cec5SDimitry Andric AttributeSet LAS = L.getAttributes(i);
1230b57cec5SDimitry Andric AttributeSet RAS = R.getAttributes(i);
1240b57cec5SDimitry Andric AttributeSet::iterator LI = LAS.begin(), LE = LAS.end();
1250b57cec5SDimitry Andric AttributeSet::iterator RI = RAS.begin(), RE = RAS.end();
1260b57cec5SDimitry Andric for (; LI != LE && RI != RE; ++LI, ++RI) {
1270b57cec5SDimitry Andric Attribute LA = *LI;
1280b57cec5SDimitry Andric Attribute RA = *RI;
1290b57cec5SDimitry Andric if (LA.isTypeAttribute() && RA.isTypeAttribute()) {
1300b57cec5SDimitry Andric if (LA.getKindAsEnum() != RA.getKindAsEnum())
1310b57cec5SDimitry Andric return cmpNumbers(LA.getKindAsEnum(), RA.getKindAsEnum());
1320b57cec5SDimitry Andric
1330b57cec5SDimitry Andric Type *TyL = LA.getValueAsType();
1340b57cec5SDimitry Andric Type *TyR = RA.getValueAsType();
135e8d8bef9SDimitry Andric if (TyL && TyR) {
136e8d8bef9SDimitry Andric if (int Res = cmpTypes(TyL, TyR))
137e8d8bef9SDimitry Andric return Res;
138e8d8bef9SDimitry Andric continue;
139e8d8bef9SDimitry Andric }
1400b57cec5SDimitry Andric
1410b57cec5SDimitry Andric // Two pointers, at least one null, so the comparison result is
1420b57cec5SDimitry Andric // independent of the value of a real pointer.
143e8d8bef9SDimitry Andric if (int Res = cmpNumbers((uint64_t)TyL, (uint64_t)TyR))
144e8d8bef9SDimitry Andric return Res;
145e8d8bef9SDimitry Andric continue;
1460b57cec5SDimitry Andric }
1470b57cec5SDimitry Andric if (LA < RA)
1480b57cec5SDimitry Andric return -1;
1490b57cec5SDimitry Andric if (RA < LA)
1500b57cec5SDimitry Andric return 1;
1510b57cec5SDimitry Andric }
1520b57cec5SDimitry Andric if (LI != LE)
1530b57cec5SDimitry Andric return 1;
1540b57cec5SDimitry Andric if (RI != RE)
1550b57cec5SDimitry Andric return -1;
1560b57cec5SDimitry Andric }
1570b57cec5SDimitry Andric return 0;
1580b57cec5SDimitry Andric }
1590b57cec5SDimitry Andric
cmpMetadata(const Metadata * L,const Metadata * R) const160fe013be4SDimitry Andric int FunctionComparator::cmpMetadata(const Metadata *L,
161fe013be4SDimitry Andric const Metadata *R) const {
162fe013be4SDimitry Andric // TODO: the following routine coerce the metadata contents into constants
163c9157d92SDimitry Andric // or MDStrings before comparison.
164fe013be4SDimitry Andric // It ignores any other cases, so that the metadata nodes are considered
165fe013be4SDimitry Andric // equal even though this is not correct.
166fe013be4SDimitry Andric // We should structurally compare the metadata nodes to be perfect here.
167c9157d92SDimitry Andric
168c9157d92SDimitry Andric auto *MDStringL = dyn_cast<MDString>(L);
169c9157d92SDimitry Andric auto *MDStringR = dyn_cast<MDString>(R);
170c9157d92SDimitry Andric if (MDStringL && MDStringR) {
171c9157d92SDimitry Andric if (MDStringL == MDStringR)
172c9157d92SDimitry Andric return 0;
173c9157d92SDimitry Andric return MDStringL->getString().compare(MDStringR->getString());
174c9157d92SDimitry Andric }
175c9157d92SDimitry Andric if (MDStringR)
176c9157d92SDimitry Andric return -1;
177c9157d92SDimitry Andric if (MDStringL)
178c9157d92SDimitry Andric return 1;
179c9157d92SDimitry Andric
180fe013be4SDimitry Andric auto *CL = dyn_cast<ConstantAsMetadata>(L);
181fe013be4SDimitry Andric auto *CR = dyn_cast<ConstantAsMetadata>(R);
182fe013be4SDimitry Andric if (CL == CR)
183fe013be4SDimitry Andric return 0;
184fe013be4SDimitry Andric if (!CL)
185fe013be4SDimitry Andric return -1;
186fe013be4SDimitry Andric if (!CR)
187fe013be4SDimitry Andric return 1;
188fe013be4SDimitry Andric return cmpConstants(CL->getValue(), CR->getValue());
189fe013be4SDimitry Andric }
190fe013be4SDimitry Andric
cmpMDNode(const MDNode * L,const MDNode * R) const191fe013be4SDimitry Andric int FunctionComparator::cmpMDNode(const MDNode *L, const MDNode *R) const {
1920b57cec5SDimitry Andric if (L == R)
1930b57cec5SDimitry Andric return 0;
1940b57cec5SDimitry Andric if (!L)
1950b57cec5SDimitry Andric return -1;
1960b57cec5SDimitry Andric if (!R)
1970b57cec5SDimitry Andric return 1;
1980b57cec5SDimitry Andric // TODO: Note that as this is metadata, it is possible to drop and/or merge
1990b57cec5SDimitry Andric // this data when considering functions to merge. Thus this comparison would
2000b57cec5SDimitry Andric // return 0 (i.e. equivalent), but merging would become more complicated
2010b57cec5SDimitry Andric // because the ranges would need to be unioned. It is not likely that
2020b57cec5SDimitry Andric // functions differ ONLY in this metadata if they are actually the same
2030b57cec5SDimitry Andric // function semantically.
2040b57cec5SDimitry Andric if (int Res = cmpNumbers(L->getNumOperands(), R->getNumOperands()))
2050b57cec5SDimitry Andric return Res;
206fe013be4SDimitry Andric for (size_t I = 0; I < L->getNumOperands(); ++I)
207fe013be4SDimitry Andric if (int Res = cmpMetadata(L->getOperand(I), R->getOperand(I)))
208fe013be4SDimitry Andric return Res;
209fe013be4SDimitry Andric return 0;
210fe013be4SDimitry Andric }
211fe013be4SDimitry Andric
cmpInstMetadata(Instruction const * L,Instruction const * R) const212fe013be4SDimitry Andric int FunctionComparator::cmpInstMetadata(Instruction const *L,
213fe013be4SDimitry Andric Instruction const *R) const {
214fe013be4SDimitry Andric /// These metadata affects the other optimization passes by making assertions
215fe013be4SDimitry Andric /// or constraints.
216fe013be4SDimitry Andric /// Values that carry different expectations should be considered different.
217fe013be4SDimitry Andric SmallVector<std::pair<unsigned, MDNode *>> MDL, MDR;
218fe013be4SDimitry Andric L->getAllMetadataOtherThanDebugLoc(MDL);
219fe013be4SDimitry Andric R->getAllMetadataOtherThanDebugLoc(MDR);
220fe013be4SDimitry Andric if (MDL.size() > MDR.size())
221fe013be4SDimitry Andric return 1;
222fe013be4SDimitry Andric else if (MDL.size() < MDR.size())
223fe013be4SDimitry Andric return -1;
224fe013be4SDimitry Andric for (size_t I = 0, N = MDL.size(); I < N; ++I) {
225fe013be4SDimitry Andric auto const [KeyL, ML] = MDL[I];
226fe013be4SDimitry Andric auto const [KeyR, MR] = MDR[I];
227fe013be4SDimitry Andric if (int Res = cmpNumbers(KeyL, KeyR))
228fe013be4SDimitry Andric return Res;
229fe013be4SDimitry Andric if (int Res = cmpMDNode(ML, MR))
2300b57cec5SDimitry Andric return Res;
2310b57cec5SDimitry Andric }
2320b57cec5SDimitry Andric return 0;
2330b57cec5SDimitry Andric }
2340b57cec5SDimitry Andric
cmpOperandBundlesSchema(const CallBase & LCS,const CallBase & RCS) const2355ffd83dbSDimitry Andric int FunctionComparator::cmpOperandBundlesSchema(const CallBase &LCS,
2365ffd83dbSDimitry Andric const CallBase &RCS) const {
2375ffd83dbSDimitry Andric assert(LCS.getOpcode() == RCS.getOpcode() && "Can't compare otherwise!");
2380b57cec5SDimitry Andric
2390b57cec5SDimitry Andric if (int Res =
2400b57cec5SDimitry Andric cmpNumbers(LCS.getNumOperandBundles(), RCS.getNumOperandBundles()))
2410b57cec5SDimitry Andric return Res;
2420b57cec5SDimitry Andric
2435ffd83dbSDimitry Andric for (unsigned I = 0, E = LCS.getNumOperandBundles(); I != E; ++I) {
2445ffd83dbSDimitry Andric auto OBL = LCS.getOperandBundleAt(I);
2455ffd83dbSDimitry Andric auto OBR = RCS.getOperandBundleAt(I);
2460b57cec5SDimitry Andric
2470b57cec5SDimitry Andric if (int Res = OBL.getTagName().compare(OBR.getTagName()))
2480b57cec5SDimitry Andric return Res;
2490b57cec5SDimitry Andric
2500b57cec5SDimitry Andric if (int Res = cmpNumbers(OBL.Inputs.size(), OBR.Inputs.size()))
2510b57cec5SDimitry Andric return Res;
2520b57cec5SDimitry Andric }
2530b57cec5SDimitry Andric
2540b57cec5SDimitry Andric return 0;
2550b57cec5SDimitry Andric }
2560b57cec5SDimitry Andric
2570b57cec5SDimitry Andric /// Constants comparison:
2580b57cec5SDimitry Andric /// 1. Check whether type of L constant could be losslessly bitcasted to R
2590b57cec5SDimitry Andric /// type.
2600b57cec5SDimitry Andric /// 2. Compare constant contents.
2610b57cec5SDimitry Andric /// For more details see declaration comments.
cmpConstants(const Constant * L,const Constant * R) const2620b57cec5SDimitry Andric int FunctionComparator::cmpConstants(const Constant *L,
2630b57cec5SDimitry Andric const Constant *R) const {
2640b57cec5SDimitry Andric Type *TyL = L->getType();
2650b57cec5SDimitry Andric Type *TyR = R->getType();
2660b57cec5SDimitry Andric
2670b57cec5SDimitry Andric // Check whether types are bitcastable. This part is just re-factored
2680b57cec5SDimitry Andric // Type::canLosslesslyBitCastTo method, but instead of returning true/false,
2690b57cec5SDimitry Andric // we also pack into result which type is "less" for us.
2700b57cec5SDimitry Andric int TypesRes = cmpTypes(TyL, TyR);
2710b57cec5SDimitry Andric if (TypesRes != 0) {
2720b57cec5SDimitry Andric // Types are different, but check whether we can bitcast them.
2730b57cec5SDimitry Andric if (!TyL->isFirstClassType()) {
2740b57cec5SDimitry Andric if (TyR->isFirstClassType())
2750b57cec5SDimitry Andric return -1;
2760b57cec5SDimitry Andric // Neither TyL nor TyR are values of first class type. Return the result
2770b57cec5SDimitry Andric // of comparing the types
2780b57cec5SDimitry Andric return TypesRes;
2790b57cec5SDimitry Andric }
2800b57cec5SDimitry Andric if (!TyR->isFirstClassType()) {
2810b57cec5SDimitry Andric if (TyL->isFirstClassType())
2820b57cec5SDimitry Andric return 1;
2830b57cec5SDimitry Andric return TypesRes;
2840b57cec5SDimitry Andric }
2850b57cec5SDimitry Andric
2860b57cec5SDimitry Andric // Vector -> Vector conversions are always lossless if the two vector types
2870b57cec5SDimitry Andric // have the same size, otherwise not.
2880b57cec5SDimitry Andric unsigned TyLWidth = 0;
2890b57cec5SDimitry Andric unsigned TyRWidth = 0;
2900b57cec5SDimitry Andric
2910b57cec5SDimitry Andric if (auto *VecTyL = dyn_cast<VectorType>(TyL))
292bdd1243dSDimitry Andric TyLWidth = VecTyL->getPrimitiveSizeInBits().getFixedValue();
2930b57cec5SDimitry Andric if (auto *VecTyR = dyn_cast<VectorType>(TyR))
294bdd1243dSDimitry Andric TyRWidth = VecTyR->getPrimitiveSizeInBits().getFixedValue();
2950b57cec5SDimitry Andric
2960b57cec5SDimitry Andric if (TyLWidth != TyRWidth)
2970b57cec5SDimitry Andric return cmpNumbers(TyLWidth, TyRWidth);
2980b57cec5SDimitry Andric
2990b57cec5SDimitry Andric // Zero bit-width means neither TyL nor TyR are vectors.
3000b57cec5SDimitry Andric if (!TyLWidth) {
3010b57cec5SDimitry Andric PointerType *PTyL = dyn_cast<PointerType>(TyL);
3020b57cec5SDimitry Andric PointerType *PTyR = dyn_cast<PointerType>(TyR);
3030b57cec5SDimitry Andric if (PTyL && PTyR) {
3040b57cec5SDimitry Andric unsigned AddrSpaceL = PTyL->getAddressSpace();
3050b57cec5SDimitry Andric unsigned AddrSpaceR = PTyR->getAddressSpace();
3060b57cec5SDimitry Andric if (int Res = cmpNumbers(AddrSpaceL, AddrSpaceR))
3070b57cec5SDimitry Andric return Res;
3080b57cec5SDimitry Andric }
3090b57cec5SDimitry Andric if (PTyL)
3100b57cec5SDimitry Andric return 1;
3110b57cec5SDimitry Andric if (PTyR)
3120b57cec5SDimitry Andric return -1;
3130b57cec5SDimitry Andric
3140b57cec5SDimitry Andric // TyL and TyR aren't vectors, nor pointers. We don't know how to
3150b57cec5SDimitry Andric // bitcast them.
3160b57cec5SDimitry Andric return TypesRes;
3170b57cec5SDimitry Andric }
3180b57cec5SDimitry Andric }
3190b57cec5SDimitry Andric
3200b57cec5SDimitry Andric // OK, types are bitcastable, now check constant contents.
3210b57cec5SDimitry Andric
3220b57cec5SDimitry Andric if (L->isNullValue() && R->isNullValue())
3230b57cec5SDimitry Andric return TypesRes;
3240b57cec5SDimitry Andric if (L->isNullValue() && !R->isNullValue())
3250b57cec5SDimitry Andric return 1;
3260b57cec5SDimitry Andric if (!L->isNullValue() && R->isNullValue())
3270b57cec5SDimitry Andric return -1;
3280b57cec5SDimitry Andric
3290b57cec5SDimitry Andric auto GlobalValueL = const_cast<GlobalValue *>(dyn_cast<GlobalValue>(L));
3300b57cec5SDimitry Andric auto GlobalValueR = const_cast<GlobalValue *>(dyn_cast<GlobalValue>(R));
3310b57cec5SDimitry Andric if (GlobalValueL && GlobalValueR) {
3320b57cec5SDimitry Andric return cmpGlobalValues(GlobalValueL, GlobalValueR);
3330b57cec5SDimitry Andric }
3340b57cec5SDimitry Andric
3350b57cec5SDimitry Andric if (int Res = cmpNumbers(L->getValueID(), R->getValueID()))
3360b57cec5SDimitry Andric return Res;
3370b57cec5SDimitry Andric
3380b57cec5SDimitry Andric if (const auto *SeqL = dyn_cast<ConstantDataSequential>(L)) {
3390b57cec5SDimitry Andric const auto *SeqR = cast<ConstantDataSequential>(R);
3400b57cec5SDimitry Andric // This handles ConstantDataArray and ConstantDataVector. Note that we
3410b57cec5SDimitry Andric // compare the two raw data arrays, which might differ depending on the host
3420b57cec5SDimitry Andric // endianness. This isn't a problem though, because the endiness of a module
3430b57cec5SDimitry Andric // will affect the order of the constants, but this order is the same
3440b57cec5SDimitry Andric // for a given input module and host platform.
3450b57cec5SDimitry Andric return cmpMem(SeqL->getRawDataValues(), SeqR->getRawDataValues());
3460b57cec5SDimitry Andric }
3470b57cec5SDimitry Andric
3480b57cec5SDimitry Andric switch (L->getValueID()) {
3490b57cec5SDimitry Andric case Value::UndefValueVal:
350e8d8bef9SDimitry Andric case Value::PoisonValueVal:
3510b57cec5SDimitry Andric case Value::ConstantTokenNoneVal:
3520b57cec5SDimitry Andric return TypesRes;
3530b57cec5SDimitry Andric case Value::ConstantIntVal: {
3540b57cec5SDimitry Andric const APInt &LInt = cast<ConstantInt>(L)->getValue();
3550b57cec5SDimitry Andric const APInt &RInt = cast<ConstantInt>(R)->getValue();
3560b57cec5SDimitry Andric return cmpAPInts(LInt, RInt);
3570b57cec5SDimitry Andric }
3580b57cec5SDimitry Andric case Value::ConstantFPVal: {
3590b57cec5SDimitry Andric const APFloat &LAPF = cast<ConstantFP>(L)->getValueAPF();
3600b57cec5SDimitry Andric const APFloat &RAPF = cast<ConstantFP>(R)->getValueAPF();
3610b57cec5SDimitry Andric return cmpAPFloats(LAPF, RAPF);
3620b57cec5SDimitry Andric }
3630b57cec5SDimitry Andric case Value::ConstantArrayVal: {
3640b57cec5SDimitry Andric const ConstantArray *LA = cast<ConstantArray>(L);
3650b57cec5SDimitry Andric const ConstantArray *RA = cast<ConstantArray>(R);
3660b57cec5SDimitry Andric uint64_t NumElementsL = cast<ArrayType>(TyL)->getNumElements();
3670b57cec5SDimitry Andric uint64_t NumElementsR = cast<ArrayType>(TyR)->getNumElements();
3680b57cec5SDimitry Andric if (int Res = cmpNumbers(NumElementsL, NumElementsR))
3690b57cec5SDimitry Andric return Res;
3700b57cec5SDimitry Andric for (uint64_t i = 0; i < NumElementsL; ++i) {
3710b57cec5SDimitry Andric if (int Res = cmpConstants(cast<Constant>(LA->getOperand(i)),
3720b57cec5SDimitry Andric cast<Constant>(RA->getOperand(i))))
3730b57cec5SDimitry Andric return Res;
3740b57cec5SDimitry Andric }
3750b57cec5SDimitry Andric return 0;
3760b57cec5SDimitry Andric }
3770b57cec5SDimitry Andric case Value::ConstantStructVal: {
3780b57cec5SDimitry Andric const ConstantStruct *LS = cast<ConstantStruct>(L);
3790b57cec5SDimitry Andric const ConstantStruct *RS = cast<ConstantStruct>(R);
3800b57cec5SDimitry Andric unsigned NumElementsL = cast<StructType>(TyL)->getNumElements();
3810b57cec5SDimitry Andric unsigned NumElementsR = cast<StructType>(TyR)->getNumElements();
3820b57cec5SDimitry Andric if (int Res = cmpNumbers(NumElementsL, NumElementsR))
3830b57cec5SDimitry Andric return Res;
3840b57cec5SDimitry Andric for (unsigned i = 0; i != NumElementsL; ++i) {
3850b57cec5SDimitry Andric if (int Res = cmpConstants(cast<Constant>(LS->getOperand(i)),
3860b57cec5SDimitry Andric cast<Constant>(RS->getOperand(i))))
3870b57cec5SDimitry Andric return Res;
3880b57cec5SDimitry Andric }
3890b57cec5SDimitry Andric return 0;
3900b57cec5SDimitry Andric }
3910b57cec5SDimitry Andric case Value::ConstantVectorVal: {
3920b57cec5SDimitry Andric const ConstantVector *LV = cast<ConstantVector>(L);
3930b57cec5SDimitry Andric const ConstantVector *RV = cast<ConstantVector>(R);
3945ffd83dbSDimitry Andric unsigned NumElementsL = cast<FixedVectorType>(TyL)->getNumElements();
3955ffd83dbSDimitry Andric unsigned NumElementsR = cast<FixedVectorType>(TyR)->getNumElements();
3960b57cec5SDimitry Andric if (int Res = cmpNumbers(NumElementsL, NumElementsR))
3970b57cec5SDimitry Andric return Res;
3980b57cec5SDimitry Andric for (uint64_t i = 0; i < NumElementsL; ++i) {
3990b57cec5SDimitry Andric if (int Res = cmpConstants(cast<Constant>(LV->getOperand(i)),
4000b57cec5SDimitry Andric cast<Constant>(RV->getOperand(i))))
4010b57cec5SDimitry Andric return Res;
4020b57cec5SDimitry Andric }
4030b57cec5SDimitry Andric return 0;
4040b57cec5SDimitry Andric }
4050b57cec5SDimitry Andric case Value::ConstantExprVal: {
4060b57cec5SDimitry Andric const ConstantExpr *LE = cast<ConstantExpr>(L);
4070b57cec5SDimitry Andric const ConstantExpr *RE = cast<ConstantExpr>(R);
408*e710425bSDimitry Andric if (int Res = cmpNumbers(LE->getOpcode(), RE->getOpcode()))
409*e710425bSDimitry Andric return Res;
4100b57cec5SDimitry Andric unsigned NumOperandsL = LE->getNumOperands();
4110b57cec5SDimitry Andric unsigned NumOperandsR = RE->getNumOperands();
4120b57cec5SDimitry Andric if (int Res = cmpNumbers(NumOperandsL, NumOperandsR))
4130b57cec5SDimitry Andric return Res;
4140b57cec5SDimitry Andric for (unsigned i = 0; i < NumOperandsL; ++i) {
4150b57cec5SDimitry Andric if (int Res = cmpConstants(cast<Constant>(LE->getOperand(i)),
4160b57cec5SDimitry Andric cast<Constant>(RE->getOperand(i))))
4170b57cec5SDimitry Andric return Res;
4180b57cec5SDimitry Andric }
419*e710425bSDimitry Andric if (LE->isCompare())
420*e710425bSDimitry Andric if (int Res = cmpNumbers(LE->getPredicate(), RE->getPredicate()))
421*e710425bSDimitry Andric return Res;
422*e710425bSDimitry Andric if (auto *GEPL = dyn_cast<GEPOperator>(LE)) {
423*e710425bSDimitry Andric auto *GEPR = cast<GEPOperator>(RE);
424*e710425bSDimitry Andric if (int Res = cmpTypes(GEPL->getSourceElementType(),
425*e710425bSDimitry Andric GEPR->getSourceElementType()))
426*e710425bSDimitry Andric return Res;
427*e710425bSDimitry Andric if (int Res = cmpNumbers(GEPL->isInBounds(), GEPR->isInBounds()))
428*e710425bSDimitry Andric return Res;
429*e710425bSDimitry Andric if (int Res = cmpNumbers(GEPL->getInRangeIndex().value_or(unsigned(-1)),
430*e710425bSDimitry Andric GEPR->getInRangeIndex().value_or(unsigned(-1))))
431*e710425bSDimitry Andric return Res;
432*e710425bSDimitry Andric }
433*e710425bSDimitry Andric if (auto *OBOL = dyn_cast<OverflowingBinaryOperator>(LE)) {
434*e710425bSDimitry Andric auto *OBOR = cast<OverflowingBinaryOperator>(RE);
435*e710425bSDimitry Andric if (int Res =
436*e710425bSDimitry Andric cmpNumbers(OBOL->hasNoUnsignedWrap(), OBOR->hasNoUnsignedWrap()))
437*e710425bSDimitry Andric return Res;
438*e710425bSDimitry Andric if (int Res =
439*e710425bSDimitry Andric cmpNumbers(OBOL->hasNoSignedWrap(), OBOR->hasNoSignedWrap()))
440*e710425bSDimitry Andric return Res;
441*e710425bSDimitry Andric }
4420b57cec5SDimitry Andric return 0;
4430b57cec5SDimitry Andric }
4440b57cec5SDimitry Andric case Value::BlockAddressVal: {
4450b57cec5SDimitry Andric const BlockAddress *LBA = cast<BlockAddress>(L);
4460b57cec5SDimitry Andric const BlockAddress *RBA = cast<BlockAddress>(R);
4470b57cec5SDimitry Andric if (int Res = cmpValues(LBA->getFunction(), RBA->getFunction()))
4480b57cec5SDimitry Andric return Res;
4490b57cec5SDimitry Andric if (LBA->getFunction() == RBA->getFunction()) {
4500b57cec5SDimitry Andric // They are BBs in the same function. Order by which comes first in the
4510b57cec5SDimitry Andric // BB order of the function. This order is deterministic.
4520b57cec5SDimitry Andric Function *F = LBA->getFunction();
4530b57cec5SDimitry Andric BasicBlock *LBB = LBA->getBasicBlock();
4540b57cec5SDimitry Andric BasicBlock *RBB = RBA->getBasicBlock();
4550b57cec5SDimitry Andric if (LBB == RBB)
4560b57cec5SDimitry Andric return 0;
457bdd1243dSDimitry Andric for (BasicBlock &BB : *F) {
4580b57cec5SDimitry Andric if (&BB == LBB) {
4590b57cec5SDimitry Andric assert(&BB != RBB);
4600b57cec5SDimitry Andric return -1;
4610b57cec5SDimitry Andric }
4620b57cec5SDimitry Andric if (&BB == RBB)
4630b57cec5SDimitry Andric return 1;
4640b57cec5SDimitry Andric }
4650b57cec5SDimitry Andric llvm_unreachable("Basic Block Address does not point to a basic block in "
4660b57cec5SDimitry Andric "its function.");
4670b57cec5SDimitry Andric return -1;
4680b57cec5SDimitry Andric } else {
4690b57cec5SDimitry Andric // cmpValues said the functions are the same. So because they aren't
4700b57cec5SDimitry Andric // literally the same pointer, they must respectively be the left and
4710b57cec5SDimitry Andric // right functions.
4720b57cec5SDimitry Andric assert(LBA->getFunction() == FnL && RBA->getFunction() == FnR);
4730b57cec5SDimitry Andric // cmpValues will tell us if these are equivalent BasicBlocks, in the
4740b57cec5SDimitry Andric // context of their respective functions.
4750b57cec5SDimitry Andric return cmpValues(LBA->getBasicBlock(), RBA->getBasicBlock());
4760b57cec5SDimitry Andric }
4770b57cec5SDimitry Andric }
478bdd1243dSDimitry Andric case Value::DSOLocalEquivalentVal: {
479bdd1243dSDimitry Andric // dso_local_equivalent is functionally equivalent to whatever it points to.
480bdd1243dSDimitry Andric // This means the behavior of the IR should be the exact same as if the
481bdd1243dSDimitry Andric // function was referenced directly rather than through a
482bdd1243dSDimitry Andric // dso_local_equivalent.
483bdd1243dSDimitry Andric const auto *LEquiv = cast<DSOLocalEquivalent>(L);
484bdd1243dSDimitry Andric const auto *REquiv = cast<DSOLocalEquivalent>(R);
485bdd1243dSDimitry Andric return cmpGlobalValues(LEquiv->getGlobalValue(), REquiv->getGlobalValue());
486bdd1243dSDimitry Andric }
4870b57cec5SDimitry Andric default: // Unknown constant, abort.
4880b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "Looking at valueID " << L->getValueID() << "\n");
4890b57cec5SDimitry Andric llvm_unreachable("Constant ValueID not recognized.");
4900b57cec5SDimitry Andric return -1;
4910b57cec5SDimitry Andric }
4920b57cec5SDimitry Andric }
4930b57cec5SDimitry Andric
cmpGlobalValues(GlobalValue * L,GlobalValue * R) const4940b57cec5SDimitry Andric int FunctionComparator::cmpGlobalValues(GlobalValue *L, GlobalValue *R) const {
4950b57cec5SDimitry Andric uint64_t LNumber = GlobalNumbers->getNumber(L);
4960b57cec5SDimitry Andric uint64_t RNumber = GlobalNumbers->getNumber(R);
4970b57cec5SDimitry Andric return cmpNumbers(LNumber, RNumber);
4980b57cec5SDimitry Andric }
4990b57cec5SDimitry Andric
5000b57cec5SDimitry Andric /// cmpType - compares two types,
5010b57cec5SDimitry Andric /// defines total ordering among the types set.
5020b57cec5SDimitry Andric /// See method declaration comments for more details.
cmpTypes(Type * TyL,Type * TyR) const5030b57cec5SDimitry Andric int FunctionComparator::cmpTypes(Type *TyL, Type *TyR) const {
5040b57cec5SDimitry Andric PointerType *PTyL = dyn_cast<PointerType>(TyL);
5050b57cec5SDimitry Andric PointerType *PTyR = dyn_cast<PointerType>(TyR);
5060b57cec5SDimitry Andric
5070b57cec5SDimitry Andric const DataLayout &DL = FnL->getParent()->getDataLayout();
5080b57cec5SDimitry Andric if (PTyL && PTyL->getAddressSpace() == 0)
5090b57cec5SDimitry Andric TyL = DL.getIntPtrType(TyL);
5100b57cec5SDimitry Andric if (PTyR && PTyR->getAddressSpace() == 0)
5110b57cec5SDimitry Andric TyR = DL.getIntPtrType(TyR);
5120b57cec5SDimitry Andric
5130b57cec5SDimitry Andric if (TyL == TyR)
5140b57cec5SDimitry Andric return 0;
5150b57cec5SDimitry Andric
5160b57cec5SDimitry Andric if (int Res = cmpNumbers(TyL->getTypeID(), TyR->getTypeID()))
5170b57cec5SDimitry Andric return Res;
5180b57cec5SDimitry Andric
5190b57cec5SDimitry Andric switch (TyL->getTypeID()) {
5200b57cec5SDimitry Andric default:
5210b57cec5SDimitry Andric llvm_unreachable("Unknown type!");
5220b57cec5SDimitry Andric case Type::IntegerTyID:
5230b57cec5SDimitry Andric return cmpNumbers(cast<IntegerType>(TyL)->getBitWidth(),
5240b57cec5SDimitry Andric cast<IntegerType>(TyR)->getBitWidth());
5250b57cec5SDimitry Andric // TyL == TyR would have returned true earlier, because types are uniqued.
5260b57cec5SDimitry Andric case Type::VoidTyID:
5270b57cec5SDimitry Andric case Type::FloatTyID:
5280b57cec5SDimitry Andric case Type::DoubleTyID:
5290b57cec5SDimitry Andric case Type::X86_FP80TyID:
5300b57cec5SDimitry Andric case Type::FP128TyID:
5310b57cec5SDimitry Andric case Type::PPC_FP128TyID:
5320b57cec5SDimitry Andric case Type::LabelTyID:
5330b57cec5SDimitry Andric case Type::MetadataTyID:
5340b57cec5SDimitry Andric case Type::TokenTyID:
5350b57cec5SDimitry Andric return 0;
5360b57cec5SDimitry Andric
5370b57cec5SDimitry Andric case Type::PointerTyID:
5380b57cec5SDimitry Andric assert(PTyL && PTyR && "Both types must be pointers here.");
5390b57cec5SDimitry Andric return cmpNumbers(PTyL->getAddressSpace(), PTyR->getAddressSpace());
5400b57cec5SDimitry Andric
5410b57cec5SDimitry Andric case Type::StructTyID: {
5420b57cec5SDimitry Andric StructType *STyL = cast<StructType>(TyL);
5430b57cec5SDimitry Andric StructType *STyR = cast<StructType>(TyR);
5440b57cec5SDimitry Andric if (STyL->getNumElements() != STyR->getNumElements())
5450b57cec5SDimitry Andric return cmpNumbers(STyL->getNumElements(), STyR->getNumElements());
5460b57cec5SDimitry Andric
5470b57cec5SDimitry Andric if (STyL->isPacked() != STyR->isPacked())
5480b57cec5SDimitry Andric return cmpNumbers(STyL->isPacked(), STyR->isPacked());
5490b57cec5SDimitry Andric
5500b57cec5SDimitry Andric for (unsigned i = 0, e = STyL->getNumElements(); i != e; ++i) {
5510b57cec5SDimitry Andric if (int Res = cmpTypes(STyL->getElementType(i), STyR->getElementType(i)))
5520b57cec5SDimitry Andric return Res;
5530b57cec5SDimitry Andric }
5540b57cec5SDimitry Andric return 0;
5550b57cec5SDimitry Andric }
5560b57cec5SDimitry Andric
5570b57cec5SDimitry Andric case Type::FunctionTyID: {
5580b57cec5SDimitry Andric FunctionType *FTyL = cast<FunctionType>(TyL);
5590b57cec5SDimitry Andric FunctionType *FTyR = cast<FunctionType>(TyR);
5600b57cec5SDimitry Andric if (FTyL->getNumParams() != FTyR->getNumParams())
5610b57cec5SDimitry Andric return cmpNumbers(FTyL->getNumParams(), FTyR->getNumParams());
5620b57cec5SDimitry Andric
5630b57cec5SDimitry Andric if (FTyL->isVarArg() != FTyR->isVarArg())
5640b57cec5SDimitry Andric return cmpNumbers(FTyL->isVarArg(), FTyR->isVarArg());
5650b57cec5SDimitry Andric
5660b57cec5SDimitry Andric if (int Res = cmpTypes(FTyL->getReturnType(), FTyR->getReturnType()))
5670b57cec5SDimitry Andric return Res;
5680b57cec5SDimitry Andric
5690b57cec5SDimitry Andric for (unsigned i = 0, e = FTyL->getNumParams(); i != e; ++i) {
5700b57cec5SDimitry Andric if (int Res = cmpTypes(FTyL->getParamType(i), FTyR->getParamType(i)))
5710b57cec5SDimitry Andric return Res;
5720b57cec5SDimitry Andric }
5730b57cec5SDimitry Andric return 0;
5740b57cec5SDimitry Andric }
5750b57cec5SDimitry Andric
5765ffd83dbSDimitry Andric case Type::ArrayTyID: {
5775ffd83dbSDimitry Andric auto *STyL = cast<ArrayType>(TyL);
5785ffd83dbSDimitry Andric auto *STyR = cast<ArrayType>(TyR);
5790b57cec5SDimitry Andric if (STyL->getNumElements() != STyR->getNumElements())
5800b57cec5SDimitry Andric return cmpNumbers(STyL->getNumElements(), STyR->getNumElements());
5810b57cec5SDimitry Andric return cmpTypes(STyL->getElementType(), STyR->getElementType());
5820b57cec5SDimitry Andric }
5835ffd83dbSDimitry Andric case Type::FixedVectorTyID:
5845ffd83dbSDimitry Andric case Type::ScalableVectorTyID: {
5855ffd83dbSDimitry Andric auto *STyL = cast<VectorType>(TyL);
5865ffd83dbSDimitry Andric auto *STyR = cast<VectorType>(TyR);
587e8d8bef9SDimitry Andric if (STyL->getElementCount().isScalable() !=
588e8d8bef9SDimitry Andric STyR->getElementCount().isScalable())
589e8d8bef9SDimitry Andric return cmpNumbers(STyL->getElementCount().isScalable(),
590e8d8bef9SDimitry Andric STyR->getElementCount().isScalable());
591e8d8bef9SDimitry Andric if (STyL->getElementCount() != STyR->getElementCount())
592e8d8bef9SDimitry Andric return cmpNumbers(STyL->getElementCount().getKnownMinValue(),
593e8d8bef9SDimitry Andric STyR->getElementCount().getKnownMinValue());
5945ffd83dbSDimitry Andric return cmpTypes(STyL->getElementType(), STyR->getElementType());
5955ffd83dbSDimitry Andric }
5960b57cec5SDimitry Andric }
5970b57cec5SDimitry Andric }
5980b57cec5SDimitry Andric
5990b57cec5SDimitry Andric // Determine whether the two operations are the same except that pointer-to-A
6000b57cec5SDimitry Andric // and pointer-to-B are equivalent. This should be kept in sync with
6010b57cec5SDimitry Andric // Instruction::isSameOperationAs.
6020b57cec5SDimitry Andric // Read method declaration comments for more details.
cmpOperations(const Instruction * L,const Instruction * R,bool & needToCmpOperands) const6030b57cec5SDimitry Andric int FunctionComparator::cmpOperations(const Instruction *L,
6040b57cec5SDimitry Andric const Instruction *R,
6050b57cec5SDimitry Andric bool &needToCmpOperands) const {
6060b57cec5SDimitry Andric needToCmpOperands = true;
6070b57cec5SDimitry Andric if (int Res = cmpValues(L, R))
6080b57cec5SDimitry Andric return Res;
6090b57cec5SDimitry Andric
6100b57cec5SDimitry Andric // Differences from Instruction::isSameOperationAs:
6110b57cec5SDimitry Andric // * replace type comparison with calls to cmpTypes.
6120b57cec5SDimitry Andric // * we test for I->getRawSubclassOptionalData (nuw/nsw/tail) at the top.
6130b57cec5SDimitry Andric // * because of the above, we don't test for the tail bit on calls later on.
6140b57cec5SDimitry Andric if (int Res = cmpNumbers(L->getOpcode(), R->getOpcode()))
6150b57cec5SDimitry Andric return Res;
6160b57cec5SDimitry Andric
6170b57cec5SDimitry Andric if (const GetElementPtrInst *GEPL = dyn_cast<GetElementPtrInst>(L)) {
6180b57cec5SDimitry Andric needToCmpOperands = false;
6190b57cec5SDimitry Andric const GetElementPtrInst *GEPR = cast<GetElementPtrInst>(R);
6200b57cec5SDimitry Andric if (int Res =
6210b57cec5SDimitry Andric cmpValues(GEPL->getPointerOperand(), GEPR->getPointerOperand()))
6220b57cec5SDimitry Andric return Res;
6230b57cec5SDimitry Andric return cmpGEPs(GEPL, GEPR);
6240b57cec5SDimitry Andric }
6250b57cec5SDimitry Andric
6260b57cec5SDimitry Andric if (int Res = cmpNumbers(L->getNumOperands(), R->getNumOperands()))
6270b57cec5SDimitry Andric return Res;
6280b57cec5SDimitry Andric
6290b57cec5SDimitry Andric if (int Res = cmpTypes(L->getType(), R->getType()))
6300b57cec5SDimitry Andric return Res;
6310b57cec5SDimitry Andric
6320b57cec5SDimitry Andric if (int Res = cmpNumbers(L->getRawSubclassOptionalData(),
6330b57cec5SDimitry Andric R->getRawSubclassOptionalData()))
6340b57cec5SDimitry Andric return Res;
6350b57cec5SDimitry Andric
6360b57cec5SDimitry Andric // We have two instructions of identical opcode and #operands. Check to see
6370b57cec5SDimitry Andric // if all operands are the same type
6380b57cec5SDimitry Andric for (unsigned i = 0, e = L->getNumOperands(); i != e; ++i) {
6390b57cec5SDimitry Andric if (int Res =
6400b57cec5SDimitry Andric cmpTypes(L->getOperand(i)->getType(), R->getOperand(i)->getType()))
6410b57cec5SDimitry Andric return Res;
6420b57cec5SDimitry Andric }
6430b57cec5SDimitry Andric
6440b57cec5SDimitry Andric // Check special state that is a part of some instructions.
6450b57cec5SDimitry Andric if (const AllocaInst *AI = dyn_cast<AllocaInst>(L)) {
6460b57cec5SDimitry Andric if (int Res = cmpTypes(AI->getAllocatedType(),
6470b57cec5SDimitry Andric cast<AllocaInst>(R)->getAllocatedType()))
6480b57cec5SDimitry Andric return Res;
6490eae32dcSDimitry Andric return cmpAligns(AI->getAlign(), cast<AllocaInst>(R)->getAlign());
6500b57cec5SDimitry Andric }
6510b57cec5SDimitry Andric if (const LoadInst *LI = dyn_cast<LoadInst>(L)) {
6520b57cec5SDimitry Andric if (int Res = cmpNumbers(LI->isVolatile(), cast<LoadInst>(R)->isVolatile()))
6530b57cec5SDimitry Andric return Res;
6540eae32dcSDimitry Andric if (int Res = cmpAligns(LI->getAlign(), cast<LoadInst>(R)->getAlign()))
6550b57cec5SDimitry Andric return Res;
6560b57cec5SDimitry Andric if (int Res =
6570b57cec5SDimitry Andric cmpOrderings(LI->getOrdering(), cast<LoadInst>(R)->getOrdering()))
6580b57cec5SDimitry Andric return Res;
6590b57cec5SDimitry Andric if (int Res = cmpNumbers(LI->getSyncScopeID(),
6600b57cec5SDimitry Andric cast<LoadInst>(R)->getSyncScopeID()))
6610b57cec5SDimitry Andric return Res;
662fe013be4SDimitry Andric return cmpInstMetadata(L, R);
6630b57cec5SDimitry Andric }
6640b57cec5SDimitry Andric if (const StoreInst *SI = dyn_cast<StoreInst>(L)) {
6650b57cec5SDimitry Andric if (int Res =
6660b57cec5SDimitry Andric cmpNumbers(SI->isVolatile(), cast<StoreInst>(R)->isVolatile()))
6670b57cec5SDimitry Andric return Res;
6680eae32dcSDimitry Andric if (int Res = cmpAligns(SI->getAlign(), cast<StoreInst>(R)->getAlign()))
6690b57cec5SDimitry Andric return Res;
6700b57cec5SDimitry Andric if (int Res =
6710b57cec5SDimitry Andric cmpOrderings(SI->getOrdering(), cast<StoreInst>(R)->getOrdering()))
6720b57cec5SDimitry Andric return Res;
6730b57cec5SDimitry Andric return cmpNumbers(SI->getSyncScopeID(),
6740b57cec5SDimitry Andric cast<StoreInst>(R)->getSyncScopeID());
6750b57cec5SDimitry Andric }
6760b57cec5SDimitry Andric if (const CmpInst *CI = dyn_cast<CmpInst>(L))
6770b57cec5SDimitry Andric return cmpNumbers(CI->getPredicate(), cast<CmpInst>(R)->getPredicate());
6785ffd83dbSDimitry Andric if (auto *CBL = dyn_cast<CallBase>(L)) {
6795ffd83dbSDimitry Andric auto *CBR = cast<CallBase>(R);
6805ffd83dbSDimitry Andric if (int Res = cmpNumbers(CBL->getCallingConv(), CBR->getCallingConv()))
6810b57cec5SDimitry Andric return Res;
6825ffd83dbSDimitry Andric if (int Res = cmpAttrs(CBL->getAttributes(), CBR->getAttributes()))
6830b57cec5SDimitry Andric return Res;
6845ffd83dbSDimitry Andric if (int Res = cmpOperandBundlesSchema(*CBL, *CBR))
6850b57cec5SDimitry Andric return Res;
6860b57cec5SDimitry Andric if (const CallInst *CI = dyn_cast<CallInst>(L))
6870b57cec5SDimitry Andric if (int Res = cmpNumbers(CI->getTailCallKind(),
6880b57cec5SDimitry Andric cast<CallInst>(R)->getTailCallKind()))
6890b57cec5SDimitry Andric return Res;
690fe013be4SDimitry Andric return cmpMDNode(L->getMetadata(LLVMContext::MD_range),
6910b57cec5SDimitry Andric R->getMetadata(LLVMContext::MD_range));
6920b57cec5SDimitry Andric }
6930b57cec5SDimitry Andric if (const InsertValueInst *IVI = dyn_cast<InsertValueInst>(L)) {
6940b57cec5SDimitry Andric ArrayRef<unsigned> LIndices = IVI->getIndices();
6950b57cec5SDimitry Andric ArrayRef<unsigned> RIndices = cast<InsertValueInst>(R)->getIndices();
6960b57cec5SDimitry Andric if (int Res = cmpNumbers(LIndices.size(), RIndices.size()))
6970b57cec5SDimitry Andric return Res;
6980b57cec5SDimitry Andric for (size_t i = 0, e = LIndices.size(); i != e; ++i) {
6990b57cec5SDimitry Andric if (int Res = cmpNumbers(LIndices[i], RIndices[i]))
7000b57cec5SDimitry Andric return Res;
7010b57cec5SDimitry Andric }
7020b57cec5SDimitry Andric return 0;
7030b57cec5SDimitry Andric }
7040b57cec5SDimitry Andric if (const ExtractValueInst *EVI = dyn_cast<ExtractValueInst>(L)) {
7050b57cec5SDimitry Andric ArrayRef<unsigned> LIndices = EVI->getIndices();
7060b57cec5SDimitry Andric ArrayRef<unsigned> RIndices = cast<ExtractValueInst>(R)->getIndices();
7070b57cec5SDimitry Andric if (int Res = cmpNumbers(LIndices.size(), RIndices.size()))
7080b57cec5SDimitry Andric return Res;
7090b57cec5SDimitry Andric for (size_t i = 0, e = LIndices.size(); i != e; ++i) {
7100b57cec5SDimitry Andric if (int Res = cmpNumbers(LIndices[i], RIndices[i]))
7110b57cec5SDimitry Andric return Res;
7120b57cec5SDimitry Andric }
7130b57cec5SDimitry Andric }
7140b57cec5SDimitry Andric if (const FenceInst *FI = dyn_cast<FenceInst>(L)) {
7150b57cec5SDimitry Andric if (int Res =
7160b57cec5SDimitry Andric cmpOrderings(FI->getOrdering(), cast<FenceInst>(R)->getOrdering()))
7170b57cec5SDimitry Andric return Res;
7180b57cec5SDimitry Andric return cmpNumbers(FI->getSyncScopeID(),
7190b57cec5SDimitry Andric cast<FenceInst>(R)->getSyncScopeID());
7200b57cec5SDimitry Andric }
7210b57cec5SDimitry Andric if (const AtomicCmpXchgInst *CXI = dyn_cast<AtomicCmpXchgInst>(L)) {
7220b57cec5SDimitry Andric if (int Res = cmpNumbers(CXI->isVolatile(),
7230b57cec5SDimitry Andric cast<AtomicCmpXchgInst>(R)->isVolatile()))
7240b57cec5SDimitry Andric return Res;
7255ffd83dbSDimitry Andric if (int Res =
7265ffd83dbSDimitry Andric cmpNumbers(CXI->isWeak(), cast<AtomicCmpXchgInst>(R)->isWeak()))
7270b57cec5SDimitry Andric return Res;
7280b57cec5SDimitry Andric if (int Res =
7290b57cec5SDimitry Andric cmpOrderings(CXI->getSuccessOrdering(),
7300b57cec5SDimitry Andric cast<AtomicCmpXchgInst>(R)->getSuccessOrdering()))
7310b57cec5SDimitry Andric return Res;
7320b57cec5SDimitry Andric if (int Res =
7330b57cec5SDimitry Andric cmpOrderings(CXI->getFailureOrdering(),
7340b57cec5SDimitry Andric cast<AtomicCmpXchgInst>(R)->getFailureOrdering()))
7350b57cec5SDimitry Andric return Res;
7360b57cec5SDimitry Andric return cmpNumbers(CXI->getSyncScopeID(),
7370b57cec5SDimitry Andric cast<AtomicCmpXchgInst>(R)->getSyncScopeID());
7380b57cec5SDimitry Andric }
7390b57cec5SDimitry Andric if (const AtomicRMWInst *RMWI = dyn_cast<AtomicRMWInst>(L)) {
7400b57cec5SDimitry Andric if (int Res = cmpNumbers(RMWI->getOperation(),
7410b57cec5SDimitry Andric cast<AtomicRMWInst>(R)->getOperation()))
7420b57cec5SDimitry Andric return Res;
7430b57cec5SDimitry Andric if (int Res = cmpNumbers(RMWI->isVolatile(),
7440b57cec5SDimitry Andric cast<AtomicRMWInst>(R)->isVolatile()))
7450b57cec5SDimitry Andric return Res;
7460b57cec5SDimitry Andric if (int Res = cmpOrderings(RMWI->getOrdering(),
7470b57cec5SDimitry Andric cast<AtomicRMWInst>(R)->getOrdering()))
7480b57cec5SDimitry Andric return Res;
7490b57cec5SDimitry Andric return cmpNumbers(RMWI->getSyncScopeID(),
7500b57cec5SDimitry Andric cast<AtomicRMWInst>(R)->getSyncScopeID());
7510b57cec5SDimitry Andric }
7525ffd83dbSDimitry Andric if (const ShuffleVectorInst *SVI = dyn_cast<ShuffleVectorInst>(L)) {
7535ffd83dbSDimitry Andric ArrayRef<int> LMask = SVI->getShuffleMask();
7545ffd83dbSDimitry Andric ArrayRef<int> RMask = cast<ShuffleVectorInst>(R)->getShuffleMask();
7555ffd83dbSDimitry Andric if (int Res = cmpNumbers(LMask.size(), RMask.size()))
7565ffd83dbSDimitry Andric return Res;
7575ffd83dbSDimitry Andric for (size_t i = 0, e = LMask.size(); i != e; ++i) {
7585ffd83dbSDimitry Andric if (int Res = cmpNumbers(LMask[i], RMask[i]))
7595ffd83dbSDimitry Andric return Res;
7605ffd83dbSDimitry Andric }
7615ffd83dbSDimitry Andric }
7620b57cec5SDimitry Andric if (const PHINode *PNL = dyn_cast<PHINode>(L)) {
7630b57cec5SDimitry Andric const PHINode *PNR = cast<PHINode>(R);
7640b57cec5SDimitry Andric // Ensure that in addition to the incoming values being identical
7650b57cec5SDimitry Andric // (checked by the caller of this function), the incoming blocks
7660b57cec5SDimitry Andric // are also identical.
7670b57cec5SDimitry Andric for (unsigned i = 0, e = PNL->getNumIncomingValues(); i != e; ++i) {
7680b57cec5SDimitry Andric if (int Res =
7690b57cec5SDimitry Andric cmpValues(PNL->getIncomingBlock(i), PNR->getIncomingBlock(i)))
7700b57cec5SDimitry Andric return Res;
7710b57cec5SDimitry Andric }
7720b57cec5SDimitry Andric }
7730b57cec5SDimitry Andric return 0;
7740b57cec5SDimitry Andric }
7750b57cec5SDimitry Andric
7760b57cec5SDimitry Andric // Determine whether two GEP operations perform the same underlying arithmetic.
7770b57cec5SDimitry Andric // Read method declaration comments for more details.
cmpGEPs(const GEPOperator * GEPL,const GEPOperator * GEPR) const7780b57cec5SDimitry Andric int FunctionComparator::cmpGEPs(const GEPOperator *GEPL,
7790b57cec5SDimitry Andric const GEPOperator *GEPR) const {
7800b57cec5SDimitry Andric unsigned int ASL = GEPL->getPointerAddressSpace();
7810b57cec5SDimitry Andric unsigned int ASR = GEPR->getPointerAddressSpace();
7820b57cec5SDimitry Andric
7830b57cec5SDimitry Andric if (int Res = cmpNumbers(ASL, ASR))
7840b57cec5SDimitry Andric return Res;
7850b57cec5SDimitry Andric
7860b57cec5SDimitry Andric // When we have target data, we can reduce the GEP down to the value in bytes
7870b57cec5SDimitry Andric // added to the address.
7880b57cec5SDimitry Andric const DataLayout &DL = FnL->getParent()->getDataLayout();
789fe013be4SDimitry Andric unsigned OffsetBitWidth = DL.getIndexSizeInBits(ASL);
790fe013be4SDimitry Andric APInt OffsetL(OffsetBitWidth, 0), OffsetR(OffsetBitWidth, 0);
7910b57cec5SDimitry Andric if (GEPL->accumulateConstantOffset(DL, OffsetL) &&
7920b57cec5SDimitry Andric GEPR->accumulateConstantOffset(DL, OffsetR))
7930b57cec5SDimitry Andric return cmpAPInts(OffsetL, OffsetR);
7945ffd83dbSDimitry Andric if (int Res =
7955ffd83dbSDimitry Andric cmpTypes(GEPL->getSourceElementType(), GEPR->getSourceElementType()))
7960b57cec5SDimitry Andric return Res;
7970b57cec5SDimitry Andric
7980b57cec5SDimitry Andric if (int Res = cmpNumbers(GEPL->getNumOperands(), GEPR->getNumOperands()))
7990b57cec5SDimitry Andric return Res;
8000b57cec5SDimitry Andric
8010b57cec5SDimitry Andric for (unsigned i = 0, e = GEPL->getNumOperands(); i != e; ++i) {
8020b57cec5SDimitry Andric if (int Res = cmpValues(GEPL->getOperand(i), GEPR->getOperand(i)))
8030b57cec5SDimitry Andric return Res;
8040b57cec5SDimitry Andric }
8050b57cec5SDimitry Andric
8060b57cec5SDimitry Andric return 0;
8070b57cec5SDimitry Andric }
8080b57cec5SDimitry Andric
cmpInlineAsm(const InlineAsm * L,const InlineAsm * R) const8090b57cec5SDimitry Andric int FunctionComparator::cmpInlineAsm(const InlineAsm *L,
8100b57cec5SDimitry Andric const InlineAsm *R) const {
8110b57cec5SDimitry Andric // InlineAsm's are uniqued. If they are the same pointer, obviously they are
8120b57cec5SDimitry Andric // the same, otherwise compare the fields.
8130b57cec5SDimitry Andric if (L == R)
8140b57cec5SDimitry Andric return 0;
8150b57cec5SDimitry Andric if (int Res = cmpTypes(L->getFunctionType(), R->getFunctionType()))
8160b57cec5SDimitry Andric return Res;
8170b57cec5SDimitry Andric if (int Res = cmpMem(L->getAsmString(), R->getAsmString()))
8180b57cec5SDimitry Andric return Res;
8190b57cec5SDimitry Andric if (int Res = cmpMem(L->getConstraintString(), R->getConstraintString()))
8200b57cec5SDimitry Andric return Res;
8210b57cec5SDimitry Andric if (int Res = cmpNumbers(L->hasSideEffects(), R->hasSideEffects()))
8220b57cec5SDimitry Andric return Res;
8230b57cec5SDimitry Andric if (int Res = cmpNumbers(L->isAlignStack(), R->isAlignStack()))
8240b57cec5SDimitry Andric return Res;
8250b57cec5SDimitry Andric if (int Res = cmpNumbers(L->getDialect(), R->getDialect()))
8260b57cec5SDimitry Andric return Res;
8270b57cec5SDimitry Andric assert(L->getFunctionType() != R->getFunctionType());
8280b57cec5SDimitry Andric return 0;
8290b57cec5SDimitry Andric }
8300b57cec5SDimitry Andric
8310b57cec5SDimitry Andric /// Compare two values used by the two functions under pair-wise comparison. If
8320b57cec5SDimitry Andric /// this is the first time the values are seen, they're added to the mapping so
8330b57cec5SDimitry Andric /// that we will detect mismatches on next use.
8340b57cec5SDimitry Andric /// See comments in declaration for more details.
cmpValues(const Value * L,const Value * R) const8350b57cec5SDimitry Andric int FunctionComparator::cmpValues(const Value *L, const Value *R) const {
8360b57cec5SDimitry Andric // Catch self-reference case.
8370b57cec5SDimitry Andric if (L == FnL) {
8380b57cec5SDimitry Andric if (R == FnR)
8390b57cec5SDimitry Andric return 0;
8400b57cec5SDimitry Andric return -1;
8410b57cec5SDimitry Andric }
8420b57cec5SDimitry Andric if (R == FnR) {
8430b57cec5SDimitry Andric if (L == FnL)
8440b57cec5SDimitry Andric return 0;
8450b57cec5SDimitry Andric return 1;
8460b57cec5SDimitry Andric }
8470b57cec5SDimitry Andric
8480b57cec5SDimitry Andric const Constant *ConstL = dyn_cast<Constant>(L);
8490b57cec5SDimitry Andric const Constant *ConstR = dyn_cast<Constant>(R);
8500b57cec5SDimitry Andric if (ConstL && ConstR) {
8510b57cec5SDimitry Andric if (L == R)
8520b57cec5SDimitry Andric return 0;
8530b57cec5SDimitry Andric return cmpConstants(ConstL, ConstR);
8540b57cec5SDimitry Andric }
8550b57cec5SDimitry Andric
8560b57cec5SDimitry Andric if (ConstL)
8570b57cec5SDimitry Andric return 1;
8580b57cec5SDimitry Andric if (ConstR)
8590b57cec5SDimitry Andric return -1;
8600b57cec5SDimitry Andric
861c9157d92SDimitry Andric const MetadataAsValue *MetadataValueL = dyn_cast<MetadataAsValue>(L);
862c9157d92SDimitry Andric const MetadataAsValue *MetadataValueR = dyn_cast<MetadataAsValue>(R);
863c9157d92SDimitry Andric if (MetadataValueL && MetadataValueR) {
864c9157d92SDimitry Andric if (MetadataValueL == MetadataValueR)
865c9157d92SDimitry Andric return 0;
866c9157d92SDimitry Andric
867c9157d92SDimitry Andric return cmpMetadata(MetadataValueL->getMetadata(),
868c9157d92SDimitry Andric MetadataValueR->getMetadata());
869c9157d92SDimitry Andric }
870c9157d92SDimitry Andric
871c9157d92SDimitry Andric if (MetadataValueL)
872c9157d92SDimitry Andric return 1;
873c9157d92SDimitry Andric if (MetadataValueR)
874c9157d92SDimitry Andric return -1;
875c9157d92SDimitry Andric
8760b57cec5SDimitry Andric const InlineAsm *InlineAsmL = dyn_cast<InlineAsm>(L);
8770b57cec5SDimitry Andric const InlineAsm *InlineAsmR = dyn_cast<InlineAsm>(R);
8780b57cec5SDimitry Andric
8790b57cec5SDimitry Andric if (InlineAsmL && InlineAsmR)
8800b57cec5SDimitry Andric return cmpInlineAsm(InlineAsmL, InlineAsmR);
8810b57cec5SDimitry Andric if (InlineAsmL)
8820b57cec5SDimitry Andric return 1;
8830b57cec5SDimitry Andric if (InlineAsmR)
8840b57cec5SDimitry Andric return -1;
8850b57cec5SDimitry Andric
8860b57cec5SDimitry Andric auto LeftSN = sn_mapL.insert(std::make_pair(L, sn_mapL.size())),
8870b57cec5SDimitry Andric RightSN = sn_mapR.insert(std::make_pair(R, sn_mapR.size()));
8880b57cec5SDimitry Andric
8890b57cec5SDimitry Andric return cmpNumbers(LeftSN.first->second, RightSN.first->second);
8900b57cec5SDimitry Andric }
8910b57cec5SDimitry Andric
8920b57cec5SDimitry Andric // Test whether two basic blocks have equivalent behaviour.
cmpBasicBlocks(const BasicBlock * BBL,const BasicBlock * BBR) const8930b57cec5SDimitry Andric int FunctionComparator::cmpBasicBlocks(const BasicBlock *BBL,
8940b57cec5SDimitry Andric const BasicBlock *BBR) const {
8950b57cec5SDimitry Andric BasicBlock::const_iterator InstL = BBL->begin(), InstLE = BBL->end();
8960b57cec5SDimitry Andric BasicBlock::const_iterator InstR = BBR->begin(), InstRE = BBR->end();
8970b57cec5SDimitry Andric
8980b57cec5SDimitry Andric do {
8990b57cec5SDimitry Andric bool needToCmpOperands = true;
9000b57cec5SDimitry Andric if (int Res = cmpOperations(&*InstL, &*InstR, needToCmpOperands))
9010b57cec5SDimitry Andric return Res;
9020b57cec5SDimitry Andric if (needToCmpOperands) {
9030b57cec5SDimitry Andric assert(InstL->getNumOperands() == InstR->getNumOperands());
9040b57cec5SDimitry Andric
9050b57cec5SDimitry Andric for (unsigned i = 0, e = InstL->getNumOperands(); i != e; ++i) {
9060b57cec5SDimitry Andric Value *OpL = InstL->getOperand(i);
9070b57cec5SDimitry Andric Value *OpR = InstR->getOperand(i);
9080b57cec5SDimitry Andric if (int Res = cmpValues(OpL, OpR))
9090b57cec5SDimitry Andric return Res;
9100b57cec5SDimitry Andric // cmpValues should ensure this is true.
9110b57cec5SDimitry Andric assert(cmpTypes(OpL->getType(), OpR->getType()) == 0);
9120b57cec5SDimitry Andric }
9130b57cec5SDimitry Andric }
9140b57cec5SDimitry Andric
9150b57cec5SDimitry Andric ++InstL;
9160b57cec5SDimitry Andric ++InstR;
9170b57cec5SDimitry Andric } while (InstL != InstLE && InstR != InstRE);
9180b57cec5SDimitry Andric
9190b57cec5SDimitry Andric if (InstL != InstLE && InstR == InstRE)
9200b57cec5SDimitry Andric return 1;
9210b57cec5SDimitry Andric if (InstL == InstLE && InstR != InstRE)
9220b57cec5SDimitry Andric return -1;
9230b57cec5SDimitry Andric return 0;
9240b57cec5SDimitry Andric }
9250b57cec5SDimitry Andric
compareSignature() const9260b57cec5SDimitry Andric int FunctionComparator::compareSignature() const {
9270b57cec5SDimitry Andric if (int Res = cmpAttrs(FnL->getAttributes(), FnR->getAttributes()))
9280b57cec5SDimitry Andric return Res;
9290b57cec5SDimitry Andric
9300b57cec5SDimitry Andric if (int Res = cmpNumbers(FnL->hasGC(), FnR->hasGC()))
9310b57cec5SDimitry Andric return Res;
9320b57cec5SDimitry Andric
9330b57cec5SDimitry Andric if (FnL->hasGC()) {
9340b57cec5SDimitry Andric if (int Res = cmpMem(FnL->getGC(), FnR->getGC()))
9350b57cec5SDimitry Andric return Res;
9360b57cec5SDimitry Andric }
9370b57cec5SDimitry Andric
9380b57cec5SDimitry Andric if (int Res = cmpNumbers(FnL->hasSection(), FnR->hasSection()))
9390b57cec5SDimitry Andric return Res;
9400b57cec5SDimitry Andric
9410b57cec5SDimitry Andric if (FnL->hasSection()) {
9420b57cec5SDimitry Andric if (int Res = cmpMem(FnL->getSection(), FnR->getSection()))
9430b57cec5SDimitry Andric return Res;
9440b57cec5SDimitry Andric }
9450b57cec5SDimitry Andric
9460b57cec5SDimitry Andric if (int Res = cmpNumbers(FnL->isVarArg(), FnR->isVarArg()))
9470b57cec5SDimitry Andric return Res;
9480b57cec5SDimitry Andric
9490b57cec5SDimitry Andric // TODO: if it's internal and only used in direct calls, we could handle this
9500b57cec5SDimitry Andric // case too.
9510b57cec5SDimitry Andric if (int Res = cmpNumbers(FnL->getCallingConv(), FnR->getCallingConv()))
9520b57cec5SDimitry Andric return Res;
9530b57cec5SDimitry Andric
9540b57cec5SDimitry Andric if (int Res = cmpTypes(FnL->getFunctionType(), FnR->getFunctionType()))
9550b57cec5SDimitry Andric return Res;
9560b57cec5SDimitry Andric
9570b57cec5SDimitry Andric assert(FnL->arg_size() == FnR->arg_size() &&
9580b57cec5SDimitry Andric "Identically typed functions have different numbers of args!");
9590b57cec5SDimitry Andric
9600b57cec5SDimitry Andric // Visit the arguments so that they get enumerated in the order they're
9610b57cec5SDimitry Andric // passed in.
9620b57cec5SDimitry Andric for (Function::const_arg_iterator ArgLI = FnL->arg_begin(),
9630b57cec5SDimitry Andric ArgRI = FnR->arg_begin(),
9640b57cec5SDimitry Andric ArgLE = FnL->arg_end();
9650b57cec5SDimitry Andric ArgLI != ArgLE; ++ArgLI, ++ArgRI) {
9660b57cec5SDimitry Andric if (cmpValues(&*ArgLI, &*ArgRI) != 0)
9670b57cec5SDimitry Andric llvm_unreachable("Arguments repeat!");
9680b57cec5SDimitry Andric }
9690b57cec5SDimitry Andric return 0;
9700b57cec5SDimitry Andric }
9710b57cec5SDimitry Andric
9720b57cec5SDimitry Andric // Test whether the two functions have equivalent behaviour.
compare()9730b57cec5SDimitry Andric int FunctionComparator::compare() {
9740b57cec5SDimitry Andric beginCompare();
9750b57cec5SDimitry Andric
9760b57cec5SDimitry Andric if (int Res = compareSignature())
9770b57cec5SDimitry Andric return Res;
9780b57cec5SDimitry Andric
9790b57cec5SDimitry Andric // We do a CFG-ordered walk since the actual ordering of the blocks in the
9800b57cec5SDimitry Andric // linked list is immaterial. Our walk starts at the entry block for both
9810b57cec5SDimitry Andric // functions, then takes each block from each terminator in order. As an
9820b57cec5SDimitry Andric // artifact, this also means that unreachable blocks are ignored.
9830b57cec5SDimitry Andric SmallVector<const BasicBlock *, 8> FnLBBs, FnRBBs;
9840b57cec5SDimitry Andric SmallPtrSet<const BasicBlock *, 32> VisitedBBs; // in terms of F1.
9850b57cec5SDimitry Andric
9860b57cec5SDimitry Andric FnLBBs.push_back(&FnL->getEntryBlock());
9870b57cec5SDimitry Andric FnRBBs.push_back(&FnR->getEntryBlock());
9880b57cec5SDimitry Andric
9890b57cec5SDimitry Andric VisitedBBs.insert(FnLBBs[0]);
9900b57cec5SDimitry Andric while (!FnLBBs.empty()) {
9910b57cec5SDimitry Andric const BasicBlock *BBL = FnLBBs.pop_back_val();
9920b57cec5SDimitry Andric const BasicBlock *BBR = FnRBBs.pop_back_val();
9930b57cec5SDimitry Andric
9940b57cec5SDimitry Andric if (int Res = cmpValues(BBL, BBR))
9950b57cec5SDimitry Andric return Res;
9960b57cec5SDimitry Andric
9970b57cec5SDimitry Andric if (int Res = cmpBasicBlocks(BBL, BBR))
9980b57cec5SDimitry Andric return Res;
9990b57cec5SDimitry Andric
10000b57cec5SDimitry Andric const Instruction *TermL = BBL->getTerminator();
10010b57cec5SDimitry Andric const Instruction *TermR = BBR->getTerminator();
10020b57cec5SDimitry Andric
10030b57cec5SDimitry Andric assert(TermL->getNumSuccessors() == TermR->getNumSuccessors());
10040b57cec5SDimitry Andric for (unsigned i = 0, e = TermL->getNumSuccessors(); i != e; ++i) {
10050b57cec5SDimitry Andric if (!VisitedBBs.insert(TermL->getSuccessor(i)).second)
10060b57cec5SDimitry Andric continue;
10070b57cec5SDimitry Andric
10080b57cec5SDimitry Andric FnLBBs.push_back(TermL->getSuccessor(i));
10090b57cec5SDimitry Andric FnRBBs.push_back(TermR->getSuccessor(i));
10100b57cec5SDimitry Andric }
10110b57cec5SDimitry Andric }
10120b57cec5SDimitry Andric return 0;
10130b57cec5SDimitry Andric }
1014