[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;
|
||||
/// Mapping of all the operands.
|
||||
/// Note: Use a SmallVector to avoid heap allocation in most cases.
|
||||
SmallVector<ValueMapping, 8> OperandsMapping;
|
||||
SmallVector<const ValueMapping *, 8> OperandsMapping;
|
||||
/// Number of operands.
|
||||
unsigned NumOperands;
|
||||
|
||||
ValueMapping &getOperandMapping(unsigned i) {
|
||||
const ValueMapping *&getOperandMapping(unsigned i) {
|
||||
assert(i < getNumOperands() && "Out of bound operand");
|
||||
return OperandsMapping[i];
|
||||
}
|
||||
|
|
@ -142,7 +142,7 @@ public:
|
|||
: ID(ID), Cost(Cost), NumOperands(NumOperands) {
|
||||
assert(getID() != InvalidMappingID &&
|
||||
"Use the default constructor for invalid mapping");
|
||||
OperandsMapping.resize(getNumOperands());
|
||||
OperandsMapping.resize(getNumOperands(), nullptr);
|
||||
}
|
||||
|
||||
/// Default constructor.
|
||||
|
|
@ -159,13 +159,24 @@ public:
|
|||
unsigned getNumOperands() const { return NumOperands; }
|
||||
|
||||
/// 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 {
|
||||
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.
|
||||
void setOperandMapping(unsigned i, const ValueMapping &ValMapping) {
|
||||
getOperandMapping(i) = ValMapping;
|
||||
getOperandMapping(i) = &ValMapping;
|
||||
}
|
||||
|
||||
/// Check whether this object is valid.
|
||||
|
|
@ -300,6 +311,10 @@ protected:
|
|||
/// This shouldn't be needed when everything gets TableGen'ed.
|
||||
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
|
||||
/// RegisterBank instances.
|
||||
///
|
||||
|
|
@ -373,6 +388,19 @@ protected:
|
|||
const PartialMapping &getPartialMapping(unsigned StartIdx, unsigned Length,
|
||||
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
|
||||
/// the encoding constraints, if any.
|
||||
///
|
||||
|
|
@ -578,6 +606,10 @@ operator<<(raw_ostream &OS, const RegisterBankInfo::OperandsMapper &OpdMapper) {
|
|||
OpdMapper.print(OS, /*ForDebug*/ false);
|
||||
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.
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -57,6 +57,8 @@ RegisterBankInfo::RegisterBankInfo(RegisterBank **RegBanks,
|
|||
RegisterBankInfo::~RegisterBankInfo() {
|
||||
for (auto It : MapOfPartialMappings)
|
||||
delete It.second;
|
||||
for (auto It : MapOfValueMappings)
|
||||
delete It.second;
|
||||
}
|
||||
|
||||
bool RegisterBankInfo::verify(const TargetRegisterInfo &TRI) const {
|
||||
|
|
@ -283,8 +285,7 @@ RegisterBankInfo::getInstrMappingImpl(const MachineInstr &MI) const {
|
|||
}
|
||||
RegBank = CurRegBank;
|
||||
RegSize = getSizeInBits(Reg, MRI, TRI);
|
||||
Mapping.setOperandMapping(
|
||||
OpIdx, ValueMapping{&getPartialMapping(0, RegSize, *CurRegBank), 1});
|
||||
Mapping.setOperandMapping(OpIdx, getValueMapping(0, RegSize, *CurRegBank));
|
||||
}
|
||||
|
||||
if (CompleteMapping)
|
||||
|
|
@ -306,23 +307,33 @@ RegisterBankInfo::getInstrMappingImpl(const MachineInstr &MI) const {
|
|||
continue;
|
||||
|
||||
// If a mapping already exists, do not touch it.
|
||||
if (static_cast<const InstructionMapping *>(&Mapping)
|
||||
->getOperandMapping(OpIdx)
|
||||
.NumBreakDowns)
|
||||
if (Mapping.isOperandMappingSet(OpIdx))
|
||||
continue;
|
||||
|
||||
Mapping.setOperandMapping(
|
||||
OpIdx, ValueMapping{&getPartialMapping(0, RegSize, *RegBank), 1});
|
||||
Mapping.setOperandMapping(OpIdx, getValueMapping(0, RegSize, *RegBank));
|
||||
}
|
||||
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 &
|
||||
RegisterBankInfo::getPartialMapping(unsigned StartIdx, unsigned Length,
|
||||
const RegisterBank &RegBank) const {
|
||||
++NumPartialMappingsAccessed;
|
||||
|
||||
hash_code Hash = hash_combine(StartIdx, Length, RegBank.getID());
|
||||
hash_code Hash = hashPartialMapping(StartIdx, Length, &RegBank);
|
||||
const auto &It = MapOfPartialMappings.find(Hash);
|
||||
if (It != MapOfPartialMappings.end())
|
||||
return *It->second;
|
||||
|
|
@ -334,6 +345,34 @@ RegisterBankInfo::getPartialMapping(unsigned StartIdx, unsigned Length,
|
|||
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::getInstrMapping(const MachineInstr &MI) const {
|
||||
RegisterBankInfo::InstructionMapping Mapping = getInstrMappingImpl(MI);
|
||||
|
|
@ -496,16 +535,18 @@ bool RegisterBankInfo::InstructionMapping::verify(
|
|||
|
||||
for (unsigned Idx = 0; Idx < NumOperands; ++Idx) {
|
||||
const MachineOperand &MO = MI.getOperand(Idx);
|
||||
const RegisterBankInfo::ValueMapping &MOMapping = getOperandMapping(Idx);
|
||||
(void)MOMapping;
|
||||
if (!MO.isReg()) {
|
||||
assert(!MOMapping.NumBreakDowns &&
|
||||
assert(!isOperandMappingSet(Idx) &&
|
||||
"We should not care about non-reg mapping");
|
||||
continue;
|
||||
}
|
||||
unsigned Reg = MO.getReg();
|
||||
if (!Reg)
|
||||
continue;
|
||||
assert(isOperandMappingSet(Idx) &&
|
||||
"We must have a mapping for reg operands");
|
||||
const RegisterBankInfo::ValueMapping &MOMapping = getOperandMapping(Idx);
|
||||
(void)MOMapping;
|
||||
// Register size in bits.
|
||||
// This size must match what the mapping expects.
|
||||
assert(MOMapping.verify(getSizeInBits(
|
||||
|
|
|
|||
|
|
@ -205,15 +205,15 @@ AArch64RegisterBankInfo::getInstrAlternativeMappings(
|
|||
InstructionMapping FPRMapping(/*ID*/ 2, /*Cost*/ 1, /*NumOperands*/ 3);
|
||||
for (unsigned Idx = 0; Idx != 3; ++Idx) {
|
||||
GPRMapping.setOperandMapping(
|
||||
Idx,
|
||||
ValueMapping{&AArch64::PartMappings[AArch64::getRegBankBaseIdx(Size) +
|
||||
AArch64::FirstGPR],
|
||||
1});
|
||||
Idx, getValueMapping(
|
||||
&AArch64::PartMappings[AArch64::getRegBankBaseIdx(Size) +
|
||||
AArch64::FirstGPR],
|
||||
1));
|
||||
FPRMapping.setOperandMapping(
|
||||
Idx,
|
||||
ValueMapping{&AArch64::PartMappings[AArch64::getRegBankBaseIdx(Size) +
|
||||
AArch64::FirstFPR],
|
||||
1});
|
||||
Idx, getValueMapping(
|
||||
&AArch64::PartMappings[AArch64::getRegBankBaseIdx(Size) +
|
||||
AArch64::FirstFPR],
|
||||
1));
|
||||
}
|
||||
AltMappings.emplace_back(std::move(GPRMapping));
|
||||
AltMappings.emplace_back(std::move(FPRMapping));
|
||||
|
|
@ -325,7 +325,7 @@ AArch64RegisterBankInfo::getInstrMapping(const MachineInstr &MI) const {
|
|||
for (unsigned Idx = 0; Idx < MI.getNumOperands(); ++Idx)
|
||||
if (MI.getOperand(Idx).isReg())
|
||||
Mapping.setOperandMapping(
|
||||
Idx, ValueMapping{&AArch64::PartMappings[OpFinalIdx[Idx]], 1});
|
||||
Idx, getValueMapping(&AArch64::PartMappings[OpFinalIdx[Idx]], 1));
|
||||
|
||||
return Mapping;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue