1 //===- IRSimilarityIdentifier.cpp - Find similarity in a module -----------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // \file
10 // Implementation file for the IRSimilarityIdentifier for identifying
11 // similarities in IR including the IRInstructionMapper.
12 //
13 //===----------------------------------------------------------------------===//
14 
15 #include "llvm/Analysis/IRSimilarityIdentifier.h"
16 #include "llvm/ADT/DenseMap.h"
17 #include "llvm/IR/Intrinsics.h"
18 #include "llvm/IR/Operator.h"
19 #include "llvm/IR/User.h"
20 #include "llvm/InitializePasses.h"
21 #include "llvm/Support/SuffixTree.h"
22 
23 using namespace llvm;
24 using namespace IRSimilarity;
25 
26 namespace llvm {
27 cl::opt<bool>
28     DisableBranches("no-ir-sim-branch-matching", cl::init(false),
29                     cl::ReallyHidden,
30                     cl::desc("disable similarity matching, and outlining, "
31                              "across branches for debugging purposes."));
32 } // namespace llvm
33 
34 cl::opt<bool>
35     DisableIndirectCalls("no-ir-sim-indirect-calls", cl::init(false),
36                          cl::ReallyHidden,
37                          cl::desc("disable outlining indirect calls."));
38 
39 cl::opt<bool>
40     MatchCallsByName("ir-sim-calls-by-name", cl::init(false), cl::ReallyHidden,
41                      cl::desc("only allow matching call instructions if the "
42                               "name and type signature match."));
43 
44 
45 IRInstructionData::IRInstructionData(Instruction &I, bool Legality,
46                                      IRInstructionDataList &IDList)
47     : Inst(&I), Legal(Legality), IDL(&IDList) {
48   initializeInstruction();
49 }
50 
51 void IRInstructionData::initializeInstruction() {
52   // We check for whether we have a comparison instruction.  If it is, we
53   // find the "less than" version of the predicate for consistency for
54   // comparison instructions throught the program.
55   if (CmpInst *C = dyn_cast<CmpInst>(Inst)) {
56     CmpInst::Predicate Predicate = predicateForConsistency(C);
57     if (Predicate != C->getPredicate())
58       RevisedPredicate = Predicate;
59   }
60 
61   // Here we collect the operands and their types for determining whether
62   // the structure of the operand use matches between two different candidates.
63   for (Use &OI : Inst->operands()) {
64     if (isa<CmpInst>(Inst) && RevisedPredicate.hasValue()) {
65       // If we have a CmpInst where the predicate is reversed, it means the
66       // operands must be reversed as well.
67       OperVals.insert(OperVals.begin(), OI.get());
68       continue;
69     }
70 
71     OperVals.push_back(OI.get());
72   }
73 
74   // We capture the incoming BasicBlocks as values as well as the incoming
75   // Values in order to check for structural similarity.
76   if (PHINode *PN = dyn_cast<PHINode>(Inst))
77     for (BasicBlock *BB : PN->blocks())
78       OperVals.push_back(BB);
79 }
80 
81 IRInstructionData::IRInstructionData(IRInstructionDataList &IDList)
82     : IDL(&IDList) {}
83 
84 void IRInstructionData::setBranchSuccessors(
85     DenseMap<BasicBlock *, unsigned> &BasicBlockToInteger) {
86   assert(isa<BranchInst>(Inst) && "Instruction must be branch");
87 
88   BranchInst *BI = cast<BranchInst>(Inst);
89   DenseMap<BasicBlock *, unsigned>::iterator BBNumIt;
90 
91   BBNumIt = BasicBlockToInteger.find(BI->getParent());
92   assert(BBNumIt != BasicBlockToInteger.end() &&
93          "Could not find location for BasicBlock!");
94 
95   int CurrentBlockNumber = static_cast<int>(BBNumIt->second);
96 
97   for (BasicBlock *Successor : BI->successors()) {
98     BBNumIt = BasicBlockToInteger.find(Successor);
99     assert(BBNumIt != BasicBlockToInteger.end() &&
100            "Could not find number for BasicBlock!");
101     int OtherBlockNumber = static_cast<int>(BBNumIt->second);
102 
103     int Relative = OtherBlockNumber - CurrentBlockNumber;
104     RelativeBlockLocations.push_back(Relative);
105   }
106 }
107 
108 void IRInstructionData::setCalleeName(bool MatchByName) {
109   CallInst *CI = dyn_cast<CallInst>(Inst);
110   assert(CI && "Instruction must be call");
111 
112   CalleeName = "";
113   if (!CI->isIndirectCall() && MatchByName)
114     CalleeName = CI->getCalledFunction()->getName().str();
115 }
116 
117 void IRInstructionData::setPHIPredecessors(
118     DenseMap<BasicBlock *, unsigned> &BasicBlockToInteger) {
119   assert(isa<PHINode>(Inst) && "Instruction must be phi node");
120 
121   PHINode *PN = cast<PHINode>(Inst);
122   DenseMap<BasicBlock *, unsigned>::iterator BBNumIt;
123 
124   BBNumIt = BasicBlockToInteger.find(PN->getParent());
125   assert(BBNumIt != BasicBlockToInteger.end() &&
126          "Could not find location for BasicBlock!");
127 
128   int CurrentBlockNumber = static_cast<int>(BBNumIt->second);
129 
130   // Convert the incoming blocks of the PHINode to an integer value, based on
131   // the relative distances between the current block and the incoming block.
132   for (unsigned Idx = 0; Idx < PN->getNumIncomingValues(); Idx++) {
133     BasicBlock *Incoming = PN->getIncomingBlock(Idx);
134     BBNumIt = BasicBlockToInteger.find(Incoming);
135     assert(BBNumIt != BasicBlockToInteger.end() &&
136            "Could not find number for BasicBlock!");
137     int OtherBlockNumber = static_cast<int>(BBNumIt->second);
138 
139     int Relative = OtherBlockNumber - CurrentBlockNumber;
140     RelativeBlockLocations.push_back(Relative);
141     RelativeBlockLocations.push_back(Relative);
142   }
143 }
144 
145 CmpInst::Predicate IRInstructionData::predicateForConsistency(CmpInst *CI) {
146   switch (CI->getPredicate()) {
147   case CmpInst::FCMP_OGT:
148   case CmpInst::FCMP_UGT:
149   case CmpInst::FCMP_OGE:
150   case CmpInst::FCMP_UGE:
151   case CmpInst::ICMP_SGT:
152   case CmpInst::ICMP_UGT:
153   case CmpInst::ICMP_SGE:
154   case CmpInst::ICMP_UGE:
155     return CI->getSwappedPredicate();
156   default:
157     return CI->getPredicate();
158   }
159 }
160 
161 CmpInst::Predicate IRInstructionData::getPredicate() const {
162   assert(isa<CmpInst>(Inst) &&
163          "Can only get a predicate from a compare instruction");
164 
165   if (RevisedPredicate.hasValue())
166     return RevisedPredicate.getValue();
167 
168   return cast<CmpInst>(Inst)->getPredicate();
169 }
170 
171 StringRef IRInstructionData::getCalleeName() const {
172   assert(isa<CallInst>(Inst) &&
173          "Can only get a name from a call instruction");
174 
175   assert(CalleeName.hasValue() && "CalleeName has not been set");
176 
177   return *CalleeName;
178 }
179 
180 bool IRSimilarity::isClose(const IRInstructionData &A,
181                            const IRInstructionData &B) {
182 
183   if (!A.Legal || !B.Legal)
184     return false;
185 
186   // Check if we are performing the same sort of operation on the same types
187   // but not on the same values.
188   if (!A.Inst->isSameOperationAs(B.Inst)) {
189     // If there is a predicate, this means that either there is a swapped
190     // predicate, or that the types are different, we want to make sure that
191     // the predicates are equivalent via swapping.
192     if (isa<CmpInst>(A.Inst) && isa<CmpInst>(B.Inst)) {
193 
194       if (A.getPredicate() != B.getPredicate())
195         return false;
196 
197       // If the predicates are the same via swap, make sure that the types are
198       // still the same.
199       auto ZippedTypes = zip(A.OperVals, B.OperVals);
200 
201       return all_of(
202           ZippedTypes, [](std::tuple<llvm::Value *, llvm::Value *> R) {
203             return std::get<0>(R)->getType() == std::get<1>(R)->getType();
204           });
205     }
206 
207     return false;
208   }
209 
210   // Since any GEP Instruction operands after the first operand cannot be
211   // defined by a register, we must make sure that the operands after the first
212   // are the same in the two instructions
213   if (auto *GEP = dyn_cast<GetElementPtrInst>(A.Inst)) {
214     auto *OtherGEP = cast<GetElementPtrInst>(B.Inst);
215 
216     // If the instructions do not have the same inbounds restrictions, we do
217     // not consider them the same.
218     if (GEP->isInBounds() != OtherGEP->isInBounds())
219       return false;
220 
221     auto ZippedOperands = zip(GEP->indices(), OtherGEP->indices());
222 
223     // We increment here since we do not care about the first instruction,
224     // we only care about the following operands since they must be the
225     // exact same to be considered similar.
226     return all_of(drop_begin(ZippedOperands),
227                   [](std::tuple<llvm::Use &, llvm::Use &> R) {
228                     return std::get<0>(R) == std::get<1>(R);
229                   });
230   }
231 
232   // If the instructions are functions calls, we make sure that the function
233   // name is the same.  We already know that the types are since is
234   // isSameOperationAs is true.
235   if (isa<CallInst>(A.Inst) && isa<CallInst>(B.Inst)) {
236     if (A.getCalleeName().str().compare(B.getCalleeName().str()) != 0)
237       return false;
238   }
239 
240   if (isa<BranchInst>(A.Inst) && isa<BranchInst>(B.Inst) &&
241       A.RelativeBlockLocations.size() != B.RelativeBlockLocations.size())
242     return false;
243 
244   return true;
245 }
246 
247 // TODO: This is the same as the MachineOutliner, and should be consolidated
248 // into the same interface.
249 void IRInstructionMapper::convertToUnsignedVec(
250     BasicBlock &BB, std::vector<IRInstructionData *> &InstrList,
251     std::vector<unsigned> &IntegerMapping) {
252   BasicBlock::iterator It = BB.begin();
253 
254   std::vector<unsigned> IntegerMappingForBB;
255   std::vector<IRInstructionData *> InstrListForBB;
256 
257   for (BasicBlock::iterator Et = BB.end(); It != Et; ++It) {
258     switch (InstClassifier.visit(*It)) {
259     case InstrType::Legal:
260       mapToLegalUnsigned(It, IntegerMappingForBB, InstrListForBB);
261       break;
262     case InstrType::Illegal:
263       mapToIllegalUnsigned(It, IntegerMappingForBB, InstrListForBB);
264       break;
265     case InstrType::Invisible:
266       AddedIllegalLastTime = false;
267       break;
268     }
269   }
270 
271   if (HaveLegalRange) {
272     if (AddedIllegalLastTime)
273       mapToIllegalUnsigned(It, IntegerMappingForBB, InstrListForBB, true);
274     for (IRInstructionData *ID : InstrListForBB)
275       this->IDL->push_back(*ID);
276     llvm::append_range(InstrList, InstrListForBB);
277     llvm::append_range(IntegerMapping, IntegerMappingForBB);
278   }
279 }
280 
281 // TODO: This is the same as the MachineOutliner, and should be consolidated
282 // into the same interface.
283 unsigned IRInstructionMapper::mapToLegalUnsigned(
284     BasicBlock::iterator &It, std::vector<unsigned> &IntegerMappingForBB,
285     std::vector<IRInstructionData *> &InstrListForBB) {
286   // We added something legal, so we should unset the AddedLegalLastTime
287   // flag.
288   AddedIllegalLastTime = false;
289 
290   // If we have at least two adjacent legal instructions (which may have
291   // invisible instructions in between), remember that.
292   if (CanCombineWithPrevInstr)
293     HaveLegalRange = true;
294   CanCombineWithPrevInstr = true;
295 
296   // Get the integer for this instruction or give it the current
297   // LegalInstrNumber.
298   IRInstructionData *ID = allocateIRInstructionData(*It, true, *IDL);
299   InstrListForBB.push_back(ID);
300 
301   if (isa<BranchInst>(*It))
302     ID->setBranchSuccessors(BasicBlockToInteger);
303 
304   if (isa<CallInst>(*It))
305     ID->setCalleeName(EnableMatchCallsByName);
306 
307   if (isa<PHINode>(*It))
308     ID->setPHIPredecessors(BasicBlockToInteger);
309 
310   // Add to the instruction list
311   bool WasInserted;
312   DenseMap<IRInstructionData *, unsigned, IRInstructionDataTraits>::iterator
313       ResultIt;
314   std::tie(ResultIt, WasInserted) =
315       InstructionIntegerMap.insert(std::make_pair(ID, LegalInstrNumber));
316   unsigned INumber = ResultIt->second;
317 
318   // There was an insertion.
319   if (WasInserted)
320     LegalInstrNumber++;
321 
322   IntegerMappingForBB.push_back(INumber);
323 
324   // Make sure we don't overflow or use any integers reserved by the DenseMap.
325   assert(LegalInstrNumber < IllegalInstrNumber &&
326          "Instruction mapping overflow!");
327 
328   assert(LegalInstrNumber != DenseMapInfo<unsigned>::getEmptyKey() &&
329          "Tried to assign DenseMap tombstone or empty key to instruction.");
330   assert(LegalInstrNumber != DenseMapInfo<unsigned>::getTombstoneKey() &&
331          "Tried to assign DenseMap tombstone or empty key to instruction.");
332 
333   return INumber;
334 }
335 
336 IRInstructionData *
337 IRInstructionMapper::allocateIRInstructionData(Instruction &I, bool Legality,
338                                                IRInstructionDataList &IDL) {
339   return new (InstDataAllocator->Allocate()) IRInstructionData(I, Legality, IDL);
340 }
341 
342 IRInstructionData *
343 IRInstructionMapper::allocateIRInstructionData(IRInstructionDataList &IDL) {
344   return new (InstDataAllocator->Allocate()) IRInstructionData(IDL);
345 }
346 
347 IRInstructionDataList *
348 IRInstructionMapper::allocateIRInstructionDataList() {
349   return new (IDLAllocator->Allocate()) IRInstructionDataList();
350 }
351 
352 // TODO: This is the same as the MachineOutliner, and should be consolidated
353 // into the same interface.
354 unsigned IRInstructionMapper::mapToIllegalUnsigned(
355     BasicBlock::iterator &It, std::vector<unsigned> &IntegerMappingForBB,
356     std::vector<IRInstructionData *> &InstrListForBB, bool End) {
357   // Can't combine an illegal instruction. Set the flag.
358   CanCombineWithPrevInstr = false;
359 
360   // Only add one illegal number per range of legal numbers.
361   if (AddedIllegalLastTime)
362     return IllegalInstrNumber;
363 
364   IRInstructionData *ID = nullptr;
365   if (!End)
366     ID = allocateIRInstructionData(*It, false, *IDL);
367   else
368     ID = allocateIRInstructionData(*IDL);
369   InstrListForBB.push_back(ID);
370 
371   // Remember that we added an illegal number last time.
372   AddedIllegalLastTime = true;
373   unsigned INumber = IllegalInstrNumber;
374   IntegerMappingForBB.push_back(IllegalInstrNumber--);
375 
376   assert(LegalInstrNumber < IllegalInstrNumber &&
377          "Instruction mapping overflow!");
378 
379   assert(IllegalInstrNumber != DenseMapInfo<unsigned>::getEmptyKey() &&
380          "IllegalInstrNumber cannot be DenseMap tombstone or empty key!");
381 
382   assert(IllegalInstrNumber != DenseMapInfo<unsigned>::getTombstoneKey() &&
383          "IllegalInstrNumber cannot be DenseMap tombstone or empty key!");
384 
385   return INumber;
386 }
387 
388 IRSimilarityCandidate::IRSimilarityCandidate(unsigned StartIdx, unsigned Len,
389                                              IRInstructionData *FirstInstIt,
390                                              IRInstructionData *LastInstIt)
391     : StartIdx(StartIdx), Len(Len) {
392 
393   assert(FirstInstIt != nullptr && "Instruction is nullptr!");
394   assert(LastInstIt != nullptr && "Instruction is nullptr!");
395   assert(StartIdx + Len > StartIdx &&
396          "Overflow for IRSimilarityCandidate range?");
397   assert(Len - 1 == static_cast<unsigned>(std::distance(
398                         iterator(FirstInstIt), iterator(LastInstIt))) &&
399          "Length of the first and last IRInstructionData do not match the "
400          "given length");
401 
402   // We iterate over the given instructions, and map each unique value
403   // to a unique number in the IRSimilarityCandidate ValueToNumber and
404   // NumberToValue maps.  A constant get its own value globally, the individual
405   // uses of the constants are not considered to be unique.
406   //
407   // IR:                    Mapping Added:
408   // %add1 = add i32 %a, c1    %add1 -> 3, %a -> 1, c1 -> 2
409   // %add2 = add i32 %a, %1    %add2 -> 4
410   // %add3 = add i32 c2, c1    %add3 -> 6, c2 -> 5
411   //
412   // when replace with global values, starting from 1, would be
413   //
414   // 3 = add i32 1, 2
415   // 4 = add i32 1, 3
416   // 6 = add i32 5, 2
417   unsigned LocalValNumber = 1;
418   IRInstructionDataList::iterator ID = iterator(*FirstInstIt);
419   for (unsigned Loc = StartIdx; Loc < StartIdx + Len; Loc++, ID++) {
420     // Map the operand values to an unsigned integer if it does not already
421     // have an unsigned integer assigned to it.
422     for (Value *Arg : ID->OperVals)
423       if (ValueToNumber.find(Arg) == ValueToNumber.end()) {
424         ValueToNumber.try_emplace(Arg, LocalValNumber);
425         NumberToValue.try_emplace(LocalValNumber, Arg);
426         LocalValNumber++;
427       }
428 
429     // Mapping the instructions to an unsigned integer if it is not already
430     // exist in the mapping.
431     if (ValueToNumber.find(ID->Inst) == ValueToNumber.end()) {
432       ValueToNumber.try_emplace(ID->Inst, LocalValNumber);
433       NumberToValue.try_emplace(LocalValNumber, ID->Inst);
434       LocalValNumber++;
435     }
436   }
437 
438   // Setting the first and last instruction data pointers for the candidate.  If
439   // we got through the entire for loop without hitting an assert, we know
440   // that both of these instructions are not nullptrs.
441   FirstInst = FirstInstIt;
442   LastInst = LastInstIt;
443 }
444 
445 bool IRSimilarityCandidate::isSimilar(const IRSimilarityCandidate &A,
446                                       const IRSimilarityCandidate &B) {
447   if (A.getLength() != B.getLength())
448     return false;
449 
450   auto InstrDataForBoth =
451       zip(make_range(A.begin(), A.end()), make_range(B.begin(), B.end()));
452 
453   return all_of(InstrDataForBoth,
454                 [](std::tuple<IRInstructionData &, IRInstructionData &> R) {
455                   IRInstructionData &A = std::get<0>(R);
456                   IRInstructionData &B = std::get<1>(R);
457                   if (!A.Legal || !B.Legal)
458                     return false;
459                   return isClose(A, B);
460                 });
461 }
462 
463 /// Determine if one or more of the assigned global value numbers for the
464 /// operands in \p TargetValueNumbers is in the current mapping set for operand
465 /// numbers in \p SourceOperands.  The set of possible corresponding global
466 /// value numbers are replaced with the most recent version of compatible
467 /// values.
468 ///
469 /// \param [in] SourceValueToNumberMapping - The mapping of a Value to global
470 /// value number for the source IRInstructionCandidate.
471 /// \param [in, out] CurrentSrcTgtNumberMapping - The current mapping of source
472 /// IRSimilarityCandidate global value numbers to a set of possible numbers in
473 /// the target.
474 /// \param [in] SourceOperands - The operands in the original
475 /// IRSimilarityCandidate in the current instruction.
476 /// \param [in] TargetValueNumbers - The global value numbers of the operands in
477 /// the corresponding Instruction in the other IRSimilarityCandidate.
478 /// \returns true if there exists a possible mapping between the source
479 /// Instruction operands and the target Instruction operands, and false if not.
480 static bool checkNumberingAndReplaceCommutative(
481   const DenseMap<Value *, unsigned> &SourceValueToNumberMapping,
482   DenseMap<unsigned, DenseSet<unsigned>> &CurrentSrcTgtNumberMapping,
483   ArrayRef<Value *> &SourceOperands,
484   DenseSet<unsigned> &TargetValueNumbers){
485 
486   DenseMap<unsigned, DenseSet<unsigned>>::iterator ValueMappingIt;
487 
488   unsigned ArgVal;
489   bool WasInserted;
490 
491   // Iterate over the operands in the source IRSimilarityCandidate to determine
492   // whether there exists an operand in the other IRSimilarityCandidate that
493   // creates a valid mapping of Value to Value between the
494   // IRSimilarityCaniddates.
495   for (Value *V : SourceOperands) {
496     ArgVal = SourceValueToNumberMapping.find(V)->second;
497 
498     std::tie(ValueMappingIt, WasInserted) = CurrentSrcTgtNumberMapping.insert(
499         std::make_pair(ArgVal, TargetValueNumbers));
500 
501     // Instead of finding a current mapping, we inserted a set.  This means a
502     // mapping did not exist for the source Instruction operand, it has no
503     // current constraints we need to check.
504     if (WasInserted)
505       continue;
506 
507     // If a mapping already exists for the source operand to the values in the
508     // other IRSimilarityCandidate we need to iterate over the items in other
509     // IRSimilarityCandidate's Instruction to determine whether there is a valid
510     // mapping of Value to Value.
511     DenseSet<unsigned> NewSet;
512     for (unsigned &Curr : ValueMappingIt->second)
513       // If we can find the value in the mapping, we add it to the new set.
514       if (TargetValueNumbers.contains(Curr))
515         NewSet.insert(Curr);
516 
517     // If we could not find a Value, return 0.
518     if (NewSet.empty())
519       return false;
520 
521     // Otherwise replace the old mapping with the newly constructed one.
522     if (NewSet.size() != ValueMappingIt->second.size())
523       ValueMappingIt->second.swap(NewSet);
524 
525     // We have reached no conclusions about the mapping, and cannot remove
526     // any items from the other operands, so we move to check the next operand.
527     if (ValueMappingIt->second.size() != 1)
528       continue;
529 
530 
531     unsigned ValToRemove = *ValueMappingIt->second.begin();
532     // When there is only one item left in the mapping for and operand, remove
533     // the value from the other operands.  If it results in there being no
534     // mapping, return false, it means the mapping is wrong
535     for (Value *InnerV : SourceOperands) {
536       if (V == InnerV)
537         continue;
538 
539       unsigned InnerVal = SourceValueToNumberMapping.find(InnerV)->second;
540       ValueMappingIt = CurrentSrcTgtNumberMapping.find(InnerVal);
541       if (ValueMappingIt == CurrentSrcTgtNumberMapping.end())
542         continue;
543 
544       ValueMappingIt->second.erase(ValToRemove);
545       if (ValueMappingIt->second.empty())
546         return false;
547     }
548   }
549 
550   return true;
551 }
552 
553 /// Determine if operand number \p TargetArgVal is in the current mapping set
554 /// for operand number \p SourceArgVal.
555 ///
556 /// \param [in, out] CurrentSrcTgtNumberMapping current mapping of global
557 /// value numbers from source IRSimilarityCandidate to target
558 /// IRSimilarityCandidate.
559 /// \param [in] SourceArgVal The global value number for an operand in the
560 /// in the original candidate.
561 /// \param [in] TargetArgVal The global value number for the corresponding
562 /// operand in the other candidate.
563 /// \returns True if there exists a mapping and false if not.
564 bool checkNumberingAndReplace(
565     DenseMap<unsigned, DenseSet<unsigned>> &CurrentSrcTgtNumberMapping,
566     unsigned SourceArgVal, unsigned TargetArgVal) {
567   // We are given two unsigned integers representing the global values of
568   // the operands in different IRSimilarityCandidates and a current mapping
569   // between the two.
570   //
571   // Source Operand GVN: 1
572   // Target Operand GVN: 2
573   // CurrentMapping: {1: {1, 2}}
574   //
575   // Since we have mapping, and the target operand is contained in the set, we
576   // update it to:
577   // CurrentMapping: {1: {2}}
578   // and can return true. But, if the mapping was
579   // CurrentMapping: {1: {3}}
580   // we would return false.
581 
582   bool WasInserted;
583   DenseMap<unsigned, DenseSet<unsigned>>::iterator Val;
584 
585   std::tie(Val, WasInserted) = CurrentSrcTgtNumberMapping.insert(
586       std::make_pair(SourceArgVal, DenseSet<unsigned>({TargetArgVal})));
587 
588   // If we created a new mapping, then we are done.
589   if (WasInserted)
590     return true;
591 
592   // If there is more than one option in the mapping set, and the target value
593   // is included in the mapping set replace that set with one that only includes
594   // the target value, as it is the only valid mapping via the non commutative
595   // instruction.
596 
597   DenseSet<unsigned> &TargetSet = Val->second;
598   if (TargetSet.size() > 1 && TargetSet.contains(TargetArgVal)) {
599     TargetSet.clear();
600     TargetSet.insert(TargetArgVal);
601     return true;
602   }
603 
604   // Return true if we can find the value in the set.
605   return TargetSet.contains(TargetArgVal);
606 }
607 
608 bool IRSimilarityCandidate::compareNonCommutativeOperandMapping(
609     OperandMapping A, OperandMapping B) {
610   // Iterators to keep track of where we are in the operands for each
611   // Instruction.
612   ArrayRef<Value *>::iterator VItA = A.OperVals.begin();
613   ArrayRef<Value *>::iterator VItB = B.OperVals.begin();
614   unsigned OperandLength = A.OperVals.size();
615 
616   // For each operand, get the value numbering and ensure it is consistent.
617   for (unsigned Idx = 0; Idx < OperandLength; Idx++, VItA++, VItB++) {
618     unsigned OperValA = A.IRSC.ValueToNumber.find(*VItA)->second;
619     unsigned OperValB = B.IRSC.ValueToNumber.find(*VItB)->second;
620 
621     // Attempt to add a set with only the target value.  If there is no mapping
622     // we can create it here.
623     //
624     // For an instruction like a subtraction:
625     // IRSimilarityCandidateA:  IRSimilarityCandidateB:
626     // %resultA = sub %a, %b    %resultB = sub %d, %e
627     //
628     // We map %a -> %d and %b -> %e.
629     //
630     // And check to see whether their mapping is consistent in
631     // checkNumberingAndReplace.
632 
633     if (!checkNumberingAndReplace(A.ValueNumberMapping, OperValA, OperValB))
634       return false;
635 
636     if (!checkNumberingAndReplace(B.ValueNumberMapping, OperValB, OperValA))
637       return false;
638   }
639   return true;
640 }
641 
642 bool IRSimilarityCandidate::compareCommutativeOperandMapping(
643     OperandMapping A, OperandMapping B) {
644   DenseSet<unsigned> ValueNumbersA;
645   DenseSet<unsigned> ValueNumbersB;
646 
647   ArrayRef<Value *>::iterator VItA = A.OperVals.begin();
648   ArrayRef<Value *>::iterator VItB = B.OperVals.begin();
649   unsigned OperandLength = A.OperVals.size();
650 
651   // Find the value number sets for the operands.
652   for (unsigned Idx = 0; Idx < OperandLength;
653        Idx++, VItA++, VItB++) {
654     ValueNumbersA.insert(A.IRSC.ValueToNumber.find(*VItA)->second);
655     ValueNumbersB.insert(B.IRSC.ValueToNumber.find(*VItB)->second);
656   }
657 
658   // Iterate over the operands in the first IRSimilarityCandidate and make sure
659   // there exists a possible mapping with the operands in the second
660   // IRSimilarityCandidate.
661   if (!checkNumberingAndReplaceCommutative(A.IRSC.ValueToNumber,
662                                            A.ValueNumberMapping, A.OperVals,
663                                            ValueNumbersB))
664     return false;
665 
666   // Iterate over the operands in the second IRSimilarityCandidate and make sure
667   // there exists a possible mapping with the operands in the first
668   // IRSimilarityCandidate.
669   if (!checkNumberingAndReplaceCommutative(B.IRSC.ValueToNumber,
670                                            B.ValueNumberMapping, B.OperVals,
671                                            ValueNumbersA))
672     return false;
673 
674   return true;
675 }
676 
677 bool IRSimilarityCandidate::checkRelativeLocations(RelativeLocMapping A,
678                                                    RelativeLocMapping B) {
679   // Get the basic blocks the label refers to.
680   BasicBlock *ABB = static_cast<BasicBlock *>(A.OperVal);
681   BasicBlock *BBB = static_cast<BasicBlock *>(B.OperVal);
682 
683   // Get the basic blocks contained in each region.
684   DenseSet<BasicBlock *> BasicBlockA;
685   DenseSet<BasicBlock *> BasicBlockB;
686   A.IRSC.getBasicBlocks(BasicBlockA);
687   B.IRSC.getBasicBlocks(BasicBlockB);
688 
689   // Determine if the block is contained in the region.
690   bool AContained = BasicBlockA.contains(ABB);
691   bool BContained = BasicBlockB.contains(BBB);
692 
693   // Both blocks need to be contained in the region, or both need to be outside
694   // the reigon.
695   if (AContained != BContained)
696     return false;
697 
698   // If both are contained, then we need to make sure that the relative
699   // distance to the target blocks are the same.
700   if (AContained)
701     return A.RelativeLocation == B.RelativeLocation;
702   return true;
703 }
704 
705 bool IRSimilarityCandidate::compareStructure(const IRSimilarityCandidate &A,
706                                              const IRSimilarityCandidate &B) {
707   DenseMap<unsigned, DenseSet<unsigned>> MappingA;
708   DenseMap<unsigned, DenseSet<unsigned>> MappingB;
709   return IRSimilarityCandidate::compareStructure(A, B, MappingA, MappingB);
710 }
711 
712 typedef detail::zippy<detail::zip_shortest, SmallVector<int, 4> &,
713                       SmallVector<int, 4> &, ArrayRef<Value *> &,
714                       ArrayRef<Value *> &>
715     ZippedRelativeLocationsT;
716 
717 bool IRSimilarityCandidate::compareStructure(
718     const IRSimilarityCandidate &A, const IRSimilarityCandidate &B,
719     DenseMap<unsigned, DenseSet<unsigned>> &ValueNumberMappingA,
720     DenseMap<unsigned, DenseSet<unsigned>> &ValueNumberMappingB) {
721   if (A.getLength() != B.getLength())
722     return false;
723 
724   if (A.ValueToNumber.size() != B.ValueToNumber.size())
725     return false;
726 
727   iterator ItA = A.begin();
728   iterator ItB = B.begin();
729 
730   // These ValueNumber Mapping sets create a create a mapping between the values
731   // in one candidate to values in the other candidate.  If we create a set with
732   // one element, and that same element maps to the original element in the
733   // candidate we have a good mapping.
734   DenseMap<unsigned, DenseSet<unsigned>>::iterator ValueMappingIt;
735 
736 
737   // Iterate over the instructions contained in each candidate
738   unsigned SectionLength = A.getStartIdx() + A.getLength();
739   for (unsigned Loc = A.getStartIdx(); Loc < SectionLength;
740        ItA++, ItB++, Loc++) {
741     // Make sure the instructions are similar to one another.
742     if (!isClose(*ItA, *ItB))
743       return false;
744 
745     Instruction *IA = ItA->Inst;
746     Instruction *IB = ItB->Inst;
747 
748     if (!ItA->Legal || !ItB->Legal)
749       return false;
750 
751     // Get the operand sets for the instructions.
752     ArrayRef<Value *> OperValsA = ItA->OperVals;
753     ArrayRef<Value *> OperValsB = ItB->OperVals;
754 
755     unsigned InstValA = A.ValueToNumber.find(IA)->second;
756     unsigned InstValB = B.ValueToNumber.find(IB)->second;
757 
758     bool WasInserted;
759     // Ensure that the mappings for the instructions exists.
760     std::tie(ValueMappingIt, WasInserted) = ValueNumberMappingA.insert(
761         std::make_pair(InstValA, DenseSet<unsigned>({InstValB})));
762     if (!WasInserted && !ValueMappingIt->second.contains(InstValB))
763       return false;
764 
765     std::tie(ValueMappingIt, WasInserted) = ValueNumberMappingB.insert(
766         std::make_pair(InstValB, DenseSet<unsigned>({InstValA})));
767     if (!WasInserted && !ValueMappingIt->second.contains(InstValA))
768       return false;
769 
770     // We have different paths for commutative instructions and non-commutative
771     // instructions since commutative instructions could allow multiple mappings
772     // to certain values.
773     if (IA->isCommutative() && !isa<FPMathOperator>(IA)) {
774       if (!compareCommutativeOperandMapping(
775               {A, OperValsA, ValueNumberMappingA},
776               {B, OperValsB, ValueNumberMappingB}))
777         return false;
778       continue;
779     }
780 
781     // Handle the non-commutative cases.
782     if (!compareNonCommutativeOperandMapping(
783             {A, OperValsA, ValueNumberMappingA},
784             {B, OperValsB, ValueNumberMappingB}))
785       return false;
786 
787     // Here we check that between two corresponding instructions,
788     // when referring to a basic block in the same region, the
789     // relative locations are the same. And, that the instructions refer to
790     // basic blocks outside the region in the same corresponding locations.
791 
792     // We are able to make the assumption about blocks outside of the region
793     // since the target block labels are considered values and will follow the
794     // same number matching that we defined for the other instructions in the
795     // region.  So, at this point, in each location we target a specific block
796     // outside the region, we are targeting a corresponding block in each
797     // analagous location in the region we are comparing to.
798     if (!(isa<BranchInst>(IA) && isa<BranchInst>(IB)) &&
799         !(isa<PHINode>(IA) && isa<PHINode>(IB)))
800       continue;
801 
802     SmallVector<int, 4> &RelBlockLocsA = ItA->RelativeBlockLocations;
803     SmallVector<int, 4> &RelBlockLocsB = ItB->RelativeBlockLocations;
804     if (RelBlockLocsA.size() != RelBlockLocsB.size() &&
805         OperValsA.size() != OperValsB.size())
806       return false;
807 
808     ZippedRelativeLocationsT ZippedRelativeLocations =
809         zip(RelBlockLocsA, RelBlockLocsB, OperValsA, OperValsB);
810     if (any_of(ZippedRelativeLocations,
811                [&A, &B](std::tuple<int, int, Value *, Value *> R) {
812                  return !checkRelativeLocations(
813                      {A, std::get<0>(R), std::get<2>(R)},
814                      {B, std::get<1>(R), std::get<3>(R)});
815                }))
816       return false;
817   }
818   return true;
819 }
820 
821 bool IRSimilarityCandidate::overlap(const IRSimilarityCandidate &A,
822                                     const IRSimilarityCandidate &B) {
823   auto DoesOverlap = [](const IRSimilarityCandidate &X,
824                         const IRSimilarityCandidate &Y) {
825     // Check:
826     // XXXXXX        X starts before Y ends
827     //      YYYYYYY  Y starts after X starts
828     return X.StartIdx <= Y.getEndIdx() && Y.StartIdx >= X.StartIdx;
829   };
830 
831   return DoesOverlap(A, B) || DoesOverlap(B, A);
832 }
833 
834 void IRSimilarityIdentifier::populateMapper(
835     Module &M, std::vector<IRInstructionData *> &InstrList,
836     std::vector<unsigned> &IntegerMapping) {
837 
838   std::vector<IRInstructionData *> InstrListForModule;
839   std::vector<unsigned> IntegerMappingForModule;
840   // Iterate over the functions in the module to map each Instruction in each
841   // BasicBlock to an unsigned integer.
842   Mapper.initializeForBBs(M);
843 
844   for (Function &F : M) {
845 
846     if (F.empty())
847       continue;
848 
849     for (BasicBlock &BB : F) {
850 
851       // BB has potential to have similarity since it has a size greater than 2
852       // and can therefore match other regions greater than 2. Map it to a list
853       // of unsigned integers.
854       Mapper.convertToUnsignedVec(BB, InstrListForModule,
855                                   IntegerMappingForModule);
856     }
857 
858     BasicBlock::iterator It = F.begin()->end();
859     Mapper.mapToIllegalUnsigned(It, IntegerMappingForModule, InstrListForModule,
860                                 true);
861     if (InstrListForModule.size() > 0)
862       Mapper.IDL->push_back(*InstrListForModule.back());
863   }
864 
865   // Insert the InstrListForModule at the end of the overall InstrList so that
866   // we can have a long InstrList for the entire set of Modules being analyzed.
867   llvm::append_range(InstrList, InstrListForModule);
868   // Do the same as above, but for IntegerMapping.
869   llvm::append_range(IntegerMapping, IntegerMappingForModule);
870 }
871 
872 void IRSimilarityIdentifier::populateMapper(
873     ArrayRef<std::unique_ptr<Module>> &Modules,
874     std::vector<IRInstructionData *> &InstrList,
875     std::vector<unsigned> &IntegerMapping) {
876 
877   // Iterate over, and map the instructions in each module.
878   for (const std::unique_ptr<Module> &M : Modules)
879     populateMapper(*M, InstrList, IntegerMapping);
880 }
881 
882 /// From a repeated subsequence, find all the different instances of the
883 /// subsequence from the \p InstrList, and create an IRSimilarityCandidate from
884 /// the IRInstructionData in subsequence.
885 ///
886 /// \param [in] Mapper - The instruction mapper for basic correctness checks.
887 /// \param [in] InstrList - The vector that holds the instruction data.
888 /// \param [in] IntegerMapping - The vector that holds the mapped integers.
889 /// \param [out] CandsForRepSubstring - The vector to store the generated
890 /// IRSimilarityCandidates.
891 static void createCandidatesFromSuffixTree(
892     const IRInstructionMapper& Mapper, std::vector<IRInstructionData *> &InstrList,
893     std::vector<unsigned> &IntegerMapping, SuffixTree::RepeatedSubstring &RS,
894     std::vector<IRSimilarityCandidate> &CandsForRepSubstring) {
895 
896   unsigned StringLen = RS.Length;
897   if (StringLen < 2)
898     return;
899 
900   // Create an IRSimilarityCandidate for instance of this subsequence \p RS.
901   for (const unsigned &StartIdx : RS.StartIndices) {
902     unsigned EndIdx = StartIdx + StringLen - 1;
903 
904     // Check that this subsequence does not contain an illegal instruction.
905     bool ContainsIllegal = false;
906     for (unsigned CurrIdx = StartIdx; CurrIdx <= EndIdx; CurrIdx++) {
907       unsigned Key = IntegerMapping[CurrIdx];
908       if (Key > Mapper.IllegalInstrNumber) {
909         ContainsIllegal = true;
910         break;
911       }
912     }
913 
914     // If we have an illegal instruction, we should not create an
915     // IRSimilarityCandidate for this region.
916     if (ContainsIllegal)
917       continue;
918 
919     // We are getting iterators to the instructions in this region of code
920     // by advancing the start and end indices from the start of the
921     // InstrList.
922     std::vector<IRInstructionData *>::iterator StartIt = InstrList.begin();
923     std::advance(StartIt, StartIdx);
924     std::vector<IRInstructionData *>::iterator EndIt = InstrList.begin();
925     std::advance(EndIt, EndIdx);
926 
927     CandsForRepSubstring.emplace_back(StartIdx, StringLen, *StartIt, *EndIt);
928   }
929 }
930 
931 void IRSimilarityCandidate::createCanonicalRelationFrom(
932     IRSimilarityCandidate &SourceCand,
933     DenseMap<unsigned, DenseSet<unsigned>> &ToSourceMapping,
934     DenseMap<unsigned, DenseSet<unsigned>> &FromSourceMapping) {
935   assert(SourceCand.CanonNumToNumber.size() != 0 &&
936          "Base canonical relationship is empty!");
937   assert(SourceCand.NumberToCanonNum.size() != 0 &&
938          "Base canonical relationship is empty!");
939 
940   assert(CanonNumToNumber.size() == 0 && "Canonical Relationship is non-empty");
941   assert(NumberToCanonNum.size() == 0 && "Canonical Relationship is non-empty");
942 
943   DenseSet<unsigned> UsedGVNs;
944   // Iterate over the mappings provided from this candidate to SourceCand.  We
945   // are then able to map the GVN in this candidate to the same canonical number
946   // given to the corresponding GVN in SourceCand.
947   for (std::pair<unsigned, DenseSet<unsigned>> &GVNMapping : ToSourceMapping) {
948     unsigned SourceGVN = GVNMapping.first;
949 
950     assert(GVNMapping.second.size() != 0 && "Possible GVNs is 0!");
951 
952     unsigned ResultGVN;
953     // We need special handling if we have more than one potential value.  This
954     // means that there are at least two GVNs that could correspond to this GVN.
955     // This could lead to potential swapping later on, so we make a decision
956     // here to ensure a one-to-one mapping.
957     if (GVNMapping.second.size() > 1) {
958       bool Found = false;
959       for (unsigned Val : GVNMapping.second) {
960         // We make sure the target value number hasn't already been reserved.
961         if (UsedGVNs.contains(Val))
962           continue;
963 
964         // We make sure that the opposite mapping is still consistent.
965         DenseMap<unsigned, DenseSet<unsigned>>::iterator It =
966             FromSourceMapping.find(Val);
967 
968         if (!It->second.contains(SourceGVN))
969           continue;
970 
971         // We pick the first item that satisfies these conditions.
972         Found = true;
973         ResultGVN = Val;
974         break;
975       }
976 
977       assert(Found && "Could not find matching value for source GVN");
978       (void)Found;
979 
980     } else
981       ResultGVN = *GVNMapping.second.begin();
982 
983     // Whatever GVN is found, we mark it as used.
984     UsedGVNs.insert(ResultGVN);
985 
986     unsigned CanonNum = *SourceCand.getCanonicalNum(ResultGVN);
987     CanonNumToNumber.insert(std::make_pair(CanonNum, SourceGVN));
988     NumberToCanonNum.insert(std::make_pair(SourceGVN, CanonNum));
989   }
990 }
991 
992 void IRSimilarityCandidate::createCanonicalMappingFor(
993     IRSimilarityCandidate &CurrCand) {
994   assert(CurrCand.CanonNumToNumber.size() == 0 &&
995          "Canonical Relationship is non-empty");
996   assert(CurrCand.NumberToCanonNum.size() == 0 &&
997          "Canonical Relationship is non-empty");
998 
999   unsigned CanonNum = 0;
1000   // Iterate over the value numbers found, the order does not matter in this
1001   // case.
1002   for (std::pair<unsigned, Value *> &NumToVal : CurrCand.NumberToValue) {
1003     CurrCand.NumberToCanonNum.insert(std::make_pair(NumToVal.first, CanonNum));
1004     CurrCand.CanonNumToNumber.insert(std::make_pair(CanonNum, NumToVal.first));
1005     CanonNum++;
1006   }
1007 }
1008 
1009 /// From the list of IRSimilarityCandidates, perform a comparison between each
1010 /// IRSimilarityCandidate to determine if there are overlapping
1011 /// IRInstructionData, or if they do not have the same structure.
1012 ///
1013 /// \param [in] CandsForRepSubstring - The vector containing the
1014 /// IRSimilarityCandidates.
1015 /// \param [out] StructuralGroups - the mapping of unsigned integers to vector
1016 /// of IRSimilarityCandidates where each of the IRSimilarityCandidates in the
1017 /// vector are structurally similar to one another.
1018 static void findCandidateStructures(
1019     std::vector<IRSimilarityCandidate> &CandsForRepSubstring,
1020     DenseMap<unsigned, SimilarityGroup> &StructuralGroups) {
1021   std::vector<IRSimilarityCandidate>::iterator CandIt, CandEndIt, InnerCandIt,
1022       InnerCandEndIt;
1023 
1024   // IRSimilarityCandidates each have a structure for operand use.  It is
1025   // possible that two instances of the same subsequences have different
1026   // structure. Each type of structure found is assigned a number.  This
1027   // DenseMap maps an IRSimilarityCandidate to which type of similarity
1028   // discovered it fits within.
1029   DenseMap<IRSimilarityCandidate *, unsigned> CandToGroup;
1030 
1031   // Find the compatibility from each candidate to the others to determine
1032   // which candidates overlap and which have the same structure by mapping
1033   // each structure to a different group.
1034   bool SameStructure;
1035   bool Inserted;
1036   unsigned CurrentGroupNum = 0;
1037   unsigned OuterGroupNum;
1038   DenseMap<IRSimilarityCandidate *, unsigned>::iterator CandToGroupIt;
1039   DenseMap<IRSimilarityCandidate *, unsigned>::iterator CandToGroupItInner;
1040   DenseMap<unsigned, SimilarityGroup>::iterator CurrentGroupPair;
1041 
1042   // Iterate over the candidates to determine its structural and overlapping
1043   // compatibility with other instructions
1044   DenseMap<unsigned, DenseSet<unsigned>> ValueNumberMappingA;
1045   DenseMap<unsigned, DenseSet<unsigned>> ValueNumberMappingB;
1046   for (CandIt = CandsForRepSubstring.begin(),
1047       CandEndIt = CandsForRepSubstring.end();
1048        CandIt != CandEndIt; CandIt++) {
1049 
1050     // Determine if it has an assigned structural group already.
1051     CandToGroupIt = CandToGroup.find(&*CandIt);
1052     if (CandToGroupIt == CandToGroup.end()) {
1053       // If not, we assign it one, and add it to our mapping.
1054       std::tie(CandToGroupIt, Inserted) =
1055           CandToGroup.insert(std::make_pair(&*CandIt, CurrentGroupNum++));
1056     }
1057 
1058     // Get the structural group number from the iterator.
1059     OuterGroupNum = CandToGroupIt->second;
1060 
1061     // Check if we already have a list of IRSimilarityCandidates for the current
1062     // structural group.  Create one if one does not exist.
1063     CurrentGroupPair = StructuralGroups.find(OuterGroupNum);
1064     if (CurrentGroupPair == StructuralGroups.end()) {
1065       IRSimilarityCandidate::createCanonicalMappingFor(*CandIt);
1066       std::tie(CurrentGroupPair, Inserted) = StructuralGroups.insert(
1067           std::make_pair(OuterGroupNum, SimilarityGroup({*CandIt})));
1068     }
1069 
1070     // Iterate over the IRSimilarityCandidates following the current
1071     // IRSimilarityCandidate in the list to determine whether the two
1072     // IRSimilarityCandidates are compatible.  This is so we do not repeat pairs
1073     // of IRSimilarityCandidates.
1074     for (InnerCandIt = std::next(CandIt),
1075         InnerCandEndIt = CandsForRepSubstring.end();
1076          InnerCandIt != InnerCandEndIt; InnerCandIt++) {
1077 
1078       // We check if the inner item has a group already, if it does, we skip it.
1079       CandToGroupItInner = CandToGroup.find(&*InnerCandIt);
1080       if (CandToGroupItInner != CandToGroup.end())
1081         continue;
1082 
1083       // Otherwise we determine if they have the same structure and add it to
1084       // vector if they match.
1085       ValueNumberMappingA.clear();
1086       ValueNumberMappingB.clear();
1087       SameStructure = IRSimilarityCandidate::compareStructure(
1088           *CandIt, *InnerCandIt, ValueNumberMappingA, ValueNumberMappingB);
1089       if (!SameStructure)
1090         continue;
1091 
1092       InnerCandIt->createCanonicalRelationFrom(*CandIt, ValueNumberMappingA,
1093                                                ValueNumberMappingB);
1094       CandToGroup.insert(std::make_pair(&*InnerCandIt, OuterGroupNum));
1095       CurrentGroupPair->second.push_back(*InnerCandIt);
1096     }
1097   }
1098 }
1099 
1100 void IRSimilarityIdentifier::findCandidates(
1101     std::vector<IRInstructionData *> &InstrList,
1102     std::vector<unsigned> &IntegerMapping) {
1103   SuffixTree ST(IntegerMapping);
1104 
1105   std::vector<IRSimilarityCandidate> CandsForRepSubstring;
1106   std::vector<SimilarityGroup> NewCandidateGroups;
1107 
1108   DenseMap<unsigned, SimilarityGroup> StructuralGroups;
1109 
1110   // Iterate over the subsequences found by the Suffix Tree to create
1111   // IRSimilarityCandidates for each repeated subsequence and determine which
1112   // instances are structurally similar to one another.
1113   for (SuffixTree::RepeatedSubstring &RS : ST) {
1114     createCandidatesFromSuffixTree(Mapper, InstrList, IntegerMapping, RS,
1115                                    CandsForRepSubstring);
1116 
1117     if (CandsForRepSubstring.size() < 2)
1118       continue;
1119 
1120     findCandidateStructures(CandsForRepSubstring, StructuralGroups);
1121     for (std::pair<unsigned, SimilarityGroup> &Group : StructuralGroups)
1122       // We only add the group if it contains more than one
1123       // IRSimilarityCandidate.  If there is only one, that means there is no
1124       // other repeated subsequence with the same structure.
1125       if (Group.second.size() > 1)
1126         SimilarityCandidates->push_back(Group.second);
1127 
1128     CandsForRepSubstring.clear();
1129     StructuralGroups.clear();
1130     NewCandidateGroups.clear();
1131   }
1132 }
1133 
1134 SimilarityGroupList &IRSimilarityIdentifier::findSimilarity(
1135     ArrayRef<std::unique_ptr<Module>> Modules) {
1136   resetSimilarityCandidates();
1137 
1138   std::vector<IRInstructionData *> InstrList;
1139   std::vector<unsigned> IntegerMapping;
1140   Mapper.InstClassifier.EnableBranches = this->EnableBranches;
1141   Mapper.InstClassifier.EnableIndirectCalls = EnableIndirectCalls;
1142   Mapper.EnableMatchCallsByName = EnableMatchingCallsByName;
1143 
1144   populateMapper(Modules, InstrList, IntegerMapping);
1145   findCandidates(InstrList, IntegerMapping);
1146 
1147   return SimilarityCandidates.getValue();
1148 }
1149 
1150 SimilarityGroupList &IRSimilarityIdentifier::findSimilarity(Module &M) {
1151   resetSimilarityCandidates();
1152   Mapper.InstClassifier.EnableBranches = this->EnableBranches;
1153   Mapper.InstClassifier.EnableIndirectCalls = EnableIndirectCalls;
1154   Mapper.EnableMatchCallsByName = EnableMatchingCallsByName;
1155 
1156   std::vector<IRInstructionData *> InstrList;
1157   std::vector<unsigned> IntegerMapping;
1158 
1159   populateMapper(M, InstrList, IntegerMapping);
1160   findCandidates(InstrList, IntegerMapping);
1161 
1162   return SimilarityCandidates.getValue();
1163 }
1164 
1165 INITIALIZE_PASS(IRSimilarityIdentifierWrapperPass, "ir-similarity-identifier",
1166                 "ir-similarity-identifier", false, true)
1167 
1168 IRSimilarityIdentifierWrapperPass::IRSimilarityIdentifierWrapperPass()
1169     : ModulePass(ID) {
1170   initializeIRSimilarityIdentifierWrapperPassPass(
1171       *PassRegistry::getPassRegistry());
1172 }
1173 
1174 bool IRSimilarityIdentifierWrapperPass::doInitialization(Module &M) {
1175   IRSI.reset(new IRSimilarityIdentifier(!DisableBranches, !DisableIndirectCalls,
1176                                         MatchCallsByName));
1177   return false;
1178 }
1179 
1180 bool IRSimilarityIdentifierWrapperPass::doFinalization(Module &M) {
1181   IRSI.reset();
1182   return false;
1183 }
1184 
1185 bool IRSimilarityIdentifierWrapperPass::runOnModule(Module &M) {
1186   IRSI->findSimilarity(M);
1187   return false;
1188 }
1189 
1190 AnalysisKey IRSimilarityAnalysis::Key;
1191 IRSimilarityIdentifier IRSimilarityAnalysis::run(Module &M,
1192                                                  ModuleAnalysisManager &) {
1193 
1194   auto IRSI = IRSimilarityIdentifier(!DisableBranches, !DisableIndirectCalls,
1195                                      MatchCallsByName);
1196   IRSI.findSimilarity(M);
1197   return IRSI;
1198 }
1199 
1200 PreservedAnalyses
1201 IRSimilarityAnalysisPrinterPass::run(Module &M, ModuleAnalysisManager &AM) {
1202   IRSimilarityIdentifier &IRSI = AM.getResult<IRSimilarityAnalysis>(M);
1203   Optional<SimilarityGroupList> &SimilarityCandidatesOpt = IRSI.getSimilarity();
1204 
1205   for (std::vector<IRSimilarityCandidate> &CandVec : *SimilarityCandidatesOpt) {
1206     OS << CandVec.size() << " candidates of length "
1207        << CandVec.begin()->getLength() << ".  Found in: \n";
1208     for (IRSimilarityCandidate &Cand : CandVec) {
1209       OS << "  Function: " << Cand.front()->Inst->getFunction()->getName().str()
1210          << ", Basic Block: ";
1211       if (Cand.front()->Inst->getParent()->getName().str() == "")
1212         OS << "(unnamed)";
1213       else
1214         OS << Cand.front()->Inst->getParent()->getName().str();
1215       OS << "\n    Start Instruction: ";
1216       Cand.frontInstruction()->print(OS);
1217       OS << "\n      End Instruction: ";
1218       Cand.backInstruction()->print(OS);
1219       OS << "\n";
1220     }
1221   }
1222 
1223   return PreservedAnalyses::all();
1224 }
1225 
1226 char IRSimilarityIdentifierWrapperPass::ID = 0;
1227