File: CastToGASAnalysis.h

package info (click to toggle)
intel-graphics-compiler 1.0.17791.18-1
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 102,312 kB
  • sloc: cpp: 935,343; lisp: 286,143; ansic: 16,196; python: 3,279; yacc: 2,487; lex: 1,642; pascal: 300; sh: 174; makefile: 27
file content (152 lines) | stat: -rw-r--r-- 4,472 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
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
/*========================== begin_copyright_notice ============================

Copyright (C) 2022 Intel Corporation

SPDX-License-Identifier: MIT

============================= end_copyright_notice ===========================*/

#pragma once

#include "common/LLVMWarningsPush.hpp"
#include <llvm/Pass.h>
#include <llvm/IR/InstVisitor.h>
#include <llvm/Analysis/CallGraph.h>
#include "common/LLVMWarningsPop.hpp"

#include "Compiler/CodeGenContextWrapper.hpp"

#include <utility>

namespace IGC
{
    enum {
        HasPrivateToGenericCast = 1 << 0,
        HasLocalToGenericCast = 1 << 1,
    };

    class GASInfo {
    public:
        bool canGenericPointToPrivate(llvm::Function& F) const {
            auto E = FunctionMap.find(&F);
            if (E == FunctionMap.end())
                return true;

            return E->second & HasPrivateToGenericCast;
        }

        bool isPrivateAllocatedInGlobalMemory() const {
            return allocatePrivateAsGlobalBuffer;
        }

        bool canGenericPointToLocal(llvm::Function& F) const {
            auto E = FunctionMap.find(&F);
            if (E == FunctionMap.end())
                return true;

            return E->second & HasLocalToGenericCast;
        }

        bool isNoLocalToGenericOptionEnabled() const {
            return noLocalToGenericOptionEnabled;
        }

    private:
        using FunctionMapTy = llvm::DenseMap<const llvm::Function*, unsigned>;
        FunctionMapTy FunctionMap;

        // True when -cl-intel-no-local-to-generic is enabled
        bool noLocalToGenericOptionEnabled = false;
        bool allocatePrivateAsGlobalBuffer = false;

        friend class CastToGASAnalysis;
    };

    class CastToGASAnalysis : public llvm::ModulePass {
    public:
        static char ID;

        CastToGASAnalysis() : llvm::ModulePass(ID) {}

        ~CastToGASAnalysis() = default;

        virtual llvm::StringRef getPassName() const override
        {
            return "Cast To GAS Analysis";
        }

        bool runOnModule(llvm::Module & M) override;

        void getAnalysisUsage(llvm::AnalysisUsage & AU) const override {
            AU.setPreservesAll();
            AU.addRequired<llvm::CallGraphWrapperPass>();
            AU.addRequired<CodeGenContextWrapper>();
        }

        GASInfo& getGASInfo() { return GI; }

    private:
        CodeGenContext* m_ctx = nullptr;
        GASInfo GI;
        llvm::DenseMap<const llvm::Function*, unsigned> castInfoCache;

        void setInfoForGroup(
            llvm::SmallPtrSetImpl<const llvm::Function*>& functionsGroup,
            unsigned castInfo);

        unsigned hasCastsToGeneric(const llvm::Function* F);

        void getAllFuncsAccessibleFromKernel(
            const llvm::Function* F,
            llvm::CallGraph& CG,
            llvm::SmallPtrSetImpl<const llvm::Function*>& funcs,
            bool& disruptAnalysis) const;
    };

    // EmitPass's analysis passes are either function passes or immutable
    // passes for performance reason. To pass the CastToGASAnalysis's
    // info to EmitPass, the following immutable pass is used for holding
    // info and CastToGASInfoWrapper is used to create this immutable pass.
    // Note that no more CastToGASAnalysis after CastToGASInfoWrapper, as
    // CastToGASInfoWrapper invalides CastToGASAnalysis by taking its 'GI'.
    // Any pass after CastToGASInfoWrapper should use CastToGASInfo immutable
    // pass to access the info.
    class CastToGASInfo : public llvm::ImmutablePass {
    public:
        static char ID;
        GASInfo GI;
    public:
        CastToGASInfo();

        virtual llvm::StringRef getPassName() const override
        {
            return "Cast To GAS info for EmitPass";
        }

        const GASInfo& getGASInfo() const { return GI; }
        void setGASInfo(GASInfo& aGI) {
            GI.~GASInfo();
            GI = std::move(aGI);
        }
    };

    class CastToGASInfoWrapper : public llvm::ModulePass {
    public:
        static char ID;

        CastToGASInfoWrapper();

        bool runOnModule(llvm::Module& M) override;

        virtual llvm::StringRef getPassName() const override
        {
            return "Cast To GAS Info Generation for EmitPass";
        }

        void getAnalysisUsage(llvm::AnalysisUsage& AU) const override {
            AU.setPreservesAll();
            AU.addRequired<CastToGASAnalysis>();
            AU.addRequired<CastToGASInfo>();
        }
    };
}