1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170
|
/*========================== begin_copyright_notice ============================
Copyright (C) 2017-2021 Intel Corporation
SPDX-License-Identifier: MIT
============================= end_copyright_notice ===========================*/
#pragma once
#include "common/LLVMWarningsPush.hpp"
#include <llvm/Pass.h>
#include <llvm/IR/Function.h>
#include "common/LLVMWarningsPop.hpp"
namespace IGC
{
class CodeGenContextWrapper;
class WIAnalysis;
class FastValueMapBase;
class TranslationTable : public llvm::FunctionPass
{
public:
static char ID;
TranslationTable();
void RegisterListener(FastValueMapBase* fvmb)
{
m_ValueMaps.push_back(fvmb);
}
void getAnalysisUsage(llvm::AnalysisUsage& AU) const override {
AU.setPreservesAll();
}
bool runOnFunction(llvm::Function& F) override;
bool run(llvm::Function& F);
llvm::StringRef getPassName() const override {
return "TranslationTable";
}
unsigned int GetNumIDs() const { return m_NumIDS; }
void RegisterNewValueAndAssignID(llvm::Value* val);
private:
unsigned int m_NumIDS;
llvm::SmallVector<FastValueMapBase*, 8> m_ValueMaps;
}; //class TranslationTable
//Since we are mapping Value pointers to attribute, to avoid confusion
//we will not call this as 'key to value' mapping but 'value to attribute' mapping
//Each mapped attribute type should provide an implementation of this template
//specialization.
template<typename T>
struct FastValueMapAttributeInfo {
//no default implementation
};
// Provide FastValueMapAttributeInfo for unsigned ints.
template<> struct FastValueMapAttributeInfo<unsigned> {
static inline unsigned getEmptyAttribute() { return ~0U; }
};
//===----------------------------------------------------------------------===//
class FastValueMapBase
{
public:
FastValueMapBase() : m_pTT(nullptr)
{
}
FastValueMapBase(TranslationTable* table) : m_pTT(table)
{
}
//This have to be virtual, since only a concrete class knows the exact
//type of the attribute which is to be initialized.
virtual void Update() = 0;
public:
TranslationTable* m_pTT;
};
//===----------------------------------------------------------------------===//
template<typename A, typename T, typename AttributeInfoT = FastValueMapAttributeInfo<T> >
class FastValueMapImpl : public FastValueMapBase
{
//No default implementation.
};
//===----------------------------------------------------------------------===//
//Let us use llvm::DenseMap as a type selector for this specialization.
template<typename T, typename AttributeInfoT>
class FastValueMapImpl<llvm::DenseMap<const llvm::Value*, T>, T, AttributeInfoT> : public FastValueMapBase
{
public:
FastValueMapImpl(TranslationTable* table) : FastValueMapBase(table)
{
Initialize(table);
}
FastValueMapImpl()
{
}
void Initialize(const TranslationTable* table)
{
//DenseMap should be kept at less than 75% of its capacity.
unsigned int preferredSize = (unsigned int)(table->GetNumIDs() * 1.4); //be little bit conservative
//Add some more space for growing.
preferredSize = (unsigned int)(preferredSize * 1.1);
m_attributeMap.reserve(preferredSize);
}
T GetAttributeWithoutCreating(const llvm::Value* val) const
{
typename llvm::DenseMap<const llvm::Value*, T>::const_iterator it;
it = m_attributeMap.find(val);
if (it != m_attributeMap.end())
{
return (*it).second;
}
return AttributeInfoT::getEmptyAttribute();
}
void SetAttribute(const llvm::Value* val, T attr)
{
m_attributeMap[val] = attr;
}
void Update() override
{
//TODO: what do we do? Should we re-size?
}
T end() const
{
return AttributeInfoT::getEmptyAttribute();
}
void clear()
{
//TODO: need to think more about this scenario
m_attributeMap.clear();
}
private:
llvm::DenseMap<const llvm::Value*, T> m_attributeMap;
};
template<typename T, typename AttributeInfoT>
class FastValueMap : public FastValueMapImpl<llvm::DenseMap<const llvm::Value*, T>, T, AttributeInfoT>
{
};
} //namespace IGC
|