xref: /src/contrib/llvm-project/llvm/lib/Transforms/Utils/FunctionComparator.cpp (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583) !
1b915e9e0SDimitry Andric //===- FunctionComparator.h - Function Comparator -------------------------===//
2b915e9e0SDimitry Andric //
3e6d15924SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4e6d15924SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5e6d15924SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6b915e9e0SDimitry Andric //
7b915e9e0SDimitry Andric //===----------------------------------------------------------------------===//
8b915e9e0SDimitry Andric //
9b915e9e0SDimitry Andric // This file implements the FunctionComparator and GlobalNumberState classes
10b915e9e0SDimitry Andric // which are used by the MergeFunctions pass for comparing functions.
11b915e9e0SDimitry Andric //
12b915e9e0SDimitry Andric //===----------------------------------------------------------------------===//
13b915e9e0SDimitry Andric 
14b915e9e0SDimitry Andric #include "llvm/Transforms/Utils/FunctionComparator.h"
15044eb2f6SDimitry Andric #include "llvm/ADT/APFloat.h"
16044eb2f6SDimitry Andric #include "llvm/ADT/APInt.h"
17044eb2f6SDimitry Andric #include "llvm/ADT/ArrayRef.h"
18044eb2f6SDimitry Andric #include "llvm/ADT/Hashing.h"
19044eb2f6SDimitry Andric #include "llvm/ADT/SmallPtrSet.h"
20044eb2f6SDimitry Andric #include "llvm/ADT/SmallVector.h"
21044eb2f6SDimitry Andric #include "llvm/IR/Attributes.h"
22044eb2f6SDimitry Andric #include "llvm/IR/BasicBlock.h"
23044eb2f6SDimitry Andric #include "llvm/IR/Constant.h"
24044eb2f6SDimitry Andric #include "llvm/IR/Constants.h"
25044eb2f6SDimitry Andric #include "llvm/IR/DataLayout.h"
26044eb2f6SDimitry Andric #include "llvm/IR/DerivedTypes.h"
27044eb2f6SDimitry Andric #include "llvm/IR/Function.h"
28044eb2f6SDimitry Andric #include "llvm/IR/GlobalValue.h"
29b915e9e0SDimitry Andric #include "llvm/IR/InlineAsm.h"
30044eb2f6SDimitry Andric #include "llvm/IR/InstrTypes.h"
31044eb2f6SDimitry Andric #include "llvm/IR/Instruction.h"
327ab83427SDimitry Andric #include "llvm/IR/Instructions.h"
33044eb2f6SDimitry Andric #include "llvm/IR/LLVMContext.h"
34044eb2f6SDimitry Andric #include "llvm/IR/Metadata.h"
35b915e9e0SDimitry Andric #include "llvm/IR/Module.h"
36044eb2f6SDimitry Andric #include "llvm/IR/Operator.h"
37044eb2f6SDimitry Andric #include "llvm/IR/Type.h"
38044eb2f6SDimitry Andric #include "llvm/IR/Value.h"
39044eb2f6SDimitry Andric #include "llvm/Support/Casting.h"
40044eb2f6SDimitry Andric #include "llvm/Support/Compiler.h"
41b915e9e0SDimitry Andric #include "llvm/Support/Debug.h"
42044eb2f6SDimitry Andric #include "llvm/Support/ErrorHandling.h"
43b915e9e0SDimitry Andric #include "llvm/Support/raw_ostream.h"
44044eb2f6SDimitry Andric #include <cassert>
45044eb2f6SDimitry Andric #include <cstddef>
46044eb2f6SDimitry Andric #include <cstdint>
47044eb2f6SDimitry Andric #include <utility>
48b915e9e0SDimitry Andric 
49b915e9e0SDimitry Andric using namespace llvm;
50b915e9e0SDimitry Andric 
51b915e9e0SDimitry Andric #define DEBUG_TYPE "functioncomparator"
52b915e9e0SDimitry Andric 
cmpNumbers(uint64_t L,uint64_t R) const53b915e9e0SDimitry Andric int FunctionComparator::cmpNumbers(uint64_t L, uint64_t R) const {
54cfca06d7SDimitry Andric   if (L < R)
55cfca06d7SDimitry Andric     return -1;
56cfca06d7SDimitry Andric   if (L > R)
57cfca06d7SDimitry Andric     return 1;
58b915e9e0SDimitry Andric   return 0;
59b915e9e0SDimitry Andric }
60b915e9e0SDimitry Andric 
cmpAligns(Align L,Align R) const6177fc4c14SDimitry Andric int FunctionComparator::cmpAligns(Align L, Align R) const {
6277fc4c14SDimitry Andric   if (L.value() < R.value())
6377fc4c14SDimitry Andric     return -1;
6477fc4c14SDimitry Andric   if (L.value() > R.value())
6577fc4c14SDimitry Andric     return 1;
6677fc4c14SDimitry Andric   return 0;
6777fc4c14SDimitry Andric }
6877fc4c14SDimitry Andric 
cmpOrderings(AtomicOrdering L,AtomicOrdering R) const69b915e9e0SDimitry Andric int FunctionComparator::cmpOrderings(AtomicOrdering L, AtomicOrdering R) const {
70cfca06d7SDimitry Andric   if ((int)L < (int)R)
71cfca06d7SDimitry Andric     return -1;
72cfca06d7SDimitry Andric   if ((int)L > (int)R)
73cfca06d7SDimitry Andric     return 1;
74b915e9e0SDimitry Andric   return 0;
75b915e9e0SDimitry Andric }
76b915e9e0SDimitry Andric 
cmpAPInts(const APInt & L,const APInt & R) const77b915e9e0SDimitry Andric int FunctionComparator::cmpAPInts(const APInt &L, const APInt &R) const {
78b915e9e0SDimitry Andric   if (int Res = cmpNumbers(L.getBitWidth(), R.getBitWidth()))
79b915e9e0SDimitry Andric     return Res;
80cfca06d7SDimitry Andric   if (L.ugt(R))
81cfca06d7SDimitry Andric     return 1;
82cfca06d7SDimitry Andric   if (R.ugt(L))
83cfca06d7SDimitry Andric     return -1;
84b915e9e0SDimitry Andric   return 0;
85b915e9e0SDimitry Andric }
86b915e9e0SDimitry Andric 
cmpAPFloats(const APFloat & L,const APFloat & R) const87b915e9e0SDimitry Andric int FunctionComparator::cmpAPFloats(const APFloat &L, const APFloat &R) const {
88b915e9e0SDimitry Andric   // Floats are ordered first by semantics (i.e. float, double, half, etc.),
89b915e9e0SDimitry Andric   // then by value interpreted as a bitstring (aka APInt).
90b915e9e0SDimitry Andric   const fltSemantics &SL = L.getSemantics(), &SR = R.getSemantics();
91b915e9e0SDimitry Andric   if (int Res = cmpNumbers(APFloat::semanticsPrecision(SL),
92b915e9e0SDimitry Andric                            APFloat::semanticsPrecision(SR)))
93b915e9e0SDimitry Andric     return Res;
94b915e9e0SDimitry Andric   if (int Res = cmpNumbers(APFloat::semanticsMaxExponent(SL),
95b915e9e0SDimitry Andric                            APFloat::semanticsMaxExponent(SR)))
96b915e9e0SDimitry Andric     return Res;
97b915e9e0SDimitry Andric   if (int Res = cmpNumbers(APFloat::semanticsMinExponent(SL),
98b915e9e0SDimitry Andric                            APFloat::semanticsMinExponent(SR)))
99b915e9e0SDimitry Andric     return Res;
100b915e9e0SDimitry Andric   if (int Res = cmpNumbers(APFloat::semanticsSizeInBits(SL),
101b915e9e0SDimitry Andric                            APFloat::semanticsSizeInBits(SR)))
102b915e9e0SDimitry Andric     return Res;
103b915e9e0SDimitry Andric   return cmpAPInts(L.bitcastToAPInt(), R.bitcastToAPInt());
104b915e9e0SDimitry Andric }
105b915e9e0SDimitry Andric 
cmpMem(StringRef L,StringRef R) const106b915e9e0SDimitry Andric int FunctionComparator::cmpMem(StringRef L, StringRef R) const {
107b915e9e0SDimitry Andric   // Prevent heavy comparison, compare sizes first.
108b915e9e0SDimitry Andric   if (int Res = cmpNumbers(L.size(), R.size()))
109b915e9e0SDimitry Andric     return Res;
110b915e9e0SDimitry Andric 
111b915e9e0SDimitry Andric   // Compare strings lexicographically only when it is necessary: only when
112b915e9e0SDimitry Andric   // strings are equal in size.
113e3b55780SDimitry Andric   return std::clamp(L.compare(R), -1, 1);
114b915e9e0SDimitry Andric }
115b915e9e0SDimitry Andric 
cmpAttrs(const AttributeList L,const AttributeList R) const11671d5a254SDimitry Andric int FunctionComparator::cmpAttrs(const AttributeList L,
11771d5a254SDimitry Andric                                  const AttributeList R) const {
118ab44ce3dSDimitry Andric   if (int Res = cmpNumbers(L.getNumAttrSets(), R.getNumAttrSets()))
119b915e9e0SDimitry Andric     return Res;
120b915e9e0SDimitry Andric 
121c0981da4SDimitry Andric   for (unsigned i : L.indexes()) {
122ab44ce3dSDimitry Andric     AttributeSet LAS = L.getAttributes(i);
123ab44ce3dSDimitry Andric     AttributeSet RAS = R.getAttributes(i);
124ab44ce3dSDimitry Andric     AttributeSet::iterator LI = LAS.begin(), LE = LAS.end();
125ab44ce3dSDimitry Andric     AttributeSet::iterator RI = RAS.begin(), RE = RAS.end();
126b915e9e0SDimitry Andric     for (; LI != LE && RI != RE; ++LI, ++RI) {
127b915e9e0SDimitry Andric       Attribute LA = *LI;
128b915e9e0SDimitry Andric       Attribute RA = *RI;
129e6d15924SDimitry Andric       if (LA.isTypeAttribute() && RA.isTypeAttribute()) {
130e6d15924SDimitry Andric         if (LA.getKindAsEnum() != RA.getKindAsEnum())
131e6d15924SDimitry Andric           return cmpNumbers(LA.getKindAsEnum(), RA.getKindAsEnum());
132e6d15924SDimitry Andric 
133e6d15924SDimitry Andric         Type *TyL = LA.getValueAsType();
134e6d15924SDimitry Andric         Type *TyR = RA.getValueAsType();
135b60736ecSDimitry Andric         if (TyL && TyR) {
136b60736ecSDimitry Andric           if (int Res = cmpTypes(TyL, TyR))
137b60736ecSDimitry Andric             return Res;
138b60736ecSDimitry Andric           continue;
139b60736ecSDimitry Andric         }
140e6d15924SDimitry Andric 
141e6d15924SDimitry Andric         // Two pointers, at least one null, so the comparison result is
142e6d15924SDimitry Andric         // independent of the value of a real pointer.
143b60736ecSDimitry Andric         if (int Res = cmpNumbers((uint64_t)TyL, (uint64_t)TyR))
144b60736ecSDimitry Andric           return Res;
145b60736ecSDimitry Andric         continue;
146ac9a064cSDimitry Andric       } else if (LA.isConstantRangeAttribute() &&
147ac9a064cSDimitry Andric                  RA.isConstantRangeAttribute()) {
148ac9a064cSDimitry Andric         if (LA.getKindAsEnum() != RA.getKindAsEnum())
149ac9a064cSDimitry Andric           return cmpNumbers(LA.getKindAsEnum(), RA.getKindAsEnum());
150ac9a064cSDimitry Andric 
151ac9a064cSDimitry Andric         const ConstantRange &LCR = LA.getRange();
152ac9a064cSDimitry Andric         const ConstantRange &RCR = RA.getRange();
153ac9a064cSDimitry Andric         if (int Res = cmpAPInts(LCR.getLower(), RCR.getLower()))
154ac9a064cSDimitry Andric           return Res;
155ac9a064cSDimitry Andric         if (int Res = cmpAPInts(LCR.getUpper(), RCR.getUpper()))
156ac9a064cSDimitry Andric           return Res;
157ac9a064cSDimitry Andric         continue;
158e6d15924SDimitry Andric       }
159b915e9e0SDimitry Andric       if (LA < RA)
160b915e9e0SDimitry Andric         return -1;
161b915e9e0SDimitry Andric       if (RA < LA)
162b915e9e0SDimitry Andric         return 1;
163b915e9e0SDimitry Andric     }
164b915e9e0SDimitry Andric     if (LI != LE)
165b915e9e0SDimitry Andric       return 1;
166b915e9e0SDimitry Andric     if (RI != RE)
167b915e9e0SDimitry Andric       return -1;
168b915e9e0SDimitry Andric   }
169b915e9e0SDimitry Andric   return 0;
170b915e9e0SDimitry Andric }
171b915e9e0SDimitry Andric 
cmpMetadata(const Metadata * L,const Metadata * R) const1727fa27ce4SDimitry Andric int FunctionComparator::cmpMetadata(const Metadata *L,
1737fa27ce4SDimitry Andric                                     const Metadata *R) const {
1747fa27ce4SDimitry Andric   // TODO: the following routine coerce the metadata contents into constants
175b1c73532SDimitry Andric   // or MDStrings before comparison.
1767fa27ce4SDimitry Andric   // It ignores any other cases, so that the metadata nodes are considered
1777fa27ce4SDimitry Andric   // equal even though this is not correct.
1787fa27ce4SDimitry Andric   // We should structurally compare the metadata nodes to be perfect here.
179b1c73532SDimitry Andric 
180b1c73532SDimitry Andric   auto *MDStringL = dyn_cast<MDString>(L);
181b1c73532SDimitry Andric   auto *MDStringR = dyn_cast<MDString>(R);
182b1c73532SDimitry Andric   if (MDStringL && MDStringR) {
183b1c73532SDimitry Andric     if (MDStringL == MDStringR)
184b1c73532SDimitry Andric       return 0;
185b1c73532SDimitry Andric     return MDStringL->getString().compare(MDStringR->getString());
186b1c73532SDimitry Andric   }
187b1c73532SDimitry Andric   if (MDStringR)
188b1c73532SDimitry Andric     return -1;
189b1c73532SDimitry Andric   if (MDStringL)
190b1c73532SDimitry Andric     return 1;
191b1c73532SDimitry Andric 
1927fa27ce4SDimitry Andric   auto *CL = dyn_cast<ConstantAsMetadata>(L);
1937fa27ce4SDimitry Andric   auto *CR = dyn_cast<ConstantAsMetadata>(R);
1947fa27ce4SDimitry Andric   if (CL == CR)
1957fa27ce4SDimitry Andric     return 0;
1967fa27ce4SDimitry Andric   if (!CL)
1977fa27ce4SDimitry Andric     return -1;
1987fa27ce4SDimitry Andric   if (!CR)
1997fa27ce4SDimitry Andric     return 1;
2007fa27ce4SDimitry Andric   return cmpConstants(CL->getValue(), CR->getValue());
2017fa27ce4SDimitry Andric }
2027fa27ce4SDimitry Andric 
cmpMDNode(const MDNode * L,const MDNode * R) const2037fa27ce4SDimitry Andric int FunctionComparator::cmpMDNode(const MDNode *L, const MDNode *R) const {
204b915e9e0SDimitry Andric   if (L == R)
205b915e9e0SDimitry Andric     return 0;
206b915e9e0SDimitry Andric   if (!L)
207b915e9e0SDimitry Andric     return -1;
208b915e9e0SDimitry Andric   if (!R)
209b915e9e0SDimitry Andric     return 1;
210b915e9e0SDimitry Andric   // TODO: Note that as this is metadata, it is possible to drop and/or merge
211b915e9e0SDimitry Andric   // this data when considering functions to merge. Thus this comparison would
212b915e9e0SDimitry Andric   // return 0 (i.e. equivalent), but merging would become more complicated
213b915e9e0SDimitry Andric   // because the ranges would need to be unioned. It is not likely that
214b915e9e0SDimitry Andric   // functions differ ONLY in this metadata if they are actually the same
215b915e9e0SDimitry Andric   // function semantically.
216b915e9e0SDimitry Andric   if (int Res = cmpNumbers(L->getNumOperands(), R->getNumOperands()))
217b915e9e0SDimitry Andric     return Res;
2187fa27ce4SDimitry Andric   for (size_t I = 0; I < L->getNumOperands(); ++I)
2197fa27ce4SDimitry Andric     if (int Res = cmpMetadata(L->getOperand(I), R->getOperand(I)))
2207fa27ce4SDimitry Andric       return Res;
2217fa27ce4SDimitry Andric   return 0;
2227fa27ce4SDimitry Andric }
2237fa27ce4SDimitry Andric 
cmpInstMetadata(Instruction const * L,Instruction const * R) const2247fa27ce4SDimitry Andric int FunctionComparator::cmpInstMetadata(Instruction const *L,
2257fa27ce4SDimitry Andric                                         Instruction const *R) const {
2267fa27ce4SDimitry Andric   /// These metadata affects the other optimization passes by making assertions
2277fa27ce4SDimitry Andric   /// or constraints.
2287fa27ce4SDimitry Andric   /// Values that carry different expectations should be considered different.
2297fa27ce4SDimitry Andric   SmallVector<std::pair<unsigned, MDNode *>> MDL, MDR;
2307fa27ce4SDimitry Andric   L->getAllMetadataOtherThanDebugLoc(MDL);
2317fa27ce4SDimitry Andric   R->getAllMetadataOtherThanDebugLoc(MDR);
2327fa27ce4SDimitry Andric   if (MDL.size() > MDR.size())
2337fa27ce4SDimitry Andric     return 1;
2347fa27ce4SDimitry Andric   else if (MDL.size() < MDR.size())
2357fa27ce4SDimitry Andric     return -1;
2367fa27ce4SDimitry Andric   for (size_t I = 0, N = MDL.size(); I < N; ++I) {
2377fa27ce4SDimitry Andric     auto const [KeyL, ML] = MDL[I];
2387fa27ce4SDimitry Andric     auto const [KeyR, MR] = MDR[I];
2397fa27ce4SDimitry Andric     if (int Res = cmpNumbers(KeyL, KeyR))
2407fa27ce4SDimitry Andric       return Res;
2417fa27ce4SDimitry Andric     if (int Res = cmpMDNode(ML, MR))
242b915e9e0SDimitry Andric       return Res;
243b915e9e0SDimitry Andric   }
244b915e9e0SDimitry Andric   return 0;
245b915e9e0SDimitry Andric }
246b915e9e0SDimitry Andric 
cmpOperandBundlesSchema(const CallBase & LCS,const CallBase & RCS) const247cfca06d7SDimitry Andric int FunctionComparator::cmpOperandBundlesSchema(const CallBase &LCS,
248cfca06d7SDimitry Andric                                                 const CallBase &RCS) const {
249cfca06d7SDimitry Andric   assert(LCS.getOpcode() == RCS.getOpcode() && "Can't compare otherwise!");
250b915e9e0SDimitry Andric 
251b915e9e0SDimitry Andric   if (int Res =
252b915e9e0SDimitry Andric           cmpNumbers(LCS.getNumOperandBundles(), RCS.getNumOperandBundles()))
253b915e9e0SDimitry Andric     return Res;
254b915e9e0SDimitry Andric 
255cfca06d7SDimitry Andric   for (unsigned I = 0, E = LCS.getNumOperandBundles(); I != E; ++I) {
256cfca06d7SDimitry Andric     auto OBL = LCS.getOperandBundleAt(I);
257cfca06d7SDimitry Andric     auto OBR = RCS.getOperandBundleAt(I);
258b915e9e0SDimitry Andric 
259b915e9e0SDimitry Andric     if (int Res = OBL.getTagName().compare(OBR.getTagName()))
260b915e9e0SDimitry Andric       return Res;
261b915e9e0SDimitry Andric 
262b915e9e0SDimitry Andric     if (int Res = cmpNumbers(OBL.Inputs.size(), OBR.Inputs.size()))
263b915e9e0SDimitry Andric       return Res;
264b915e9e0SDimitry Andric   }
265b915e9e0SDimitry Andric 
266b915e9e0SDimitry Andric   return 0;
267b915e9e0SDimitry Andric }
268b915e9e0SDimitry Andric 
269b915e9e0SDimitry Andric /// Constants comparison:
270b915e9e0SDimitry Andric /// 1. Check whether type of L constant could be losslessly bitcasted to R
271b915e9e0SDimitry Andric /// type.
272b915e9e0SDimitry Andric /// 2. Compare constant contents.
273b915e9e0SDimitry Andric /// For more details see declaration comments.
cmpConstants(const Constant * L,const Constant * R) const274b915e9e0SDimitry Andric int FunctionComparator::cmpConstants(const Constant *L,
275b915e9e0SDimitry Andric                                      const Constant *R) const {
276b915e9e0SDimitry Andric   Type *TyL = L->getType();
277b915e9e0SDimitry Andric   Type *TyR = R->getType();
278b915e9e0SDimitry Andric 
279b915e9e0SDimitry Andric   // Check whether types are bitcastable. This part is just re-factored
280b915e9e0SDimitry Andric   // Type::canLosslesslyBitCastTo method, but instead of returning true/false,
281b915e9e0SDimitry Andric   // we also pack into result which type is "less" for us.
282b915e9e0SDimitry Andric   int TypesRes = cmpTypes(TyL, TyR);
283b915e9e0SDimitry Andric   if (TypesRes != 0) {
284b915e9e0SDimitry Andric     // Types are different, but check whether we can bitcast them.
285b915e9e0SDimitry Andric     if (!TyL->isFirstClassType()) {
286b915e9e0SDimitry Andric       if (TyR->isFirstClassType())
287b915e9e0SDimitry Andric         return -1;
288b915e9e0SDimitry Andric       // Neither TyL nor TyR are values of first class type. Return the result
289b915e9e0SDimitry Andric       // of comparing the types
290b915e9e0SDimitry Andric       return TypesRes;
291b915e9e0SDimitry Andric     }
292b915e9e0SDimitry Andric     if (!TyR->isFirstClassType()) {
293b915e9e0SDimitry Andric       if (TyL->isFirstClassType())
294b915e9e0SDimitry Andric         return 1;
295b915e9e0SDimitry Andric       return TypesRes;
296b915e9e0SDimitry Andric     }
297b915e9e0SDimitry Andric 
298b915e9e0SDimitry Andric     // Vector -> Vector conversions are always lossless if the two vector types
299b915e9e0SDimitry Andric     // have the same size, otherwise not.
300b915e9e0SDimitry Andric     unsigned TyLWidth = 0;
301b915e9e0SDimitry Andric     unsigned TyRWidth = 0;
302b915e9e0SDimitry Andric 
303b915e9e0SDimitry Andric     if (auto *VecTyL = dyn_cast<VectorType>(TyL))
304e3b55780SDimitry Andric       TyLWidth = VecTyL->getPrimitiveSizeInBits().getFixedValue();
305b915e9e0SDimitry Andric     if (auto *VecTyR = dyn_cast<VectorType>(TyR))
306e3b55780SDimitry Andric       TyRWidth = VecTyR->getPrimitiveSizeInBits().getFixedValue();
307b915e9e0SDimitry Andric 
308b915e9e0SDimitry Andric     if (TyLWidth != TyRWidth)
309b915e9e0SDimitry Andric       return cmpNumbers(TyLWidth, TyRWidth);
310b915e9e0SDimitry Andric 
311b915e9e0SDimitry Andric     // Zero bit-width means neither TyL nor TyR are vectors.
312b915e9e0SDimitry Andric     if (!TyLWidth) {
313b915e9e0SDimitry Andric       PointerType *PTyL = dyn_cast<PointerType>(TyL);
314b915e9e0SDimitry Andric       PointerType *PTyR = dyn_cast<PointerType>(TyR);
315b915e9e0SDimitry Andric       if (PTyL && PTyR) {
316b915e9e0SDimitry Andric         unsigned AddrSpaceL = PTyL->getAddressSpace();
317b915e9e0SDimitry Andric         unsigned AddrSpaceR = PTyR->getAddressSpace();
318b915e9e0SDimitry Andric         if (int Res = cmpNumbers(AddrSpaceL, AddrSpaceR))
319b915e9e0SDimitry Andric           return Res;
320b915e9e0SDimitry Andric       }
321b915e9e0SDimitry Andric       if (PTyL)
322b915e9e0SDimitry Andric         return 1;
323b915e9e0SDimitry Andric       if (PTyR)
324b915e9e0SDimitry Andric         return -1;
325b915e9e0SDimitry Andric 
326b915e9e0SDimitry Andric       // TyL and TyR aren't vectors, nor pointers. We don't know how to
327b915e9e0SDimitry Andric       // bitcast them.
328b915e9e0SDimitry Andric       return TypesRes;
329b915e9e0SDimitry Andric     }
330b915e9e0SDimitry Andric   }
331b915e9e0SDimitry Andric 
332b915e9e0SDimitry Andric   // OK, types are bitcastable, now check constant contents.
333b915e9e0SDimitry Andric 
334b915e9e0SDimitry Andric   if (L->isNullValue() && R->isNullValue())
335b915e9e0SDimitry Andric     return TypesRes;
336b915e9e0SDimitry Andric   if (L->isNullValue() && !R->isNullValue())
337b915e9e0SDimitry Andric     return 1;
338b915e9e0SDimitry Andric   if (!L->isNullValue() && R->isNullValue())
339b915e9e0SDimitry Andric     return -1;
340b915e9e0SDimitry Andric 
341b915e9e0SDimitry Andric   auto GlobalValueL = const_cast<GlobalValue *>(dyn_cast<GlobalValue>(L));
342b915e9e0SDimitry Andric   auto GlobalValueR = const_cast<GlobalValue *>(dyn_cast<GlobalValue>(R));
343b915e9e0SDimitry Andric   if (GlobalValueL && GlobalValueR) {
344b915e9e0SDimitry Andric     return cmpGlobalValues(GlobalValueL, GlobalValueR);
345b915e9e0SDimitry Andric   }
346b915e9e0SDimitry Andric 
347b915e9e0SDimitry Andric   if (int Res = cmpNumbers(L->getValueID(), R->getValueID()))
348b915e9e0SDimitry Andric     return Res;
349b915e9e0SDimitry Andric 
350b915e9e0SDimitry Andric   if (const auto *SeqL = dyn_cast<ConstantDataSequential>(L)) {
351b915e9e0SDimitry Andric     const auto *SeqR = cast<ConstantDataSequential>(R);
352b915e9e0SDimitry Andric     // This handles ConstantDataArray and ConstantDataVector. Note that we
353b915e9e0SDimitry Andric     // compare the two raw data arrays, which might differ depending on the host
354b915e9e0SDimitry Andric     // endianness. This isn't a problem though, because the endiness of a module
355b915e9e0SDimitry Andric     // will affect the order of the constants, but this order is the same
356b915e9e0SDimitry Andric     // for a given input module and host platform.
357b915e9e0SDimitry Andric     return cmpMem(SeqL->getRawDataValues(), SeqR->getRawDataValues());
358b915e9e0SDimitry Andric   }
359b915e9e0SDimitry Andric 
360b915e9e0SDimitry Andric   switch (L->getValueID()) {
361b915e9e0SDimitry Andric   case Value::UndefValueVal:
362b60736ecSDimitry Andric   case Value::PoisonValueVal:
363b915e9e0SDimitry Andric   case Value::ConstantTokenNoneVal:
364b915e9e0SDimitry Andric     return TypesRes;
365b915e9e0SDimitry Andric   case Value::ConstantIntVal: {
366b915e9e0SDimitry Andric     const APInt &LInt = cast<ConstantInt>(L)->getValue();
367b915e9e0SDimitry Andric     const APInt &RInt = cast<ConstantInt>(R)->getValue();
368b915e9e0SDimitry Andric     return cmpAPInts(LInt, RInt);
369b915e9e0SDimitry Andric   }
370b915e9e0SDimitry Andric   case Value::ConstantFPVal: {
371b915e9e0SDimitry Andric     const APFloat &LAPF = cast<ConstantFP>(L)->getValueAPF();
372b915e9e0SDimitry Andric     const APFloat &RAPF = cast<ConstantFP>(R)->getValueAPF();
373b915e9e0SDimitry Andric     return cmpAPFloats(LAPF, RAPF);
374b915e9e0SDimitry Andric   }
375b915e9e0SDimitry Andric   case Value::ConstantArrayVal: {
376b915e9e0SDimitry Andric     const ConstantArray *LA = cast<ConstantArray>(L);
377b915e9e0SDimitry Andric     const ConstantArray *RA = cast<ConstantArray>(R);
378b915e9e0SDimitry Andric     uint64_t NumElementsL = cast<ArrayType>(TyL)->getNumElements();
379b915e9e0SDimitry Andric     uint64_t NumElementsR = cast<ArrayType>(TyR)->getNumElements();
380b915e9e0SDimitry Andric     if (int Res = cmpNumbers(NumElementsL, NumElementsR))
381b915e9e0SDimitry Andric       return Res;
382b915e9e0SDimitry Andric     for (uint64_t i = 0; i < NumElementsL; ++i) {
383b915e9e0SDimitry Andric       if (int Res = cmpConstants(cast<Constant>(LA->getOperand(i)),
384b915e9e0SDimitry Andric                                  cast<Constant>(RA->getOperand(i))))
385b915e9e0SDimitry Andric         return Res;
386b915e9e0SDimitry Andric     }
387b915e9e0SDimitry Andric     return 0;
388b915e9e0SDimitry Andric   }
389b915e9e0SDimitry Andric   case Value::ConstantStructVal: {
390b915e9e0SDimitry Andric     const ConstantStruct *LS = cast<ConstantStruct>(L);
391b915e9e0SDimitry Andric     const ConstantStruct *RS = cast<ConstantStruct>(R);
392b915e9e0SDimitry Andric     unsigned NumElementsL = cast<StructType>(TyL)->getNumElements();
393b915e9e0SDimitry Andric     unsigned NumElementsR = cast<StructType>(TyR)->getNumElements();
394b915e9e0SDimitry Andric     if (int Res = cmpNumbers(NumElementsL, NumElementsR))
395b915e9e0SDimitry Andric       return Res;
396b915e9e0SDimitry Andric     for (unsigned i = 0; i != NumElementsL; ++i) {
397b915e9e0SDimitry Andric       if (int Res = cmpConstants(cast<Constant>(LS->getOperand(i)),
398b915e9e0SDimitry Andric                                  cast<Constant>(RS->getOperand(i))))
399b915e9e0SDimitry Andric         return Res;
400b915e9e0SDimitry Andric     }
401b915e9e0SDimitry Andric     return 0;
402b915e9e0SDimitry Andric   }
403b915e9e0SDimitry Andric   case Value::ConstantVectorVal: {
404b915e9e0SDimitry Andric     const ConstantVector *LV = cast<ConstantVector>(L);
405b915e9e0SDimitry Andric     const ConstantVector *RV = cast<ConstantVector>(R);
406cfca06d7SDimitry Andric     unsigned NumElementsL = cast<FixedVectorType>(TyL)->getNumElements();
407cfca06d7SDimitry Andric     unsigned NumElementsR = cast<FixedVectorType>(TyR)->getNumElements();
408b915e9e0SDimitry Andric     if (int Res = cmpNumbers(NumElementsL, NumElementsR))
409b915e9e0SDimitry Andric       return Res;
410b915e9e0SDimitry Andric     for (uint64_t i = 0; i < NumElementsL; ++i) {
411b915e9e0SDimitry Andric       if (int Res = cmpConstants(cast<Constant>(LV->getOperand(i)),
412b915e9e0SDimitry Andric                                  cast<Constant>(RV->getOperand(i))))
413b915e9e0SDimitry Andric         return Res;
414b915e9e0SDimitry Andric     }
415b915e9e0SDimitry Andric     return 0;
416b915e9e0SDimitry Andric   }
417b915e9e0SDimitry Andric   case Value::ConstantExprVal: {
418b915e9e0SDimitry Andric     const ConstantExpr *LE = cast<ConstantExpr>(L);
419b915e9e0SDimitry Andric     const ConstantExpr *RE = cast<ConstantExpr>(R);
42099aabd70SDimitry Andric     if (int Res = cmpNumbers(LE->getOpcode(), RE->getOpcode()))
42199aabd70SDimitry Andric       return Res;
422b915e9e0SDimitry Andric     unsigned NumOperandsL = LE->getNumOperands();
423b915e9e0SDimitry Andric     unsigned NumOperandsR = RE->getNumOperands();
424b915e9e0SDimitry Andric     if (int Res = cmpNumbers(NumOperandsL, NumOperandsR))
425b915e9e0SDimitry Andric       return Res;
426b915e9e0SDimitry Andric     for (unsigned i = 0; i < NumOperandsL; ++i) {
427b915e9e0SDimitry Andric       if (int Res = cmpConstants(cast<Constant>(LE->getOperand(i)),
428b915e9e0SDimitry Andric                                  cast<Constant>(RE->getOperand(i))))
429b915e9e0SDimitry Andric         return Res;
430b915e9e0SDimitry Andric     }
43199aabd70SDimitry Andric     if (auto *GEPL = dyn_cast<GEPOperator>(LE)) {
43299aabd70SDimitry Andric       auto *GEPR = cast<GEPOperator>(RE);
43399aabd70SDimitry Andric       if (int Res = cmpTypes(GEPL->getSourceElementType(),
43499aabd70SDimitry Andric                              GEPR->getSourceElementType()))
43599aabd70SDimitry Andric         return Res;
436ac9a064cSDimitry Andric       if (int Res = cmpNumbers(GEPL->getNoWrapFlags().getRaw(),
437ac9a064cSDimitry Andric                                GEPR->getNoWrapFlags().getRaw()))
43899aabd70SDimitry Andric         return Res;
439ac9a064cSDimitry Andric 
440ac9a064cSDimitry Andric       std::optional<ConstantRange> InRangeL = GEPL->getInRange();
441ac9a064cSDimitry Andric       std::optional<ConstantRange> InRangeR = GEPR->getInRange();
442ac9a064cSDimitry Andric       if (InRangeL) {
443ac9a064cSDimitry Andric         if (!InRangeR)
444ac9a064cSDimitry Andric           return 1;
445ac9a064cSDimitry Andric         if (int Res = cmpAPInts(InRangeL->getLower(), InRangeR->getLower()))
44699aabd70SDimitry Andric           return Res;
447ac9a064cSDimitry Andric         if (int Res = cmpAPInts(InRangeL->getUpper(), InRangeR->getUpper()))
448ac9a064cSDimitry Andric           return Res;
449ac9a064cSDimitry Andric       } else if (InRangeR) {
450ac9a064cSDimitry Andric         return -1;
451ac9a064cSDimitry Andric       }
45299aabd70SDimitry Andric     }
45399aabd70SDimitry Andric     if (auto *OBOL = dyn_cast<OverflowingBinaryOperator>(LE)) {
45499aabd70SDimitry Andric       auto *OBOR = cast<OverflowingBinaryOperator>(RE);
45599aabd70SDimitry Andric       if (int Res =
45699aabd70SDimitry Andric               cmpNumbers(OBOL->hasNoUnsignedWrap(), OBOR->hasNoUnsignedWrap()))
45799aabd70SDimitry Andric         return Res;
45899aabd70SDimitry Andric       if (int Res =
45999aabd70SDimitry Andric               cmpNumbers(OBOL->hasNoSignedWrap(), OBOR->hasNoSignedWrap()))
46099aabd70SDimitry Andric         return Res;
46199aabd70SDimitry Andric     }
462b915e9e0SDimitry Andric     return 0;
463b915e9e0SDimitry Andric   }
464b915e9e0SDimitry Andric   case Value::BlockAddressVal: {
465b915e9e0SDimitry Andric     const BlockAddress *LBA = cast<BlockAddress>(L);
466b915e9e0SDimitry Andric     const BlockAddress *RBA = cast<BlockAddress>(R);
467b915e9e0SDimitry Andric     if (int Res = cmpValues(LBA->getFunction(), RBA->getFunction()))
468b915e9e0SDimitry Andric       return Res;
469b915e9e0SDimitry Andric     if (LBA->getFunction() == RBA->getFunction()) {
470b915e9e0SDimitry Andric       // They are BBs in the same function. Order by which comes first in the
471b915e9e0SDimitry Andric       // BB order of the function. This order is deterministic.
472b915e9e0SDimitry Andric       Function *F = LBA->getFunction();
473b915e9e0SDimitry Andric       BasicBlock *LBB = LBA->getBasicBlock();
474b915e9e0SDimitry Andric       BasicBlock *RBB = RBA->getBasicBlock();
475b915e9e0SDimitry Andric       if (LBB == RBB)
476b915e9e0SDimitry Andric         return 0;
477e3b55780SDimitry Andric       for (BasicBlock &BB : *F) {
478b915e9e0SDimitry Andric         if (&BB == LBB) {
479b915e9e0SDimitry Andric           assert(&BB != RBB);
480b915e9e0SDimitry Andric           return -1;
481b915e9e0SDimitry Andric         }
482b915e9e0SDimitry Andric         if (&BB == RBB)
483b915e9e0SDimitry Andric           return 1;
484b915e9e0SDimitry Andric       }
485b915e9e0SDimitry Andric       llvm_unreachable("Basic Block Address does not point to a basic block in "
486b915e9e0SDimitry Andric                        "its function.");
487b915e9e0SDimitry Andric       return -1;
488b915e9e0SDimitry Andric     } else {
489b915e9e0SDimitry Andric       // cmpValues said the functions are the same. So because they aren't
490b915e9e0SDimitry Andric       // literally the same pointer, they must respectively be the left and
491b915e9e0SDimitry Andric       // right functions.
492b915e9e0SDimitry Andric       assert(LBA->getFunction() == FnL && RBA->getFunction() == FnR);
493b915e9e0SDimitry Andric       // cmpValues will tell us if these are equivalent BasicBlocks, in the
494b915e9e0SDimitry Andric       // context of their respective functions.
495b915e9e0SDimitry Andric       return cmpValues(LBA->getBasicBlock(), RBA->getBasicBlock());
496b915e9e0SDimitry Andric     }
497b915e9e0SDimitry Andric   }
498e3b55780SDimitry Andric   case Value::DSOLocalEquivalentVal: {
499e3b55780SDimitry Andric     // dso_local_equivalent is functionally equivalent to whatever it points to.
500e3b55780SDimitry Andric     // This means the behavior of the IR should be the exact same as if the
501e3b55780SDimitry Andric     // function was referenced directly rather than through a
502e3b55780SDimitry Andric     // dso_local_equivalent.
503e3b55780SDimitry Andric     const auto *LEquiv = cast<DSOLocalEquivalent>(L);
504e3b55780SDimitry Andric     const auto *REquiv = cast<DSOLocalEquivalent>(R);
505e3b55780SDimitry Andric     return cmpGlobalValues(LEquiv->getGlobalValue(), REquiv->getGlobalValue());
506e3b55780SDimitry Andric   }
507b915e9e0SDimitry Andric   default: // Unknown constant, abort.
508eb11fae6SDimitry Andric     LLVM_DEBUG(dbgs() << "Looking at valueID " << L->getValueID() << "\n");
509b915e9e0SDimitry Andric     llvm_unreachable("Constant ValueID not recognized.");
510b915e9e0SDimitry Andric     return -1;
511b915e9e0SDimitry Andric   }
512b915e9e0SDimitry Andric }
513b915e9e0SDimitry Andric 
cmpGlobalValues(GlobalValue * L,GlobalValue * R) const514b915e9e0SDimitry Andric int FunctionComparator::cmpGlobalValues(GlobalValue *L, GlobalValue *R) const {
515b915e9e0SDimitry Andric   uint64_t LNumber = GlobalNumbers->getNumber(L);
516b915e9e0SDimitry Andric   uint64_t RNumber = GlobalNumbers->getNumber(R);
517b915e9e0SDimitry Andric   return cmpNumbers(LNumber, RNumber);
518b915e9e0SDimitry Andric }
519b915e9e0SDimitry Andric 
520b915e9e0SDimitry Andric /// cmpType - compares two types,
521b915e9e0SDimitry Andric /// defines total ordering among the types set.
522b915e9e0SDimitry Andric /// See method declaration comments for more details.
cmpTypes(Type * TyL,Type * TyR) const523b915e9e0SDimitry Andric int FunctionComparator::cmpTypes(Type *TyL, Type *TyR) const {
524b915e9e0SDimitry Andric   PointerType *PTyL = dyn_cast<PointerType>(TyL);
525b915e9e0SDimitry Andric   PointerType *PTyR = dyn_cast<PointerType>(TyR);
526b915e9e0SDimitry Andric 
527ac9a064cSDimitry Andric   const DataLayout &DL = FnL->getDataLayout();
528b915e9e0SDimitry Andric   if (PTyL && PTyL->getAddressSpace() == 0)
529b915e9e0SDimitry Andric     TyL = DL.getIntPtrType(TyL);
530b915e9e0SDimitry Andric   if (PTyR && PTyR->getAddressSpace() == 0)
531b915e9e0SDimitry Andric     TyR = DL.getIntPtrType(TyR);
532b915e9e0SDimitry Andric 
533b915e9e0SDimitry Andric   if (TyL == TyR)
534b915e9e0SDimitry Andric     return 0;
535b915e9e0SDimitry Andric 
536b915e9e0SDimitry Andric   if (int Res = cmpNumbers(TyL->getTypeID(), TyR->getTypeID()))
537b915e9e0SDimitry Andric     return Res;
538b915e9e0SDimitry Andric 
539b915e9e0SDimitry Andric   switch (TyL->getTypeID()) {
540b915e9e0SDimitry Andric   default:
541b915e9e0SDimitry Andric     llvm_unreachable("Unknown type!");
542b915e9e0SDimitry Andric   case Type::IntegerTyID:
543b915e9e0SDimitry Andric     return cmpNumbers(cast<IntegerType>(TyL)->getBitWidth(),
544b915e9e0SDimitry Andric                       cast<IntegerType>(TyR)->getBitWidth());
545b915e9e0SDimitry Andric   // TyL == TyR would have returned true earlier, because types are uniqued.
546b915e9e0SDimitry Andric   case Type::VoidTyID:
547b915e9e0SDimitry Andric   case Type::FloatTyID:
548b915e9e0SDimitry Andric   case Type::DoubleTyID:
549b915e9e0SDimitry Andric   case Type::X86_FP80TyID:
550b915e9e0SDimitry Andric   case Type::FP128TyID:
551b915e9e0SDimitry Andric   case Type::PPC_FP128TyID:
552b915e9e0SDimitry Andric   case Type::LabelTyID:
553b915e9e0SDimitry Andric   case Type::MetadataTyID:
554b915e9e0SDimitry Andric   case Type::TokenTyID:
555b915e9e0SDimitry Andric     return 0;
556b915e9e0SDimitry Andric 
557044eb2f6SDimitry Andric   case Type::PointerTyID:
558b915e9e0SDimitry Andric     assert(PTyL && PTyR && "Both types must be pointers here.");
559b915e9e0SDimitry Andric     return cmpNumbers(PTyL->getAddressSpace(), PTyR->getAddressSpace());
560b915e9e0SDimitry Andric 
561b915e9e0SDimitry Andric   case Type::StructTyID: {
562b915e9e0SDimitry Andric     StructType *STyL = cast<StructType>(TyL);
563b915e9e0SDimitry Andric     StructType *STyR = cast<StructType>(TyR);
564b915e9e0SDimitry Andric     if (STyL->getNumElements() != STyR->getNumElements())
565b915e9e0SDimitry Andric       return cmpNumbers(STyL->getNumElements(), STyR->getNumElements());
566b915e9e0SDimitry Andric 
567b915e9e0SDimitry Andric     if (STyL->isPacked() != STyR->isPacked())
568b915e9e0SDimitry Andric       return cmpNumbers(STyL->isPacked(), STyR->isPacked());
569b915e9e0SDimitry Andric 
570b915e9e0SDimitry Andric     for (unsigned i = 0, e = STyL->getNumElements(); i != e; ++i) {
571b915e9e0SDimitry Andric       if (int Res = cmpTypes(STyL->getElementType(i), STyR->getElementType(i)))
572b915e9e0SDimitry Andric         return Res;
573b915e9e0SDimitry Andric     }
574b915e9e0SDimitry Andric     return 0;
575b915e9e0SDimitry Andric   }
576b915e9e0SDimitry Andric 
577b915e9e0SDimitry Andric   case Type::FunctionTyID: {
578b915e9e0SDimitry Andric     FunctionType *FTyL = cast<FunctionType>(TyL);
579b915e9e0SDimitry Andric     FunctionType *FTyR = cast<FunctionType>(TyR);
580b915e9e0SDimitry Andric     if (FTyL->getNumParams() != FTyR->getNumParams())
581b915e9e0SDimitry Andric       return cmpNumbers(FTyL->getNumParams(), FTyR->getNumParams());
582b915e9e0SDimitry Andric 
583b915e9e0SDimitry Andric     if (FTyL->isVarArg() != FTyR->isVarArg())
584b915e9e0SDimitry Andric       return cmpNumbers(FTyL->isVarArg(), FTyR->isVarArg());
585b915e9e0SDimitry Andric 
586b915e9e0SDimitry Andric     if (int Res = cmpTypes(FTyL->getReturnType(), FTyR->getReturnType()))
587b915e9e0SDimitry Andric       return Res;
588b915e9e0SDimitry Andric 
589b915e9e0SDimitry Andric     for (unsigned i = 0, e = FTyL->getNumParams(); i != e; ++i) {
590b915e9e0SDimitry Andric       if (int Res = cmpTypes(FTyL->getParamType(i), FTyR->getParamType(i)))
591b915e9e0SDimitry Andric         return Res;
592b915e9e0SDimitry Andric     }
593b915e9e0SDimitry Andric     return 0;
594b915e9e0SDimitry Andric   }
595b915e9e0SDimitry Andric 
596cfca06d7SDimitry Andric   case Type::ArrayTyID: {
597cfca06d7SDimitry Andric     auto *STyL = cast<ArrayType>(TyL);
598cfca06d7SDimitry Andric     auto *STyR = cast<ArrayType>(TyR);
599b915e9e0SDimitry Andric     if (STyL->getNumElements() != STyR->getNumElements())
600b915e9e0SDimitry Andric       return cmpNumbers(STyL->getNumElements(), STyR->getNumElements());
601b915e9e0SDimitry Andric     return cmpTypes(STyL->getElementType(), STyR->getElementType());
602b915e9e0SDimitry Andric   }
603cfca06d7SDimitry Andric   case Type::FixedVectorTyID:
604cfca06d7SDimitry Andric   case Type::ScalableVectorTyID: {
605cfca06d7SDimitry Andric     auto *STyL = cast<VectorType>(TyL);
606cfca06d7SDimitry Andric     auto *STyR = cast<VectorType>(TyR);
607b60736ecSDimitry Andric     if (STyL->getElementCount().isScalable() !=
608b60736ecSDimitry Andric         STyR->getElementCount().isScalable())
609b60736ecSDimitry Andric       return cmpNumbers(STyL->getElementCount().isScalable(),
610b60736ecSDimitry Andric                         STyR->getElementCount().isScalable());
611b60736ecSDimitry Andric     if (STyL->getElementCount() != STyR->getElementCount())
612b60736ecSDimitry Andric       return cmpNumbers(STyL->getElementCount().getKnownMinValue(),
613b60736ecSDimitry Andric                         STyR->getElementCount().getKnownMinValue());
614cfca06d7SDimitry Andric     return cmpTypes(STyL->getElementType(), STyR->getElementType());
615cfca06d7SDimitry Andric   }
616b915e9e0SDimitry Andric   }
617b915e9e0SDimitry Andric }
618b915e9e0SDimitry Andric 
619b915e9e0SDimitry Andric // Determine whether the two operations are the same except that pointer-to-A
620b915e9e0SDimitry Andric // and pointer-to-B are equivalent. This should be kept in sync with
621b915e9e0SDimitry Andric // Instruction::isSameOperationAs.
622b915e9e0SDimitry Andric // Read method declaration comments for more details.
cmpOperations(const Instruction * L,const Instruction * R,bool & needToCmpOperands) const623b915e9e0SDimitry Andric int FunctionComparator::cmpOperations(const Instruction *L,
624b915e9e0SDimitry Andric                                       const Instruction *R,
625b915e9e0SDimitry Andric                                       bool &needToCmpOperands) const {
626b915e9e0SDimitry Andric   needToCmpOperands = true;
627b915e9e0SDimitry Andric   if (int Res = cmpValues(L, R))
628b915e9e0SDimitry Andric     return Res;
629b915e9e0SDimitry Andric 
630b915e9e0SDimitry Andric   // Differences from Instruction::isSameOperationAs:
631b915e9e0SDimitry Andric   //  * replace type comparison with calls to cmpTypes.
632b915e9e0SDimitry Andric   //  * we test for I->getRawSubclassOptionalData (nuw/nsw/tail) at the top.
633b915e9e0SDimitry Andric   //  * because of the above, we don't test for the tail bit on calls later on.
634b915e9e0SDimitry Andric   if (int Res = cmpNumbers(L->getOpcode(), R->getOpcode()))
635b915e9e0SDimitry Andric     return Res;
636b915e9e0SDimitry Andric 
637b915e9e0SDimitry Andric   if (const GetElementPtrInst *GEPL = dyn_cast<GetElementPtrInst>(L)) {
638b915e9e0SDimitry Andric     needToCmpOperands = false;
639b915e9e0SDimitry Andric     const GetElementPtrInst *GEPR = cast<GetElementPtrInst>(R);
640b915e9e0SDimitry Andric     if (int Res =
641b915e9e0SDimitry Andric             cmpValues(GEPL->getPointerOperand(), GEPR->getPointerOperand()))
642b915e9e0SDimitry Andric       return Res;
643b915e9e0SDimitry Andric     return cmpGEPs(GEPL, GEPR);
644b915e9e0SDimitry Andric   }
645b915e9e0SDimitry Andric 
646b915e9e0SDimitry Andric   if (int Res = cmpNumbers(L->getNumOperands(), R->getNumOperands()))
647b915e9e0SDimitry Andric     return Res;
648b915e9e0SDimitry Andric 
649b915e9e0SDimitry Andric   if (int Res = cmpTypes(L->getType(), R->getType()))
650b915e9e0SDimitry Andric     return Res;
651b915e9e0SDimitry Andric 
652b915e9e0SDimitry Andric   if (int Res = cmpNumbers(L->getRawSubclassOptionalData(),
653b915e9e0SDimitry Andric                            R->getRawSubclassOptionalData()))
654b915e9e0SDimitry Andric     return Res;
655b915e9e0SDimitry Andric 
656b915e9e0SDimitry Andric   // We have two instructions of identical opcode and #operands.  Check to see
657b915e9e0SDimitry Andric   // if all operands are the same type
658b915e9e0SDimitry Andric   for (unsigned i = 0, e = L->getNumOperands(); i != e; ++i) {
659b915e9e0SDimitry Andric     if (int Res =
660b915e9e0SDimitry Andric             cmpTypes(L->getOperand(i)->getType(), R->getOperand(i)->getType()))
661b915e9e0SDimitry Andric       return Res;
662b915e9e0SDimitry Andric   }
663b915e9e0SDimitry Andric 
664b915e9e0SDimitry Andric   // Check special state that is a part of some instructions.
665b915e9e0SDimitry Andric   if (const AllocaInst *AI = dyn_cast<AllocaInst>(L)) {
666b915e9e0SDimitry Andric     if (int Res = cmpTypes(AI->getAllocatedType(),
667b915e9e0SDimitry Andric                            cast<AllocaInst>(R)->getAllocatedType()))
668b915e9e0SDimitry Andric       return Res;
66977fc4c14SDimitry Andric     return cmpAligns(AI->getAlign(), cast<AllocaInst>(R)->getAlign());
670b915e9e0SDimitry Andric   }
671b915e9e0SDimitry Andric   if (const LoadInst *LI = dyn_cast<LoadInst>(L)) {
672b915e9e0SDimitry Andric     if (int Res = cmpNumbers(LI->isVolatile(), cast<LoadInst>(R)->isVolatile()))
673b915e9e0SDimitry Andric       return Res;
67477fc4c14SDimitry Andric     if (int Res = cmpAligns(LI->getAlign(), cast<LoadInst>(R)->getAlign()))
675b915e9e0SDimitry Andric       return Res;
676b915e9e0SDimitry Andric     if (int Res =
677b915e9e0SDimitry Andric             cmpOrderings(LI->getOrdering(), cast<LoadInst>(R)->getOrdering()))
678b915e9e0SDimitry Andric       return Res;
679ca089b24SDimitry Andric     if (int Res = cmpNumbers(LI->getSyncScopeID(),
680ca089b24SDimitry Andric                              cast<LoadInst>(R)->getSyncScopeID()))
681b915e9e0SDimitry Andric       return Res;
6827fa27ce4SDimitry Andric     return cmpInstMetadata(L, R);
683b915e9e0SDimitry Andric   }
684b915e9e0SDimitry Andric   if (const StoreInst *SI = dyn_cast<StoreInst>(L)) {
685b915e9e0SDimitry Andric     if (int Res =
686b915e9e0SDimitry Andric             cmpNumbers(SI->isVolatile(), cast<StoreInst>(R)->isVolatile()))
687b915e9e0SDimitry Andric       return Res;
68877fc4c14SDimitry Andric     if (int Res = cmpAligns(SI->getAlign(), cast<StoreInst>(R)->getAlign()))
689b915e9e0SDimitry Andric       return Res;
690b915e9e0SDimitry Andric     if (int Res =
691b915e9e0SDimitry Andric             cmpOrderings(SI->getOrdering(), cast<StoreInst>(R)->getOrdering()))
692b915e9e0SDimitry Andric       return Res;
693ca089b24SDimitry Andric     return cmpNumbers(SI->getSyncScopeID(),
694ca089b24SDimitry Andric                       cast<StoreInst>(R)->getSyncScopeID());
695b915e9e0SDimitry Andric   }
696b915e9e0SDimitry Andric   if (const CmpInst *CI = dyn_cast<CmpInst>(L))
697b915e9e0SDimitry Andric     return cmpNumbers(CI->getPredicate(), cast<CmpInst>(R)->getPredicate());
698cfca06d7SDimitry Andric   if (auto *CBL = dyn_cast<CallBase>(L)) {
699cfca06d7SDimitry Andric     auto *CBR = cast<CallBase>(R);
700cfca06d7SDimitry Andric     if (int Res = cmpNumbers(CBL->getCallingConv(), CBR->getCallingConv()))
701b915e9e0SDimitry Andric       return Res;
702cfca06d7SDimitry Andric     if (int Res = cmpAttrs(CBL->getAttributes(), CBR->getAttributes()))
703b915e9e0SDimitry Andric       return Res;
704cfca06d7SDimitry Andric     if (int Res = cmpOperandBundlesSchema(*CBL, *CBR))
705b915e9e0SDimitry Andric       return Res;
706e6d15924SDimitry Andric     if (const CallInst *CI = dyn_cast<CallInst>(L))
707e6d15924SDimitry Andric       if (int Res = cmpNumbers(CI->getTailCallKind(),
708e6d15924SDimitry Andric                                cast<CallInst>(R)->getTailCallKind()))
709b915e9e0SDimitry Andric         return Res;
7107fa27ce4SDimitry Andric     return cmpMDNode(L->getMetadata(LLVMContext::MD_range),
711e6d15924SDimitry Andric                      R->getMetadata(LLVMContext::MD_range));
712b915e9e0SDimitry Andric   }
713b915e9e0SDimitry Andric   if (const InsertValueInst *IVI = dyn_cast<InsertValueInst>(L)) {
714b915e9e0SDimitry Andric     ArrayRef<unsigned> LIndices = IVI->getIndices();
715b915e9e0SDimitry Andric     ArrayRef<unsigned> RIndices = cast<InsertValueInst>(R)->getIndices();
716b915e9e0SDimitry Andric     if (int Res = cmpNumbers(LIndices.size(), RIndices.size()))
717b915e9e0SDimitry Andric       return Res;
718b915e9e0SDimitry Andric     for (size_t i = 0, e = LIndices.size(); i != e; ++i) {
719b915e9e0SDimitry Andric       if (int Res = cmpNumbers(LIndices[i], RIndices[i]))
720b915e9e0SDimitry Andric         return Res;
721b915e9e0SDimitry Andric     }
722b915e9e0SDimitry Andric     return 0;
723b915e9e0SDimitry Andric   }
724b915e9e0SDimitry Andric   if (const ExtractValueInst *EVI = dyn_cast<ExtractValueInst>(L)) {
725b915e9e0SDimitry Andric     ArrayRef<unsigned> LIndices = EVI->getIndices();
726b915e9e0SDimitry Andric     ArrayRef<unsigned> RIndices = cast<ExtractValueInst>(R)->getIndices();
727b915e9e0SDimitry Andric     if (int Res = cmpNumbers(LIndices.size(), RIndices.size()))
728b915e9e0SDimitry Andric       return Res;
729b915e9e0SDimitry Andric     for (size_t i = 0, e = LIndices.size(); i != e; ++i) {
730b915e9e0SDimitry Andric       if (int Res = cmpNumbers(LIndices[i], RIndices[i]))
731b915e9e0SDimitry Andric         return Res;
732b915e9e0SDimitry Andric     }
733b915e9e0SDimitry Andric   }
734b915e9e0SDimitry Andric   if (const FenceInst *FI = dyn_cast<FenceInst>(L)) {
735b915e9e0SDimitry Andric     if (int Res =
736b915e9e0SDimitry Andric             cmpOrderings(FI->getOrdering(), cast<FenceInst>(R)->getOrdering()))
737b915e9e0SDimitry Andric       return Res;
738ca089b24SDimitry Andric     return cmpNumbers(FI->getSyncScopeID(),
739ca089b24SDimitry Andric                       cast<FenceInst>(R)->getSyncScopeID());
740b915e9e0SDimitry Andric   }
741b915e9e0SDimitry Andric   if (const AtomicCmpXchgInst *CXI = dyn_cast<AtomicCmpXchgInst>(L)) {
742b915e9e0SDimitry Andric     if (int Res = cmpNumbers(CXI->isVolatile(),
743b915e9e0SDimitry Andric                              cast<AtomicCmpXchgInst>(R)->isVolatile()))
744b915e9e0SDimitry Andric       return Res;
745cfca06d7SDimitry Andric     if (int Res =
746cfca06d7SDimitry Andric             cmpNumbers(CXI->isWeak(), cast<AtomicCmpXchgInst>(R)->isWeak()))
747b915e9e0SDimitry Andric       return Res;
748b915e9e0SDimitry Andric     if (int Res =
749b915e9e0SDimitry Andric             cmpOrderings(CXI->getSuccessOrdering(),
750b915e9e0SDimitry Andric                          cast<AtomicCmpXchgInst>(R)->getSuccessOrdering()))
751b915e9e0SDimitry Andric       return Res;
752b915e9e0SDimitry Andric     if (int Res =
753b915e9e0SDimitry Andric             cmpOrderings(CXI->getFailureOrdering(),
754b915e9e0SDimitry Andric                          cast<AtomicCmpXchgInst>(R)->getFailureOrdering()))
755b915e9e0SDimitry Andric       return Res;
756ca089b24SDimitry Andric     return cmpNumbers(CXI->getSyncScopeID(),
757ca089b24SDimitry Andric                       cast<AtomicCmpXchgInst>(R)->getSyncScopeID());
758b915e9e0SDimitry Andric   }
759b915e9e0SDimitry Andric   if (const AtomicRMWInst *RMWI = dyn_cast<AtomicRMWInst>(L)) {
760b915e9e0SDimitry Andric     if (int Res = cmpNumbers(RMWI->getOperation(),
761b915e9e0SDimitry Andric                              cast<AtomicRMWInst>(R)->getOperation()))
762b915e9e0SDimitry Andric       return Res;
763b915e9e0SDimitry Andric     if (int Res = cmpNumbers(RMWI->isVolatile(),
764b915e9e0SDimitry Andric                              cast<AtomicRMWInst>(R)->isVolatile()))
765b915e9e0SDimitry Andric       return Res;
766b915e9e0SDimitry Andric     if (int Res = cmpOrderings(RMWI->getOrdering(),
767b915e9e0SDimitry Andric                                cast<AtomicRMWInst>(R)->getOrdering()))
768b915e9e0SDimitry Andric       return Res;
769ca089b24SDimitry Andric     return cmpNumbers(RMWI->getSyncScopeID(),
770ca089b24SDimitry Andric                       cast<AtomicRMWInst>(R)->getSyncScopeID());
771b915e9e0SDimitry Andric   }
772cfca06d7SDimitry Andric   if (const ShuffleVectorInst *SVI = dyn_cast<ShuffleVectorInst>(L)) {
773cfca06d7SDimitry Andric     ArrayRef<int> LMask = SVI->getShuffleMask();
774cfca06d7SDimitry Andric     ArrayRef<int> RMask = cast<ShuffleVectorInst>(R)->getShuffleMask();
775cfca06d7SDimitry Andric     if (int Res = cmpNumbers(LMask.size(), RMask.size()))
776cfca06d7SDimitry Andric       return Res;
777cfca06d7SDimitry Andric     for (size_t i = 0, e = LMask.size(); i != e; ++i) {
778cfca06d7SDimitry Andric       if (int Res = cmpNumbers(LMask[i], RMask[i]))
779cfca06d7SDimitry Andric         return Res;
780cfca06d7SDimitry Andric     }
781cfca06d7SDimitry Andric   }
782b915e9e0SDimitry Andric   if (const PHINode *PNL = dyn_cast<PHINode>(L)) {
783b915e9e0SDimitry Andric     const PHINode *PNR = cast<PHINode>(R);
784b915e9e0SDimitry Andric     // Ensure that in addition to the incoming values being identical
785b915e9e0SDimitry Andric     // (checked by the caller of this function), the incoming blocks
786b915e9e0SDimitry Andric     // are also identical.
787b915e9e0SDimitry Andric     for (unsigned i = 0, e = PNL->getNumIncomingValues(); i != e; ++i) {
788b915e9e0SDimitry Andric       if (int Res =
789b915e9e0SDimitry Andric               cmpValues(PNL->getIncomingBlock(i), PNR->getIncomingBlock(i)))
790b915e9e0SDimitry Andric         return Res;
791b915e9e0SDimitry Andric     }
792b915e9e0SDimitry Andric   }
793b915e9e0SDimitry Andric   return 0;
794b915e9e0SDimitry Andric }
795b915e9e0SDimitry Andric 
796b915e9e0SDimitry Andric // Determine whether two GEP operations perform the same underlying arithmetic.
797b915e9e0SDimitry Andric // Read method declaration comments for more details.
cmpGEPs(const GEPOperator * GEPL,const GEPOperator * GEPR) const798b915e9e0SDimitry Andric int FunctionComparator::cmpGEPs(const GEPOperator *GEPL,
799b915e9e0SDimitry Andric                                 const GEPOperator *GEPR) const {
800b915e9e0SDimitry Andric   unsigned int ASL = GEPL->getPointerAddressSpace();
801b915e9e0SDimitry Andric   unsigned int ASR = GEPR->getPointerAddressSpace();
802b915e9e0SDimitry Andric 
803b915e9e0SDimitry Andric   if (int Res = cmpNumbers(ASL, ASR))
804b915e9e0SDimitry Andric     return Res;
805b915e9e0SDimitry Andric 
806b915e9e0SDimitry Andric   // When we have target data, we can reduce the GEP down to the value in bytes
807b915e9e0SDimitry Andric   // added to the address.
808ac9a064cSDimitry Andric   const DataLayout &DL = FnL->getDataLayout();
8097fa27ce4SDimitry Andric   unsigned OffsetBitWidth = DL.getIndexSizeInBits(ASL);
8107fa27ce4SDimitry Andric   APInt OffsetL(OffsetBitWidth, 0), OffsetR(OffsetBitWidth, 0);
811b915e9e0SDimitry Andric   if (GEPL->accumulateConstantOffset(DL, OffsetL) &&
812b915e9e0SDimitry Andric       GEPR->accumulateConstantOffset(DL, OffsetR))
813b915e9e0SDimitry Andric     return cmpAPInts(OffsetL, OffsetR);
814cfca06d7SDimitry Andric   if (int Res =
815cfca06d7SDimitry Andric           cmpTypes(GEPL->getSourceElementType(), GEPR->getSourceElementType()))
816b915e9e0SDimitry Andric     return Res;
817b915e9e0SDimitry Andric 
818b915e9e0SDimitry Andric   if (int Res = cmpNumbers(GEPL->getNumOperands(), GEPR->getNumOperands()))
819b915e9e0SDimitry Andric     return Res;
820b915e9e0SDimitry Andric 
821b915e9e0SDimitry Andric   for (unsigned i = 0, e = GEPL->getNumOperands(); i != e; ++i) {
822b915e9e0SDimitry Andric     if (int Res = cmpValues(GEPL->getOperand(i), GEPR->getOperand(i)))
823b915e9e0SDimitry Andric       return Res;
824b915e9e0SDimitry Andric   }
825b915e9e0SDimitry Andric 
826b915e9e0SDimitry Andric   return 0;
827b915e9e0SDimitry Andric }
828b915e9e0SDimitry Andric 
cmpInlineAsm(const InlineAsm * L,const InlineAsm * R) const829b915e9e0SDimitry Andric int FunctionComparator::cmpInlineAsm(const InlineAsm *L,
830b915e9e0SDimitry Andric                                      const InlineAsm *R) const {
831b915e9e0SDimitry Andric   // InlineAsm's are uniqued. If they are the same pointer, obviously they are
832b915e9e0SDimitry Andric   // the same, otherwise compare the fields.
833b915e9e0SDimitry Andric   if (L == R)
834b915e9e0SDimitry Andric     return 0;
835b915e9e0SDimitry Andric   if (int Res = cmpTypes(L->getFunctionType(), R->getFunctionType()))
836b915e9e0SDimitry Andric     return Res;
837b915e9e0SDimitry Andric   if (int Res = cmpMem(L->getAsmString(), R->getAsmString()))
838b915e9e0SDimitry Andric     return Res;
839b915e9e0SDimitry Andric   if (int Res = cmpMem(L->getConstraintString(), R->getConstraintString()))
840b915e9e0SDimitry Andric     return Res;
841b915e9e0SDimitry Andric   if (int Res = cmpNumbers(L->hasSideEffects(), R->hasSideEffects()))
842b915e9e0SDimitry Andric     return Res;
843b915e9e0SDimitry Andric   if (int Res = cmpNumbers(L->isAlignStack(), R->isAlignStack()))
844b915e9e0SDimitry Andric     return Res;
845b915e9e0SDimitry Andric   if (int Res = cmpNumbers(L->getDialect(), R->getDialect()))
846b915e9e0SDimitry Andric     return Res;
847eb11fae6SDimitry Andric   assert(L->getFunctionType() != R->getFunctionType());
848b915e9e0SDimitry Andric   return 0;
849b915e9e0SDimitry Andric }
850b915e9e0SDimitry Andric 
851b915e9e0SDimitry Andric /// Compare two values used by the two functions under pair-wise comparison. If
852b915e9e0SDimitry Andric /// this is the first time the values are seen, they're added to the mapping so
853b915e9e0SDimitry Andric /// that we will detect mismatches on next use.
854b915e9e0SDimitry Andric /// See comments in declaration for more details.
cmpValues(const Value * L,const Value * R) const855b915e9e0SDimitry Andric int FunctionComparator::cmpValues(const Value *L, const Value *R) const {
856b915e9e0SDimitry Andric   // Catch self-reference case.
857b915e9e0SDimitry Andric   if (L == FnL) {
858b915e9e0SDimitry Andric     if (R == FnR)
859b915e9e0SDimitry Andric       return 0;
860b915e9e0SDimitry Andric     return -1;
861b915e9e0SDimitry Andric   }
862b915e9e0SDimitry Andric   if (R == FnR) {
863b915e9e0SDimitry Andric     if (L == FnL)
864b915e9e0SDimitry Andric       return 0;
865b915e9e0SDimitry Andric     return 1;
866b915e9e0SDimitry Andric   }
867b915e9e0SDimitry Andric 
868b915e9e0SDimitry Andric   const Constant *ConstL = dyn_cast<Constant>(L);
869b915e9e0SDimitry Andric   const Constant *ConstR = dyn_cast<Constant>(R);
870b915e9e0SDimitry Andric   if (ConstL && ConstR) {
871b915e9e0SDimitry Andric     if (L == R)
872b915e9e0SDimitry Andric       return 0;
873b915e9e0SDimitry Andric     return cmpConstants(ConstL, ConstR);
874b915e9e0SDimitry Andric   }
875b915e9e0SDimitry Andric 
876b915e9e0SDimitry Andric   if (ConstL)
877b915e9e0SDimitry Andric     return 1;
878b915e9e0SDimitry Andric   if (ConstR)
879b915e9e0SDimitry Andric     return -1;
880b915e9e0SDimitry Andric 
881b1c73532SDimitry Andric   const MetadataAsValue *MetadataValueL = dyn_cast<MetadataAsValue>(L);
882b1c73532SDimitry Andric   const MetadataAsValue *MetadataValueR = dyn_cast<MetadataAsValue>(R);
883b1c73532SDimitry Andric   if (MetadataValueL && MetadataValueR) {
884b1c73532SDimitry Andric     if (MetadataValueL == MetadataValueR)
885b1c73532SDimitry Andric       return 0;
886b1c73532SDimitry Andric 
887b1c73532SDimitry Andric     return cmpMetadata(MetadataValueL->getMetadata(),
888b1c73532SDimitry Andric                        MetadataValueR->getMetadata());
889b1c73532SDimitry Andric   }
890b1c73532SDimitry Andric 
891b1c73532SDimitry Andric   if (MetadataValueL)
892b1c73532SDimitry Andric     return 1;
893b1c73532SDimitry Andric   if (MetadataValueR)
894b1c73532SDimitry Andric     return -1;
895b1c73532SDimitry Andric 
896b915e9e0SDimitry Andric   const InlineAsm *InlineAsmL = dyn_cast<InlineAsm>(L);
897b915e9e0SDimitry Andric   const InlineAsm *InlineAsmR = dyn_cast<InlineAsm>(R);
898b915e9e0SDimitry Andric 
899b915e9e0SDimitry Andric   if (InlineAsmL && InlineAsmR)
900b915e9e0SDimitry Andric     return cmpInlineAsm(InlineAsmL, InlineAsmR);
901b915e9e0SDimitry Andric   if (InlineAsmL)
902b915e9e0SDimitry Andric     return 1;
903b915e9e0SDimitry Andric   if (InlineAsmR)
904b915e9e0SDimitry Andric     return -1;
905b915e9e0SDimitry Andric 
906b915e9e0SDimitry Andric   auto LeftSN = sn_mapL.insert(std::make_pair(L, sn_mapL.size())),
907b915e9e0SDimitry Andric        RightSN = sn_mapR.insert(std::make_pair(R, sn_mapR.size()));
908b915e9e0SDimitry Andric 
909b915e9e0SDimitry Andric   return cmpNumbers(LeftSN.first->second, RightSN.first->second);
910b915e9e0SDimitry Andric }
911b915e9e0SDimitry Andric 
912b915e9e0SDimitry Andric // Test whether two basic blocks have equivalent behaviour.
cmpBasicBlocks(const BasicBlock * BBL,const BasicBlock * BBR) const913b915e9e0SDimitry Andric int FunctionComparator::cmpBasicBlocks(const BasicBlock *BBL,
914b915e9e0SDimitry Andric                                        const BasicBlock *BBR) const {
915b915e9e0SDimitry Andric   BasicBlock::const_iterator InstL = BBL->begin(), InstLE = BBL->end();
916b915e9e0SDimitry Andric   BasicBlock::const_iterator InstR = BBR->begin(), InstRE = BBR->end();
917b915e9e0SDimitry Andric 
918b915e9e0SDimitry Andric   do {
919b915e9e0SDimitry Andric     bool needToCmpOperands = true;
920b915e9e0SDimitry Andric     if (int Res = cmpOperations(&*InstL, &*InstR, needToCmpOperands))
921b915e9e0SDimitry Andric       return Res;
922b915e9e0SDimitry Andric     if (needToCmpOperands) {
923b915e9e0SDimitry Andric       assert(InstL->getNumOperands() == InstR->getNumOperands());
924b915e9e0SDimitry Andric 
925b915e9e0SDimitry Andric       for (unsigned i = 0, e = InstL->getNumOperands(); i != e; ++i) {
926b915e9e0SDimitry Andric         Value *OpL = InstL->getOperand(i);
927b915e9e0SDimitry Andric         Value *OpR = InstR->getOperand(i);
928b915e9e0SDimitry Andric         if (int Res = cmpValues(OpL, OpR))
929b915e9e0SDimitry Andric           return Res;
930b915e9e0SDimitry Andric         // cmpValues should ensure this is true.
931b915e9e0SDimitry Andric         assert(cmpTypes(OpL->getType(), OpR->getType()) == 0);
932b915e9e0SDimitry Andric       }
933b915e9e0SDimitry Andric     }
934b915e9e0SDimitry Andric 
935b915e9e0SDimitry Andric     ++InstL;
936b915e9e0SDimitry Andric     ++InstR;
937b915e9e0SDimitry Andric   } while (InstL != InstLE && InstR != InstRE);
938b915e9e0SDimitry Andric 
939b915e9e0SDimitry Andric   if (InstL != InstLE && InstR == InstRE)
940b915e9e0SDimitry Andric     return 1;
941b915e9e0SDimitry Andric   if (InstL == InstLE && InstR != InstRE)
942b915e9e0SDimitry Andric     return -1;
943b915e9e0SDimitry Andric   return 0;
944b915e9e0SDimitry Andric }
945b915e9e0SDimitry Andric 
compareSignature() const946b915e9e0SDimitry Andric int FunctionComparator::compareSignature() const {
947b915e9e0SDimitry Andric   if (int Res = cmpAttrs(FnL->getAttributes(), FnR->getAttributes()))
948b915e9e0SDimitry Andric     return Res;
949b915e9e0SDimitry Andric 
950b915e9e0SDimitry Andric   if (int Res = cmpNumbers(FnL->hasGC(), FnR->hasGC()))
951b915e9e0SDimitry Andric     return Res;
952b915e9e0SDimitry Andric 
953b915e9e0SDimitry Andric   if (FnL->hasGC()) {
954b915e9e0SDimitry Andric     if (int Res = cmpMem(FnL->getGC(), FnR->getGC()))
955b915e9e0SDimitry Andric       return Res;
956b915e9e0SDimitry Andric   }
957b915e9e0SDimitry Andric 
958b915e9e0SDimitry Andric   if (int Res = cmpNumbers(FnL->hasSection(), FnR->hasSection()))
959b915e9e0SDimitry Andric     return Res;
960b915e9e0SDimitry Andric 
961b915e9e0SDimitry Andric   if (FnL->hasSection()) {
962b915e9e0SDimitry Andric     if (int Res = cmpMem(FnL->getSection(), FnR->getSection()))
963b915e9e0SDimitry Andric       return Res;
964b915e9e0SDimitry Andric   }
965b915e9e0SDimitry Andric 
966b915e9e0SDimitry Andric   if (int Res = cmpNumbers(FnL->isVarArg(), FnR->isVarArg()))
967b915e9e0SDimitry Andric     return Res;
968b915e9e0SDimitry Andric 
969b915e9e0SDimitry Andric   // TODO: if it's internal and only used in direct calls, we could handle this
970b915e9e0SDimitry Andric   // case too.
971b915e9e0SDimitry Andric   if (int Res = cmpNumbers(FnL->getCallingConv(), FnR->getCallingConv()))
972b915e9e0SDimitry Andric     return Res;
973b915e9e0SDimitry Andric 
974b915e9e0SDimitry Andric   if (int Res = cmpTypes(FnL->getFunctionType(), FnR->getFunctionType()))
975b915e9e0SDimitry Andric     return Res;
976b915e9e0SDimitry Andric 
977b915e9e0SDimitry Andric   assert(FnL->arg_size() == FnR->arg_size() &&
978b915e9e0SDimitry Andric          "Identically typed functions have different numbers of args!");
979b915e9e0SDimitry Andric 
980b915e9e0SDimitry Andric   // Visit the arguments so that they get enumerated in the order they're
981b915e9e0SDimitry Andric   // passed in.
982b915e9e0SDimitry Andric   for (Function::const_arg_iterator ArgLI = FnL->arg_begin(),
983b915e9e0SDimitry Andric                                     ArgRI = FnR->arg_begin(),
984b915e9e0SDimitry Andric                                     ArgLE = FnL->arg_end();
985b915e9e0SDimitry Andric        ArgLI != ArgLE; ++ArgLI, ++ArgRI) {
986b915e9e0SDimitry Andric     if (cmpValues(&*ArgLI, &*ArgRI) != 0)
987b915e9e0SDimitry Andric       llvm_unreachable("Arguments repeat!");
988b915e9e0SDimitry Andric   }
989b915e9e0SDimitry Andric   return 0;
990b915e9e0SDimitry Andric }
991b915e9e0SDimitry Andric 
992b915e9e0SDimitry Andric // Test whether the two functions have equivalent behaviour.
compare()993b915e9e0SDimitry Andric int FunctionComparator::compare() {
994b915e9e0SDimitry Andric   beginCompare();
995b915e9e0SDimitry Andric 
996b915e9e0SDimitry Andric   if (int Res = compareSignature())
997b915e9e0SDimitry Andric     return Res;
998b915e9e0SDimitry Andric 
999b915e9e0SDimitry Andric   // We do a CFG-ordered walk since the actual ordering of the blocks in the
1000b915e9e0SDimitry Andric   // linked list is immaterial. Our walk starts at the entry block for both
1001b915e9e0SDimitry Andric   // functions, then takes each block from each terminator in order. As an
1002b915e9e0SDimitry Andric   // artifact, this also means that unreachable blocks are ignored.
1003b915e9e0SDimitry Andric   SmallVector<const BasicBlock *, 8> FnLBBs, FnRBBs;
1004b915e9e0SDimitry Andric   SmallPtrSet<const BasicBlock *, 32> VisitedBBs; // in terms of F1.
1005b915e9e0SDimitry Andric 
1006b915e9e0SDimitry Andric   FnLBBs.push_back(&FnL->getEntryBlock());
1007b915e9e0SDimitry Andric   FnRBBs.push_back(&FnR->getEntryBlock());
1008b915e9e0SDimitry Andric 
1009b915e9e0SDimitry Andric   VisitedBBs.insert(FnLBBs[0]);
1010b915e9e0SDimitry Andric   while (!FnLBBs.empty()) {
1011b915e9e0SDimitry Andric     const BasicBlock *BBL = FnLBBs.pop_back_val();
1012b915e9e0SDimitry Andric     const BasicBlock *BBR = FnRBBs.pop_back_val();
1013b915e9e0SDimitry Andric 
1014b915e9e0SDimitry Andric     if (int Res = cmpValues(BBL, BBR))
1015b915e9e0SDimitry Andric       return Res;
1016b915e9e0SDimitry Andric 
1017b915e9e0SDimitry Andric     if (int Res = cmpBasicBlocks(BBL, BBR))
1018b915e9e0SDimitry Andric       return Res;
1019b915e9e0SDimitry Andric 
1020d8e91e46SDimitry Andric     const Instruction *TermL = BBL->getTerminator();
1021d8e91e46SDimitry Andric     const Instruction *TermR = BBR->getTerminator();
1022b915e9e0SDimitry Andric 
1023b915e9e0SDimitry Andric     assert(TermL->getNumSuccessors() == TermR->getNumSuccessors());
1024b915e9e0SDimitry Andric     for (unsigned i = 0, e = TermL->getNumSuccessors(); i != e; ++i) {
1025b915e9e0SDimitry Andric       if (!VisitedBBs.insert(TermL->getSuccessor(i)).second)
1026b915e9e0SDimitry Andric         continue;
1027b915e9e0SDimitry Andric 
1028b915e9e0SDimitry Andric       FnLBBs.push_back(TermL->getSuccessor(i));
1029b915e9e0SDimitry Andric       FnRBBs.push_back(TermR->getSuccessor(i));
1030b915e9e0SDimitry Andric     }
1031b915e9e0SDimitry Andric   }
1032b915e9e0SDimitry Andric   return 0;
1033b915e9e0SDimitry Andric }
1034