diff --git a/llvm/include/llvm/Analysis/IRSimilarityIdentifier.h b/llvm/include/llvm/Analysis/IRSimilarityIdentifier.h --- a/llvm/include/llvm/Analysis/IRSimilarityIdentifier.h +++ b/llvm/include/llvm/Analysis/IRSimilarityIdentifier.h @@ -50,6 +50,8 @@ namespace llvm { namespace IRSimilarity { +struct IRInstructionDataList; + /// This represents what is and is not supported when finding similarity in /// Instructions. /// @@ -116,7 +118,7 @@ /// operands. This extra information allows for similarity matching to make /// assertions that allow for more flexibility when checking for whether an /// Instruction performs the same operation. - IRInstructionData(Instruction &I, bool Legality); + IRInstructionData(Instruction &I, bool Legality, IRInstructionDataList &IDL); /// Hashes \p Value based on its opcode, types, and operand types. /// Two IRInstructionData instances produce the same hash when they perform @@ -155,8 +157,12 @@ llvm::hash_value(ID.Inst->getType()), llvm::hash_combine_range(OperTypes.begin(), OperTypes.end())); } + + IRInstructionDataList *IDL = nullptr; }; +struct IRInstructionDataList : simple_ilist {}; + /// Compare one IRInstructionData class to another IRInstructionData class for /// whether they are performing a the same operation, and can mapped to the /// same value. For regular instructions if the hash value is the same, then @@ -263,13 +269,28 @@ /// with the information. SpecificBumpPtrAllocator *InstDataAllocator = nullptr; + /// This allocator pointer is in charge of creating the IRInstructionDataList + /// so it is not deallocated until whatever external tool is using it is done + /// with the information. + SpecificBumpPtrAllocator *IDLAllocator = nullptr; + /// Get an allocated IRInstructionData struct using the InstDataAllocator. /// /// \param I - The Instruction to wrap with IRInstructionData. /// \param Legality - A boolean value that is true if the instruction is to /// be considered for similarity, and false if not. + /// \param IDL - The InstructionDataList that the IRInstructionData is + /// inserted into. /// \returns An allocated IRInstructionData struct. - IRInstructionData *allocateIRInstructionData(Instruction &I, bool Legality); + IRInstructionData *allocateIRInstructionData(Instruction &I, bool Legality, + IRInstructionDataList &IDL); + + /// Get an allocated IRInstructionDataList object using the IDLAllocator. + /// + /// \returns An allocated IRInstructionDataList object. + IRInstructionDataList *allocateIRInstructionDataList(); + + IRInstructionDataList *IDL = nullptr; /// Maps the Instructions in a BasicBlock \p BB to legal or illegal integers /// determined by \p InstrType. Two Instructions are mapped to the same value @@ -306,8 +327,9 @@ BasicBlock::iterator &It, std::vector &IntegerMappingForBB, std::vector &InstrListForBB, bool End = false); - IRInstructionMapper(SpecificBumpPtrAllocator *IDA) - : InstDataAllocator(IDA) { + IRInstructionMapper(SpecificBumpPtrAllocator *IDA, + SpecificBumpPtrAllocator *IDLA) + : InstDataAllocator(IDA), IDLAllocator(IDLA) { // Make sure that the implementation of DenseMapInfo hasn't // changed. assert(DenseMapInfo::getEmptyKey() == static_cast(-1) && @@ -315,6 +337,9 @@ assert(DenseMapInfo::getTombstoneKey() == static_cast(-2) && "DenseMapInfo's tombstone key isn't -2!"); + + IDL = new (IDLAllocator->Allocate()) + IRInstructionDataList(); } /// Custom InstVisitor to classify different instructions for whether it can diff --git a/llvm/lib/Analysis/IRSimilarityIdentifier.cpp b/llvm/lib/Analysis/IRSimilarityIdentifier.cpp --- a/llvm/lib/Analysis/IRSimilarityIdentifier.cpp +++ b/llvm/lib/Analysis/IRSimilarityIdentifier.cpp @@ -20,8 +20,9 @@ using namespace llvm; using namespace IRSimilarity; -IRInstructionData::IRInstructionData(Instruction &I, bool Legality) - : Inst(&I), Legal(Legality) { +IRInstructionData::IRInstructionData(Instruction &I, bool Legality, + IRInstructionDataList &IDList) + : Inst(&I), Legal(Legality), IDL(&IDList) { // Here we collect the operands to be used to determine whether two // instructions are similar to one another. for (Use &OI : I.operands()) @@ -63,6 +64,8 @@ if (HaveLegalRange) { mapToIllegalUnsigned(It, IntegerMappingForBB, InstrListForBB, true); + for_each(InstrListForBB, + [this](IRInstructionData *ID) { this->IDL->push_back(*ID); }); InstrList.insert(InstrList.end(), InstrListForBB.begin(), InstrListForBB.end()); IntegerMapping.insert(IntegerMapping.end(), IntegerMappingForBB.begin(), @@ -87,7 +90,7 @@ // Get the integer for this instruction or give it the current // LegalInstrNumber. - IRInstructionData *ID = allocateIRInstructionData(*It, true); + IRInstructionData *ID = allocateIRInstructionData(*It, true, *IDL); InstrListForBB.push_back(ID); // Add to the instruction list @@ -117,8 +120,14 @@ } IRInstructionData * -IRInstructionMapper::allocateIRInstructionData(Instruction &I, bool Legality) { - return new (InstDataAllocator->Allocate()) IRInstructionData(I, Legality); +IRInstructionMapper::allocateIRInstructionData(Instruction &I, bool Legality, + IRInstructionDataList &IDL) { + return new (InstDataAllocator->Allocate()) IRInstructionData(I, Legality, IDL); +} + +IRInstructionDataList * +IRInstructionMapper::allocateIRInstructionDataList() { + return new (IDLAllocator->Allocate()) IRInstructionDataList(); } // TODO: This is the same as the MachineOutliner, and should be consolidated @@ -135,7 +144,7 @@ IRInstructionData *ID = nullptr; if (!End) - ID = allocateIRInstructionData(*It, false); + ID = allocateIRInstructionData(*It, false, *IDL); InstrListForBB.push_back(ID); // Remember that we added an illegal number last time. diff --git a/llvm/unittests/Analysis/IRSimilarityIdentifierTest.cpp b/llvm/unittests/Analysis/IRSimilarityIdentifierTest.cpp --- a/llvm/unittests/Analysis/IRSimilarityIdentifierTest.cpp +++ b/llvm/unittests/Analysis/IRSimilarityIdentifierTest.cpp @@ -33,7 +33,8 @@ void getVectors(Module &M, std::vector &InstrList, std::vector &UnsignedVec) { SpecificBumpPtrAllocator InstDataAllocator; - IRInstructionMapper Mapper(&InstDataAllocator); + SpecificBumpPtrAllocator IDLAllocator; + IRInstructionMapper Mapper(&InstDataAllocator, &IDLAllocator); for (Function &F : M) for (BasicBlock &BB : F) @@ -297,7 +298,6 @@ ASSERT_TRUE(UnsignedVec[0] != UnsignedVec[1]); } - // Checks that the sexts that have the different type parameters map to the // different unsigned integers. TEST(IRInstructionMapper, SextTypeDifference) {