xref: /freebsd/contrib/llvm-project/llvm/include/llvm/CodeGen/PBQP/CostAllocator.h (revision 06c3fb2749bda94cb5201f81ffdb8fa6c3161b2e)
10b57cec5SDimitry Andric //===- CostAllocator.h - PBQP Cost Allocator --------------------*- C++ -*-===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric //
90b57cec5SDimitry Andric // Defines classes conforming to the PBQP cost value manager concept.
100b57cec5SDimitry Andric //
110b57cec5SDimitry Andric // Cost value managers are memory managers for PBQP cost values (vectors and
120b57cec5SDimitry Andric // matrices). Since PBQP graphs can grow very large (E.g. hundreds of thousands
130b57cec5SDimitry Andric // of edges on the largest function in SPEC2006).
140b57cec5SDimitry Andric //
150b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
160b57cec5SDimitry Andric 
170b57cec5SDimitry Andric #ifndef LLVM_CODEGEN_PBQP_COSTALLOCATOR_H
180b57cec5SDimitry Andric #define LLVM_CODEGEN_PBQP_COSTALLOCATOR_H
190b57cec5SDimitry Andric 
200b57cec5SDimitry Andric #include "llvm/ADT/DenseSet.h"
210b57cec5SDimitry Andric #include <algorithm>
220b57cec5SDimitry Andric #include <cstdint>
230b57cec5SDimitry Andric #include <memory>
240b57cec5SDimitry Andric 
250b57cec5SDimitry Andric namespace llvm {
260b57cec5SDimitry Andric namespace PBQP {
270b57cec5SDimitry Andric 
280b57cec5SDimitry Andric template <typename ValueT> class ValuePool {
290b57cec5SDimitry Andric public:
300b57cec5SDimitry Andric   using PoolRef = std::shared_ptr<const ValueT>;
310b57cec5SDimitry Andric 
320b57cec5SDimitry Andric private:
330b57cec5SDimitry Andric   class PoolEntry : public std::enable_shared_from_this<PoolEntry> {
340b57cec5SDimitry Andric   public:
350b57cec5SDimitry Andric     template <typename ValueKeyT>
PoolEntry(ValuePool & Pool,ValueKeyT Value)360b57cec5SDimitry Andric     PoolEntry(ValuePool &Pool, ValueKeyT Value)
370b57cec5SDimitry Andric         : Pool(Pool), Value(std::move(Value)) {}
380b57cec5SDimitry Andric 
~PoolEntry()390b57cec5SDimitry Andric     ~PoolEntry() { Pool.removeEntry(this); }
400b57cec5SDimitry Andric 
getValue()410b57cec5SDimitry Andric     const ValueT &getValue() const { return Value; }
420b57cec5SDimitry Andric 
430b57cec5SDimitry Andric   private:
440b57cec5SDimitry Andric     ValuePool &Pool;
450b57cec5SDimitry Andric     ValueT Value;
460b57cec5SDimitry Andric   };
470b57cec5SDimitry Andric 
480b57cec5SDimitry Andric   class PoolEntryDSInfo {
490b57cec5SDimitry Andric   public:
getEmptyKey()500b57cec5SDimitry Andric     static inline PoolEntry *getEmptyKey() { return nullptr; }
510b57cec5SDimitry Andric 
getTombstoneKey()520b57cec5SDimitry Andric     static inline PoolEntry *getTombstoneKey() {
530b57cec5SDimitry Andric       return reinterpret_cast<PoolEntry *>(static_cast<uintptr_t>(1));
540b57cec5SDimitry Andric     }
550b57cec5SDimitry Andric 
560b57cec5SDimitry Andric     template <typename ValueKeyT>
getHashValue(const ValueKeyT & C)570b57cec5SDimitry Andric     static unsigned getHashValue(const ValueKeyT &C) {
580b57cec5SDimitry Andric       return hash_value(C);
590b57cec5SDimitry Andric     }
600b57cec5SDimitry Andric 
getHashValue(PoolEntry * P)610b57cec5SDimitry Andric     static unsigned getHashValue(PoolEntry *P) {
620b57cec5SDimitry Andric       return getHashValue(P->getValue());
630b57cec5SDimitry Andric     }
640b57cec5SDimitry Andric 
getHashValue(const PoolEntry * P)650b57cec5SDimitry Andric     static unsigned getHashValue(const PoolEntry *P) {
660b57cec5SDimitry Andric       return getHashValue(P->getValue());
670b57cec5SDimitry Andric     }
680b57cec5SDimitry Andric 
690b57cec5SDimitry Andric     template <typename ValueKeyT1, typename ValueKeyT2>
isEqual(const ValueKeyT1 & C1,const ValueKeyT2 & C2)700b57cec5SDimitry Andric     static bool isEqual(const ValueKeyT1 &C1, const ValueKeyT2 &C2) {
710b57cec5SDimitry Andric       return C1 == C2;
720b57cec5SDimitry Andric     }
730b57cec5SDimitry Andric 
740b57cec5SDimitry Andric     template <typename ValueKeyT>
isEqual(const ValueKeyT & C,PoolEntry * P)750b57cec5SDimitry Andric     static bool isEqual(const ValueKeyT &C, PoolEntry *P) {
760b57cec5SDimitry Andric       if (P == getEmptyKey() || P == getTombstoneKey())
770b57cec5SDimitry Andric         return false;
780b57cec5SDimitry Andric       return isEqual(C, P->getValue());
790b57cec5SDimitry Andric     }
800b57cec5SDimitry Andric 
isEqual(PoolEntry * P1,PoolEntry * P2)810b57cec5SDimitry Andric     static bool isEqual(PoolEntry *P1, PoolEntry *P2) {
820b57cec5SDimitry Andric       if (P1 == getEmptyKey() || P1 == getTombstoneKey())
830b57cec5SDimitry Andric         return P1 == P2;
840b57cec5SDimitry Andric       return isEqual(P1->getValue(), P2);
850b57cec5SDimitry Andric     }
860b57cec5SDimitry Andric   };
870b57cec5SDimitry Andric 
880b57cec5SDimitry Andric   using EntrySetT = DenseSet<PoolEntry *, PoolEntryDSInfo>;
890b57cec5SDimitry Andric 
900b57cec5SDimitry Andric   EntrySetT EntrySet;
910b57cec5SDimitry Andric 
removeEntry(PoolEntry * P)920b57cec5SDimitry Andric   void removeEntry(PoolEntry *P) { EntrySet.erase(P); }
930b57cec5SDimitry Andric 
940b57cec5SDimitry Andric public:
getValue(ValueKeyT ValueKey)950b57cec5SDimitry Andric   template <typename ValueKeyT> PoolRef getValue(ValueKeyT ValueKey) {
960b57cec5SDimitry Andric     typename EntrySetT::iterator I = EntrySet.find_as(ValueKey);
970b57cec5SDimitry Andric 
980b57cec5SDimitry Andric     if (I != EntrySet.end())
990b57cec5SDimitry Andric       return PoolRef((*I)->shared_from_this(), &(*I)->getValue());
1000b57cec5SDimitry Andric 
1010b57cec5SDimitry Andric     auto P = std::make_shared<PoolEntry>(*this, std::move(ValueKey));
1020b57cec5SDimitry Andric     EntrySet.insert(P.get());
103*06c3fb27SDimitry Andric     return PoolRef(P, &P->getValue());
1040b57cec5SDimitry Andric   }
1050b57cec5SDimitry Andric };
1060b57cec5SDimitry Andric 
1070b57cec5SDimitry Andric template <typename VectorT, typename MatrixT> class PoolCostAllocator {
1080b57cec5SDimitry Andric private:
1090b57cec5SDimitry Andric   using VectorCostPool = ValuePool<VectorT>;
1100b57cec5SDimitry Andric   using MatrixCostPool = ValuePool<MatrixT>;
1110b57cec5SDimitry Andric 
1120b57cec5SDimitry Andric public:
1130b57cec5SDimitry Andric   using Vector = VectorT;
1140b57cec5SDimitry Andric   using Matrix = MatrixT;
1150b57cec5SDimitry Andric   using VectorPtr = typename VectorCostPool::PoolRef;
1160b57cec5SDimitry Andric   using MatrixPtr = typename MatrixCostPool::PoolRef;
1170b57cec5SDimitry Andric 
getVector(VectorKeyT v)1180b57cec5SDimitry Andric   template <typename VectorKeyT> VectorPtr getVector(VectorKeyT v) {
1190b57cec5SDimitry Andric     return VectorPool.getValue(std::move(v));
1200b57cec5SDimitry Andric   }
1210b57cec5SDimitry Andric 
getMatrix(MatrixKeyT m)1220b57cec5SDimitry Andric   template <typename MatrixKeyT> MatrixPtr getMatrix(MatrixKeyT m) {
1230b57cec5SDimitry Andric     return MatrixPool.getValue(std::move(m));
1240b57cec5SDimitry Andric   }
1250b57cec5SDimitry Andric 
1260b57cec5SDimitry Andric private:
1270b57cec5SDimitry Andric   VectorCostPool VectorPool;
1280b57cec5SDimitry Andric   MatrixCostPool MatrixPool;
1290b57cec5SDimitry Andric };
1300b57cec5SDimitry Andric 
1310b57cec5SDimitry Andric } // end namespace PBQP
1320b57cec5SDimitry Andric } // end namespace llvm
1330b57cec5SDimitry Andric 
1340b57cec5SDimitry Andric #endif // LLVM_CODEGEN_PBQP_COSTALLOCATOR_H
135