xref: /freebsd-src/contrib/llvm-project/llvm/tools/llvm-diff/lib/DifferenceEngine.cpp (revision 349cc55c9796c4596a5b9904cd3281af295f878f)
1*349cc55cSDimitry Andric //===-- DifferenceEngine.cpp - Structural function/module comparison ------===//
2*349cc55cSDimitry Andric //
3*349cc55cSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*349cc55cSDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5*349cc55cSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*349cc55cSDimitry Andric //
7*349cc55cSDimitry Andric //===----------------------------------------------------------------------===//
8*349cc55cSDimitry Andric //
9*349cc55cSDimitry Andric // This header defines the implementation of the LLVM difference
10*349cc55cSDimitry Andric // engine, which structurally compares global values within a module.
11*349cc55cSDimitry Andric //
12*349cc55cSDimitry Andric //===----------------------------------------------------------------------===//
13*349cc55cSDimitry Andric 
14*349cc55cSDimitry Andric #include "DifferenceEngine.h"
15*349cc55cSDimitry Andric #include "llvm/ADT/DenseMap.h"
16*349cc55cSDimitry Andric #include "llvm/ADT/DenseSet.h"
17*349cc55cSDimitry Andric #include "llvm/ADT/SmallString.h"
18*349cc55cSDimitry Andric #include "llvm/ADT/SmallVector.h"
19*349cc55cSDimitry Andric #include "llvm/ADT/StringSet.h"
20*349cc55cSDimitry Andric #include "llvm/IR/CFG.h"
21*349cc55cSDimitry Andric #include "llvm/IR/Constants.h"
22*349cc55cSDimitry Andric #include "llvm/IR/Function.h"
23*349cc55cSDimitry Andric #include "llvm/IR/Instructions.h"
24*349cc55cSDimitry Andric #include "llvm/IR/Module.h"
25*349cc55cSDimitry Andric #include "llvm/Support/ErrorHandling.h"
26*349cc55cSDimitry Andric #include "llvm/Support/raw_ostream.h"
27*349cc55cSDimitry Andric #include "llvm/Support/type_traits.h"
28*349cc55cSDimitry Andric #include <utility>
29*349cc55cSDimitry Andric 
30*349cc55cSDimitry Andric using namespace llvm;
31*349cc55cSDimitry Andric 
32*349cc55cSDimitry Andric namespace {
33*349cc55cSDimitry Andric 
34*349cc55cSDimitry Andric /// A priority queue, implemented as a heap.
35*349cc55cSDimitry Andric template <class T, class Sorter, unsigned InlineCapacity>
36*349cc55cSDimitry Andric class PriorityQueue {
37*349cc55cSDimitry Andric   Sorter Precedes;
38*349cc55cSDimitry Andric   llvm::SmallVector<T, InlineCapacity> Storage;
39*349cc55cSDimitry Andric 
40*349cc55cSDimitry Andric public:
41*349cc55cSDimitry Andric   PriorityQueue(const Sorter &Precedes) : Precedes(Precedes) {}
42*349cc55cSDimitry Andric 
43*349cc55cSDimitry Andric   /// Checks whether the heap is empty.
44*349cc55cSDimitry Andric   bool empty() const { return Storage.empty(); }
45*349cc55cSDimitry Andric 
46*349cc55cSDimitry Andric   /// Insert a new value on the heap.
47*349cc55cSDimitry Andric   void insert(const T &V) {
48*349cc55cSDimitry Andric     unsigned Index = Storage.size();
49*349cc55cSDimitry Andric     Storage.push_back(V);
50*349cc55cSDimitry Andric     if (Index == 0) return;
51*349cc55cSDimitry Andric 
52*349cc55cSDimitry Andric     T *data = Storage.data();
53*349cc55cSDimitry Andric     while (true) {
54*349cc55cSDimitry Andric       unsigned Target = (Index + 1) / 2 - 1;
55*349cc55cSDimitry Andric       if (!Precedes(data[Index], data[Target])) return;
56*349cc55cSDimitry Andric       std::swap(data[Index], data[Target]);
57*349cc55cSDimitry Andric       if (Target == 0) return;
58*349cc55cSDimitry Andric       Index = Target;
59*349cc55cSDimitry Andric     }
60*349cc55cSDimitry Andric   }
61*349cc55cSDimitry Andric 
62*349cc55cSDimitry Andric   /// Remove the minimum value in the heap.  Only valid on a non-empty heap.
63*349cc55cSDimitry Andric   T remove_min() {
64*349cc55cSDimitry Andric     assert(!empty());
65*349cc55cSDimitry Andric     T tmp = Storage[0];
66*349cc55cSDimitry Andric 
67*349cc55cSDimitry Andric     unsigned NewSize = Storage.size() - 1;
68*349cc55cSDimitry Andric     if (NewSize) {
69*349cc55cSDimitry Andric       // Move the slot at the end to the beginning.
70*349cc55cSDimitry Andric       if (std::is_trivially_copyable<T>::value)
71*349cc55cSDimitry Andric         Storage[0] = Storage[NewSize];
72*349cc55cSDimitry Andric       else
73*349cc55cSDimitry Andric         std::swap(Storage[0], Storage[NewSize]);
74*349cc55cSDimitry Andric 
75*349cc55cSDimitry Andric       // Bubble the root up as necessary.
76*349cc55cSDimitry Andric       unsigned Index = 0;
77*349cc55cSDimitry Andric       while (true) {
78*349cc55cSDimitry Andric         // With a 1-based index, the children would be Index*2 and Index*2+1.
79*349cc55cSDimitry Andric         unsigned R = (Index + 1) * 2;
80*349cc55cSDimitry Andric         unsigned L = R - 1;
81*349cc55cSDimitry Andric 
82*349cc55cSDimitry Andric         // If R is out of bounds, we're done after this in any case.
83*349cc55cSDimitry Andric         if (R >= NewSize) {
84*349cc55cSDimitry Andric           // If L is also out of bounds, we're done immediately.
85*349cc55cSDimitry Andric           if (L >= NewSize) break;
86*349cc55cSDimitry Andric 
87*349cc55cSDimitry Andric           // Otherwise, test whether we should swap L and Index.
88*349cc55cSDimitry Andric           if (Precedes(Storage[L], Storage[Index]))
89*349cc55cSDimitry Andric             std::swap(Storage[L], Storage[Index]);
90*349cc55cSDimitry Andric           break;
91*349cc55cSDimitry Andric         }
92*349cc55cSDimitry Andric 
93*349cc55cSDimitry Andric         // Otherwise, we need to compare with the smaller of L and R.
94*349cc55cSDimitry Andric         // Prefer R because it's closer to the end of the array.
95*349cc55cSDimitry Andric         unsigned IndexToTest = (Precedes(Storage[L], Storage[R]) ? L : R);
96*349cc55cSDimitry Andric 
97*349cc55cSDimitry Andric         // If Index is >= the min of L and R, then heap ordering is restored.
98*349cc55cSDimitry Andric         if (!Precedes(Storage[IndexToTest], Storage[Index]))
99*349cc55cSDimitry Andric           break;
100*349cc55cSDimitry Andric 
101*349cc55cSDimitry Andric         // Otherwise, keep bubbling up.
102*349cc55cSDimitry Andric         std::swap(Storage[IndexToTest], Storage[Index]);
103*349cc55cSDimitry Andric         Index = IndexToTest;
104*349cc55cSDimitry Andric       }
105*349cc55cSDimitry Andric     }
106*349cc55cSDimitry Andric     Storage.pop_back();
107*349cc55cSDimitry Andric 
108*349cc55cSDimitry Andric     return tmp;
109*349cc55cSDimitry Andric   }
110*349cc55cSDimitry Andric };
111*349cc55cSDimitry Andric 
112*349cc55cSDimitry Andric /// A function-scope difference engine.
113*349cc55cSDimitry Andric class FunctionDifferenceEngine {
114*349cc55cSDimitry Andric   DifferenceEngine &Engine;
115*349cc55cSDimitry Andric 
116*349cc55cSDimitry Andric   // Some initializers may reference the variable we're currently checking. This
117*349cc55cSDimitry Andric   // can cause an infinite loop. The Saved[LR]HS ivars can be checked to prevent
118*349cc55cSDimitry Andric   // recursing.
119*349cc55cSDimitry Andric   const Value *SavedLHS;
120*349cc55cSDimitry Andric   const Value *SavedRHS;
121*349cc55cSDimitry Andric 
122*349cc55cSDimitry Andric   /// The current mapping from old local values to new local values.
123*349cc55cSDimitry Andric   DenseMap<const Value *, const Value *> Values;
124*349cc55cSDimitry Andric 
125*349cc55cSDimitry Andric   /// The current mapping from old blocks to new blocks.
126*349cc55cSDimitry Andric   DenseMap<const BasicBlock *, const BasicBlock *> Blocks;
127*349cc55cSDimitry Andric 
128*349cc55cSDimitry Andric   DenseSet<std::pair<const Value *, const Value *>> TentativeValues;
129*349cc55cSDimitry Andric 
130*349cc55cSDimitry Andric   unsigned getUnprocPredCount(const BasicBlock *Block) const {
131*349cc55cSDimitry Andric     unsigned Count = 0;
132*349cc55cSDimitry Andric     for (const_pred_iterator I = pred_begin(Block), E = pred_end(Block); I != E;
133*349cc55cSDimitry Andric          ++I)
134*349cc55cSDimitry Andric       if (!Blocks.count(*I)) Count++;
135*349cc55cSDimitry Andric     return Count;
136*349cc55cSDimitry Andric   }
137*349cc55cSDimitry Andric 
138*349cc55cSDimitry Andric   typedef std::pair<const BasicBlock *, const BasicBlock *> BlockPair;
139*349cc55cSDimitry Andric 
140*349cc55cSDimitry Andric   /// A type which sorts a priority queue by the number of unprocessed
141*349cc55cSDimitry Andric   /// predecessor blocks it has remaining.
142*349cc55cSDimitry Andric   ///
143*349cc55cSDimitry Andric   /// This is actually really expensive to calculate.
144*349cc55cSDimitry Andric   struct QueueSorter {
145*349cc55cSDimitry Andric     const FunctionDifferenceEngine &fde;
146*349cc55cSDimitry Andric     explicit QueueSorter(const FunctionDifferenceEngine &fde) : fde(fde) {}
147*349cc55cSDimitry Andric 
148*349cc55cSDimitry Andric     bool operator()(BlockPair &Old, BlockPair &New) {
149*349cc55cSDimitry Andric       return fde.getUnprocPredCount(Old.first)
150*349cc55cSDimitry Andric            < fde.getUnprocPredCount(New.first);
151*349cc55cSDimitry Andric     }
152*349cc55cSDimitry Andric   };
153*349cc55cSDimitry Andric 
154*349cc55cSDimitry Andric   /// A queue of unified blocks to process.
155*349cc55cSDimitry Andric   PriorityQueue<BlockPair, QueueSorter, 20> Queue;
156*349cc55cSDimitry Andric 
157*349cc55cSDimitry Andric   /// Try to unify the given two blocks.  Enqueues them for processing
158*349cc55cSDimitry Andric   /// if they haven't already been processed.
159*349cc55cSDimitry Andric   ///
160*349cc55cSDimitry Andric   /// Returns true if there was a problem unifying them.
161*349cc55cSDimitry Andric   bool tryUnify(const BasicBlock *L, const BasicBlock *R) {
162*349cc55cSDimitry Andric     const BasicBlock *&Ref = Blocks[L];
163*349cc55cSDimitry Andric 
164*349cc55cSDimitry Andric     if (Ref) {
165*349cc55cSDimitry Andric       if (Ref == R) return false;
166*349cc55cSDimitry Andric 
167*349cc55cSDimitry Andric       Engine.logf("successor %l cannot be equivalent to %r; "
168*349cc55cSDimitry Andric                   "it's already equivalent to %r")
169*349cc55cSDimitry Andric         << L << R << Ref;
170*349cc55cSDimitry Andric       return true;
171*349cc55cSDimitry Andric     }
172*349cc55cSDimitry Andric 
173*349cc55cSDimitry Andric     Ref = R;
174*349cc55cSDimitry Andric     Queue.insert(BlockPair(L, R));
175*349cc55cSDimitry Andric     return false;
176*349cc55cSDimitry Andric   }
177*349cc55cSDimitry Andric 
178*349cc55cSDimitry Andric   /// Unifies two instructions, given that they're known not to have
179*349cc55cSDimitry Andric   /// structural differences.
180*349cc55cSDimitry Andric   void unify(const Instruction *L, const Instruction *R) {
181*349cc55cSDimitry Andric     DifferenceEngine::Context C(Engine, L, R);
182*349cc55cSDimitry Andric 
183*349cc55cSDimitry Andric     bool Result = diff(L, R, true, true);
184*349cc55cSDimitry Andric     assert(!Result && "structural differences second time around?");
185*349cc55cSDimitry Andric     (void) Result;
186*349cc55cSDimitry Andric     if (!L->use_empty())
187*349cc55cSDimitry Andric       Values[L] = R;
188*349cc55cSDimitry Andric   }
189*349cc55cSDimitry Andric 
190*349cc55cSDimitry Andric   void processQueue() {
191*349cc55cSDimitry Andric     while (!Queue.empty()) {
192*349cc55cSDimitry Andric       BlockPair Pair = Queue.remove_min();
193*349cc55cSDimitry Andric       diff(Pair.first, Pair.second);
194*349cc55cSDimitry Andric     }
195*349cc55cSDimitry Andric   }
196*349cc55cSDimitry Andric 
197*349cc55cSDimitry Andric   void diff(const BasicBlock *L, const BasicBlock *R) {
198*349cc55cSDimitry Andric     DifferenceEngine::Context C(Engine, L, R);
199*349cc55cSDimitry Andric 
200*349cc55cSDimitry Andric     BasicBlock::const_iterator LI = L->begin(), LE = L->end();
201*349cc55cSDimitry Andric     BasicBlock::const_iterator RI = R->begin();
202*349cc55cSDimitry Andric 
203*349cc55cSDimitry Andric     do {
204*349cc55cSDimitry Andric       assert(LI != LE && RI != R->end());
205*349cc55cSDimitry Andric       const Instruction *LeftI = &*LI, *RightI = &*RI;
206*349cc55cSDimitry Andric 
207*349cc55cSDimitry Andric       // If the instructions differ, start the more sophisticated diff
208*349cc55cSDimitry Andric       // algorithm at the start of the block.
209*349cc55cSDimitry Andric       if (diff(LeftI, RightI, false, false)) {
210*349cc55cSDimitry Andric         TentativeValues.clear();
211*349cc55cSDimitry Andric         return runBlockDiff(L->begin(), R->begin());
212*349cc55cSDimitry Andric       }
213*349cc55cSDimitry Andric 
214*349cc55cSDimitry Andric       // Otherwise, tentatively unify them.
215*349cc55cSDimitry Andric       if (!LeftI->use_empty())
216*349cc55cSDimitry Andric         TentativeValues.insert(std::make_pair(LeftI, RightI));
217*349cc55cSDimitry Andric 
218*349cc55cSDimitry Andric       ++LI;
219*349cc55cSDimitry Andric       ++RI;
220*349cc55cSDimitry Andric     } while (LI != LE); // This is sufficient: we can't get equality of
221*349cc55cSDimitry Andric                         // terminators if there are residual instructions.
222*349cc55cSDimitry Andric 
223*349cc55cSDimitry Andric     // Unify everything in the block, non-tentatively this time.
224*349cc55cSDimitry Andric     TentativeValues.clear();
225*349cc55cSDimitry Andric     for (LI = L->begin(), RI = R->begin(); LI != LE; ++LI, ++RI)
226*349cc55cSDimitry Andric       unify(&*LI, &*RI);
227*349cc55cSDimitry Andric   }
228*349cc55cSDimitry Andric 
229*349cc55cSDimitry Andric   bool matchForBlockDiff(const Instruction *L, const Instruction *R);
230*349cc55cSDimitry Andric   void runBlockDiff(BasicBlock::const_iterator LI,
231*349cc55cSDimitry Andric                     BasicBlock::const_iterator RI);
232*349cc55cSDimitry Andric 
233*349cc55cSDimitry Andric   bool diffCallSites(const CallBase &L, const CallBase &R, bool Complain) {
234*349cc55cSDimitry Andric     // FIXME: call attributes
235*349cc55cSDimitry Andric     if (!equivalentAsOperands(L.getCalledOperand(), R.getCalledOperand())) {
236*349cc55cSDimitry Andric       if (Complain) Engine.log("called functions differ");
237*349cc55cSDimitry Andric       return true;
238*349cc55cSDimitry Andric     }
239*349cc55cSDimitry Andric     if (L.arg_size() != R.arg_size()) {
240*349cc55cSDimitry Andric       if (Complain) Engine.log("argument counts differ");
241*349cc55cSDimitry Andric       return true;
242*349cc55cSDimitry Andric     }
243*349cc55cSDimitry Andric     for (unsigned I = 0, E = L.arg_size(); I != E; ++I)
244*349cc55cSDimitry Andric       if (!equivalentAsOperands(L.getArgOperand(I), R.getArgOperand(I))) {
245*349cc55cSDimitry Andric         if (Complain)
246*349cc55cSDimitry Andric           Engine.logf("arguments %l and %r differ")
247*349cc55cSDimitry Andric               << L.getArgOperand(I) << R.getArgOperand(I);
248*349cc55cSDimitry Andric         return true;
249*349cc55cSDimitry Andric       }
250*349cc55cSDimitry Andric     return false;
251*349cc55cSDimitry Andric   }
252*349cc55cSDimitry Andric 
253*349cc55cSDimitry Andric   bool diff(const Instruction *L, const Instruction *R, bool Complain,
254*349cc55cSDimitry Andric             bool TryUnify) {
255*349cc55cSDimitry Andric     // FIXME: metadata (if Complain is set)
256*349cc55cSDimitry Andric 
257*349cc55cSDimitry Andric     // Different opcodes always imply different operations.
258*349cc55cSDimitry Andric     if (L->getOpcode() != R->getOpcode()) {
259*349cc55cSDimitry Andric       if (Complain) Engine.log("different instruction types");
260*349cc55cSDimitry Andric       return true;
261*349cc55cSDimitry Andric     }
262*349cc55cSDimitry Andric 
263*349cc55cSDimitry Andric     if (isa<CmpInst>(L)) {
264*349cc55cSDimitry Andric       if (cast<CmpInst>(L)->getPredicate()
265*349cc55cSDimitry Andric             != cast<CmpInst>(R)->getPredicate()) {
266*349cc55cSDimitry Andric         if (Complain) Engine.log("different predicates");
267*349cc55cSDimitry Andric         return true;
268*349cc55cSDimitry Andric       }
269*349cc55cSDimitry Andric     } else if (isa<CallInst>(L)) {
270*349cc55cSDimitry Andric       return diffCallSites(cast<CallInst>(*L), cast<CallInst>(*R), Complain);
271*349cc55cSDimitry Andric     } else if (isa<PHINode>(L)) {
272*349cc55cSDimitry Andric       // FIXME: implement.
273*349cc55cSDimitry Andric 
274*349cc55cSDimitry Andric       // This is really weird;  type uniquing is broken?
275*349cc55cSDimitry Andric       if (L->getType() != R->getType()) {
276*349cc55cSDimitry Andric         if (!L->getType()->isPointerTy() || !R->getType()->isPointerTy()) {
277*349cc55cSDimitry Andric           if (Complain) Engine.log("different phi types");
278*349cc55cSDimitry Andric           return true;
279*349cc55cSDimitry Andric         }
280*349cc55cSDimitry Andric       }
281*349cc55cSDimitry Andric       return false;
282*349cc55cSDimitry Andric 
283*349cc55cSDimitry Andric     // Terminators.
284*349cc55cSDimitry Andric     } else if (isa<InvokeInst>(L)) {
285*349cc55cSDimitry Andric       const InvokeInst &LI = cast<InvokeInst>(*L);
286*349cc55cSDimitry Andric       const InvokeInst &RI = cast<InvokeInst>(*R);
287*349cc55cSDimitry Andric       if (diffCallSites(LI, RI, Complain))
288*349cc55cSDimitry Andric         return true;
289*349cc55cSDimitry Andric 
290*349cc55cSDimitry Andric       if (TryUnify) {
291*349cc55cSDimitry Andric         tryUnify(LI.getNormalDest(), RI.getNormalDest());
292*349cc55cSDimitry Andric         tryUnify(LI.getUnwindDest(), RI.getUnwindDest());
293*349cc55cSDimitry Andric       }
294*349cc55cSDimitry Andric       return false;
295*349cc55cSDimitry Andric 
296*349cc55cSDimitry Andric     } else if (isa<CallBrInst>(L)) {
297*349cc55cSDimitry Andric       const CallBrInst &LI = cast<CallBrInst>(*L);
298*349cc55cSDimitry Andric       const CallBrInst &RI = cast<CallBrInst>(*R);
299*349cc55cSDimitry Andric       if (LI.getNumIndirectDests() != RI.getNumIndirectDests()) {
300*349cc55cSDimitry Andric         if (Complain)
301*349cc55cSDimitry Andric           Engine.log("callbr # of indirect destinations differ");
302*349cc55cSDimitry Andric         return true;
303*349cc55cSDimitry Andric       }
304*349cc55cSDimitry Andric 
305*349cc55cSDimitry Andric       // Perform the "try unify" step so that we can equate the indirect
306*349cc55cSDimitry Andric       // destinations before checking the call site.
307*349cc55cSDimitry Andric       for (unsigned I = 0; I < LI.getNumIndirectDests(); I++)
308*349cc55cSDimitry Andric         tryUnify(LI.getIndirectDest(I), RI.getIndirectDest(I));
309*349cc55cSDimitry Andric 
310*349cc55cSDimitry Andric       if (diffCallSites(LI, RI, Complain))
311*349cc55cSDimitry Andric         return true;
312*349cc55cSDimitry Andric 
313*349cc55cSDimitry Andric       if (TryUnify)
314*349cc55cSDimitry Andric         tryUnify(LI.getDefaultDest(), RI.getDefaultDest());
315*349cc55cSDimitry Andric       return false;
316*349cc55cSDimitry Andric 
317*349cc55cSDimitry Andric     } else if (isa<BranchInst>(L)) {
318*349cc55cSDimitry Andric       const BranchInst *LI = cast<BranchInst>(L);
319*349cc55cSDimitry Andric       const BranchInst *RI = cast<BranchInst>(R);
320*349cc55cSDimitry Andric       if (LI->isConditional() != RI->isConditional()) {
321*349cc55cSDimitry Andric         if (Complain) Engine.log("branch conditionality differs");
322*349cc55cSDimitry Andric         return true;
323*349cc55cSDimitry Andric       }
324*349cc55cSDimitry Andric 
325*349cc55cSDimitry Andric       if (LI->isConditional()) {
326*349cc55cSDimitry Andric         if (!equivalentAsOperands(LI->getCondition(), RI->getCondition())) {
327*349cc55cSDimitry Andric           if (Complain) Engine.log("branch conditions differ");
328*349cc55cSDimitry Andric           return true;
329*349cc55cSDimitry Andric         }
330*349cc55cSDimitry Andric         if (TryUnify) tryUnify(LI->getSuccessor(1), RI->getSuccessor(1));
331*349cc55cSDimitry Andric       }
332*349cc55cSDimitry Andric       if (TryUnify) tryUnify(LI->getSuccessor(0), RI->getSuccessor(0));
333*349cc55cSDimitry Andric       return false;
334*349cc55cSDimitry Andric 
335*349cc55cSDimitry Andric     } else if (isa<IndirectBrInst>(L)) {
336*349cc55cSDimitry Andric       const IndirectBrInst *LI = cast<IndirectBrInst>(L);
337*349cc55cSDimitry Andric       const IndirectBrInst *RI = cast<IndirectBrInst>(R);
338*349cc55cSDimitry Andric       if (LI->getNumDestinations() != RI->getNumDestinations()) {
339*349cc55cSDimitry Andric         if (Complain) Engine.log("indirectbr # of destinations differ");
340*349cc55cSDimitry Andric         return true;
341*349cc55cSDimitry Andric       }
342*349cc55cSDimitry Andric 
343*349cc55cSDimitry Andric       if (!equivalentAsOperands(LI->getAddress(), RI->getAddress())) {
344*349cc55cSDimitry Andric         if (Complain) Engine.log("indirectbr addresses differ");
345*349cc55cSDimitry Andric         return true;
346*349cc55cSDimitry Andric       }
347*349cc55cSDimitry Andric 
348*349cc55cSDimitry Andric       if (TryUnify) {
349*349cc55cSDimitry Andric         for (unsigned i = 0; i < LI->getNumDestinations(); i++) {
350*349cc55cSDimitry Andric           tryUnify(LI->getDestination(i), RI->getDestination(i));
351*349cc55cSDimitry Andric         }
352*349cc55cSDimitry Andric       }
353*349cc55cSDimitry Andric       return false;
354*349cc55cSDimitry Andric 
355*349cc55cSDimitry Andric     } else if (isa<SwitchInst>(L)) {
356*349cc55cSDimitry Andric       const SwitchInst *LI = cast<SwitchInst>(L);
357*349cc55cSDimitry Andric       const SwitchInst *RI = cast<SwitchInst>(R);
358*349cc55cSDimitry Andric       if (!equivalentAsOperands(LI->getCondition(), RI->getCondition())) {
359*349cc55cSDimitry Andric         if (Complain) Engine.log("switch conditions differ");
360*349cc55cSDimitry Andric         return true;
361*349cc55cSDimitry Andric       }
362*349cc55cSDimitry Andric       if (TryUnify) tryUnify(LI->getDefaultDest(), RI->getDefaultDest());
363*349cc55cSDimitry Andric 
364*349cc55cSDimitry Andric       bool Difference = false;
365*349cc55cSDimitry Andric 
366*349cc55cSDimitry Andric       DenseMap<const ConstantInt *, const BasicBlock *> LCases;
367*349cc55cSDimitry Andric       for (auto Case : LI->cases())
368*349cc55cSDimitry Andric         LCases[Case.getCaseValue()] = Case.getCaseSuccessor();
369*349cc55cSDimitry Andric 
370*349cc55cSDimitry Andric       for (auto Case : RI->cases()) {
371*349cc55cSDimitry Andric         const ConstantInt *CaseValue = Case.getCaseValue();
372*349cc55cSDimitry Andric         const BasicBlock *LCase = LCases[CaseValue];
373*349cc55cSDimitry Andric         if (LCase) {
374*349cc55cSDimitry Andric           if (TryUnify)
375*349cc55cSDimitry Andric             tryUnify(LCase, Case.getCaseSuccessor());
376*349cc55cSDimitry Andric           LCases.erase(CaseValue);
377*349cc55cSDimitry Andric         } else if (Complain || !Difference) {
378*349cc55cSDimitry Andric           if (Complain)
379*349cc55cSDimitry Andric             Engine.logf("right switch has extra case %r") << CaseValue;
380*349cc55cSDimitry Andric           Difference = true;
381*349cc55cSDimitry Andric         }
382*349cc55cSDimitry Andric       }
383*349cc55cSDimitry Andric       if (!Difference)
384*349cc55cSDimitry Andric         for (DenseMap<const ConstantInt *, const BasicBlock *>::iterator
385*349cc55cSDimitry Andric                  I = LCases.begin(),
386*349cc55cSDimitry Andric                  E = LCases.end();
387*349cc55cSDimitry Andric              I != E; ++I) {
388*349cc55cSDimitry Andric           if (Complain)
389*349cc55cSDimitry Andric             Engine.logf("left switch has extra case %l") << I->first;
390*349cc55cSDimitry Andric           Difference = true;
391*349cc55cSDimitry Andric         }
392*349cc55cSDimitry Andric       return Difference;
393*349cc55cSDimitry Andric     } else if (isa<UnreachableInst>(L)) {
394*349cc55cSDimitry Andric       return false;
395*349cc55cSDimitry Andric     }
396*349cc55cSDimitry Andric 
397*349cc55cSDimitry Andric     if (L->getNumOperands() != R->getNumOperands()) {
398*349cc55cSDimitry Andric       if (Complain) Engine.log("instructions have different operand counts");
399*349cc55cSDimitry Andric       return true;
400*349cc55cSDimitry Andric     }
401*349cc55cSDimitry Andric 
402*349cc55cSDimitry Andric     for (unsigned I = 0, E = L->getNumOperands(); I != E; ++I) {
403*349cc55cSDimitry Andric       Value *LO = L->getOperand(I), *RO = R->getOperand(I);
404*349cc55cSDimitry Andric       if (!equivalentAsOperands(LO, RO)) {
405*349cc55cSDimitry Andric         if (Complain) Engine.logf("operands %l and %r differ") << LO << RO;
406*349cc55cSDimitry Andric         return true;
407*349cc55cSDimitry Andric       }
408*349cc55cSDimitry Andric     }
409*349cc55cSDimitry Andric 
410*349cc55cSDimitry Andric     return false;
411*349cc55cSDimitry Andric   }
412*349cc55cSDimitry Andric 
413*349cc55cSDimitry Andric public:
414*349cc55cSDimitry Andric   bool equivalentAsOperands(const Constant *L, const Constant *R) {
415*349cc55cSDimitry Andric     // Use equality as a preliminary filter.
416*349cc55cSDimitry Andric     if (L == R)
417*349cc55cSDimitry Andric       return true;
418*349cc55cSDimitry Andric 
419*349cc55cSDimitry Andric     if (L->getValueID() != R->getValueID())
420*349cc55cSDimitry Andric       return false;
421*349cc55cSDimitry Andric 
422*349cc55cSDimitry Andric     // Ask the engine about global values.
423*349cc55cSDimitry Andric     if (isa<GlobalValue>(L))
424*349cc55cSDimitry Andric       return Engine.equivalentAsOperands(cast<GlobalValue>(L),
425*349cc55cSDimitry Andric                                          cast<GlobalValue>(R));
426*349cc55cSDimitry Andric 
427*349cc55cSDimitry Andric     // Compare constant expressions structurally.
428*349cc55cSDimitry Andric     if (isa<ConstantExpr>(L))
429*349cc55cSDimitry Andric       return equivalentAsOperands(cast<ConstantExpr>(L),
430*349cc55cSDimitry Andric                                   cast<ConstantExpr>(R));
431*349cc55cSDimitry Andric 
432*349cc55cSDimitry Andric     // Constants of the "same type" don't always actually have the same
433*349cc55cSDimitry Andric     // type; I don't know why.  Just white-list them.
434*349cc55cSDimitry Andric     if (isa<ConstantPointerNull>(L) || isa<UndefValue>(L) || isa<ConstantAggregateZero>(L))
435*349cc55cSDimitry Andric       return true;
436*349cc55cSDimitry Andric 
437*349cc55cSDimitry Andric     // Block addresses only match if we've already encountered the
438*349cc55cSDimitry Andric     // block.  FIXME: tentative matches?
439*349cc55cSDimitry Andric     if (isa<BlockAddress>(L))
440*349cc55cSDimitry Andric       return Blocks[cast<BlockAddress>(L)->getBasicBlock()]
441*349cc55cSDimitry Andric                  == cast<BlockAddress>(R)->getBasicBlock();
442*349cc55cSDimitry Andric 
443*349cc55cSDimitry Andric     // If L and R are ConstantVectors, compare each element
444*349cc55cSDimitry Andric     if (isa<ConstantVector>(L)) {
445*349cc55cSDimitry Andric       const ConstantVector *CVL = cast<ConstantVector>(L);
446*349cc55cSDimitry Andric       const ConstantVector *CVR = cast<ConstantVector>(R);
447*349cc55cSDimitry Andric       if (CVL->getType()->getNumElements() != CVR->getType()->getNumElements())
448*349cc55cSDimitry Andric         return false;
449*349cc55cSDimitry Andric       for (unsigned i = 0; i < CVL->getType()->getNumElements(); i++) {
450*349cc55cSDimitry Andric         if (!equivalentAsOperands(CVL->getOperand(i), CVR->getOperand(i)))
451*349cc55cSDimitry Andric           return false;
452*349cc55cSDimitry Andric       }
453*349cc55cSDimitry Andric       return true;
454*349cc55cSDimitry Andric     }
455*349cc55cSDimitry Andric 
456*349cc55cSDimitry Andric     // If L and R are ConstantArrays, compare the element count and types.
457*349cc55cSDimitry Andric     if (isa<ConstantArray>(L)) {
458*349cc55cSDimitry Andric       const ConstantArray *CAL = cast<ConstantArray>(L);
459*349cc55cSDimitry Andric       const ConstantArray *CAR = cast<ConstantArray>(R);
460*349cc55cSDimitry Andric       // Sometimes a type may be equivalent, but not uniquified---e.g. it may
461*349cc55cSDimitry Andric       // contain a GEP instruction. Do a deeper comparison of the types.
462*349cc55cSDimitry Andric       if (CAL->getType()->getNumElements() != CAR->getType()->getNumElements())
463*349cc55cSDimitry Andric         return false;
464*349cc55cSDimitry Andric 
465*349cc55cSDimitry Andric       for (unsigned I = 0; I < CAL->getType()->getNumElements(); ++I) {
466*349cc55cSDimitry Andric         if (!equivalentAsOperands(CAL->getAggregateElement(I),
467*349cc55cSDimitry Andric                                   CAR->getAggregateElement(I)))
468*349cc55cSDimitry Andric           return false;
469*349cc55cSDimitry Andric       }
470*349cc55cSDimitry Andric 
471*349cc55cSDimitry Andric       return true;
472*349cc55cSDimitry Andric     }
473*349cc55cSDimitry Andric 
474*349cc55cSDimitry Andric     // If L and R are ConstantStructs, compare each field and type.
475*349cc55cSDimitry Andric     if (isa<ConstantStruct>(L)) {
476*349cc55cSDimitry Andric       const ConstantStruct *CSL = cast<ConstantStruct>(L);
477*349cc55cSDimitry Andric       const ConstantStruct *CSR = cast<ConstantStruct>(R);
478*349cc55cSDimitry Andric 
479*349cc55cSDimitry Andric       const StructType *LTy = cast<StructType>(CSL->getType());
480*349cc55cSDimitry Andric       const StructType *RTy = cast<StructType>(CSR->getType());
481*349cc55cSDimitry Andric 
482*349cc55cSDimitry Andric       // The StructTypes should have the same attributes. Don't use
483*349cc55cSDimitry Andric       // isLayoutIdentical(), because that just checks the element pointers,
484*349cc55cSDimitry Andric       // which may not work here.
485*349cc55cSDimitry Andric       if (LTy->getNumElements() != RTy->getNumElements() ||
486*349cc55cSDimitry Andric           LTy->isPacked() != RTy->isPacked())
487*349cc55cSDimitry Andric         return false;
488*349cc55cSDimitry Andric 
489*349cc55cSDimitry Andric       for (unsigned I = 0; I < LTy->getNumElements(); I++) {
490*349cc55cSDimitry Andric         const Value *LAgg = CSL->getAggregateElement(I);
491*349cc55cSDimitry Andric         const Value *RAgg = CSR->getAggregateElement(I);
492*349cc55cSDimitry Andric 
493*349cc55cSDimitry Andric         if (LAgg == SavedLHS || RAgg == SavedRHS) {
494*349cc55cSDimitry Andric           if (LAgg != SavedLHS || RAgg != SavedRHS)
495*349cc55cSDimitry Andric             // If the left and right operands aren't both re-analyzing the
496*349cc55cSDimitry Andric             // variable, then the initialiers don't match, so report "false".
497*349cc55cSDimitry Andric             // Otherwise, we skip these operands..
498*349cc55cSDimitry Andric             return false;
499*349cc55cSDimitry Andric 
500*349cc55cSDimitry Andric           continue;
501*349cc55cSDimitry Andric         }
502*349cc55cSDimitry Andric 
503*349cc55cSDimitry Andric         if (!equivalentAsOperands(LAgg, RAgg)) {
504*349cc55cSDimitry Andric           return false;
505*349cc55cSDimitry Andric         }
506*349cc55cSDimitry Andric       }
507*349cc55cSDimitry Andric 
508*349cc55cSDimitry Andric       return true;
509*349cc55cSDimitry Andric     }
510*349cc55cSDimitry Andric 
511*349cc55cSDimitry Andric     return false;
512*349cc55cSDimitry Andric   }
513*349cc55cSDimitry Andric 
514*349cc55cSDimitry Andric   bool equivalentAsOperands(const ConstantExpr *L, const ConstantExpr *R) {
515*349cc55cSDimitry Andric     if (L == R)
516*349cc55cSDimitry Andric       return true;
517*349cc55cSDimitry Andric 
518*349cc55cSDimitry Andric     if (L->getOpcode() != R->getOpcode())
519*349cc55cSDimitry Andric       return false;
520*349cc55cSDimitry Andric 
521*349cc55cSDimitry Andric     switch (L->getOpcode()) {
522*349cc55cSDimitry Andric     case Instruction::ICmp:
523*349cc55cSDimitry Andric     case Instruction::FCmp:
524*349cc55cSDimitry Andric       if (L->getPredicate() != R->getPredicate())
525*349cc55cSDimitry Andric         return false;
526*349cc55cSDimitry Andric       break;
527*349cc55cSDimitry Andric 
528*349cc55cSDimitry Andric     case Instruction::GetElementPtr:
529*349cc55cSDimitry Andric       // FIXME: inbounds?
530*349cc55cSDimitry Andric       break;
531*349cc55cSDimitry Andric 
532*349cc55cSDimitry Andric     default:
533*349cc55cSDimitry Andric       break;
534*349cc55cSDimitry Andric     }
535*349cc55cSDimitry Andric 
536*349cc55cSDimitry Andric     if (L->getNumOperands() != R->getNumOperands())
537*349cc55cSDimitry Andric       return false;
538*349cc55cSDimitry Andric 
539*349cc55cSDimitry Andric     for (unsigned I = 0, E = L->getNumOperands(); I != E; ++I) {
540*349cc55cSDimitry Andric       const auto *LOp = L->getOperand(I);
541*349cc55cSDimitry Andric       const auto *ROp = R->getOperand(I);
542*349cc55cSDimitry Andric 
543*349cc55cSDimitry Andric       if (LOp == SavedLHS || ROp == SavedRHS) {
544*349cc55cSDimitry Andric         if (LOp != SavedLHS || ROp != SavedRHS)
545*349cc55cSDimitry Andric           // If the left and right operands aren't both re-analyzing the
546*349cc55cSDimitry Andric           // variable, then the initialiers don't match, so report "false".
547*349cc55cSDimitry Andric           // Otherwise, we skip these operands..
548*349cc55cSDimitry Andric           return false;
549*349cc55cSDimitry Andric 
550*349cc55cSDimitry Andric         continue;
551*349cc55cSDimitry Andric       }
552*349cc55cSDimitry Andric 
553*349cc55cSDimitry Andric       if (!equivalentAsOperands(LOp, ROp))
554*349cc55cSDimitry Andric         return false;
555*349cc55cSDimitry Andric     }
556*349cc55cSDimitry Andric 
557*349cc55cSDimitry Andric     return true;
558*349cc55cSDimitry Andric   }
559*349cc55cSDimitry Andric 
560*349cc55cSDimitry Andric   bool equivalentAsOperands(const Value *L, const Value *R) {
561*349cc55cSDimitry Andric     // Fall out if the values have different kind.
562*349cc55cSDimitry Andric     // This possibly shouldn't take priority over oracles.
563*349cc55cSDimitry Andric     if (L->getValueID() != R->getValueID())
564*349cc55cSDimitry Andric       return false;
565*349cc55cSDimitry Andric 
566*349cc55cSDimitry Andric     // Value subtypes:  Argument, Constant, Instruction, BasicBlock,
567*349cc55cSDimitry Andric     //                  InlineAsm, MDNode, MDString, PseudoSourceValue
568*349cc55cSDimitry Andric 
569*349cc55cSDimitry Andric     if (isa<Constant>(L))
570*349cc55cSDimitry Andric       return equivalentAsOperands(cast<Constant>(L), cast<Constant>(R));
571*349cc55cSDimitry Andric 
572*349cc55cSDimitry Andric     if (isa<Instruction>(L))
573*349cc55cSDimitry Andric       return Values[L] == R || TentativeValues.count(std::make_pair(L, R));
574*349cc55cSDimitry Andric 
575*349cc55cSDimitry Andric     if (isa<Argument>(L))
576*349cc55cSDimitry Andric       return Values[L] == R;
577*349cc55cSDimitry Andric 
578*349cc55cSDimitry Andric     if (isa<BasicBlock>(L))
579*349cc55cSDimitry Andric       return Blocks[cast<BasicBlock>(L)] != R;
580*349cc55cSDimitry Andric 
581*349cc55cSDimitry Andric     // Pretend everything else is identical.
582*349cc55cSDimitry Andric     return true;
583*349cc55cSDimitry Andric   }
584*349cc55cSDimitry Andric 
585*349cc55cSDimitry Andric   // Avoid a gcc warning about accessing 'this' in an initializer.
586*349cc55cSDimitry Andric   FunctionDifferenceEngine *this_() { return this; }
587*349cc55cSDimitry Andric 
588*349cc55cSDimitry Andric public:
589*349cc55cSDimitry Andric   FunctionDifferenceEngine(DifferenceEngine &Engine,
590*349cc55cSDimitry Andric                            const Value *SavedLHS = nullptr,
591*349cc55cSDimitry Andric                            const Value *SavedRHS = nullptr)
592*349cc55cSDimitry Andric       : Engine(Engine), SavedLHS(SavedLHS), SavedRHS(SavedRHS),
593*349cc55cSDimitry Andric         Queue(QueueSorter(*this_())) {}
594*349cc55cSDimitry Andric 
595*349cc55cSDimitry Andric   void diff(const Function *L, const Function *R) {
596*349cc55cSDimitry Andric     if (L->arg_size() != R->arg_size())
597*349cc55cSDimitry Andric       Engine.log("different argument counts");
598*349cc55cSDimitry Andric 
599*349cc55cSDimitry Andric     // Map the arguments.
600*349cc55cSDimitry Andric     for (Function::const_arg_iterator LI = L->arg_begin(), LE = L->arg_end(),
601*349cc55cSDimitry Andric                                       RI = R->arg_begin(), RE = R->arg_end();
602*349cc55cSDimitry Andric          LI != LE && RI != RE; ++LI, ++RI)
603*349cc55cSDimitry Andric       Values[&*LI] = &*RI;
604*349cc55cSDimitry Andric 
605*349cc55cSDimitry Andric     tryUnify(&*L->begin(), &*R->begin());
606*349cc55cSDimitry Andric     processQueue();
607*349cc55cSDimitry Andric   }
608*349cc55cSDimitry Andric };
609*349cc55cSDimitry Andric 
610*349cc55cSDimitry Andric struct DiffEntry {
611*349cc55cSDimitry Andric   DiffEntry() : Cost(0) {}
612*349cc55cSDimitry Andric 
613*349cc55cSDimitry Andric   unsigned Cost;
614*349cc55cSDimitry Andric   llvm::SmallVector<char, 8> Path; // actually of DifferenceEngine::DiffChange
615*349cc55cSDimitry Andric };
616*349cc55cSDimitry Andric 
617*349cc55cSDimitry Andric bool FunctionDifferenceEngine::matchForBlockDiff(const Instruction *L,
618*349cc55cSDimitry Andric                                                  const Instruction *R) {
619*349cc55cSDimitry Andric   return !diff(L, R, false, false);
620*349cc55cSDimitry Andric }
621*349cc55cSDimitry Andric 
622*349cc55cSDimitry Andric void FunctionDifferenceEngine::runBlockDiff(BasicBlock::const_iterator LStart,
623*349cc55cSDimitry Andric                                             BasicBlock::const_iterator RStart) {
624*349cc55cSDimitry Andric   BasicBlock::const_iterator LE = LStart->getParent()->end();
625*349cc55cSDimitry Andric   BasicBlock::const_iterator RE = RStart->getParent()->end();
626*349cc55cSDimitry Andric 
627*349cc55cSDimitry Andric   unsigned NL = std::distance(LStart, LE);
628*349cc55cSDimitry Andric 
629*349cc55cSDimitry Andric   SmallVector<DiffEntry, 20> Paths1(NL+1);
630*349cc55cSDimitry Andric   SmallVector<DiffEntry, 20> Paths2(NL+1);
631*349cc55cSDimitry Andric 
632*349cc55cSDimitry Andric   DiffEntry *Cur = Paths1.data();
633*349cc55cSDimitry Andric   DiffEntry *Next = Paths2.data();
634*349cc55cSDimitry Andric 
635*349cc55cSDimitry Andric   const unsigned LeftCost = 2;
636*349cc55cSDimitry Andric   const unsigned RightCost = 2;
637*349cc55cSDimitry Andric   const unsigned MatchCost = 0;
638*349cc55cSDimitry Andric 
639*349cc55cSDimitry Andric   assert(TentativeValues.empty());
640*349cc55cSDimitry Andric 
641*349cc55cSDimitry Andric   // Initialize the first column.
642*349cc55cSDimitry Andric   for (unsigned I = 0; I != NL+1; ++I) {
643*349cc55cSDimitry Andric     Cur[I].Cost = I * LeftCost;
644*349cc55cSDimitry Andric     for (unsigned J = 0; J != I; ++J)
645*349cc55cSDimitry Andric       Cur[I].Path.push_back(DC_left);
646*349cc55cSDimitry Andric   }
647*349cc55cSDimitry Andric 
648*349cc55cSDimitry Andric   for (BasicBlock::const_iterator RI = RStart; RI != RE; ++RI) {
649*349cc55cSDimitry Andric     // Initialize the first row.
650*349cc55cSDimitry Andric     Next[0] = Cur[0];
651*349cc55cSDimitry Andric     Next[0].Cost += RightCost;
652*349cc55cSDimitry Andric     Next[0].Path.push_back(DC_right);
653*349cc55cSDimitry Andric 
654*349cc55cSDimitry Andric     unsigned Index = 1;
655*349cc55cSDimitry Andric     for (BasicBlock::const_iterator LI = LStart; LI != LE; ++LI, ++Index) {
656*349cc55cSDimitry Andric       if (matchForBlockDiff(&*LI, &*RI)) {
657*349cc55cSDimitry Andric         Next[Index] = Cur[Index-1];
658*349cc55cSDimitry Andric         Next[Index].Cost += MatchCost;
659*349cc55cSDimitry Andric         Next[Index].Path.push_back(DC_match);
660*349cc55cSDimitry Andric         TentativeValues.insert(std::make_pair(&*LI, &*RI));
661*349cc55cSDimitry Andric       } else if (Next[Index-1].Cost <= Cur[Index].Cost) {
662*349cc55cSDimitry Andric         Next[Index] = Next[Index-1];
663*349cc55cSDimitry Andric         Next[Index].Cost += LeftCost;
664*349cc55cSDimitry Andric         Next[Index].Path.push_back(DC_left);
665*349cc55cSDimitry Andric       } else {
666*349cc55cSDimitry Andric         Next[Index] = Cur[Index];
667*349cc55cSDimitry Andric         Next[Index].Cost += RightCost;
668*349cc55cSDimitry Andric         Next[Index].Path.push_back(DC_right);
669*349cc55cSDimitry Andric       }
670*349cc55cSDimitry Andric     }
671*349cc55cSDimitry Andric 
672*349cc55cSDimitry Andric     std::swap(Cur, Next);
673*349cc55cSDimitry Andric   }
674*349cc55cSDimitry Andric 
675*349cc55cSDimitry Andric   // We don't need the tentative values anymore; everything from here
676*349cc55cSDimitry Andric   // on out should be non-tentative.
677*349cc55cSDimitry Andric   TentativeValues.clear();
678*349cc55cSDimitry Andric 
679*349cc55cSDimitry Andric   SmallVectorImpl<char> &Path = Cur[NL].Path;
680*349cc55cSDimitry Andric   BasicBlock::const_iterator LI = LStart, RI = RStart;
681*349cc55cSDimitry Andric 
682*349cc55cSDimitry Andric   DiffLogBuilder Diff(Engine.getConsumer());
683*349cc55cSDimitry Andric 
684*349cc55cSDimitry Andric   // Drop trailing matches.
685*349cc55cSDimitry Andric   while (Path.size() && Path.back() == DC_match)
686*349cc55cSDimitry Andric     Path.pop_back();
687*349cc55cSDimitry Andric 
688*349cc55cSDimitry Andric   // Skip leading matches.
689*349cc55cSDimitry Andric   SmallVectorImpl<char>::iterator
690*349cc55cSDimitry Andric     PI = Path.begin(), PE = Path.end();
691*349cc55cSDimitry Andric   while (PI != PE && *PI == DC_match) {
692*349cc55cSDimitry Andric     unify(&*LI, &*RI);
693*349cc55cSDimitry Andric     ++PI;
694*349cc55cSDimitry Andric     ++LI;
695*349cc55cSDimitry Andric     ++RI;
696*349cc55cSDimitry Andric   }
697*349cc55cSDimitry Andric 
698*349cc55cSDimitry Andric   for (; PI != PE; ++PI) {
699*349cc55cSDimitry Andric     switch (static_cast<DiffChange>(*PI)) {
700*349cc55cSDimitry Andric     case DC_match:
701*349cc55cSDimitry Andric       assert(LI != LE && RI != RE);
702*349cc55cSDimitry Andric       {
703*349cc55cSDimitry Andric         const Instruction *L = &*LI, *R = &*RI;
704*349cc55cSDimitry Andric         unify(L, R);
705*349cc55cSDimitry Andric         Diff.addMatch(L, R);
706*349cc55cSDimitry Andric       }
707*349cc55cSDimitry Andric       ++LI; ++RI;
708*349cc55cSDimitry Andric       break;
709*349cc55cSDimitry Andric 
710*349cc55cSDimitry Andric     case DC_left:
711*349cc55cSDimitry Andric       assert(LI != LE);
712*349cc55cSDimitry Andric       Diff.addLeft(&*LI);
713*349cc55cSDimitry Andric       ++LI;
714*349cc55cSDimitry Andric       break;
715*349cc55cSDimitry Andric 
716*349cc55cSDimitry Andric     case DC_right:
717*349cc55cSDimitry Andric       assert(RI != RE);
718*349cc55cSDimitry Andric       Diff.addRight(&*RI);
719*349cc55cSDimitry Andric       ++RI;
720*349cc55cSDimitry Andric       break;
721*349cc55cSDimitry Andric     }
722*349cc55cSDimitry Andric   }
723*349cc55cSDimitry Andric 
724*349cc55cSDimitry Andric   // Finishing unifying and complaining about the tails of the block,
725*349cc55cSDimitry Andric   // which should be matches all the way through.
726*349cc55cSDimitry Andric   while (LI != LE) {
727*349cc55cSDimitry Andric     assert(RI != RE);
728*349cc55cSDimitry Andric     unify(&*LI, &*RI);
729*349cc55cSDimitry Andric     ++LI;
730*349cc55cSDimitry Andric     ++RI;
731*349cc55cSDimitry Andric   }
732*349cc55cSDimitry Andric 
733*349cc55cSDimitry Andric   // If the terminators have different kinds, but one is an invoke and the
734*349cc55cSDimitry Andric   // other is an unconditional branch immediately following a call, unify
735*349cc55cSDimitry Andric   // the results and the destinations.
736*349cc55cSDimitry Andric   const Instruction *LTerm = LStart->getParent()->getTerminator();
737*349cc55cSDimitry Andric   const Instruction *RTerm = RStart->getParent()->getTerminator();
738*349cc55cSDimitry Andric   if (isa<BranchInst>(LTerm) && isa<InvokeInst>(RTerm)) {
739*349cc55cSDimitry Andric     if (cast<BranchInst>(LTerm)->isConditional()) return;
740*349cc55cSDimitry Andric     BasicBlock::const_iterator I = LTerm->getIterator();
741*349cc55cSDimitry Andric     if (I == LStart->getParent()->begin()) return;
742*349cc55cSDimitry Andric     --I;
743*349cc55cSDimitry Andric     if (!isa<CallInst>(*I)) return;
744*349cc55cSDimitry Andric     const CallInst *LCall = cast<CallInst>(&*I);
745*349cc55cSDimitry Andric     const InvokeInst *RInvoke = cast<InvokeInst>(RTerm);
746*349cc55cSDimitry Andric     if (!equivalentAsOperands(LCall->getCalledOperand(),
747*349cc55cSDimitry Andric                               RInvoke->getCalledOperand()))
748*349cc55cSDimitry Andric       return;
749*349cc55cSDimitry Andric     if (!LCall->use_empty())
750*349cc55cSDimitry Andric       Values[LCall] = RInvoke;
751*349cc55cSDimitry Andric     tryUnify(LTerm->getSuccessor(0), RInvoke->getNormalDest());
752*349cc55cSDimitry Andric   } else if (isa<InvokeInst>(LTerm) && isa<BranchInst>(RTerm)) {
753*349cc55cSDimitry Andric     if (cast<BranchInst>(RTerm)->isConditional()) return;
754*349cc55cSDimitry Andric     BasicBlock::const_iterator I = RTerm->getIterator();
755*349cc55cSDimitry Andric     if (I == RStart->getParent()->begin()) return;
756*349cc55cSDimitry Andric     --I;
757*349cc55cSDimitry Andric     if (!isa<CallInst>(*I)) return;
758*349cc55cSDimitry Andric     const CallInst *RCall = cast<CallInst>(I);
759*349cc55cSDimitry Andric     const InvokeInst *LInvoke = cast<InvokeInst>(LTerm);
760*349cc55cSDimitry Andric     if (!equivalentAsOperands(LInvoke->getCalledOperand(),
761*349cc55cSDimitry Andric                               RCall->getCalledOperand()))
762*349cc55cSDimitry Andric       return;
763*349cc55cSDimitry Andric     if (!LInvoke->use_empty())
764*349cc55cSDimitry Andric       Values[LInvoke] = RCall;
765*349cc55cSDimitry Andric     tryUnify(LInvoke->getNormalDest(), RTerm->getSuccessor(0));
766*349cc55cSDimitry Andric   }
767*349cc55cSDimitry Andric }
768*349cc55cSDimitry Andric }
769*349cc55cSDimitry Andric 
770*349cc55cSDimitry Andric void DifferenceEngine::Oracle::anchor() { }
771*349cc55cSDimitry Andric 
772*349cc55cSDimitry Andric void DifferenceEngine::diff(const Function *L, const Function *R) {
773*349cc55cSDimitry Andric   Context C(*this, L, R);
774*349cc55cSDimitry Andric 
775*349cc55cSDimitry Andric   // FIXME: types
776*349cc55cSDimitry Andric   // FIXME: attributes and CC
777*349cc55cSDimitry Andric   // FIXME: parameter attributes
778*349cc55cSDimitry Andric 
779*349cc55cSDimitry Andric   // If both are declarations, we're done.
780*349cc55cSDimitry Andric   if (L->empty() && R->empty())
781*349cc55cSDimitry Andric     return;
782*349cc55cSDimitry Andric   else if (L->empty())
783*349cc55cSDimitry Andric     log("left function is declaration, right function is definition");
784*349cc55cSDimitry Andric   else if (R->empty())
785*349cc55cSDimitry Andric     log("right function is declaration, left function is definition");
786*349cc55cSDimitry Andric   else
787*349cc55cSDimitry Andric     FunctionDifferenceEngine(*this).diff(L, R);
788*349cc55cSDimitry Andric }
789*349cc55cSDimitry Andric 
790*349cc55cSDimitry Andric void DifferenceEngine::diff(const Module *L, const Module *R) {
791*349cc55cSDimitry Andric   StringSet<> LNames;
792*349cc55cSDimitry Andric   SmallVector<std::pair<const Function *, const Function *>, 20> Queue;
793*349cc55cSDimitry Andric 
794*349cc55cSDimitry Andric   unsigned LeftAnonCount = 0;
795*349cc55cSDimitry Andric   unsigned RightAnonCount = 0;
796*349cc55cSDimitry Andric 
797*349cc55cSDimitry Andric   for (Module::const_iterator I = L->begin(), E = L->end(); I != E; ++I) {
798*349cc55cSDimitry Andric     const Function *LFn = &*I;
799*349cc55cSDimitry Andric     StringRef Name = LFn->getName();
800*349cc55cSDimitry Andric     if (Name.empty()) {
801*349cc55cSDimitry Andric       ++LeftAnonCount;
802*349cc55cSDimitry Andric       continue;
803*349cc55cSDimitry Andric     }
804*349cc55cSDimitry Andric 
805*349cc55cSDimitry Andric     LNames.insert(Name);
806*349cc55cSDimitry Andric 
807*349cc55cSDimitry Andric     if (Function *RFn = R->getFunction(LFn->getName()))
808*349cc55cSDimitry Andric       Queue.push_back(std::make_pair(LFn, RFn));
809*349cc55cSDimitry Andric     else
810*349cc55cSDimitry Andric       logf("function %l exists only in left module") << LFn;
811*349cc55cSDimitry Andric   }
812*349cc55cSDimitry Andric 
813*349cc55cSDimitry Andric   for (Module::const_iterator I = R->begin(), E = R->end(); I != E; ++I) {
814*349cc55cSDimitry Andric     const Function *RFn = &*I;
815*349cc55cSDimitry Andric     StringRef Name = RFn->getName();
816*349cc55cSDimitry Andric     if (Name.empty()) {
817*349cc55cSDimitry Andric       ++RightAnonCount;
818*349cc55cSDimitry Andric       continue;
819*349cc55cSDimitry Andric     }
820*349cc55cSDimitry Andric 
821*349cc55cSDimitry Andric     if (!LNames.count(Name))
822*349cc55cSDimitry Andric       logf("function %r exists only in right module") << RFn;
823*349cc55cSDimitry Andric   }
824*349cc55cSDimitry Andric 
825*349cc55cSDimitry Andric   if (LeftAnonCount != 0 || RightAnonCount != 0) {
826*349cc55cSDimitry Andric     SmallString<32> Tmp;
827*349cc55cSDimitry Andric     logf(("not comparing " + Twine(LeftAnonCount) +
828*349cc55cSDimitry Andric           " anonymous functions in the left module and " +
829*349cc55cSDimitry Andric           Twine(RightAnonCount) + " in the right module")
830*349cc55cSDimitry Andric              .toStringRef(Tmp));
831*349cc55cSDimitry Andric   }
832*349cc55cSDimitry Andric 
833*349cc55cSDimitry Andric   for (SmallVectorImpl<std::pair<const Function *, const Function *>>::iterator
834*349cc55cSDimitry Andric            I = Queue.begin(),
835*349cc55cSDimitry Andric            E = Queue.end();
836*349cc55cSDimitry Andric        I != E; ++I)
837*349cc55cSDimitry Andric     diff(I->first, I->second);
838*349cc55cSDimitry Andric }
839*349cc55cSDimitry Andric 
840*349cc55cSDimitry Andric bool DifferenceEngine::equivalentAsOperands(const GlobalValue *L,
841*349cc55cSDimitry Andric                                             const GlobalValue *R) {
842*349cc55cSDimitry Andric   if (globalValueOracle) return (*globalValueOracle)(L, R);
843*349cc55cSDimitry Andric 
844*349cc55cSDimitry Andric   if (isa<GlobalVariable>(L) && isa<GlobalVariable>(R)) {
845*349cc55cSDimitry Andric     const GlobalVariable *GVL = cast<GlobalVariable>(L);
846*349cc55cSDimitry Andric     const GlobalVariable *GVR = cast<GlobalVariable>(R);
847*349cc55cSDimitry Andric     if (GVL->hasLocalLinkage() && GVL->hasUniqueInitializer() &&
848*349cc55cSDimitry Andric         GVR->hasLocalLinkage() && GVR->hasUniqueInitializer())
849*349cc55cSDimitry Andric       return FunctionDifferenceEngine(*this, GVL, GVR)
850*349cc55cSDimitry Andric           .equivalentAsOperands(GVL->getInitializer(), GVR->getInitializer());
851*349cc55cSDimitry Andric   }
852*349cc55cSDimitry Andric 
853*349cc55cSDimitry Andric   return L->getName() == R->getName();
854*349cc55cSDimitry Andric }
855