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
|
/*========================== begin_copyright_notice ============================
Copyright (C) 2021 Intel Corporation
SPDX-License-Identifier: MIT
============================= end_copyright_notice ===========================*/
#include "spirv-tools/libspirv.h"
#include <llvm/Support/Error.h>
#include <unordered_set>
#include <unordered_map>
#include <vector>
#include "VLD.hpp"
#pragma once
namespace IGC {
namespace VLD {
using ProgramStreamType = std::vector<uint32_t>;
// Splits SPIR-V module that contains ESIMD and SPMD parts into separate
// SPIR-V modules.
// Returns a pair of binaries: first is SPMD module, second is ESIMD module.
llvm::Expected<std::pair<ProgramStreamType, ProgramStreamType>>
SplitSPMDAndESIMD(const char *spvBuffer, uint32_t spvBufferSizeInBytes);
// Detects the type of the SPIR-V module, e.g. SPMD, ESIMD, SPMD+ESIMD
llvm::Expected<SPIRVTypeEnum> DetectSPIRVType(const char* spv_buffer,
uint32_t spv_buffer_size_in_bytes);
// Class used to split SPMD and ESIMD parts of input SPIR-V module.
class SpvSplitter {
public:
// Splits SPIR-V module that contains ESIMD and SPMD parts into separate
// SPIR-V modules.
// Returns a pair of binaries: first is SPMD module, second is ESIMD module.
llvm::Expected<std::pair<ProgramStreamType, ProgramStreamType>>
Split(const char *spv_buffer, uint32_t spv_buffer_size_in_bytes);
// Detects the type of the SPIR-V module, e.g. SPMD, ESIMD, SPMD+ESIMD
llvm::Expected<SPIRVTypeEnum>
Detect(const char *spv_buffer, uint32_t spv_buffer_size_in_bytes);
const std::string &GetErrorMessage() const;
bool HasError() const;
void Reset();
// Callbacks used by SPIR-V Tools parser.
static spv_result_t
HandleInstructionCallback(void *user_data,
const spv_parsed_instruction_t *parsed_instruction);
static spv_result_t HandleHeaderCallback(void *user_data,
spv_endianness_t endian,
uint32_t magic, uint32_t version,
uint32_t generator,
uint32_t id_bound, uint32_t schema);
const ProgramStreamType &spmd_program() const { return spmd_program_; }
const ProgramStreamType &esimd_program() const { return esimd_program_; }
private:
spv_result_t HandleHeader(spv_endianness_t endian, uint32_t magic,
uint32_t version, uint32_t generator,
uint32_t id_bound, uint32_t schema);
spv_result_t
HandleInstruction(const spv_parsed_instruction_t *parsed_instruction);
spv_result_t
HandleDecorate(const spv_parsed_instruction_t *parsed_instruction);
spv_result_t
HandleGroupDecorate(const spv_parsed_instruction_t *parsed_instruction);
spv_result_t
HandleFunctionStart(const spv_parsed_instruction_t *parsed_instruction);
spv_result_t
HandleFunctionParameter(const spv_parsed_instruction_t *parsed_instruction);
spv_result_t
HandleFunctionEnd(const spv_parsed_instruction_t *parsed_instruction);
spv_result_t
HandleEntryPoint(const spv_parsed_instruction_t *parsed_instruction);
void AddInstToProgram(const spv_parsed_instruction_t *parsed_instruction,
ProgramStreamType &program);
llvm::Expected<spv_result_t> ParseSPIRV(const char* spv_buffer, uint32_t spv_buffer_size_in_bytes);
// Returns current SPIR-V Module type. Must be called after ParseSPIRV
SPIRVTypeEnum GetCurrentSPIRVType();
// When this flag is set to true, instructions will not be added to
// spmd_program_ and esimd_program_ buffers.
bool only_detect_ = false;
ProgramStreamType spmd_program_;
ProgramStreamType esimd_program_;
std::unordered_set<uint32_t> esimd_decorated_ids_;
std::unordered_set<uint32_t> entry_points_;
std::unordered_map<uint32_t, ProgramStreamType> esimd_function_declarations_;
std::unordered_set<uint32_t> esimd_functions_to_declare_;
bool is_inside_spmd_function_ = false;
bool is_inside_esimd_function_ = false;
bool has_spmd_functions_ = false;
bool has_esimd_functions_ = false;
int cur_esimd_function_id_ = -1;
std::string error_message_;
};
} // namespace VLD
} // namespace IGC
|