]> granicus.if.org Git - llvm/commitdiff
[RegisterBankInfo] Uniquely generate ValueMapping.
authorQuentin Colombet <qcolombet@apple.com>
Sat, 24 Sep 2016 04:53:52 +0000 (04:53 +0000)
committerQuentin Colombet <qcolombet@apple.com>
Sat, 24 Sep 2016 04:53:52 +0000 (04:53 +0000)
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.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@282324 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/CodeGen/GlobalISel/RegisterBankInfo.h
lib/CodeGen/GlobalISel/RegisterBankInfo.cpp
lib/Target/AArch64/AArch64RegisterBankInfo.cpp

index dd9572e60c89129ede8bd95ae450a230c3a5e98d..8ccc0421c54afe96d6e5127ad55746afe64b7943 100644 (file)
@@ -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
index 172067233a1989c7a644769088e80486e2295c0e..9c1f97e4c87d186c7455e14af305ad0a986980c2 100644 (file)
@@ -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(
index 1ef79e961dfb02d8027a26898fc52ff3e26e58fc..de66c817bc03f77e42083cb1901c754f2ea73179 100644 (file)
@@ -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;
 }