File: OCLBIUtils.h

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 (370 lines) | stat: -rw-r--r-- 13,406 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
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
/*========================== begin_copyright_notice ============================

Copyright (C) 2017-2021 Intel Corporation

SPDX-License-Identifier: MIT

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

#pragma once

#include "Compiler/CodeGenPublic.h"
#include "Compiler/MetaDataApi/MetaDataApi.h"
#include "Compiler/Optimizer/ValueTracker.h"
#include "common/LLVMWarningsPush.hpp"
#include <llvm/ADT/MapVector.h>
#include <llvm/ADT/StringRef.h>
#include <llvmWrapper/IR/Intrinsics.h>
#include "common/LLVMWarningsPop.hpp"
#include "GenISAIntrinsics/GenIntrinsics.h"
#include <map>
#include "Probe/Assertion.h"

namespace llvm
{
    class CallInst;
}

namespace IGC
{
    class CCommand
    {
    public:
        /// @brief  gets llvm function declaration for GenISA_ISA Intrinsic
        /// @param  Id          the wanted GenISA_ISA intrinsic
        /// @param  ptrTy       for intrinsic with overloaded types.
        /// @returns    llvm Function
        llvm::Function* getFunctionDeclaration(llvm::GenISAIntrinsic::ID id, llvm::ArrayRef<llvm::Type*> Tys = llvm::None);

        /// @brief  gets llvm function declaration for LLVM Intrinsic
        /// @param  Id          the wanted LLVM intrinsic
        /// @param  ptrTy       for intrinsic with overloaded types.
        /// @returns    llvm Function
        llvm::Function* getFunctionDeclaration(IGCLLVM::Intrinsic id, llvm::ArrayRef<llvm::Type*> Tys = llvm::None);

        /// @brief  Creates llvm function call for LLVM Intrinsic and replace the
        ///         current instruction with the new function call.
        /// @param  Id          the wanted LLVM intrinsic
        /// @param  ptrTy       for intrinsic with overloaded types.
        void replaceCallInst(IGCLLVM::Intrinsic intrinsicName, llvm::ArrayRef<llvm::Type*> Tys = llvm::None);


        /// @brief  Creates llvm function call for GenISA_ISA Intrinsic and replace the
        ///         current instruction with the new function call.
        /// @param  Id          the wanted GenISA_ISA intrinsic
        /// @param  ptrTy       for intrinsic with overloaded types.
        void replaceGenISACallInst(llvm::GenISAIntrinsic::ID intrinsicName, llvm::ArrayRef<llvm::Type*> Tys = llvm::None);

        /// @brief  reap init() and createIntrinsic().
        /// @param  Inst            the call instruction that need to be replaced.
        /// @param  CodeGenContext  context to return errors
        void execute(llvm::CallInst* Inst, IGC::CodeGenContext* CodeGenContext);

        /// @brief  replace the old __builtin_IB function call with the match llvm/GenISA_ISA
        ///         instructions.
        /// @param  Inst        the call instruction that need to be replaced.
        virtual void createIntrinsic() = 0;

        /// @brief  verify that there are no user errors
        virtual void verifyCommand() {}

        /// @brief  initialize the callInst,  function, context, constants and clear the arg list.
        /// @param  Inst            the call instruction that need to be replaced.
        /// @param  CodeGenContext  context to return errors
        void init(llvm::CallInst* Inst, IGC::CodeGenContext* CodeGenContext);
        void clearArgsList(void);

        enum CoordType
        {
            FloatType,
            IntType
        };

        CCommand(void) :
            m_pFloatZero(nullptr),
            m_pIntZero(nullptr),
            m_pIntOne(nullptr),
            m_pCallInst(nullptr),
            m_pFunc(nullptr),
            m_pCtx(nullptr),
            m_pCodeGenContext(nullptr),
            m_pFloatType(nullptr),
            m_pIntType(nullptr)
        {}
        virtual ~CCommand(void) {};

    protected:
        llvm::Value* m_pFloatZero;
        llvm::Value* m_pIntZero;
        llvm::Value* m_pIntOne;
        llvm::CallInst* m_pCallInst;
        llvm::Function* m_pFunc;
        llvm::LLVMContext* m_pCtx;
        IGC::CodeGenContext* m_pCodeGenContext;
        llvm::SmallVector<llvm::Value*, 10> m_args;
        llvm::DebugLoc m_DL;
        llvm::Type* m_pFloatType;
        llvm::IntegerType* m_pIntType;
    };

    static inline BufferType ResourceTypeMap(ResourceTypeEnum type)
    {
        switch (type)
        {
        case IGC::UAVResourceType:
            return UAV;
        case IGC::BindlessUAVResourceType:
            return BINDLESS;
        case IGC::SRVResourceType:
            return RESOURCE;
        case IGC::SamplerResourceType:
            return SAMPLER;
        case IGC::BindlessSamplerResourceType:
            return BINDLESS_SAMPLER;
        case IGC::OtherResourceType:
            return BUFFER_TYPE_UNKNOWN;
        default:
            IGC_ASSERT_MESSAGE(0, "unknown type!");
            return BUFFER_TYPE_UNKNOWN;
        }
    };

    class CImagesBI : public CCommand
    {
    public:
        enum Dimension
        {
            DIM_1D,
            DIM_1D_ARRAY,
            DIM_2D,
            DIM_2D_ARRAY,
            DIM_3D
        };

        enum CoordComponents
        {
            COORD_X,
            COORD_Y,
            COORD_Z,
            COORD_W
        };

        struct ParamInfo
        {
            ParamInfo(int i, ResourceTypeEnum t, ResourceExtensionTypeEnum extension) :
                index(i), type(ResourceTypeMap(t)), extension(extension) {}
            ParamInfo() :
                index(0), type(BUFFER_TYPE_UNKNOWN), extension(NonExtensionType) {}

            int index;
            BufferType type;
            ResourceExtensionTypeEnum extension;
        };

        typedef llvm::MapVector<llvm::Value*, ParamInfo> ParamMap;
        typedef std::map<int, int> InlineMap;

        class CImagesUtils
        {
        public:
            /// @brief  find the BTI of the image argumant
            /// @param  paramIndex  the index of the image paramtere in the call isntruciton
            /// @returns  the image index
            static llvm::ConstantInt* getImageIndex(ParamMap* pParamMap, llvm::CallInst* pCallInst, unsigned int paramIndex, llvm::Argument*& imageParam);

            /// @brief  find the type (UAV/RESOURCE) of the image argumant
            /// @returns  the image type
            static BufferType getImageType(ParamMap* pParamMap, llvm::CallInst* pCallInst, unsigned int paramIndex);

            /// @brief  find the image argument associated with the given bufType and idx
            /// @returns the image argument
            static llvm::Argument* findImageFromBufferPtr(const IGC::IGCMD::MetaDataUtils& MdUtils, llvm::Function* F, BufferType bufType, uint64_t idx, const IGC::ModuleMetaData* modMD);
        };

        CImagesBI(ParamMap* paramMap, InlineMap* inlineMap, int* nextSampler, Dimension Dim) :
            m_pParamMap(paramMap), m_pInlineMap(inlineMap), m_pNextSampler(nextSampler), m_dim(Dim),
            CoordX(nullptr), CoordY(nullptr), CoordZ(nullptr), m_IncorrectBti(false) {}

        /// @brief  push 3 zeros offset to the function argumant list
        void prepareZeroOffsets(void);

        /// @brief  initilaize CoordX/Y/Z with the given coordinates.
        /// @param  Dim         the image dimension
        /// @param  Coord       the coords from the original intrinsic.
        /// @param  Zero        const zero with the correct type (i.e. float or int)
        ///                     it been use only for image_1d and image_2d
        void prepareCoords(Dimension Dim, llvm::Value* Coord, llvm::Value* Zero);

        /// @brief  push the colors to the function argument list
        /// @param  Color       the Color value
        void prepareColor(llvm::Value* Color);

        /// @brief  set LOD to Zero and push the function argument list
        /// @param  Coord       the type of zero (int or float)
        void prepareLOD(CoordType Coord);


        /// @brief  push the sampler index into the function argument list
        void prepareSamplerIndex(void);

        /// @brief  create a call to the GetBufferPtr intrinsic pseudo-instruction
        /// @brief  push the image index into the function argument list
        void createGetBufferPtr(void);

        /// @brief  returns "true" if the "val" is integer or float with fractional part = 0.
        static bool derivedFromInt(const llvm::Value* pVal);

        void verifyCommand();

    protected:
        /// @brief  push the image index into the function argument list
        void prepareImageBTI(void);

        // m_pParamMap - maps image and sampler kernel parameters to BTIs
        //               and sampler array indexes, respecitvely
        ParamMap* m_pParamMap;

        // m_pInlineMap - maps inline sampler values (CLK_...) to sampler
        //                array indexes.
        InlineMap* m_pInlineMap;

        // The next sampler index to allocate a newly encountered
        // inline sampler
        int* m_pNextSampler;

        Dimension m_dim;
        llvm::Value* CoordX;
        llvm::Value* CoordY;
        llvm::Value* CoordZ;
        bool m_IncorrectBti;
    };

    class CBuiltinsResolver
    {
    private:
        std::map<llvm::StringRef, std::unique_ptr<CCommand>> m_CommandMap;

        // the list of known builtins not to be resolved
        std::vector<llvm::StringRef> m_KnownBuiltins;
        CodeGenContext* m_CodeGenContext;
    public:
        CBuiltinsResolver(CImagesBI::ParamMap* paramMap, CImagesBI::InlineMap* inlineMap, int* nextSampler, CodeGenContext* ctx);
        ~CBuiltinsResolver(void) {}

        // resolve __builtin_IB_* calls.
        // return values:
        //              true - when CallInst was __builtin_IB_* and successfully repleced
        //              false - when CallInst wasn't __builtin_IB*
        bool resolveBI(llvm::CallInst* Inst);
    };

    union InlineSamplerState
    {
        struct _state
        {
            uint64_t TCXAddressMode : 3;
            uint64_t TCYAddressMode : 3;
            uint64_t TCZAddressMode : 3;
            uint64_t MagFilterMode : 2;
            uint64_t MinFilterMode : 2;
            uint64_t MipFilterMode : 2;
            uint64_t NormalizedCoords : 1;
            uint64_t CompareFunction : 4;
            uint64_t _reserved : 44;
        } state;
        uint64_t _Value;

        InlineSamplerState() : _Value(0) {}
        InlineSamplerState(uint64_t samplerValue) : _Value(samplerValue) {}

        enum ADDRESS_MODE
        {
            ADDRESS_MODE_WRAP,
            ADDRESS_MODE_CLAMP,
            ADDRESS_MODE_MIRROR,
            ADDRESS_MODE_BORDER,
            ADDRESS_MODE_MIRRORONCE,
            ADDRESS_MODE_MIRROR101,
            NUM_ADDRESS_MODE
        };

        enum MAP_FILTER_MODE    // Applies for MagFilterMode and MinFilterMode
        {
            MAP_FILTER_MODE_POINT,
            MAP_FILTER_MODE_LINEAR,
            MAP_FILTER_MODE_ANISOTROPIC,
            MAP_FILTER_MODE_GAUSSIANQUAD,
            MAP_FILTER_MODE_PYRAMIDALQUAD,
            MAP_FILTER_MODE_MONO,
            NUM_MAP_FILTER_MODE
        };

        enum MIP_FILTER_MODE
        {
            MIP_FILTER_MODE_POINT,
            MIP_FILTER_MODE_LINEAR,
            MIP_FILTER_MODE_NONE,
            NUM_MIP_FILTER_MODE
        };

        enum NORMALIZED_MODE
        {
            NORMALIZED_MODE_FALSE,
            NORMALIZED_MODE_TRUE,
        };

        enum COMPARE_FUNC
        {
            COMPARE_FUNC_NONE,
            COMPARE_FUNC_LESS,
            COMPARE_FUNC_LESS_EQUAL = 2,
            COMPARE_FUNC_GREATER = 3,
            COMPARE_FUNC_GREATER_EQUAL = 4,
            COMPARE_FUNC_EQUAL = 5,
            COMPARE_FUNC_NOT_EQUAL = 6,
            COMPARE_FUNC_ALWAYS = 7,
            COMPARE_FUNC_NEVER = 8,
            NUM_COMPARE_FUNC
        };
    };

    // Built-in image functions
    // These values need to match the runtime equivalent
#define LEGACY_CLK_ADDRESS_NONE                         0x00
#define LEGACY_CLK_ADDRESS_CLAMP                        0x01
#define LEGACY_CLK_ADDRESS_CLAMP_TO_EDGE                0x02
#define LEGACY_CLK_ADDRESS_REPEAT                       0x03
#define LEGACY_CLK_ADDRESS_MIRRORED_REPEAT              0x04
#define LEGACY_CLK_ADDRESS_MIRRORED_REPEAT_101_INTEL     0x05

#define LEGACY_CLK_NORMALIZED_COORDS_FALSE   0x00
#define LEGACY_CLK_NORMALIZED_COORDS_TRUE    0x08

#define LEGACY_CLK_FILTER_NEAREST            0x00
#define LEGACY_CLK_FILTER_LINEAR             0x10

    // Mask values for the various components
#define LEGACY_SAMPLER_ADDRESS_MASK          0x07
#define LEGACY_SAMPLER_NORMALIZED_MASK       0x08
#define LEGACY_SAMPLER_FILTER_MASK           0x10

    // These values need to match SPIR sampler enum
#define SPIR_CLK_ADDRESS_NONE                       0x00
#define SPIR_CLK_ADDRESS_CLAMP_TO_EDGE              0x02
#define SPIR_CLK_ADDRESS_CLAMP                        0x04
#define SPIR_CLK_ADDRESS_REPEAT                     0x06
#define SPIR_CLK_ADDRESS_MIRRORED_REPEAT            0x08
#define SPIR_CLK_ADDRESS_MIRRORED_REPEAT_101_INTEL     0x0A

#define SPIR_CLK_NORMALIZED_COORDS_FALSE   0x00
#define SPIR_CLK_NORMALIZED_COORDS_TRUE    0x01

#define SPIR_CLK_FILTER_NEAREST            0x0010
#define SPIR_CLK_FILTER_LINEAR             0x0020

    // Mask values for the various components
#define SPIR_SAMPLER_NORMALIZED_MASK       0x01
#define SPIR_SAMPLER_ADDRESS_MASK          0x0e
#define SPIR_SAMPLER_FILTER_MASK           0x30

} // namespace IGC