mirror of
https://github.com/KhronosGroup/SPIRV-Tools
synced 2024-10-19 11:30:15 +00:00
257 lines
9.3 KiB
C++
257 lines
9.3 KiB
C++
// Copyright (c) 2015-2016 The Khronos Group Inc.
|
|
//
|
|
// Permission is hereby granted, free of charge, to any person obtaining a
|
|
// copy of this software and/or associated documentation files (the
|
|
// "Materials"), to deal in the Materials without restriction, including
|
|
// without limitation the rights to use, copy, modify, merge, publish,
|
|
// distribute, sublicense, and/or sell copies of the Materials, and to
|
|
// permit persons to whom the Materials are furnished to do so, subject to
|
|
// the following conditions:
|
|
//
|
|
// The above copyright notice and this permission notice shall be included
|
|
// in all copies or substantial portions of the Materials.
|
|
//
|
|
// MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS
|
|
// KHRONOS STANDARDS. THE UNMODIFIED, NORMATIVE VERSIONS OF KHRONOS
|
|
// SPECIFICATIONS AND HEADER INFORMATION ARE LOCATED AT
|
|
// https://www.khronos.org/registry/
|
|
//
|
|
// THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
|
// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
|
// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
|
// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
|
// MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
|
|
|
|
#ifndef LIBSPIRV_VAL_FUNCTION_H_
|
|
#define LIBSPIRV_VAL_FUNCTION_H_
|
|
|
|
#include <list>
|
|
#include <unordered_map>
|
|
#include <unordered_set>
|
|
#include <vector>
|
|
|
|
#include "spirv-tools/libspirv.h"
|
|
#include "spirv/1.1/spirv.h"
|
|
#include "val/BasicBlock.h"
|
|
|
|
namespace libspirv {
|
|
|
|
enum class FunctionDecl {
|
|
kFunctionDeclUnknown, /// < Unknown function declaration
|
|
kFunctionDeclDeclaration, /// < Function declaration
|
|
kFunctionDeclDefinition /// < Function definition
|
|
};
|
|
|
|
class Construct;
|
|
class ValidationState_t;
|
|
|
|
/// This class manages all function declaration and definitions in a module. It
|
|
/// handles the state and id information while parsing a function in the SPIR-V
|
|
/// binary.
|
|
class Function {
|
|
public:
|
|
Function(uint32_t id, uint32_t result_type_id,
|
|
SpvFunctionControlMask function_control, uint32_t function_type_id,
|
|
ValidationState_t& module);
|
|
|
|
/// Registers a function parameter in the current function
|
|
/// @return Returns SPV_SUCCESS if the call was successful
|
|
spv_result_t RegisterFunctionParameter(uint32_t id, uint32_t type_id);
|
|
|
|
/// Sets the declaration type of the current function
|
|
/// @return Returns SPV_SUCCESS if the call was successful
|
|
spv_result_t RegisterSetFunctionDeclType(FunctionDecl type);
|
|
|
|
/// Registers a block in the current function. Subsequent block instructions
|
|
/// will target this block
|
|
/// @param id The ID of the label of the block
|
|
/// @return Returns SPV_SUCCESS if the call was successful
|
|
spv_result_t RegisterBlock(uint32_t id, bool is_definition = true);
|
|
|
|
/// Registers a variable in the current block
|
|
///
|
|
/// @param[in] type_id The type ID of the varaible
|
|
/// @param[in] id The ID of the varaible
|
|
/// @param[in] storage The storage of the variable
|
|
/// @param[in] init_id The initializer ID of the variable
|
|
///
|
|
/// @return Returns SPV_SUCCESS if the call was successful
|
|
spv_result_t RegisterBlockVariable(uint32_t type_id, uint32_t id,
|
|
SpvStorageClass storage, uint32_t init_id);
|
|
|
|
/// Registers a loop merge construct in the function
|
|
///
|
|
/// @param[in] merge_id The merge block ID of the loop
|
|
/// @param[in] continue_id The continue block ID of the loop
|
|
///
|
|
/// @return Returns SPV_SUCCESS if the call was successful
|
|
spv_result_t RegisterLoopMerge(uint32_t merge_id, uint32_t continue_id);
|
|
|
|
/// Registers a selection merge construct in the function
|
|
/// @return Returns SPV_SUCCESS if the call was successful
|
|
spv_result_t RegisterSelectionMerge(uint32_t merge_id);
|
|
|
|
/// Registers the end of the block
|
|
///
|
|
/// @param[in] successors_list A list of ids to the block's successors
|
|
/// @param[in] branch_instruction the branch instruction that ended the block
|
|
void RegisterBlockEnd(std::vector<uint32_t> successors_list,
|
|
SpvOp branch_instruction);
|
|
|
|
/// Registers the end of the function. This is idempotent.
|
|
void RegisterFunctionEnd();
|
|
|
|
/// Returns true if the \p id block is the first block of this function
|
|
bool IsFirstBlock(uint32_t id) const;
|
|
|
|
/// Returns true if the \p merge_block_id is a BlockType of \p type
|
|
bool IsBlockType(uint32_t merge_block_id, BlockType type) const;
|
|
|
|
/// Returns a pair consisting of the BasicBlock with \p id and a bool
|
|
/// which is true if the block has been defined, and false if it is
|
|
/// declared but not defined. This function will return nullptr if the
|
|
/// \p id was not declared and not defined at the current point in the binary
|
|
std::pair<const BasicBlock*, bool> GetBlock(uint32_t id) const;
|
|
std::pair<BasicBlock*, bool> GetBlock(uint32_t id);
|
|
|
|
/// Returns the first block of the current function
|
|
const BasicBlock* first_block() const;
|
|
|
|
/// Returns the first block of the current function
|
|
BasicBlock* first_block();
|
|
|
|
/// Returns a vector of all the blocks in the function
|
|
const std::vector<BasicBlock*>& ordered_blocks() const;
|
|
|
|
/// Returns a vector of all the blocks in the function
|
|
std::vector<BasicBlock*>& ordered_blocks();
|
|
|
|
/// Returns a list of all the cfg constructs in the function
|
|
const std::list<Construct>& constructs() const;
|
|
|
|
/// Returns a list of all the cfg constructs in the function
|
|
std::list<Construct>& constructs();
|
|
|
|
/// Returns the number of blocks in the current function being parsed
|
|
size_t block_count() const;
|
|
|
|
/// Returns the id of the funciton
|
|
uint32_t id() const { return id_; }
|
|
|
|
/// Returns the number of blocks in the current function being parsed
|
|
size_t undefined_block_count() const;
|
|
const std::unordered_set<uint32_t>& undefined_blocks() const {
|
|
return undefined_blocks_;
|
|
}
|
|
|
|
/// Returns the block that is currently being parsed in the binary
|
|
BasicBlock* current_block();
|
|
|
|
/// Returns the block that is currently being parsed in the binary
|
|
const BasicBlock* current_block() const;
|
|
|
|
/// Returns the pseudo exit block
|
|
BasicBlock* pseudo_entry_block();
|
|
|
|
/// Returns the pseudo exit block
|
|
const BasicBlock* pseudo_entry_block() const;
|
|
|
|
/// Returns the pseudo exit block
|
|
BasicBlock* pseudo_exit_block();
|
|
|
|
/// Returns the pseudo exit block
|
|
const BasicBlock* pseudo_exit_block() const;
|
|
|
|
/// Returns a vector with just the pseudo entry block.
|
|
/// This serves as the predecessors of each source node in the CFG when
|
|
/// computing dominators.
|
|
const std::vector<BasicBlock*>* pseudo_entry_blocks() const {
|
|
return &pseudo_entry_blocks_;
|
|
}
|
|
|
|
/// Returns a vector with just the pseudo exit block.
|
|
/// This serves as the successors of each sink node in the CFG when computing
|
|
/// dominators.
|
|
const std::vector<BasicBlock*>* pseudo_exit_blocks() const {
|
|
return &pseudo_exit_blocks_;
|
|
}
|
|
|
|
/// Prints a GraphViz digraph of the CFG of the current funciton
|
|
void PrintDotGraph() const;
|
|
|
|
/// Prints a directed graph of the CFG of the current funciton
|
|
void PrintBlocks() const;
|
|
|
|
private:
|
|
/// Parent module
|
|
ValidationState_t& module_;
|
|
|
|
/// The result id of the OpLabel that defined this block
|
|
uint32_t id_;
|
|
|
|
/// The type of the function
|
|
uint32_t function_type_id_;
|
|
|
|
/// The type of the return value
|
|
uint32_t result_type_id_;
|
|
|
|
/// The control fo the funciton
|
|
SpvFunctionControlMask function_control_;
|
|
|
|
/// The type of declaration of each function
|
|
FunctionDecl declaration_type_;
|
|
|
|
// Have we finished parsing this function?
|
|
bool end_has_been_registered_;
|
|
|
|
/// The blocks in the function mapped by block ID
|
|
std::unordered_map<uint32_t, BasicBlock> blocks_;
|
|
|
|
/// A list of blocks in the order they appeared in the binary
|
|
std::vector<BasicBlock*> ordered_blocks_;
|
|
|
|
/// Blocks which are forward referenced by blocks but not defined
|
|
std::unordered_set<uint32_t> undefined_blocks_;
|
|
|
|
/// The block that is currently being parsed
|
|
BasicBlock* current_block_;
|
|
|
|
/// A pseudo entry block that, for the purposes of dominance analysis,
|
|
/// is considered the predecessor to any ordinary block without predecessors.
|
|
/// After the function end has been registered, its successor list consists
|
|
/// of all ordinary blocks without predecessors. It has no predecessors.
|
|
/// It does not appear in the predecessor or successor list of any
|
|
/// ordinary block.
|
|
/// It has Id 0.
|
|
BasicBlock pseudo_entry_block_;
|
|
|
|
/// A pseudo exit block that, for the purposes of dominance analysis,
|
|
/// is considered the successor to any ordinary block without successors.
|
|
/// After the function end has been registered, its predecessor list consists
|
|
/// of all ordinary blocks without successors. It has no successors.
|
|
/// It does not appear in the predecessor or successor list of any
|
|
/// ordinary block.
|
|
BasicBlock pseudo_exit_block_;
|
|
|
|
// A vector containing pseudo_entry_block_.
|
|
const std::vector<BasicBlock*> pseudo_entry_blocks_;
|
|
|
|
// A vector containing pseudo_exit_block_.
|
|
const std::vector<BasicBlock*> pseudo_exit_blocks_;
|
|
|
|
/// The constructs that are available in this function
|
|
std::list<Construct> cfg_constructs_;
|
|
|
|
/// The variable IDs of the functions
|
|
std::vector<uint32_t> variable_ids_;
|
|
|
|
/// The function parameter ids of the functions
|
|
std::vector<uint32_t> parameter_ids_;
|
|
};
|
|
|
|
} /// namespace libspirv
|
|
|
|
#endif /// LIBSPIRV_VAL_FUNCTION_H_
|