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