SPIRV-Tools/source/val/BasicBlock.h

160 lines
5.5 KiB
C
Raw Normal View History

// 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_BASICBLOCK_H_
#define LIBSPIRV_VAL_BASICBLOCK_H_
#include "spirv/1.1/spirv.h"
#include <cstdint>
#include <vector>
namespace libspirv {
// This class represents a basic block in a SPIR-V module
class BasicBlock {
public:
/// Constructor for a BasicBlock
///
/// @param[in] id The ID of the basic block
explicit BasicBlock(uint32_t id);
/// Returns the id of the BasicBlock
uint32_t get_id() const { return id_; }
/// Returns the predecessors of the BasicBlock
const std::vector<BasicBlock*>* get_predecessors() const {
return &predecessors_;
}
/// Returns the predecessors of the BasicBlock
std::vector<BasicBlock*>* get_predecessors() { return &predecessors_; }
/// Returns the successors of the BasicBlock
const std::vector<BasicBlock*>* get_successors() const {
return &successors_;
}
/// Returns the successors of the BasicBlock
std::vector<BasicBlock*>* get_successors() { return &successors_; }
/// Returns true if the block should be reachable in the CFG
bool is_reachable() const { return reachable_; }
void set_reachability(bool reachability) { reachable_ = reachability; }
/// Sets the immedate dominator of this basic block
///
/// @param[in] dom_block The dominator block
void SetImmediateDominator(BasicBlock* dom_block);
/// Returns the immedate dominator of this basic block
BasicBlock* GetImmediateDominator();
/// Returns the immedate dominator of this basic block
const BasicBlock* GetImmediateDominator() const;
/// Ends the block without a successor
void RegisterBranchInstruction(SpvOp branch_instruction);
/// Adds @p next BasicBlocks as successors of this BasicBlock
void RegisterSuccessors(std::vector<BasicBlock*> next = {});
/// Returns true if the id of the BasicBlock matches
bool operator==(const BasicBlock& other) const { return other.id_ == id_; }
/// Returns true if the id of the BasicBlock matches
bool operator==(const uint32_t& id) const { return id == id_; }
/// @brief A BasicBlock dominator iterator class
///
/// This iterator will iterate over the dominators of the block
class DominatorIterator
: public std::iterator<std::forward_iterator_tag, BasicBlock*> {
public:
/// @brief Constructs the end of dominator iterator
///
/// This will create an iterator which will represent the element
/// before the root node of the dominator tree
DominatorIterator();
/// @brief Constructs an iterator for the given block which points to
/// @p block
///
/// @param block The block which is referenced by the iterator
explicit DominatorIterator(const BasicBlock* block);
/// @brief Advances the iterator
DominatorIterator& operator++();
/// @brief Returns the current element
const BasicBlock*& operator*();
friend bool operator==(const DominatorIterator& lhs,
const DominatorIterator& rhs);
private:
const BasicBlock* current_;
};
/// Returns an iterator which points to the current block
const DominatorIterator dom_begin() const;
DominatorIterator dom_begin();
/// Returns an iterator which points to one element past the first block
const DominatorIterator dom_end() const;
DominatorIterator dom_end();
private:
/// Id of the BasicBlock
const uint32_t id_;
/// Pointer to the immediate dominator of the BasicBlock
BasicBlock* immediate_dominator_;
/// The set of predecessors of the BasicBlock
std::vector<BasicBlock*> predecessors_;
/// The set of successors of the BasicBlock
std::vector<BasicBlock*> successors_;
bool reachable_;
};
/// @brief Returns true if the iterators point to the same element or if both
/// iterators point to the @p dom_end block
bool operator==(const BasicBlock::DominatorIterator& lhs,
const BasicBlock::DominatorIterator& rhs);
/// @brief Returns true if the iterators point to different elements and they
/// do not both point to the @p dom_end block
bool operator!=(const BasicBlock::DominatorIterator& lhs,
const BasicBlock::DominatorIterator& rhs);
} /// namespace libspirv
#endif /// LIBSPIRV_VAL_BASICBLOCK_H_