[RegisterBankInfo] Uniquely generate ValueMapping.
This is a step toward statically allocate ValueMapping. Like the previous few commits, the goal is to move toward a TableGen'ed like structure with no dynamic allocation at all. llvm-svn: 282324
This commit is contained in:
		
							parent
							
								
									8159de4de9
								
							
						
					
					
						commit
						fd8c95adf4
					
				| 
						 | 
					@ -120,11 +120,11 @@ public:
 | 
				
			||||||
    unsigned Cost;
 | 
					    unsigned Cost;
 | 
				
			||||||
    /// Mapping of all the operands.
 | 
					    /// Mapping of all the operands.
 | 
				
			||||||
    /// Note: Use a SmallVector to avoid heap allocation in most cases.
 | 
					    /// Note: Use a SmallVector to avoid heap allocation in most cases.
 | 
				
			||||||
    SmallVector<ValueMapping, 8> OperandsMapping;
 | 
					    SmallVector<const ValueMapping *, 8> OperandsMapping;
 | 
				
			||||||
    /// Number of operands.
 | 
					    /// Number of operands.
 | 
				
			||||||
    unsigned NumOperands;
 | 
					    unsigned NumOperands;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    ValueMapping &getOperandMapping(unsigned i) {
 | 
					    const ValueMapping *&getOperandMapping(unsigned i) {
 | 
				
			||||||
      assert(i < getNumOperands() && "Out of bound operand");
 | 
					      assert(i < getNumOperands() && "Out of bound operand");
 | 
				
			||||||
      return OperandsMapping[i];
 | 
					      return OperandsMapping[i];
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
| 
						 | 
					@ -142,7 +142,7 @@ public:
 | 
				
			||||||
        : ID(ID), Cost(Cost), NumOperands(NumOperands) {
 | 
					        : ID(ID), Cost(Cost), NumOperands(NumOperands) {
 | 
				
			||||||
      assert(getID() != InvalidMappingID &&
 | 
					      assert(getID() != InvalidMappingID &&
 | 
				
			||||||
             "Use the default constructor for invalid mapping");
 | 
					             "Use the default constructor for invalid mapping");
 | 
				
			||||||
      OperandsMapping.resize(getNumOperands());
 | 
					      OperandsMapping.resize(getNumOperands(), nullptr);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /// Default constructor.
 | 
					    /// Default constructor.
 | 
				
			||||||
| 
						 | 
					@ -159,13 +159,24 @@ public:
 | 
				
			||||||
    unsigned getNumOperands() const { return NumOperands; }
 | 
					    unsigned getNumOperands() const { return NumOperands; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /// Get the value mapping of the ith operand.
 | 
					    /// Get the value mapping of the ith operand.
 | 
				
			||||||
 | 
					    /// \pre The mapping for the ith operand has been set.
 | 
				
			||||||
 | 
					    /// \pre The ith operand is a register.
 | 
				
			||||||
    const ValueMapping &getOperandMapping(unsigned i) const {
 | 
					    const ValueMapping &getOperandMapping(unsigned i) const {
 | 
				
			||||||
      return const_cast<InstructionMapping *>(this)->getOperandMapping(i);
 | 
					      const ValueMapping *&ValMapping =
 | 
				
			||||||
 | 
					          const_cast<InstructionMapping *>(this)->getOperandMapping(i);
 | 
				
			||||||
 | 
					      assert(ValMapping && "Trying to get the mapping for a non-reg operand?");
 | 
				
			||||||
 | 
					      return *ValMapping;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// Check if the value mapping of the ith operand has been set.
 | 
				
			||||||
 | 
					    bool isOperandMappingSet(unsigned i) const {
 | 
				
			||||||
 | 
					      return const_cast<InstructionMapping *>(this)->getOperandMapping(i) !=
 | 
				
			||||||
 | 
					             nullptr;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /// Get the value mapping of the ith operand.
 | 
					    /// Get the value mapping of the ith operand.
 | 
				
			||||||
    void setOperandMapping(unsigned i, const ValueMapping &ValMapping) {
 | 
					    void setOperandMapping(unsigned i, const ValueMapping &ValMapping) {
 | 
				
			||||||
      getOperandMapping(i) = ValMapping;
 | 
					      getOperandMapping(i) = &ValMapping;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /// Check whether this object is valid.
 | 
					    /// Check whether this object is valid.
 | 
				
			||||||
| 
						 | 
					@ -300,6 +311,10 @@ protected:
 | 
				
			||||||
  /// This shouldn't be needed when everything gets TableGen'ed.
 | 
					  /// This shouldn't be needed when everything gets TableGen'ed.
 | 
				
			||||||
  mutable DenseMap<unsigned, PartialMapping *> MapOfPartialMappings;
 | 
					  mutable DenseMap<unsigned, PartialMapping *> MapOfPartialMappings;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /// Keep dynamically allocated ValueMapping in a separate map.
 | 
				
			||||||
 | 
					  /// This shouldn't be needed when everything gets TableGen'ed.
 | 
				
			||||||
 | 
					  mutable DenseMap<unsigned, ValueMapping *> MapOfValueMappings;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /// Create a RegisterBankInfo that can accomodate up to \p NumRegBanks
 | 
					  /// Create a RegisterBankInfo that can accomodate up to \p NumRegBanks
 | 
				
			||||||
  /// RegisterBank instances.
 | 
					  /// RegisterBank instances.
 | 
				
			||||||
  ///
 | 
					  ///
 | 
				
			||||||
| 
						 | 
					@ -373,6 +388,19 @@ protected:
 | 
				
			||||||
  const PartialMapping &getPartialMapping(unsigned StartIdx, unsigned Length,
 | 
					  const PartialMapping &getPartialMapping(unsigned StartIdx, unsigned Length,
 | 
				
			||||||
                                          const RegisterBank &RegBank) const;
 | 
					                                          const RegisterBank &RegBank) const;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /// Methods to get a uniquely generated ValueMapping.
 | 
				
			||||||
 | 
					  /// @{
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /// The most common ValueMapping consists of a single PartialMapping.
 | 
				
			||||||
 | 
					  /// Feature a method for that.
 | 
				
			||||||
 | 
					  const ValueMapping &getValueMapping(unsigned StartIdx, unsigned Length,
 | 
				
			||||||
 | 
					                                      const RegisterBank &RegBank) const;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /// Get the ValueMapping for the given arguments.
 | 
				
			||||||
 | 
					  const ValueMapping &getValueMapping(const PartialMapping *BreakDown,
 | 
				
			||||||
 | 
					                                      unsigned NumBreakDowns) const;
 | 
				
			||||||
 | 
					  /// @}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /// Get the register bank for the \p OpIdx-th operand of \p MI form
 | 
					  /// Get the register bank for the \p OpIdx-th operand of \p MI form
 | 
				
			||||||
  /// the encoding constraints, if any.
 | 
					  /// the encoding constraints, if any.
 | 
				
			||||||
  ///
 | 
					  ///
 | 
				
			||||||
| 
						 | 
					@ -578,6 +606,10 @@ operator<<(raw_ostream &OS, const RegisterBankInfo::OperandsMapper &OpdMapper) {
 | 
				
			||||||
  OpdMapper.print(OS, /*ForDebug*/ false);
 | 
					  OpdMapper.print(OS, /*ForDebug*/ false);
 | 
				
			||||||
  return OS;
 | 
					  return OS;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// Hashing function for PartialMapping.
 | 
				
			||||||
 | 
					/// It is required for the hashing of ValueMapping.
 | 
				
			||||||
 | 
					hash_code hash_value(const RegisterBankInfo::PartialMapping &PartMapping);
 | 
				
			||||||
} // End namespace llvm.
 | 
					} // End namespace llvm.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -57,6 +57,8 @@ RegisterBankInfo::RegisterBankInfo(RegisterBank **RegBanks,
 | 
				
			||||||
RegisterBankInfo::~RegisterBankInfo() {
 | 
					RegisterBankInfo::~RegisterBankInfo() {
 | 
				
			||||||
  for (auto It : MapOfPartialMappings)
 | 
					  for (auto It : MapOfPartialMappings)
 | 
				
			||||||
    delete It.second;
 | 
					    delete It.second;
 | 
				
			||||||
 | 
					  for (auto It : MapOfValueMappings)
 | 
				
			||||||
 | 
					    delete It.second;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
bool RegisterBankInfo::verify(const TargetRegisterInfo &TRI) const {
 | 
					bool RegisterBankInfo::verify(const TargetRegisterInfo &TRI) const {
 | 
				
			||||||
| 
						 | 
					@ -283,8 +285,7 @@ RegisterBankInfo::getInstrMappingImpl(const MachineInstr &MI) const {
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    RegBank = CurRegBank;
 | 
					    RegBank = CurRegBank;
 | 
				
			||||||
    RegSize = getSizeInBits(Reg, MRI, TRI);
 | 
					    RegSize = getSizeInBits(Reg, MRI, TRI);
 | 
				
			||||||
    Mapping.setOperandMapping(
 | 
					    Mapping.setOperandMapping(OpIdx, getValueMapping(0, RegSize, *CurRegBank));
 | 
				
			||||||
        OpIdx, ValueMapping{&getPartialMapping(0, RegSize, *CurRegBank), 1});
 | 
					 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if (CompleteMapping)
 | 
					  if (CompleteMapping)
 | 
				
			||||||
| 
						 | 
					@ -306,23 +307,33 @@ RegisterBankInfo::getInstrMappingImpl(const MachineInstr &MI) const {
 | 
				
			||||||
      continue;
 | 
					      continue;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // If a mapping already exists, do not touch it.
 | 
					    // If a mapping already exists, do not touch it.
 | 
				
			||||||
    if (static_cast<const InstructionMapping *>(&Mapping)
 | 
					    if (Mapping.isOperandMappingSet(OpIdx))
 | 
				
			||||||
            ->getOperandMapping(OpIdx)
 | 
					 | 
				
			||||||
            .NumBreakDowns)
 | 
					 | 
				
			||||||
      continue;
 | 
					      continue;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Mapping.setOperandMapping(
 | 
					    Mapping.setOperandMapping(OpIdx, getValueMapping(0, RegSize, *RegBank));
 | 
				
			||||||
        OpIdx, ValueMapping{&getPartialMapping(0, RegSize, *RegBank), 1});
 | 
					 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  return Mapping;
 | 
					  return Mapping;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// Hashing function for PartialMapping.
 | 
				
			||||||
 | 
					static hash_code hashPartialMapping(unsigned StartIdx, unsigned Length,
 | 
				
			||||||
 | 
					                                    const RegisterBank *RegBank) {
 | 
				
			||||||
 | 
					  return hash_combine(StartIdx, Length, RegBank ? RegBank->getID() : 0);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// Overloaded version of hash_value for a PartialMapping.
 | 
				
			||||||
 | 
					hash_code
 | 
				
			||||||
 | 
					llvm::hash_value(const RegisterBankInfo::PartialMapping &PartMapping) {
 | 
				
			||||||
 | 
					  return hashPartialMapping(PartMapping.StartIdx, PartMapping.Length,
 | 
				
			||||||
 | 
					                            PartMapping.RegBank);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const RegisterBankInfo::PartialMapping &
 | 
					const RegisterBankInfo::PartialMapping &
 | 
				
			||||||
RegisterBankInfo::getPartialMapping(unsigned StartIdx, unsigned Length,
 | 
					RegisterBankInfo::getPartialMapping(unsigned StartIdx, unsigned Length,
 | 
				
			||||||
                                    const RegisterBank &RegBank) const {
 | 
					                                    const RegisterBank &RegBank) const {
 | 
				
			||||||
  ++NumPartialMappingsAccessed;
 | 
					  ++NumPartialMappingsAccessed;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  hash_code Hash = hash_combine(StartIdx, Length, RegBank.getID());
 | 
					  hash_code Hash = hashPartialMapping(StartIdx, Length, &RegBank);
 | 
				
			||||||
  const auto &It = MapOfPartialMappings.find(Hash);
 | 
					  const auto &It = MapOfPartialMappings.find(Hash);
 | 
				
			||||||
  if (It != MapOfPartialMappings.end())
 | 
					  if (It != MapOfPartialMappings.end())
 | 
				
			||||||
    return *It->second;
 | 
					    return *It->second;
 | 
				
			||||||
| 
						 | 
					@ -334,6 +345,34 @@ RegisterBankInfo::getPartialMapping(unsigned StartIdx, unsigned Length,
 | 
				
			||||||
  return *PartMapping;
 | 
					  return *PartMapping;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const RegisterBankInfo::ValueMapping &
 | 
				
			||||||
 | 
					RegisterBankInfo::getValueMapping(unsigned StartIdx, unsigned Length,
 | 
				
			||||||
 | 
					                                  const RegisterBank &RegBank) const {
 | 
				
			||||||
 | 
					  return getValueMapping(&getPartialMapping(StartIdx, Length, RegBank), 1);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const RegisterBankInfo::ValueMapping &
 | 
				
			||||||
 | 
					RegisterBankInfo::getValueMapping(const PartialMapping *BreakDown,
 | 
				
			||||||
 | 
					                                  unsigned NumBreakDowns) const {
 | 
				
			||||||
 | 
					  hash_code Hash;
 | 
				
			||||||
 | 
					  if (LLVM_LIKELY(NumBreakDowns == 1))
 | 
				
			||||||
 | 
					    Hash = hash_value(*BreakDown);
 | 
				
			||||||
 | 
					  else {
 | 
				
			||||||
 | 
					    SmallVector<size_t, 8> Hashes;
 | 
				
			||||||
 | 
					    for (unsigned Idx = 0; Idx != NumBreakDowns; ++Idx)
 | 
				
			||||||
 | 
					      Hashes.push_back(hash_value(BreakDown[Idx]));
 | 
				
			||||||
 | 
					    Hash = hash_combine_range(Hashes.begin(), Hashes.end());
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  const auto &It = MapOfValueMappings.find(Hash);
 | 
				
			||||||
 | 
					  if (It != MapOfValueMappings.end())
 | 
				
			||||||
 | 
					    return *It->second;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  ValueMapping *&ValMapping = MapOfValueMappings[Hash];
 | 
				
			||||||
 | 
					  ValMapping = new ValueMapping{BreakDown, NumBreakDowns};
 | 
				
			||||||
 | 
					  return *ValMapping;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
RegisterBankInfo::InstructionMapping
 | 
					RegisterBankInfo::InstructionMapping
 | 
				
			||||||
RegisterBankInfo::getInstrMapping(const MachineInstr &MI) const {
 | 
					RegisterBankInfo::getInstrMapping(const MachineInstr &MI) const {
 | 
				
			||||||
    RegisterBankInfo::InstructionMapping Mapping = getInstrMappingImpl(MI);
 | 
					    RegisterBankInfo::InstructionMapping Mapping = getInstrMappingImpl(MI);
 | 
				
			||||||
| 
						 | 
					@ -496,16 +535,18 @@ bool RegisterBankInfo::InstructionMapping::verify(
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  for (unsigned Idx = 0; Idx < NumOperands; ++Idx) {
 | 
					  for (unsigned Idx = 0; Idx < NumOperands; ++Idx) {
 | 
				
			||||||
    const MachineOperand &MO = MI.getOperand(Idx);
 | 
					    const MachineOperand &MO = MI.getOperand(Idx);
 | 
				
			||||||
    const RegisterBankInfo::ValueMapping &MOMapping = getOperandMapping(Idx);
 | 
					 | 
				
			||||||
    (void)MOMapping;
 | 
					 | 
				
			||||||
    if (!MO.isReg()) {
 | 
					    if (!MO.isReg()) {
 | 
				
			||||||
      assert(!MOMapping.NumBreakDowns &&
 | 
					      assert(!isOperandMappingSet(Idx) &&
 | 
				
			||||||
             "We should not care about non-reg mapping");
 | 
					             "We should not care about non-reg mapping");
 | 
				
			||||||
      continue;
 | 
					      continue;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    unsigned Reg = MO.getReg();
 | 
					    unsigned Reg = MO.getReg();
 | 
				
			||||||
    if (!Reg)
 | 
					    if (!Reg)
 | 
				
			||||||
      continue;
 | 
					      continue;
 | 
				
			||||||
 | 
					    assert(isOperandMappingSet(Idx) &&
 | 
				
			||||||
 | 
					           "We must have a mapping for reg operands");
 | 
				
			||||||
 | 
					    const RegisterBankInfo::ValueMapping &MOMapping = getOperandMapping(Idx);
 | 
				
			||||||
 | 
					    (void)MOMapping;
 | 
				
			||||||
    // Register size in bits.
 | 
					    // Register size in bits.
 | 
				
			||||||
    // This size must match what the mapping expects.
 | 
					    // This size must match what the mapping expects.
 | 
				
			||||||
    assert(MOMapping.verify(getSizeInBits(
 | 
					    assert(MOMapping.verify(getSizeInBits(
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -205,15 +205,15 @@ AArch64RegisterBankInfo::getInstrAlternativeMappings(
 | 
				
			||||||
    InstructionMapping FPRMapping(/*ID*/ 2, /*Cost*/ 1, /*NumOperands*/ 3);
 | 
					    InstructionMapping FPRMapping(/*ID*/ 2, /*Cost*/ 1, /*NumOperands*/ 3);
 | 
				
			||||||
    for (unsigned Idx = 0; Idx != 3; ++Idx) {
 | 
					    for (unsigned Idx = 0; Idx != 3; ++Idx) {
 | 
				
			||||||
      GPRMapping.setOperandMapping(
 | 
					      GPRMapping.setOperandMapping(
 | 
				
			||||||
          Idx,
 | 
					          Idx, getValueMapping(
 | 
				
			||||||
          ValueMapping{&AArch64::PartMappings[AArch64::getRegBankBaseIdx(Size) +
 | 
					                   &AArch64::PartMappings[AArch64::getRegBankBaseIdx(Size) +
 | 
				
			||||||
                                          AArch64::FirstGPR],
 | 
					                                          AArch64::FirstGPR],
 | 
				
			||||||
                       1});
 | 
					                   1));
 | 
				
			||||||
      FPRMapping.setOperandMapping(
 | 
					      FPRMapping.setOperandMapping(
 | 
				
			||||||
          Idx,
 | 
					          Idx, getValueMapping(
 | 
				
			||||||
          ValueMapping{&AArch64::PartMappings[AArch64::getRegBankBaseIdx(Size) +
 | 
					                   &AArch64::PartMappings[AArch64::getRegBankBaseIdx(Size) +
 | 
				
			||||||
                                          AArch64::FirstFPR],
 | 
					                                          AArch64::FirstFPR],
 | 
				
			||||||
                       1});
 | 
					                   1));
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    AltMappings.emplace_back(std::move(GPRMapping));
 | 
					    AltMappings.emplace_back(std::move(GPRMapping));
 | 
				
			||||||
    AltMappings.emplace_back(std::move(FPRMapping));
 | 
					    AltMappings.emplace_back(std::move(FPRMapping));
 | 
				
			||||||
| 
						 | 
					@ -325,7 +325,7 @@ AArch64RegisterBankInfo::getInstrMapping(const MachineInstr &MI) const {
 | 
				
			||||||
  for (unsigned Idx = 0; Idx < MI.getNumOperands(); ++Idx)
 | 
					  for (unsigned Idx = 0; Idx < MI.getNumOperands(); ++Idx)
 | 
				
			||||||
    if (MI.getOperand(Idx).isReg())
 | 
					    if (MI.getOperand(Idx).isReg())
 | 
				
			||||||
      Mapping.setOperandMapping(
 | 
					      Mapping.setOperandMapping(
 | 
				
			||||||
          Idx, ValueMapping{&AArch64::PartMappings[OpFinalIdx[Idx]], 1});
 | 
					          Idx, getValueMapping(&AArch64::PartMappings[OpFinalIdx[Idx]], 1));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  return Mapping;
 | 
					  return Mapping;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue