#include "llvm/Analysis/IRSimilarityIdentifier.h"
#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/SetOperations.h"
#include "llvm/IR/Intrinsics.h"
#include "llvm/IR/Operator.h"
#include "llvm/IR/User.h"
int CurrentBlockNumber = static_cast<int>(BBNumIt->second);
- for (BasicBlock *Successor : BI->successors()) {
+ for (Value *V : getBlockOperVals()) {
+ BasicBlock *Successor = cast<BasicBlock>(V);
BBNumIt = BasicBlockToInteger.find(Successor);
assert(BBNumIt != BasicBlockToInteger.end() &&
"Could not find number for BasicBlock!");
}
}
+ArrayRef<Value *> IRInstructionData::getBlockOperVals() {
+ assert((isa<BranchInst>(Inst) ||
+ isa<PHINode>(Inst)) && "Instruction must be branch or PHINode");
+
+ if (BranchInst *BI = dyn_cast<BranchInst>(Inst))
+ return ArrayRef<Value *>(
+ std::next(OperVals.begin(), BI->isConditional() ? 1 : 0),
+ OperVals.end()
+ );
+
+ if (PHINode *PN = dyn_cast<PHINode>(Inst))
+ return ArrayRef<Value *>(
+ std::next(OperVals.begin(), PN->getNumIncomingValues()),
+ OperVals.end()
+ );
+
+ return ArrayRef<Value *>();
+}
+
void IRInstructionData::setCalleeName(bool MatchByName) {
CallInst *CI = dyn_cast<CallInst>(Inst);
assert(CI && "Instruction must be call");
int Relative = OtherBlockNumber - CurrentBlockNumber;
RelativeBlockLocations.push_back(Relative);
- RelativeBlockLocations.push_back(Relative);
}
}
bool IRSimilarityCandidate::checkRelativeLocations(RelativeLocMapping A,
RelativeLocMapping B) {
// Get the basic blocks the label refers to.
- BasicBlock *ABB = static_cast<BasicBlock *>(A.OperVal);
- BasicBlock *BBB = static_cast<BasicBlock *>(B.OperVal);
+ BasicBlock *ABB = cast<BasicBlock>(A.OperVal);
+ BasicBlock *BBB = cast<BasicBlock>(B.OperVal);
// Get the basic blocks contained in each region.
DenseSet<BasicBlock *> BasicBlockA;
bool BContained = BasicBlockB.contains(BBB);
// Both blocks need to be contained in the region, or both need to be outside
- // the reigon.
+ // the region.
if (AContained != BContained)
return false;
SmallVector<int, 4> &RelBlockLocsA = ItA->RelativeBlockLocations;
SmallVector<int, 4> &RelBlockLocsB = ItB->RelativeBlockLocations;
+ ArrayRef<Value *> ABL = ItA->getBlockOperVals();
+ ArrayRef<Value *> BBL = ItB->getBlockOperVals();
+
+ // Check to make sure that the number of operands, and branching locations
+ // between BranchInsts is the same.
if (RelBlockLocsA.size() != RelBlockLocsB.size() &&
- OperValsA.size() != OperValsB.size())
+ ABL.size() != BBL.size())
return false;
+ assert(RelBlockLocsA.size() == ABL.size() &&
+ "Block information vectors not the same size.");
+ assert(RelBlockLocsB.size() == BBL.size() &&
+ "Block information vectors not the same size.");
+
ZippedRelativeLocationsT ZippedRelativeLocations =
- zip(RelBlockLocsA, RelBlockLocsB, OperValsA, OperValsB);
+ zip(RelBlockLocsA, RelBlockLocsB, ABL, BBL);
if (any_of(ZippedRelativeLocations,
[&A, &B](std::tuple<int, int, Value *, Value *> R) {
return !checkRelativeLocations(