1 /*========================== begin_copyright_notice ============================
2 
3 Copyright (C) 2017-2021 Intel Corporation
4 
5 SPDX-License-Identifier: MIT
6 
7 ============================= end_copyright_notice ===========================*/
8 
9 #pragma once
10 
11 #include "AdaptorCommon/ImplicitArgs.hpp"
12 #include "Compiler/MetaDataUtilsWrapper.h"
13 
14 #include "common/LLVMWarningsPush.hpp"
15 #include <llvm/Pass.h>
16 #include <llvm/IR/InstVisitor.h>
17 #include "common/LLVMWarningsPop.hpp"
18 
19 namespace IGC
20 {
21     /// @brief  ImageFuncResolution pass used for resolving OpenCL image dimension functions.
22     ///         This pass depends on the ImageFuncAnalysis and AddImplicitArgs passes runing before it
23 
24     class ImageFuncResolution : public llvm::FunctionPass, public llvm::InstVisitor<ImageFuncResolution>
25     {
26     public:
27         // Pass identification, replacement for typeid
28         static char ID;
29 
30         /// @brief  Constructor
31         ImageFuncResolution();
32 
33         /// @brief  Destructor
~ImageFuncResolution()34         ~ImageFuncResolution() {}
35 
36         /// @brief  Provides name of pass
getPassName() const37         virtual llvm::StringRef getPassName() const override
38         {
39             return "ImageFuncResolution";
40         }
41 
getAnalysisUsage(llvm::AnalysisUsage & AU) const42         void getAnalysisUsage(llvm::AnalysisUsage& AU) const override
43         {
44             AU.setPreservesCFG();
45             AU.addRequired<MetaDataUtilsWrapper>();
46             AU.addRequired<CodeGenContextWrapper>();
47         }
48 
49         /// @brief  Main entry point.
50         ///         Finds all OpenCL image dimension function calls and resolve them into an llvm sequence
51         /// @param  F The destination function.
52         virtual bool runOnFunction(llvm::Function& F) override;
53 
54         /// @brief  Call instructions visitor.
55         ///         Checks for OpenCL image dimension functions and resolves them into appropriate sequence of code
56         /// @param  CI The call instruction.
57         void visitCallInst(llvm::CallInst& CI);
58 
59     private:
60 
61         /// @brief  Resolves get_image_height(image).
62         ///         Adds the appropriate sequence of code before the given call instruction
63         /// @param  CI The call instruction.
64         /// @return A value representing the image height
65         llvm::Value* getImageHeight(llvm::CallInst& CI);
66 
67         /// @brief  Resolves get_image_width(image).
68         ///         Adds the appropriate sequence of code before the given call instruction
69         /// @param  CI The call instruction.
70         /// @return A value representing the image width
71         llvm::Value* getImageWidth(llvm::CallInst& CI);
72 
73         /// @brief  Resolves get_image_depth(image).
74         ///         Adds the appropriate sequence of code before the given call instruction
75         /// @param  CI The call instruction.
76         /// @return A value representing the image depth
77         llvm::Value* getImageDepth(llvm::CallInst& CI);
78 
79         /// @brief  Resolves get_image_num_mip_levels(image).
80         ///         Adds the appropriate sequence of code before the given call instruction
81         /// @param  CI The call instruction.
82         /// @return A value representing the image num mip levels
83         llvm::Value* getImageNumMipLevels(llvm::CallInst& CI);
84 
85         /// @brief  Resolves get_image_channel_data_type(image).
86         ///         Adds the approtiate sequence of code before the given call isntruction
87         /// @param  CI The call instruction.
88         /// @return A value representing the image channel data type
89         llvm::Value* getImageChannelDataType(llvm::CallInst& CI);
90 
91         /// @brief  Resolves get_image_channel_order(image).
92         ///         Adds the approtiate sequence of code before the given call isntruction
93         /// @param  CI The call instruction.
94         /// @return A value representing the image order
95         llvm::Value* getImageChannelOrder(llvm::CallInst& CI);
96 
97         /// @brief  Resolves get_image_array_size(image_array).
98         ///         Adds the approtiate sequence of code before the given call isntruction
99         /// @param  CI The call instruction.
100         /// @return A value representing the image array size
101         llvm::Value* getImageArraySize(llvm::CallInst& CI);
102 
103         /// @brief  Resolves get_image_num_samples(image).
104         ///         Adds the approtiate sequence of code before the given call instruction
105         /// @param  CI The call instruction.
106         /// @return A value representing the image number of samples.
107         llvm::Value* getImageNumSamples(llvm::CallInst& CI);
108 
109         /// @brief  Resolves the pseudo-builtin get_sampler_address_mode(sampler_t).
110         ///         Adds the approtiate sequence of code before the given call isntruction
111         /// @param  CI The call instruction.
112         /// @return A value representing the sampler address mode, which may either be
113         ///         a ConstantInt or an Argument
114         llvm::Value* getSamplerAddressMode(llvm::CallInst& CI);
115 
116         /// @brief  Resolves the pseudo-builtin get_sampler_normalized_coords(sampler_t).
117         ///         Adds the approtiate sequence of code before the given call isntruction
118         /// @param  CI The call instruction.
119         /// @return A value representing the sampler normalized coords mode, which may either be
120         ///         a ConstantInt or an Argument
121         llvm::Value* getSamplerNormalizedCoords(llvm::CallInst& CI);
122 
123         /// @brief  Resolves the pseudo-builtin get_sampler_snap_wa_reqd(sampler_t).
124         ///         Adds the approtiate sequence of code before the given call isntruction
125         /// @param  CI The call instruction.
126         /// @return A value representing whether the snap workaround is required for the sample
127         ///         which may either be a ConstantInt or an Argument
128         llvm::Value* getSamplerSnapWARequired(llvm::CallInst& CI);
129 
130         /// @brief  Returns the appropriate implicit argument of the function
131         ///         containing the given call instruction, based on the given implicit image
132         ///         argument type
133         /// @param  CI       The call instruction.
134         /// @param  argType  The implicit image argument type.
135         /// @return The function argument associated with the given implicit image arg type
136         llvm::Argument* getImplicitImageArg(llvm::CallInst& CI, ImplicitArg::ArgType argType);
137 
138         /// @brief  The implicit arguments of the current function
139         ImplicitArgs m_implicitArgs;
140 
141         /// @brief  Indicates if the pass changed the processed function
142         bool m_changed;
143     };
144 
145 } // namespace IGC
146