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
|
/*========================== begin_copyright_notice ============================
Copyright (C) 2017-2021 Intel Corporation
SPDX-License-Identifier: MIT
============================= end_copyright_notice ===========================*/
#include "AdaptorCommon/ImplicitArgs.hpp"
#include "Compiler/Optimizer/OpenCLPasses/PrivateMemory/PrivateMemoryBufferAnalysis.hpp"
#include "Compiler/MetaDataApi/MetaDataApi.h"
#include "Compiler/IGCPassSupport.h"
#include "Probe/Assertion.h"
using namespace llvm;
using namespace IGC;
using namespace IGC::IGCMD;
// Register pass to igc-opt
#define PASS_FLAG "igc-private-mem-buffer-analysis"
#define PASS_DESCRIPTION "Analizes the size and offset of private mem allocas and the total per WI size"
#define PASS_CFG_ONLY false
#define PASS_ANALYSIS true
IGC_INITIALIZE_PASS_BEGIN(PrivateMemoryBufferAnalysis, PASS_FLAG, PASS_DESCRIPTION, PASS_CFG_ONLY, PASS_ANALYSIS)
//IGC_INITIALIZE_PASS_DEPENDENCY(DataLayout)
IGC_INITIALIZE_PASS_END(PrivateMemoryBufferAnalysis, PASS_FLAG, PASS_DESCRIPTION, PASS_CFG_ONLY, PASS_ANALYSIS)
char PrivateMemoryBufferAnalysis::ID = 0;
PrivateMemoryBufferAnalysis::PrivateMemoryBufferAnalysis() : ModulePass(ID)
{
initializePrivateMemoryBufferAnalysisPass(*PassRegistry::getPassRegistry());
}
bool PrivateMemoryBufferAnalysis::runOnModule(llvm::Module& M)
{
// Get the analysis
m_DL = &M.getDataLayout();
// Clear data for processing new module
m_privateInfoMap.clear();
for (Module::iterator I = M.begin(); I != M.end(); ++I)
{
runOnFunction(*I);
}
return false;
}
void PrivateMemoryBufferAnalysis::runOnFunction(llvm::Function& F)
{
if (F.isDeclaration())
{
return;
}
// Processing new function
m_currentOffset = 0;
m_maxAlignment = 0;
visit(F);
// Align total size for the next WI
m_currentOffset = iSTD::Align(m_currentOffset, (size_t)m_maxAlignment);
// Map total private buffer size to current function
m_privateInfoMap[&F].m_bufferTotalSize = m_currentOffset;
}
void PrivateMemoryBufferAnalysis::visitAllocaInst(AllocaInst& AI)
{
IGC_ASSERT_MESSAGE(AI.getType()->getAddressSpace() == ADDRESS_SPACE_PRIVATE, "Allocaitons are expected to be in private address space");
// If private memory has no users, no point of analysing it.
if (AI.use_empty()) return;
Function* pFunc = AI.getParent()->getParent();
m_privateInfoMap[pFunc].m_allocaInsts.push_back(&AI);
alignment_t alignment = AI.getAlignment();
if (alignment == 0) {
alignment = m_DL->getABITypeAlignment(AI.getAllocatedType());
}
// Update max alignment
if (alignment > m_maxAlignment)
{
m_maxAlignment = alignment;
}
// Determine buffer offset
m_currentOffset = iSTD::Align(m_currentOffset, (size_t)alignment);
m_privateInfoMap[pFunc].m_bufferOffsets[&AI] = m_currentOffset;
// Determine buffer size
IGC_ASSERT_MESSAGE(isa<ConstantInt>(AI.getArraySize()), "Private memory array size is expected to be constant int!");
unsigned int bufferSize = static_cast<unsigned int>(cast<ConstantInt>(AI.getArraySize())->getZExtValue() * m_DL->getTypeAllocSize(AI.getAllocatedType()));
m_privateInfoMap[pFunc].m_bufferSizes[&AI] = bufferSize;
// Advance offset
m_currentOffset += bufferSize;
}
|