1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-10-19 11:02:59 +02:00

[IRSim] Adding ilist for IRInstructionData.

The IRInstructionData structs are a different representation of the
program.  This list treats the program as if it was "flattened" and
the only parent is this list.  This lets us easily create ranges of
instructions.

Differential Revision: https://reviews.llvm.org/D86969
This commit is contained in:
Andrew Litteken 2020-09-15 16:16:48 -05:00
parent e9b884a465
commit c53dab65b4
3 changed files with 46 additions and 12 deletions

View File

@ -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 @@ struct IRInstructionData : ilist_node<IRInstructionData> {
/// 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 @@ struct IRInstructionData : ilist_node<IRInstructionData> {
llvm::hash_value(ID.Inst->getType()),
llvm::hash_combine_range(OperTypes.begin(), OperTypes.end()));
}
IRInstructionDataList *IDL = nullptr;
};
struct IRInstructionDataList : simple_ilist<IRInstructionData> {};
/// 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 @@ struct IRInstructionMapper {
/// with the information.
SpecificBumpPtrAllocator<IRInstructionData> *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<IRInstructionDataList> *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 @@ struct IRInstructionMapper {
BasicBlock::iterator &It, std::vector<unsigned> &IntegerMappingForBB,
std::vector<IRInstructionData *> &InstrListForBB, bool End = false);
IRInstructionMapper(SpecificBumpPtrAllocator<IRInstructionData> *IDA)
: InstDataAllocator(IDA) {
IRInstructionMapper(SpecificBumpPtrAllocator<IRInstructionData> *IDA,
SpecificBumpPtrAllocator<IRInstructionDataList> *IDLA)
: InstDataAllocator(IDA), IDLAllocator(IDLA) {
// Make sure that the implementation of DenseMapInfo<unsigned> hasn't
// changed.
assert(DenseMapInfo<unsigned>::getEmptyKey() == static_cast<unsigned>(-1) &&
@ -315,6 +337,9 @@ struct IRInstructionMapper {
assert(DenseMapInfo<unsigned>::getTombstoneKey() ==
static_cast<unsigned>(-2) &&
"DenseMapInfo<unsigned>'s tombstone key isn't -2!");
IDL = new (IDLAllocator->Allocate())
IRInstructionDataList();
}
/// Custom InstVisitor to classify different instructions for whether it can

View File

@ -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 @@ void IRInstructionMapper::convertToUnsignedVec(
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 @@ unsigned IRInstructionMapper::mapToLegalUnsigned(
// 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 @@ unsigned IRInstructionMapper::mapToLegalUnsigned(
}
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 @@ unsigned IRInstructionMapper::mapToIllegalUnsigned(
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.

View File

@ -33,7 +33,8 @@ static std::unique_ptr<Module> makeLLVMModule(LLVMContext &Context,
void getVectors(Module &M, std::vector<IRInstructionData *> &InstrList,
std::vector<unsigned> &UnsignedVec) {
SpecificBumpPtrAllocator<IRInstructionData> InstDataAllocator;
IRInstructionMapper Mapper(&InstDataAllocator);
SpecificBumpPtrAllocator<IRInstructionDataList> IDLAllocator;
IRInstructionMapper Mapper(&InstDataAllocator, &IDLAllocator);
for (Function &F : M)
for (BasicBlock &BB : F)
@ -297,7 +298,6 @@ TEST(IRInstructionMapper, ZextTypeDifference) {
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) {