Index: llvm/include/llvm/Analysis/IRSimilarityIdentifier.h =================================================================== --- llvm/include/llvm/Analysis/IRSimilarityIdentifier.h +++ llvm/include/llvm/Analysis/IRSimilarityIdentifier.h @@ -46,6 +46,8 @@ namespace llvm { namespace IRSimilarity { +struct IRInstructionDataList; + /// This represents what is and is not supported when finding similarity in /// Instructions. /// @@ -112,7 +114,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 @@ -128,7 +130,7 @@ /// /// %add_i64 = add i64 %x2, %y2 /// \endcode - /// + /// /// Because the first two adds operate the same types, and are performing the /// same action, they will be hashed to the same value. /// @@ -143,12 +145,15 @@ /// \returns A hash_value of the IRInstructionData. friend hash_code hash_value(const IRInstructionData &Value) { return hash_combine( - hash_value(Value.Inst->getOpcode()), - hash_value(Value.Inst->getType()), + hash_value(Value.Inst->getOpcode()), hash_value(Value.Inst->getType()), hash_combine_range(Value.OperTypes.begin(), Value.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 @@ -226,7 +231,7 @@ /// MachineInstrs, rather than IRInstructionData, the wrapper for an /// Instruction. struct IRInstructionMapper { - /// The starting illegal instruction number to map to. + /// The starting illegal instruction number to map to. /// /// Set to -3 for compatibility with \p DenseMapInfo. unsigned IllegalInstrNumber = static_cast(-3); @@ -256,6 +261,8 @@ /// with the information. BumpPtrAllocator *InstDataAllocator = nullptr; + 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 /// if they are close as defined by the InstructionData class above. @@ -270,7 +277,8 @@ /// Maps an Instruction to a legal integer. /// /// \param [in] It - The Instruction to be mapped to an integer. - /// \param [in,out] UnsignedVecForBB - Vector of unsigned integers to append to. + /// \param [in,out] UnsignedVecForBB - Vector of unsigned integers to append + /// to. /// \param [in,out] InstrList - Vector of InstructionData to append to. /// \returns The integer \p It was mapped to. unsigned mapToLegalUnsigned(BasicBlock::iterator &It, @@ -280,7 +288,8 @@ /// Maps an Instruction to an illegal integer. /// /// \param [in] It - The \p Instruction to be mapped to an integer. - /// \param [in,out] UnsignedVecForBB -Vector of unsigned integers to append to. + /// \param [in,out] UnsignedVecForBB -Vector of unsigned integers to append + /// to. /// \param [in,out] InstrList - Vector of IRInstructionData to append to. /// \param End - true if creating a dummy IRInstructionData at the end of a /// basic block. @@ -289,24 +298,16 @@ BasicBlock::iterator &It, std::vector &UnsignedVecForBB, std::vector &InstrListForBB, bool End = false); - IRInstructionMapper(){ + IRInstructionMapper(BumpPtrAllocator *IDA) : InstDataAllocator(IDA) { // Make sure that the implementation of DenseMapInfo hasn't // changed. assert(DenseMapInfo::getEmptyKey() == (unsigned)-1 && "DenseMapInfo's empty key isn't -1!"); assert(DenseMapInfo::getTombstoneKey() == (unsigned)-2 && "DenseMapInfo's tombstone key isn't -2!"); - } - - IRInstructionMapper(BumpPtrAllocator *IDA) - : InstDataAllocator(IDA){ - // Make sure that the implementation of DenseMapInfo hasn't - // changed. - assert(DenseMapInfo::getEmptyKey() == (unsigned)-1 && - "DenseMapInfo's empty key isn't -1!"); - assert(DenseMapInfo::getTombstoneKey() == (unsigned)-2 && - "DenseMapInfo's tombstone key isn't -2!"); - } + IDL = new (InstDataAllocator->Allocate()) + IRInstructionDataList(); + }; /// Custom InstVisitor to classify different instructions for whether it can /// be analyzed for similarity. @@ -330,9 +331,7 @@ // DebugInfo should be included in the regions, but should not be // analyzed for similarity as it has no bearing on the outcome of the // program. - InstrType visitDbgInfoIntrinsic(DbgInfoIntrinsic &DII) { - return Invisible; - } + InstrType visitDbgInfoIntrinsic(DbgInfoIntrinsic &DII) { return Invisible; } // TODO: Handle GetElementPtrInsts InstrType visitGetElementPtrInst(GetElementPtrInst &GEPI) { return Illegal; @@ -347,9 +346,7 @@ InstrType visitCallBrInst(CallBrInst &CBI) { return Illegal; } // TODO: Handle interblock similarity. InstrType visitTerminator(Instruction &I) { return Illegal; } - InstrType visitInstruction(Instruction &I) { - return Legal; - } + InstrType visitInstruction(Instruction &I) { return Legal; } }; /// Maps an Instruction to a member of InstrType. @@ -359,4 +356,4 @@ } // end namespace IRSimilarity } // end namespace llvm -#endif // LLVM_ANALYSIS_IRSIMILARITYIDENTIFIER_H \ No newline at end of file +#endif // LLVM_ANALYSIS_IRSIMILARITYIDENTIFIER_H Index: llvm/lib/Analysis/IRSimilarityIdentifier.cpp =================================================================== --- llvm/lib/Analysis/IRSimilarityIdentifier.cpp +++ 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 and their types for determining whether // the structure of the operand use matches between two different candidates. for (Use &OI : I.operands()) { @@ -71,6 +72,8 @@ if (HaveLegalRange) { mapToIllegalUnsigned(It, UnsignedVecForBB, InstrListForBB, true); + for_each(InstrListForBB, + [this](IRInstructionData *ID) { this->IDL->push_back(*ID); }); InstrList.insert(InstrList.end(), InstrListForBB.begin(), InstrListForBB.end()); UnsignedVec.insert(UnsignedVec.end(), UnsignedVecForBB.begin(), @@ -96,7 +99,7 @@ // Get the integer for this instruction or give it the current // LegalInstrNumber. IRInstructionData *ID = new (InstDataAllocator->Allocate()) - IRInstructionData(*It, true); + IRInstructionData(*It, true, *IDL); InstrListForBB.push_back(ID); // Add to the instruction list @@ -140,7 +143,7 @@ IRInstructionData *ID = nullptr; if (!End) ID = new (InstDataAllocator->Allocate()) - IRInstructionData(*It, false); + IRInstructionData(*It, false, *IDL); InstrListForBB.push_back(ID); // Remember that we added an illegal number last time. @@ -158,4 +161,4 @@ "IllegalInstrNumber cannot be DenseMap tombstone or empty key!"); return INumber; -} \ No newline at end of file +} Index: llvm/unittests/Analysis/IRSimilarityIdentifierTest.cpp =================================================================== --- llvm/unittests/Analysis/IRSimilarityIdentifierTest.cpp +++ llvm/unittests/Analysis/IRSimilarityIdentifierTest.cpp @@ -297,7 +297,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) {