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
|
/*========================== begin_copyright_notice ============================
Copyright (C) 2017-2021 Intel Corporation
SPDX-License-Identifier: MIT
============================= end_copyright_notice ===========================*/
#pragma once
#include "Compiler/CodeGenContextWrapper.hpp"
#include "Compiler/MetaDataUtilsWrapper.h"
#include <llvm/IR/DataLayout.h>
#include "Compiler/Optimizer/OCLBIUtils.h"
#include "common/LLVMWarningsPush.hpp"
#include <llvm/Pass.h>
#include <llvm/IR/InstVisitor.h>
#include "common/LLVMWarningsPop.hpp"
#include "IGC/common/Types.hpp"
namespace IGC
{
/// @brief SubGroupFuncsResolution pass used for resolving OpenCL Sub Group functions.
class SubGroupFuncsResolution : public llvm::FunctionPass, public llvm::InstVisitor<SubGroupFuncsResolution, void>
{
public:
// Pass identification, replacement for typeid
static char ID;
/// @brief Constructor
SubGroupFuncsResolution();
/// @brief Destructor
~SubGroupFuncsResolution() {}
/// @brief Provides name of pass
virtual llvm::StringRef getPassName() const override
{
return "SubGroupFuncsResolution";
}
void getAnalysisUsage(llvm::AnalysisUsage& AU) const override
{
AU.addRequired<CodeGenContextWrapper>();
AU.addRequired<MetaDataUtilsWrapper>();
}
/// @brief Main entry point.
/// Finds all OpenCL Sub Group function calls and resolve them into an llvm sequence
/// @param F The destination function.
virtual bool runOnFunction(llvm::Function& F) override;
/// @brief Call instructions visitor.
/// Checks for OpenCL Sub Group functions and resolves them into appropriate sequence of code
/// @param CI The call instruction.
void visitCallInst(llvm::CallInst& CI);
void BTIHelper(llvm::CallInst& CI);
void mediaBlockRead(llvm::CallInst& CI);
void mediaBlockWrite(llvm::CallInst& CI);
void simdBlockRead(llvm::CallInst& CI);
void simdBlockWrite(llvm::CallInst& CI);
void pushMediaBlockArgs(llvm::SmallVector<llvm::Value*, 5> & args, llvm::CallInst& CI);
void CheckMediaBlockInstError(llvm::GenIntrinsicInst* inst, bool isRead);
void subGroupArithmetic(llvm::CallInst& CI, WaveOps op, GroupOpType groupType);
void subGroup2DBlockRead(llvm::CallInst& CI, llvm::StringRef funcName);
static const llvm::StringRef SUB_GROUP_BARRIER;
static const llvm::StringRef GET_MAX_SUB_GROUP_SIZE;
static const llvm::StringRef GET_SUB_GROUP_LOCAL_ID;
static const llvm::StringRef SUB_GROUP_SHUFFLE;
static const llvm::StringRef SUB_GROUP_SHUFFLE_US;
static const llvm::StringRef SUB_GROUP_SHUFFLE_F;
static const llvm::StringRef SUB_GROUP_SHUFFLE_H;
static const llvm::StringRef SUB_GROUP_SHUFFLE_C;
static const llvm::StringRef SUB_GROUP_SHUFFLE_B;
static const llvm::StringRef SUB_GROUP_SHUFFLE_DF;
static const llvm::StringRef SUB_GROUP_SHUFFLE_DOWN;
static const llvm::StringRef SUB_GROUP_SHUFFLE_DOWN_US;
static const llvm::StringRef SUB_GROUP_SHUFFLE_DOWN_UC;
static const llvm::StringRef SIMD_BLOCK_READ_1_GBL;
static const llvm::StringRef SIMD_BLOCK_READ_2_GBL;
static const llvm::StringRef SIMD_BLOCK_READ_4_GBL;
static const llvm::StringRef SIMD_BLOCK_READ_8_GBL;
static const llvm::StringRef SIMD_BLOCK_READ_1_GBL_H;
static const llvm::StringRef SIMD_BLOCK_READ_2_GBL_H;
static const llvm::StringRef SIMD_BLOCK_READ_4_GBL_H;
static const llvm::StringRef SIMD_BLOCK_READ_8_GBL_H;
static const llvm::StringRef SIMD_BLOCK_READ_16_GBL_H;
static const llvm::StringRef SIMD_BLOCK_READ_1_GBL_B;
static const llvm::StringRef SIMD_BLOCK_READ_2_GBL_B;
static const llvm::StringRef SIMD_BLOCK_READ_4_GBL_B;
static const llvm::StringRef SIMD_BLOCK_READ_8_GBL_B;
static const llvm::StringRef SIMD_BLOCK_READ_16_GBL_B;
static const llvm::StringRef SIMD_BLOCK_READ_1_GBL_L;
static const llvm::StringRef SIMD_BLOCK_READ_2_GBL_L;
static const llvm::StringRef SIMD_BLOCK_READ_4_GBL_L;
static const llvm::StringRef SIMD_BLOCK_READ_8_GBL_L;
static const llvm::StringRef SIMD_BLOCK_WRITE_1_GBL;
static const llvm::StringRef SIMD_BLOCK_WRITE_2_GBL;
static const llvm::StringRef SIMD_BLOCK_WRITE_4_GBL;
static const llvm::StringRef SIMD_BLOCK_WRITE_8_GBL;
static const llvm::StringRef SIMD_BLOCK_WRITE_1_GBL_H;
static const llvm::StringRef SIMD_BLOCK_WRITE_2_GBL_H;
static const llvm::StringRef SIMD_BLOCK_WRITE_4_GBL_H;
static const llvm::StringRef SIMD_BLOCK_WRITE_8_GBL_H;
static const llvm::StringRef SIMD_BLOCK_WRITE_16_GBL_H;
static const llvm::StringRef SIMD_BLOCK_WRITE_1_GBL_B;
static const llvm::StringRef SIMD_BLOCK_WRITE_2_GBL_B;
static const llvm::StringRef SIMD_BLOCK_WRITE_4_GBL_B;
static const llvm::StringRef SIMD_BLOCK_WRITE_8_GBL_B;
static const llvm::StringRef SIMD_BLOCK_WRITE_16_GBL_B;
static const llvm::StringRef SIMD_BLOCK_WRITE_1_GBL_L;
static const llvm::StringRef SIMD_BLOCK_WRITE_2_GBL_L;
static const llvm::StringRef SIMD_BLOCK_WRITE_4_GBL_L;
static const llvm::StringRef SIMD_BLOCK_WRITE_8_GBL_L;
static const llvm::StringRef SIMD_BLOCK_READ_1_LCL;
static const llvm::StringRef SIMD_BLOCK_READ_2_LCL;
static const llvm::StringRef SIMD_BLOCK_READ_4_LCL;
static const llvm::StringRef SIMD_BLOCK_READ_8_LCL;
static const llvm::StringRef SIMD_BLOCK_READ_1_LCL_H;
static const llvm::StringRef SIMD_BLOCK_READ_2_LCL_H;
static const llvm::StringRef SIMD_BLOCK_READ_4_LCL_H;
static const llvm::StringRef SIMD_BLOCK_READ_8_LCL_H;
static const llvm::StringRef SIMD_BLOCK_READ_16_LCL_H;
static const llvm::StringRef SIMD_BLOCK_READ_1_LCL_B;
static const llvm::StringRef SIMD_BLOCK_READ_2_LCL_B;
static const llvm::StringRef SIMD_BLOCK_READ_4_LCL_B;
static const llvm::StringRef SIMD_BLOCK_READ_8_LCL_B;
static const llvm::StringRef SIMD_BLOCK_READ_16_LCL_B;
static const llvm::StringRef SIMD_BLOCK_READ_1_LCL_L;
static const llvm::StringRef SIMD_BLOCK_READ_2_LCL_L;
static const llvm::StringRef SIMD_BLOCK_READ_4_LCL_L;
static const llvm::StringRef SIMD_BLOCK_READ_8_LCL_L;
static const llvm::StringRef SIMD_BLOCK_WRITE_1_LCL;
static const llvm::StringRef SIMD_BLOCK_WRITE_2_LCL;
static const llvm::StringRef SIMD_BLOCK_WRITE_4_LCL;
static const llvm::StringRef SIMD_BLOCK_WRITE_8_LCL;
static const llvm::StringRef SIMD_BLOCK_WRITE_1_LCL_H;
static const llvm::StringRef SIMD_BLOCK_WRITE_2_LCL_H;
static const llvm::StringRef SIMD_BLOCK_WRITE_4_LCL_H;
static const llvm::StringRef SIMD_BLOCK_WRITE_8_LCL_H;
static const llvm::StringRef SIMD_BLOCK_WRITE_16_LCL_H;
static const llvm::StringRef SIMD_BLOCK_WRITE_1_LCL_B;
static const llvm::StringRef SIMD_BLOCK_WRITE_2_LCL_B;
static const llvm::StringRef SIMD_BLOCK_WRITE_4_LCL_B;
static const llvm::StringRef SIMD_BLOCK_WRITE_8_LCL_B;
static const llvm::StringRef SIMD_BLOCK_WRITE_16_LCL_B;
static const llvm::StringRef SIMD_BLOCK_WRITE_1_LCL_L;
static const llvm::StringRef SIMD_BLOCK_WRITE_2_LCL_L;
static const llvm::StringRef SIMD_BLOCK_WRITE_4_LCL_L;
static const llvm::StringRef SIMD_BLOCK_WRITE_8_LCL_L;
static const llvm::StringRef SIMD_MEDIA_BLOCK_READ_1;
static const llvm::StringRef SIMD_MEDIA_BLOCK_READ_2;
static const llvm::StringRef SIMD_MEDIA_BLOCK_READ_4;
static const llvm::StringRef SIMD_MEDIA_BLOCK_READ_8;
static const llvm::StringRef SIMD_MEDIA_BLOCK_READ_1_H;
static const llvm::StringRef SIMD_MEDIA_BLOCK_READ_2_H;
static const llvm::StringRef SIMD_MEDIA_BLOCK_READ_4_H;
static const llvm::StringRef SIMD_MEDIA_BLOCK_READ_8_H;
static const llvm::StringRef SIMD_MEDIA_BLOCK_READ_16_H;
static const llvm::StringRef SIMD_MEDIA_BLOCK_READ_1_B;
static const llvm::StringRef SIMD_MEDIA_BLOCK_READ_2_B;
static const llvm::StringRef SIMD_MEDIA_BLOCK_READ_4_B;
static const llvm::StringRef SIMD_MEDIA_BLOCK_READ_8_B;
static const llvm::StringRef SIMD_MEDIA_BLOCK_READ_16_B;
static const llvm::StringRef SIMD_MEDIA_BLOCK_READ_1_L;
static const llvm::StringRef SIMD_MEDIA_BLOCK_READ_2_L;
static const llvm::StringRef SIMD_MEDIA_BLOCK_READ_4_L;
static const llvm::StringRef SIMD_MEDIA_BLOCK_READ_8_L;
static const llvm::StringRef SIMD_MEDIA_BLOCK_WRITE_1;
static const llvm::StringRef SIMD_MEDIA_BLOCK_WRITE_2;
static const llvm::StringRef SIMD_MEDIA_BLOCK_WRITE_4;
static const llvm::StringRef SIMD_MEDIA_BLOCK_WRITE_8;
static const llvm::StringRef SIMD_MEDIA_BLOCK_WRITE_1_H;
static const llvm::StringRef SIMD_MEDIA_BLOCK_WRITE_2_H;
static const llvm::StringRef SIMD_MEDIA_BLOCK_WRITE_4_H;
static const llvm::StringRef SIMD_MEDIA_BLOCK_WRITE_8_H;
static const llvm::StringRef SIMD_MEDIA_BLOCK_WRITE_16_H;
static const llvm::StringRef SIMD_MEDIA_BLOCK_WRITE_1_L;
static const llvm::StringRef SIMD_MEDIA_BLOCK_WRITE_2_L;
static const llvm::StringRef SIMD_MEDIA_BLOCK_WRITE_4_L;
static const llvm::StringRef SIMD_MEDIA_BLOCK_WRITE_8_L;
static const llvm::StringRef SIMD_MEDIA_BLOCK_WRITE_1_B;
static const llvm::StringRef SIMD_MEDIA_BLOCK_WRITE_2_B;
static const llvm::StringRef SIMD_MEDIA_BLOCK_WRITE_4_B;
static const llvm::StringRef SIMD_MEDIA_BLOCK_WRITE_8_B;
static const llvm::StringRef SIMD_MEDIA_BLOCK_WRITE_16_B;
static const llvm::StringRef MEDIA_BLOCK_READ;
static const llvm::StringRef MEDIA_BLOCK_WRITE;
static const llvm::StringRef MEDIA_BLOCK_RECTANGLE_READ;
static const llvm::StringRef GET_IMAGE_BTI;
static const llvm::StringRef SUB_GROUP_REDUCE;
static const llvm::StringRef SUB_GROUP_SCAN;
static const llvm::StringRef SUB_GROUP_CLUSTERED_REDUCE;
static const llvm::StringRef SUBGROUP_BLOCK_READ;
private:
/// @brief Container for instructions to be deleted after visiting a function.
llvm::SmallVector<llvm::Instruction*, 16> m_instsToDelete;
/// @brief - maps image and sampler kernel parameters to BTIs
CImagesBI::ParamMap m_argIndexMap;
// @brief - maps SPIR-V operation to vISA operation type
static const std::array<std::pair<std::string, WaveOps>, 13> m_spvOpToWaveOpMap;
/// @brief Indicates if the pass changed the processed function
bool m_changed;
CodeGenContext* m_pCtx;
/// @brief examine metadata for intel_reqd_sub_group_size
int32_t GetSIMDSize(llvm::Function* F);
/// @brief emits the given error message in SIMD32. Used on subgroup functions
// that aren't currently supported in SIMD32.
void CheckSIMDSize(llvm::Instruction& I, llvm::StringRef msg);
// @brief parse function name to extract spir-v operation type
// and map it to vISA operation type
WaveOps GetWaveOp(llvm::StringRef funcName);
};
} // namespace IGC
|