File: PrivateMemoryBufferAnalysis.cpp

package info (click to toggle)
intel-graphics-compiler 1.0.12504.6-1%2Bdeb12u1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 83,912 kB
  • sloc: cpp: 910,147; lisp: 202,655; ansic: 15,197; python: 4,025; yacc: 2,241; lex: 1,570; pascal: 244; sh: 104; makefile: 25
file content (104 lines) | stat: -rw-r--r-- 3,331 bytes parent folder | download
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;
}