Fix several violations of the style guide

This commit is contained in:
Umar Arshad 2016-06-24 23:45:25 -04:00 committed by David Neto
parent 3df8f7cebd
commit 886dd352d5
15 changed files with 252 additions and 260 deletions

View File

@ -33,8 +33,8 @@ using std::vector;
namespace libspirv { namespace libspirv {
BasicBlock::BasicBlock(uint32_t id) BasicBlock::BasicBlock(uint32_t label_id)
: id_(id), : id_(label_id),
immediate_dominator_(nullptr), immediate_dominator_(nullptr),
immediate_post_dominator_(nullptr), immediate_post_dominator_(nullptr),
predecessors_(), predecessors_(),
@ -50,16 +50,16 @@ void BasicBlock::SetImmediatePostDominator(BasicBlock* pdom_block) {
immediate_post_dominator_ = pdom_block; immediate_post_dominator_ = pdom_block;
} }
const BasicBlock* BasicBlock::GetImmediateDominator() const { const BasicBlock* BasicBlock::immediate_dominator() const {
return immediate_dominator_; return immediate_dominator_;
} }
const BasicBlock* BasicBlock::GetImmediatePostDominator() const { const BasicBlock* BasicBlock::immediate_post_dominator() const {
return immediate_post_dominator_; return immediate_post_dominator_;
} }
BasicBlock* BasicBlock::GetImmediateDominator() { return immediate_dominator_; } BasicBlock* BasicBlock::immediate_dominator() { return immediate_dominator_; }
BasicBlock* BasicBlock::GetImmediatePostDominator() { BasicBlock* BasicBlock::immediate_post_dominator() {
return immediate_post_dominator_; return immediate_post_dominator_;
} }
@ -102,12 +102,12 @@ BasicBlock::DominatorIterator& BasicBlock::DominatorIterator::operator++() {
const BasicBlock::DominatorIterator BasicBlock::dom_begin() const { const BasicBlock::DominatorIterator BasicBlock::dom_begin() const {
return DominatorIterator( return DominatorIterator(
this, [](const BasicBlock* b) { return b->GetImmediateDominator(); }); this, [](const BasicBlock* b) { return b->immediate_dominator(); });
} }
BasicBlock::DominatorIterator BasicBlock::dom_begin() { BasicBlock::DominatorIterator BasicBlock::dom_begin() {
return DominatorIterator( return DominatorIterator(
this, [](const BasicBlock* b) { return b->GetImmediateDominator(); }); this, [](const BasicBlock* b) { return b->immediate_dominator(); });
} }
const BasicBlock::DominatorIterator BasicBlock::dom_end() const { const BasicBlock::DominatorIterator BasicBlock::dom_end() const {
@ -120,12 +120,12 @@ BasicBlock::DominatorIterator BasicBlock::dom_end() {
const BasicBlock::DominatorIterator BasicBlock::pdom_begin() const { const BasicBlock::DominatorIterator BasicBlock::pdom_begin() const {
return DominatorIterator( return DominatorIterator(
this, [](const BasicBlock* b) { return b->GetImmediatePostDominator(); }); this, [](const BasicBlock* b) { return b->immediate_post_dominator(); });
} }
BasicBlock::DominatorIterator BasicBlock::pdom_begin() { BasicBlock::DominatorIterator BasicBlock::pdom_begin() {
return DominatorIterator( return DominatorIterator(
this, [](const BasicBlock* b) { return b->GetImmediatePostDominator(); }); this, [](const BasicBlock* b) { return b->immediate_post_dominator(); });
} }
const BasicBlock::DominatorIterator BasicBlock::pdom_end() const { const BasicBlock::DominatorIterator BasicBlock::pdom_end() const {

View File

@ -57,26 +57,24 @@ class BasicBlock {
explicit BasicBlock(uint32_t id); explicit BasicBlock(uint32_t id);
/// Returns the id of the BasicBlock /// Returns the id of the BasicBlock
uint32_t get_id() const { return id_; } uint32_t id() const { return id_; }
/// Returns the predecessors of the BasicBlock /// Returns the predecessors of the BasicBlock
const std::vector<BasicBlock*>* get_predecessors() const { const std::vector<BasicBlock*>* predecessors() const {
return &predecessors_; return &predecessors_;
} }
/// Returns the predecessors of the BasicBlock /// Returns the predecessors of the BasicBlock
std::vector<BasicBlock*>* get_predecessors() { return &predecessors_; } std::vector<BasicBlock*>* predecessors() { return &predecessors_; }
/// Returns the successors of the BasicBlock /// Returns the successors of the BasicBlock
const std::vector<BasicBlock*>* get_successors() const { const std::vector<BasicBlock*>* successors() const { return &successors_; }
return &successors_;
}
/// Returns the successors of the BasicBlock /// Returns the successors of the BasicBlock
std::vector<BasicBlock*>* get_successors() { return &successors_; } std::vector<BasicBlock*>* successors() { return &successors_; }
/// Returns true if the block is reachable in the CFG /// Returns true if the block is reachable in the CFG
bool is_reachable() const { return reachable_; } bool reachable() const { return reachable_; }
/// Returns true if BasicBlock is of the given type /// Returns true if BasicBlock is of the given type
bool is_type(BlockType type) const { bool is_type(BlockType type) const {
@ -106,16 +104,16 @@ class BasicBlock {
void SetImmediatePostDominator(BasicBlock* pdom_block); void SetImmediatePostDominator(BasicBlock* pdom_block);
/// Returns the immedate dominator of this basic block /// Returns the immedate dominator of this basic block
BasicBlock* GetImmediateDominator(); BasicBlock* immediate_dominator();
/// Returns the immedate dominator of this basic block /// Returns the immedate dominator of this basic block
const BasicBlock* GetImmediateDominator() const; const BasicBlock* immediate_dominator() const;
/// Returns the immedate post dominator of this basic block /// Returns the immedate post dominator of this basic block
BasicBlock* GetImmediatePostDominator(); BasicBlock* immediate_post_dominator();
/// Returns the immedate post dominator of this basic block /// Returns the immedate post dominator of this basic block
const BasicBlock* GetImmediatePostDominator() const; const BasicBlock* immediate_post_dominator() const;
/// Ends the block without a successor /// Ends the block without a successor
void RegisterBranchInstruction(SpvOp branch_instruction); void RegisterBranchInstruction(SpvOp branch_instruction);
@ -135,7 +133,7 @@ class BasicBlock {
bool operator==(const BasicBlock& other) const { return other.id_ == id_; } bool operator==(const BasicBlock& other) const { return other.id_ == id_; }
/// Returns true if the id of the BasicBlock matches /// Returns true if the id of the BasicBlock matches
bool operator==(const uint32_t& id) const { return id == id_; } bool operator==(const uint32_t& other_id) const { return other_id == id_; }
/// @brief A BasicBlock dominator iterator class /// @brief A BasicBlock dominator iterator class
/// ///

View File

@ -31,19 +31,20 @@
namespace libspirv { namespace libspirv {
Construct::Construct(ConstructType type, BasicBlock* entry, Construct::Construct(ConstructType construct_type,
BasicBlock* exit, std::vector<Construct*> constructs) BasicBlock* entry, BasicBlock* exit,
: type_(type), std::vector<Construct*> constructs)
: type_(construct_type),
corresponding_constructs_(constructs), corresponding_constructs_(constructs),
entry_block_(entry), entry_block_(entry),
exit_block_(exit) {} exit_block_(exit) {}
ConstructType Construct::get_type() const { return type_; } ConstructType Construct::type() const { return type_; }
const std::vector<Construct*>& Construct::get_corresponding_constructs() const { const std::vector<Construct*>& Construct::corresponding_constructs() const {
return corresponding_constructs_; return corresponding_constructs_;
} }
std::vector<Construct*>& Construct::get_corresponding_constructs() { std::vector<Construct*>& Construct::corresponding_constructs() {
return corresponding_constructs_; return corresponding_constructs_;
} }
@ -64,13 +65,11 @@ void Construct::set_corresponding_constructs(
corresponding_constructs_ = constructs; corresponding_constructs_ = constructs;
} }
const BasicBlock* Construct::get_entry() const { return entry_block_; } const BasicBlock* Construct::entry_block() const { return entry_block_; }
BasicBlock* Construct::get_entry() { return entry_block_; } BasicBlock* Construct::entry_block() { return entry_block_; }
const BasicBlock* Construct::get_exit() const { return exit_block_; } const BasicBlock* Construct::exit_block() const { return exit_block_; }
BasicBlock* Construct::get_exit() { return exit_block_; } BasicBlock* Construct::exit_block() { return exit_block_; }
void Construct::set_exit(BasicBlock* exit_block) { void Construct::set_exit(BasicBlock* block) { exit_block_ = block; }
exit_block_ = exit_block;
}
} /// namespace libspirv } /// namespace libspirv

View File

@ -61,21 +61,21 @@ class Construct {
std::vector<Construct*> constructs = {}); std::vector<Construct*> constructs = {});
/// Returns the type of the construct /// Returns the type of the construct
ConstructType get_type() const; ConstructType type() const;
const std::vector<Construct*>& get_corresponding_constructs() const; const std::vector<Construct*>& corresponding_constructs() const;
std::vector<Construct*>& get_corresponding_constructs(); std::vector<Construct*>& corresponding_constructs();
void set_corresponding_constructs(std::vector<Construct*> constructs); void set_corresponding_constructs(std::vector<Construct*> constructs);
/// Returns the dominator block of the construct. /// Returns the dominator block of the construct.
/// ///
/// This is usually the header block or the first block of the construct. /// This is usually the header block or the first block of the construct.
const BasicBlock* get_entry() const; const BasicBlock* entry_block() const;
/// Returns the dominator block of the construct. /// Returns the dominator block of the construct.
/// ///
/// This is usually the header block or the first block of the construct. /// This is usually the header block or the first block of the construct.
BasicBlock* get_entry(); BasicBlock* entry_block();
/// Returns the exit block of the construct. /// Returns the exit block of the construct.
/// ///
@ -83,7 +83,7 @@ class Construct {
/// loop construct. For the case construct it is the block that branches to /// loop construct. For the case construct it is the block that branches to
/// the OpSwitch merge block or other case blocks. Otherwise it is the merge /// the OpSwitch merge block or other case blocks. Otherwise it is the merge
/// block of the corresponding header block /// block of the corresponding header block
const BasicBlock* get_exit() const; const BasicBlock* exit_block() const;
/// Returns the exit block of the construct. /// Returns the exit block of the construct.
/// ///
@ -91,7 +91,7 @@ class Construct {
/// loop construct. For the case construct it is the block that branches to /// loop construct. For the case construct it is the block that branches to
/// the OpSwitch merge block or other case blocks. Otherwise it is the merge /// the OpSwitch merge block or other case blocks. Otherwise it is the merge
/// block of the corresponding header block /// block of the corresponding header block
BasicBlock* get_exit(); BasicBlock* exit_block();
/// Sets the exit block for this construct. This is useful for continue /// Sets the exit block for this construct. This is useful for continue
/// constructs which do not know the back-edge block during construction /// constructs which do not know the back-edge block during construction

View File

@ -48,23 +48,23 @@ namespace {
void printDot(const BasicBlock& other, const ValidationState_t& module) { void printDot(const BasicBlock& other, const ValidationState_t& module) {
string block_string; string block_string;
if (other.get_successors()->empty()) { if (other.successors()->empty()) {
block_string += "end "; block_string += "end ";
} else { } else {
for (auto block : *other.get_successors()) { for (auto block : *other.successors()) {
block_string += module.getIdOrName(block->get_id()) + " "; block_string += module.getIdOrName(block->id()) + " ";
} }
} }
printf("%10s -> {%s\b}\n", module.getIdOrName(other.get_id()).c_str(), printf("%10s -> {%s\b}\n", module.getIdOrName(other.id()).c_str(),
block_string.c_str()); block_string.c_str());
} }
} /// namespace } /// namespace
Function::Function(uint32_t id, uint32_t result_type_id, Function::Function(uint32_t function_id, uint32_t result_type_id,
SpvFunctionControlMask function_control, SpvFunctionControlMask function_control,
uint32_t function_type_id, ValidationState_t& module) uint32_t function_type_id, ValidationState_t& module)
: module_(module), : module_(module),
id_(id), id_(function_id),
function_type_id_(function_type_id), function_type_id_(function_type_id),
result_type_id_(result_type_id), result_type_id_(result_type_id),
function_control_(function_control), function_control_(function_control),
@ -80,11 +80,11 @@ Function::Function(uint32_t id, uint32_t result_type_id,
variable_ids_(), variable_ids_(),
parameter_ids_() {} parameter_ids_() {}
bool Function::IsFirstBlock(uint32_t id) const { bool Function::IsFirstBlock(uint32_t block_id) const {
return !ordered_blocks_.empty() && *get_first_block() == id; return !ordered_blocks_.empty() && *first_block() == block_id;
} }
spv_result_t Function::RegisterFunctionParameter(uint32_t id, spv_result_t Function::RegisterFunctionParameter(uint32_t parameter_id,
uint32_t type_id) { uint32_t type_id) {
assert(module_.in_function_body() == true && assert(module_.in_function_body() == true &&
"RegisterFunctionParameter can only be called when parsing the binary " "RegisterFunctionParameter can only be called when parsing the binary "
@ -94,7 +94,7 @@ spv_result_t Function::RegisterFunctionParameter(uint32_t id,
"ouside of a block"); "ouside of a block");
// TODO(umar): Validate function parameter type order and count // TODO(umar): Validate function parameter type order and count
// TODO(umar): Use these variables to validate parameter type // TODO(umar): Use these variables to validate parameter type
(void)id; (void)parameter_id;
(void)type_id; (void)type_id;
return SPV_SUCCESS; return SPV_SUCCESS;
} }
@ -128,24 +128,24 @@ spv_result_t Function::RegisterSelectionMerge(uint32_t merge_id) {
current_block_->set_type(kBlockTypeHeader); current_block_->set_type(kBlockTypeHeader);
merge_block.set_type(kBlockTypeMerge); merge_block.set_type(kBlockTypeMerge);
cfg_constructs_.emplace_back(ConstructType::kSelection, get_current_block(), cfg_constructs_.emplace_back(ConstructType::kSelection, current_block(),
&merge_block); &merge_block);
return SPV_SUCCESS; return SPV_SUCCESS;
} }
void Function::printDotGraph() const { void Function::PrintDotGraph() const {
if (get_first_block()) { if (first_block()) {
string func_name(module_.getIdOrName(id_)); string func_name(module_.getIdOrName(id_));
printf("digraph %s {\n", func_name.c_str()); printf("digraph %s {\n", func_name.c_str());
printBlocks(); PrintBlocks();
printf("}\n"); printf("}\n");
} }
} }
void Function::printBlocks() const { void Function::PrintBlocks() const {
if (get_first_block()) { if (first_block()) {
printf("%10s -> %s\n", module_.getIdOrName(id_).c_str(), printf("%10s -> %s\n", module_.getIdOrName(id_).c_str(),
module_.getIdOrName(get_first_block()->get_id()).c_str()); module_.getIdOrName(first_block()->id()).c_str());
for (const auto& block : blocks_) { for (const auto& block : blocks_) {
printDot(block.second, module_); printDot(block.second, module_);
} }
@ -158,11 +158,11 @@ spv_result_t Function::RegisterSetFunctionDeclType(FunctionDecl type) {
return SPV_SUCCESS; return SPV_SUCCESS;
} }
spv_result_t Function::RegisterBlock(uint32_t id, bool is_definition) { spv_result_t Function::RegisterBlock(uint32_t block_id, bool is_definition) {
assert(module_.in_function_body() == true && assert(module_.in_function_body() == true &&
"RegisterBlocks can only be called when parsing a binary inside of a " "RegisterBlocks can only be called when parsing a binary inside of a "
"function"); "function");
assert(module_.getLayoutSection() != assert(module_.current_layout_section() !=
ModuleLayoutSection::kLayoutFunctionDeclarations && ModuleLayoutSection::kLayoutFunctionDeclarations &&
"RegisterBlocks cannot be called within a function declaration"); "RegisterBlocks cannot be called within a function declaration");
assert( assert(
@ -171,18 +171,19 @@ spv_result_t Function::RegisterBlock(uint32_t id, bool is_definition) {
std::unordered_map<uint32_t, BasicBlock>::iterator inserted_block; std::unordered_map<uint32_t, BasicBlock>::iterator inserted_block;
bool success = false; bool success = false;
tie(inserted_block, success) = blocks_.insert({id, BasicBlock(id)}); tie(inserted_block, success) =
blocks_.insert({block_id, BasicBlock(block_id)});
if (is_definition) { // new block definition if (is_definition) { // new block definition
assert(current_block_ == nullptr && assert(current_block_ == nullptr &&
"Register Block can only be called when parsing a binary outside of " "Register Block can only be called when parsing a binary outside of "
"a BasicBlock"); "a BasicBlock");
undefined_blocks_.erase(id); undefined_blocks_.erase(block_id);
current_block_ = &inserted_block->second; current_block_ = &inserted_block->second;
ordered_blocks_.push_back(current_block_); ordered_blocks_.push_back(current_block_);
if (IsFirstBlock(id)) current_block_->set_reachable(true); if (IsFirstBlock(block_id)) current_block_->set_reachable(true);
} else if (success) { // Block doesn't exsist but this is not a definition } else if (success) { // Block doesn't exsist but this is not a definition
undefined_blocks_.insert(id); undefined_blocks_.insert(block_id);
} }
return SPV_SUCCESS; return SPV_SUCCESS;
@ -202,10 +203,11 @@ void Function::RegisterBlockEnd(vector<uint32_t> next_list,
std::unordered_map<uint32_t, BasicBlock>::iterator inserted_block; std::unordered_map<uint32_t, BasicBlock>::iterator inserted_block;
bool success; bool success;
for (uint32_t id : next_list) { for (uint32_t successor_id : next_list) {
tie(inserted_block, success) = blocks_.insert({id, BasicBlock(id)}); tie(inserted_block, success) =
blocks_.insert({successor_id, BasicBlock(successor_id)});
if (success) { if (success) {
undefined_blocks_.insert(id); undefined_blocks_.insert(successor_id);
} }
next_blocks.push_back(&inserted_block->second); next_blocks.push_back(&inserted_block->second);
} }
@ -225,48 +227,46 @@ void Function::RegisterFunctionEnd() {
vector<BasicBlock*> sources; vector<BasicBlock*> sources;
vector<BasicBlock*> sinks; vector<BasicBlock*> sinks;
for (const auto b : ordered_blocks_) { for (const auto b : ordered_blocks_) {
if (b->get_predecessors()->empty()) sources.push_back(b); if (b->predecessors()->empty()) sources.push_back(b);
if (b->get_successors()->empty()) sinks.push_back(b); if (b->successors()->empty()) sinks.push_back(b);
} }
pseudo_entry_block_.SetSuccessorsUnsafe(std::move(sources)); pseudo_entry_block_.SetSuccessorsUnsafe(std::move(sources));
pseudo_exit_block_.SetPredecessorsUnsafe(std::move(sinks)); pseudo_exit_block_.SetPredecessorsUnsafe(std::move(sinks));
} }
} }
size_t Function::get_block_count() const { return blocks_.size(); } size_t Function::block_count() const { return blocks_.size(); }
size_t Function::get_undefined_block_count() const { size_t Function::undefined_block_count() const {
return undefined_blocks_.size(); return undefined_blocks_.size();
} }
const vector<BasicBlock*>& Function::get_blocks() const { const vector<BasicBlock*>& Function::ordered_blocks() const {
return ordered_blocks_; return ordered_blocks_;
} }
vector<BasicBlock*>& Function::get_blocks() { return ordered_blocks_; } vector<BasicBlock*>& Function::ordered_blocks() { return ordered_blocks_; }
const BasicBlock* Function::get_current_block() const { return current_block_; } const BasicBlock* Function::current_block() const { return current_block_; }
BasicBlock* Function::get_current_block() { return current_block_; } BasicBlock* Function::current_block() { return current_block_; }
BasicBlock* Function::get_pseudo_entry_block() { return &pseudo_entry_block_; } BasicBlock* Function::pseudo_entry_block() { return &pseudo_entry_block_; }
const BasicBlock* Function::get_pseudo_entry_block() const { const BasicBlock* Function::pseudo_entry_block() const {
return &pseudo_entry_block_; return &pseudo_entry_block_;
} }
BasicBlock* Function::get_pseudo_exit_block() { return &pseudo_exit_block_; } BasicBlock* Function::pseudo_exit_block() { return &pseudo_exit_block_; }
const BasicBlock* Function::get_pseudo_exit_block() const { const BasicBlock* Function::pseudo_exit_block() const {
return &pseudo_exit_block_; return &pseudo_exit_block_;
} }
const list<Construct>& Function::get_constructs() const { const list<Construct>& Function::constructs() const { return cfg_constructs_; }
return cfg_constructs_; list<Construct>& Function::constructs() { return cfg_constructs_; }
}
list<Construct>& Function::get_constructs() { return cfg_constructs_; }
const BasicBlock* Function::get_first_block() const { const BasicBlock* Function::first_block() const {
if (ordered_blocks_.empty()) return nullptr; if (ordered_blocks_.empty()) return nullptr;
return ordered_blocks_[0]; return ordered_blocks_[0];
} }
BasicBlock* Function::get_first_block() { BasicBlock* Function::first_block() {
if (ordered_blocks_.empty()) return nullptr; if (ordered_blocks_.empty()) return nullptr;
return ordered_blocks_[0]; return ordered_blocks_[0];
} }
@ -281,22 +281,22 @@ bool Function::IsBlockType(uint32_t merge_block_id, BlockType type) const {
return ret; return ret;
} }
pair<const BasicBlock*, bool> Function::GetBlock(uint32_t id) const { pair<const BasicBlock*, bool> Function::GetBlock(uint32_t block_id) const {
const auto b = blocks_.find(id); const auto b = blocks_.find(block_id);
if (b != end(blocks_)) { if (b != end(blocks_)) {
const BasicBlock* block = &(b->second); const BasicBlock* block = &(b->second);
bool defined = bool defined =
undefined_blocks_.find(block->get_id()) == end(undefined_blocks_); undefined_blocks_.find(block->id()) == end(undefined_blocks_);
return make_pair(block, defined); return make_pair(block, defined);
} else { } else {
return make_pair(nullptr, false); return make_pair(nullptr, false);
} }
} }
pair<BasicBlock*, bool> Function::GetBlock(uint32_t id) { pair<BasicBlock*, bool> Function::GetBlock(uint32_t block_id) {
const BasicBlock* out; const BasicBlock* out;
bool defined; bool defined;
tie(out, defined) = const_cast<const Function*>(this)->GetBlock(id); tie(out, defined) = const_cast<const Function*>(this)->GetBlock(block_id);
return make_pair(const_cast<BasicBlock*>(out), defined); return make_pair(const_cast<BasicBlock*>(out), defined);
} }
} /// namespace libspirv } /// namespace libspirv

View File

@ -32,8 +32,8 @@
#include <unordered_set> #include <unordered_set>
#include <vector> #include <vector>
#include "spirv/1.1/spirv.h"
#include "spirv-tools/libspirv.h" #include "spirv-tools/libspirv.h"
#include "spirv/1.1/spirv.h"
#include "val/BasicBlock.h" #include "val/BasicBlock.h"
namespace libspirv { namespace libspirv {
@ -117,72 +117,72 @@ class Function {
std::pair<BasicBlock*, bool> GetBlock(uint32_t id); std::pair<BasicBlock*, bool> GetBlock(uint32_t id);
/// Returns the first block of the current function /// Returns the first block of the current function
const BasicBlock* get_first_block() const; const BasicBlock* first_block() const;
/// Returns the first block of the current function /// Returns the first block of the current function
BasicBlock* get_first_block(); BasicBlock* first_block();
/// Returns a vector of all the blocks in the function /// Returns a vector of all the blocks in the function
const std::vector<BasicBlock*>& get_blocks() const; const std::vector<BasicBlock*>& ordered_blocks() const;
/// Returns a vector of all the blocks in the function /// Returns a vector of all the blocks in the function
std::vector<BasicBlock*>& get_blocks(); std::vector<BasicBlock*>& ordered_blocks();
/// Returns a list of all the cfg constructs in the function /// Returns a list of all the cfg constructs in the function
const std::list<Construct>& get_constructs() const; const std::list<Construct>& constructs() const;
/// Returns a list of all the cfg constructs in the function /// Returns a list of all the cfg constructs in the function
std::list<Construct>& get_constructs(); std::list<Construct>& constructs();
/// Returns the number of blocks in the current function being parsed /// Returns the number of blocks in the current function being parsed
size_t get_block_count() const; size_t block_count() const;
/// Returns the id of the funciton /// Returns the id of the funciton
uint32_t get_id() const { return id_; } uint32_t id() const { return id_; }
/// Returns the number of blocks in the current function being parsed /// Returns the number of blocks in the current function being parsed
size_t get_undefined_block_count() const; size_t undefined_block_count() const;
const std::unordered_set<uint32_t>& get_undefined_blocks() const { const std::unordered_set<uint32_t>& undefined_blocks() const {
return undefined_blocks_; return undefined_blocks_;
} }
/// Returns the block that is currently being parsed in the binary /// Returns the block that is currently being parsed in the binary
BasicBlock* get_current_block(); BasicBlock* current_block();
/// Returns the block that is currently being parsed in the binary /// Returns the block that is currently being parsed in the binary
const BasicBlock* get_current_block() const; const BasicBlock* current_block() const;
/// Returns the pseudo exit block /// Returns the pseudo exit block
BasicBlock* get_pseudo_entry_block(); BasicBlock* pseudo_entry_block();
/// Returns the pseudo exit block /// Returns the pseudo exit block
const BasicBlock* get_pseudo_entry_block() const; const BasicBlock* pseudo_entry_block() const;
/// Returns the pseudo exit block /// Returns the pseudo exit block
BasicBlock* get_pseudo_exit_block(); BasicBlock* pseudo_exit_block();
/// Returns the pseudo exit block /// Returns the pseudo exit block
const BasicBlock* get_pseudo_exit_block() const; const BasicBlock* pseudo_exit_block() const;
/// Returns a vector with just the pseudo entry block. /// Returns a vector with just the pseudo entry block.
/// This serves as the predecessors of each source node in the CFG when computing /// This serves as the predecessors of each source node in the CFG when
/// dominators. /// computing dominators.
const std::vector<BasicBlock*>* get_pseudo_entry_blocks() const { const std::vector<BasicBlock*>* pseudo_entry_blocks() const {
return &pseudo_entry_blocks_; return &pseudo_entry_blocks_;
} }
/// Returns a vector with just the pseudo exit block. /// Returns a vector with just the pseudo exit block.
/// This serves as the successors of each sink node in the CFG when computing /// This serves as the successors of each sink node in the CFG when computing
/// dominators. /// dominators.
const std::vector<BasicBlock*>* get_pseudo_exit_blocks() const { const std::vector<BasicBlock*>* pseudo_exit_blocks() const {
return &pseudo_exit_blocks_; return &pseudo_exit_blocks_;
} }
/// Prints a GraphViz digraph of the CFG of the current funciton /// Prints a GraphViz digraph of the CFG of the current funciton
void printDotGraph() const; void PrintDotGraph() const;
/// Prints a directed graph of the CFG of the current funciton /// Prints a directed graph of the CFG of the current funciton
void printBlocks() const; void PrintBlocks() const;
private: private:
/// Parent module /// Parent module

View File

@ -204,17 +204,17 @@ ValidationState_t::ValidationState_t(spv_diagnostic* diagnostic,
memory_model_(SpvMemoryModelSimple), memory_model_(SpvMemoryModelSimple),
in_function_(false) {} in_function_(false) {}
spv_result_t ValidationState_t::forwardDeclareId(uint32_t id) { spv_result_t ValidationState_t::ForwardDeclareId(uint32_t id) {
unresolved_forward_ids_.insert(id); unresolved_forward_ids_.insert(id);
return SPV_SUCCESS; return SPV_SUCCESS;
} }
spv_result_t ValidationState_t::removeIfForwardDeclared(uint32_t id) { spv_result_t ValidationState_t::RemoveIfForwardDeclared(uint32_t id) {
unresolved_forward_ids_.erase(id); unresolved_forward_ids_.erase(id);
return SPV_SUCCESS; return SPV_SUCCESS;
} }
void ValidationState_t::assignNameToId(uint32_t id, string name) { void ValidationState_t::AssignNameToId(uint32_t id, string name) {
operand_names_[id] = name; operand_names_[id] = name;
} }
@ -237,30 +237,30 @@ string ValidationState_t::getIdOrName(uint32_t id) const {
return out.str(); return out.str();
} }
size_t ValidationState_t::unresolvedForwardIdCount() const { size_t ValidationState_t::unresolved_forward_id_count() const {
return unresolved_forward_ids_.size(); return unresolved_forward_ids_.size();
} }
vector<uint32_t> ValidationState_t::unresolvedForwardIds() const { vector<uint32_t> ValidationState_t::UnresolvedForwardIds() const {
vector<uint32_t> out(begin(unresolved_forward_ids_), vector<uint32_t> out(begin(unresolved_forward_ids_),
end(unresolved_forward_ids_)); end(unresolved_forward_ids_));
return out; return out;
} }
bool ValidationState_t::isDefinedId(uint32_t id) const { bool ValidationState_t::IsDefinedId(uint32_t id) const {
return usedefs_.FindDef(id).first; return usedefs_.FindDef(id).first;
} }
// Increments the instruction count. Used for diagnostic // Increments the instruction count. Used for diagnostic
int ValidationState_t::incrementInstructionCount() { int ValidationState_t::increment_instruction_count() {
return instruction_counter_++; return instruction_counter_++;
} }
ModuleLayoutSection ValidationState_t::getLayoutSection() const { ModuleLayoutSection ValidationState_t::current_layout_section() const {
return current_layout_section_; return current_layout_section_;
} }
void ValidationState_t::progressToNextLayoutSectionOrder() { void ValidationState_t::ProgressToNextLayoutSectionOrder() {
// Guard against going past the last element(kLayoutFunctionDefinitions) // Guard against going past the last element(kLayoutFunctionDefinitions)
if (current_layout_section_ <= kLayoutFunctionDefinitions) { if (current_layout_section_ <= kLayoutFunctionDefinitions) {
current_layout_section_ = current_layout_section_ =
@ -268,7 +268,7 @@ void ValidationState_t::progressToNextLayoutSectionOrder() {
} }
} }
bool ValidationState_t::isOpcodeInCurrentLayoutSection(SpvOp op) { bool ValidationState_t::IsOpcodeInCurrentLayoutSection(SpvOp op) {
return IsInstructionInLayoutSection(current_layout_section_, op); return IsInstructionInLayoutSection(current_layout_section_, op);
} }
@ -278,9 +278,9 @@ DiagnosticStream ValidationState_t::diag(spv_result_t error_code) const {
error_code); error_code);
} }
list<Function>& ValidationState_t::get_functions() { return module_functions_; } list<Function>& ValidationState_t::functions() { return module_functions_; }
Function& ValidationState_t::get_current_function() { Function& ValidationState_t::current_function() {
assert(in_function_body()); assert(in_function_body());
return module_functions_.back(); return module_functions_.back();
} }
@ -289,7 +289,7 @@ bool ValidationState_t::in_function_body() const { return in_function_; }
bool ValidationState_t::in_block() const { bool ValidationState_t::in_block() const {
return module_functions_.empty() == false && return module_functions_.empty() == false &&
module_functions_.back().get_current_block() != nullptr; module_functions_.back().current_block() != nullptr;
} }
void ValidationState_t::RegisterCapability(SpvCapability cap) { void ValidationState_t::RegisterCapability(SpvCapability cap) {
@ -301,7 +301,7 @@ void ValidationState_t::RegisterCapability(SpvCapability cap) {
[this](SpvCapability c) { RegisterCapability(c); }); [this](SpvCapability c) { RegisterCapability(c); });
} }
bool ValidationState_t::hasCapability(SpvCapability cap) const { bool ValidationState_t::has_capability(SpvCapability cap) const {
return (module_capabilities_ & SPV_CAPABILITY_AS_MASK(cap)) != 0; return (module_capabilities_ & SPV_CAPABILITY_AS_MASK(cap)) != 0;
} }
@ -310,24 +310,24 @@ bool ValidationState_t::HasAnyOf(spv_capability_mask_t capabilities) const {
return true; // No capabilities requested: trivially satisfied. return true; // No capabilities requested: trivially satisfied.
bool found = false; bool found = false;
libspirv::ForEach(capabilities, [&found, this](SpvCapability c) { libspirv::ForEach(capabilities, [&found, this](SpvCapability c) {
found |= hasCapability(c); found |= has_capability(c);
}); });
return found; return found;
} }
void ValidationState_t::setAddressingModel(SpvAddressingModel am) { void ValidationState_t::set_addressing_model(SpvAddressingModel am) {
addressing_model_ = am; addressing_model_ = am;
} }
SpvAddressingModel ValidationState_t::getAddressingModel() const { SpvAddressingModel ValidationState_t::addressing_model() const {
return addressing_model_; return addressing_model_;
} }
void ValidationState_t::setMemoryModel(SpvMemoryModel mm) { void ValidationState_t::set_memory_model(SpvMemoryModel mm) {
memory_model_ = mm; memory_model_ = mm;
} }
SpvMemoryModel ValidationState_t::getMemoryModel() const { SpvMemoryModel ValidationState_t::memory_model() const {
return memory_model_; return memory_model_;
} }
@ -353,7 +353,7 @@ spv_result_t ValidationState_t::RegisterFunctionEnd() {
assert(in_block() == false && assert(in_block() == false &&
"RegisterFunctionParameter can only be called when parsing the binary " "RegisterFunctionParameter can only be called when parsing the binary "
"ouside of a block"); "ouside of a block");
get_current_function().RegisterFunctionEnd(); current_function().RegisterFunctionEnd();
in_function_ = false; in_function_ = false;
return SPV_SUCCESS; return SPV_SUCCESS;
} }

View File

@ -84,13 +84,13 @@ class ValidationState_t {
const spv_const_context context); const spv_const_context context);
/// Forward declares the id in the module /// Forward declares the id in the module
spv_result_t forwardDeclareId(uint32_t id); spv_result_t ForwardDeclareId(uint32_t id);
/// Removes a forward declared ID if it has been defined /// Removes a forward declared ID if it has been defined
spv_result_t removeIfForwardDeclared(uint32_t id); spv_result_t RemoveIfForwardDeclared(uint32_t id);
/// Assigns a name to an ID /// Assigns a name to an ID
void assignNameToId(uint32_t id, std::string name); void AssignNameToId(uint32_t id, std::string name);
/// Returns a string representation of the ID in the format <id>[Name] where /// Returns a string representation of the ID in the format <id>[Name] where
/// the <id> is the numeric valid of the id and the Name is a name assigned by /// the <id> is the numeric valid of the id and the Name is a name assigned by
@ -102,33 +102,33 @@ class ValidationState_t {
/// Returns the number of ID which have been forward referenced but not /// Returns the number of ID which have been forward referenced but not
/// defined /// defined
size_t unresolvedForwardIdCount() const; size_t unresolved_forward_id_count() const;
/// Returns a list of unresolved forward ids. /// Returns a list of unresolved forward ids.
std::vector<uint32_t> unresolvedForwardIds() const; std::vector<uint32_t> UnresolvedForwardIds() const;
/// Returns true if the id has been defined /// Returns true if the id has been defined
bool isDefinedId(uint32_t id) const; bool IsDefinedId(uint32_t id) const;
/// Increments the instruction count. Used for diagnostic /// Increments the instruction count. Used for diagnostic
int incrementInstructionCount(); int increment_instruction_count();
/// Returns the current layout section which is being processed /// Returns the current layout section which is being processed
ModuleLayoutSection getLayoutSection() const; ModuleLayoutSection current_layout_section() const;
/// Increments the module_layout_order_section_ /// Increments the module_layout_order_section_
void progressToNextLayoutSectionOrder(); void ProgressToNextLayoutSectionOrder();
/// Determines if the op instruction is part of the current section /// Determines if the op instruction is part of the current section
bool isOpcodeInCurrentLayoutSection(SpvOp op); bool IsOpcodeInCurrentLayoutSection(SpvOp op);
libspirv::DiagnosticStream diag(spv_result_t error_code) const; libspirv::DiagnosticStream diag(spv_result_t error_code) const;
/// Returns the function states /// Returns the function states
std::list<Function>& get_functions(); std::list<Function>& functions();
/// Returns the function states /// Returns the function states
Function& get_current_function(); Function& current_function();
/// Returns true if the called after a function instruction but before the /// Returns true if the called after a function instruction but before the
/// function end instruction /// function end instruction
@ -190,23 +190,23 @@ class ValidationState_t {
spv_result_t RegisterFunctionEnd(); spv_result_t RegisterFunctionEnd();
/// Returns true if the capability is enabled in the module. /// Returns true if the capability is enabled in the module.
bool hasCapability(SpvCapability cap) const; bool has_capability(SpvCapability cap) const;
/// Returns true if any of the capabilities are enabled. Always true for /// Returns true if any of the capabilities are enabled. Always true for
/// capabilities==0. /// capabilities==0.
bool HasAnyOf(spv_capability_mask_t capabilities) const; bool HasAnyOf(spv_capability_mask_t capabilities) const;
/// Sets the addressing model of this module (logical/physical). /// Sets the addressing model of this module (logical/physical).
void setAddressingModel(SpvAddressingModel am); void set_addressing_model(SpvAddressingModel am);
/// Returns the addressing model of this module, or Logical if uninitialized. /// Returns the addressing model of this module, or Logical if uninitialized.
SpvAddressingModel getAddressingModel() const; SpvAddressingModel addressing_model() const;
/// Sets the memory model of this module. /// Sets the memory model of this module.
void setMemoryModel(SpvMemoryModel mm); void set_memory_model(SpvMemoryModel mm);
/// Returns the memory model of this module, or Simple if uninitialized. /// Returns the memory model of this module, or Simple if uninitialized.
SpvMemoryModel getMemoryModel() const; SpvMemoryModel memory_model() const;
AssemblyGrammar& grammar() { return grammar_; } AssemblyGrammar& grammar() { return grammar_; }

View File

@ -107,13 +107,13 @@ void DebugInstructionPass(ValidationState_t& _,
const uint32_t target = *(inst->words + inst->operands[0].offset); const uint32_t target = *(inst->words + inst->operands[0].offset);
const char* str = const char* str =
reinterpret_cast<const char*>(inst->words + inst->operands[1].offset); reinterpret_cast<const char*>(inst->words + inst->operands[1].offset);
_.assignNameToId(target, str); _.AssignNameToId(target, str);
} break; } break;
case SpvOpMemberName: { case SpvOpMemberName: {
const uint32_t target = *(inst->words + inst->operands[0].offset); const uint32_t target = *(inst->words + inst->operands[0].offset);
const char* str = const char* str =
reinterpret_cast<const char*>(inst->words + inst->operands[2].offset); reinterpret_cast<const char*>(inst->words + inst->operands[2].offset);
_.assignNameToId(target, str); _.AssignNameToId(target, str);
} break; } break;
case SpvOpSourceContinued: case SpvOpSourceContinued:
case SpvOpSource: case SpvOpSource:
@ -125,7 +125,6 @@ void DebugInstructionPass(ValidationState_t& _,
default: default:
break; break;
} }
} }
// Collects use-def info about an instruction's IDs. // Collects use-def info about an instruction's IDs.
@ -143,7 +142,7 @@ void ProcessIds(ValidationState_t& _, const spv_parsed_instruction_t& inst) {
spv_result_t ProcessInstruction(void* user_data, spv_result_t ProcessInstruction(void* user_data,
const spv_parsed_instruction_t* inst) { const spv_parsed_instruction_t* inst) {
ValidationState_t& _ = *(reinterpret_cast<ValidationState_t*>(user_data)); ValidationState_t& _ = *(reinterpret_cast<ValidationState_t*>(user_data));
_.incrementInstructionCount(); _.increment_instruction_count();
if (static_cast<SpvOp>(inst->opcode) == SpvOpEntryPoint) if (static_cast<SpvOp>(inst->opcode) == SpvOpEntryPoint)
_.entry_points().push_back(inst->words[2]); _.entry_points().push_back(inst->words[2]);
@ -192,9 +191,9 @@ spv_result_t spvValidate(const spv_const_context context,
// TODO(umar): Add validation checks which require the parsing of the entire // TODO(umar): Add validation checks which require the parsing of the entire
// module. Use the information from the ProcessInstruction pass to make the // module. Use the information from the ProcessInstruction pass to make the
// checks. // checks.
if (vstate.unresolvedForwardIdCount() > 0) { if (vstate.unresolved_forward_id_count() > 0) {
stringstream ss; stringstream ss;
vector<uint32_t> ids = vstate.unresolvedForwardIds(); vector<uint32_t> ids = vstate.UnresolvedForwardIds();
transform(begin(ids), end(ids), ostream_iterator<string>(ss, " "), transform(begin(ids), end(ids), ostream_iterator<string>(ss, " "),
bind(&ValidationState_t::getIdName, vstate, _1)); bind(&ValidationState_t::getIdName, vstate, _1));

View File

@ -63,8 +63,8 @@ using get_blocks_func =
/// Computes dominators using the algorithm of Cooper, Harvey, and Kennedy /// Computes dominators using the algorithm of Cooper, Harvey, and Kennedy
/// "A Simple, Fast Dominance Algorithm", 2001. /// "A Simple, Fast Dominance Algorithm", 2001.
/// ///
/// The algorithm assumes there is a unique root node (a node without predecessors), /// The algorithm assumes there is a unique root node (a node without
/// and it is therefore at the end of the postorder vector. /// predecessors), and it is therefore at the end of the postorder vector.
/// ///
/// This function calculates the dominator edges for a set of blocks in the CFG. /// This function calculates the dominator edges for a set of blocks in the CFG.
/// Uses the dominator algorithm by Cooper et al. /// Uses the dominator algorithm by Cooper et al.
@ -75,9 +75,9 @@ using get_blocks_func =
/// block /// block
/// ///
/// @return the dominator tree of the graph, as a vector of pairs of nodes. /// @return the dominator tree of the graph, as a vector of pairs of nodes.
/// The first node in the pair is a node in the graph. The second node in the pair /// The first node in the pair is a node in the graph. The second node in the
/// is its immediate dominator in the sense of Cooper et.al., where a block without /// pair is its immediate dominator in the sense of Cooper et.al., where a block
/// predecessors (such as the root node) is its own immediate dominator. /// without predecessors (such as the root node) is its own immediate dominator.
std::vector<std::pair<BasicBlock*, BasicBlock*>> CalculateDominators( std::vector<std::pair<BasicBlock*, BasicBlock*>> CalculateDominators(
const std::vector<const BasicBlock*>& postorder, const std::vector<const BasicBlock*>& postorder,
get_blocks_func predecessor_func); get_blocks_func predecessor_func);

View File

@ -77,16 +77,15 @@ struct block_info {
/// @param[in] work_list Set of blocks visited in the the depth first traversal /// @param[in] work_list Set of blocks visited in the the depth first traversal
/// of the CFG /// of the CFG
/// @param[in] id The ID of the block being checked /// @param[in] id The ID of the block being checked
/// @return true if the edge work_list.back().block->get_id() => id is a ///
/// back-edge /// @return true if the edge work_list.back().block->id() => id is a back-edge
bool FindInWorkList(const vector<block_info>& work_list, uint32_t id) { bool FindInWorkList(const vector<block_info>& work_list, uint32_t id) {
for (const auto b : work_list) { for (const auto b : work_list) {
if (b.block->get_id() == id) return true; if (b.block->id() == id) return true;
} }
return false; return false;
} }
/// @brief Depth first traversal starting from the \p entry BasicBlock /// @brief Depth first traversal starting from the \p entry BasicBlock
/// ///
/// This function performs a depth first traversal from the \p entry /// This function performs a depth first traversal from the \p entry
@ -104,7 +103,8 @@ bool FindInWorkList(const vector<block_info>& work_list, uint32_t id) {
/// @param[in] backedge A function that will be called when a backedge is /// @param[in] backedge A function that will be called when a backedge is
/// encountered during a traversal /// encountered during a traversal
/// NOTE: The @p successor_func and predecessor_func each return a pointer to a /// NOTE: The @p successor_func and predecessor_func each return a pointer to a
/// collection such that iterators to that collection remain valid for the lifetime /// collection such that iterators to that collection remain valid for the
/// lifetime
/// of the algorithm /// of the algorithm
void DepthFirstTraversal(const BasicBlock* entry, void DepthFirstTraversal(const BasicBlock* entry,
get_blocks_func successor_func, get_blocks_func successor_func,
@ -120,7 +120,7 @@ void DepthFirstTraversal(const BasicBlock* entry,
work_list.push_back({entry, begin(*successor_func(entry))}); work_list.push_back({entry, begin(*successor_func(entry))});
preorder(entry); preorder(entry);
processed.insert(entry->get_id()); processed.insert(entry->id());
while (!work_list.empty()) { while (!work_list.empty()) {
block_info& top = work_list.back(); block_info& top = work_list.back();
@ -130,14 +130,14 @@ void DepthFirstTraversal(const BasicBlock* entry,
} else { } else {
BasicBlock* child = *top.iter; BasicBlock* child = *top.iter;
top.iter++; top.iter++;
if (FindInWorkList(work_list, child->get_id())) { if (FindInWorkList(work_list, child->id())) {
backedge(top.block, child); backedge(top.block, child);
} }
if (processed.count(child->get_id()) == 0) { if (processed.count(child->id()) == 0) {
preorder(child); preorder(child);
work_list.emplace_back( work_list.emplace_back(
block_info{child, begin(*successor_func(child))}); block_info{child, begin(*successor_func(child))});
processed.insert(child->get_id()); processed.insert(child->id());
} }
} }
} }
@ -145,7 +145,6 @@ void DepthFirstTraversal(const BasicBlock* entry,
} // namespace } // namespace
vector<pair<BasicBlock*, BasicBlock*>> CalculateDominators( vector<pair<BasicBlock*, BasicBlock*>> CalculateDominators(
const vector<cbb_ptr>& postorder, get_blocks_func predecessor_func) { const vector<cbb_ptr>& postorder, get_blocks_func predecessor_func) {
struct block_detail { struct block_detail {
@ -209,11 +208,11 @@ vector<pair<BasicBlock*, BasicBlock*>> CalculateDominators(
} }
void printDominatorList(const BasicBlock& b) { void printDominatorList(const BasicBlock& b) {
std::cout << b.get_id() << " is dominated by: "; std::cout << b.id() << " is dominated by: ";
const BasicBlock* bb = &b; const BasicBlock* bb = &b;
while (bb->GetImmediateDominator() != bb) { while (bb->immediate_dominator() != bb) {
bb = bb->GetImmediateDominator(); bb = bb->immediate_dominator();
std::cout << bb->get_id() << " "; std::cout << bb->id() << " ";
} }
} }
@ -221,19 +220,17 @@ void printDominatorList(const BasicBlock& b) {
if (spv_result_t rcode = ASSERT_FUNC(_, TARGET)) return rcode if (spv_result_t rcode = ASSERT_FUNC(_, TARGET)) return rcode
spv_result_t FirstBlockAssert(ValidationState_t& _, uint32_t target) { spv_result_t FirstBlockAssert(ValidationState_t& _, uint32_t target) {
if (_.get_current_function().IsFirstBlock(target)) { if (_.current_function().IsFirstBlock(target)) {
return _.diag(SPV_ERROR_INVALID_CFG) return _.diag(SPV_ERROR_INVALID_CFG)
<< "First block " << _.getIdName(target) << " of funciton " << "First block " << _.getIdName(target) << " of funciton "
<< _.getIdName(_.get_current_function().get_id()) << _.getIdName(_.current_function().id()) << " is targeted by block "
<< " is targeted by block " << _.getIdName(_.current_function().current_block()->id());
<< _.getIdName(
_.get_current_function().get_current_block()->get_id());
} }
return SPV_SUCCESS; return SPV_SUCCESS;
} }
spv_result_t MergeBlockAssert(ValidationState_t& _, uint32_t merge_block) { spv_result_t MergeBlockAssert(ValidationState_t& _, uint32_t merge_block) {
if (_.get_current_function().IsBlockType(merge_block, kBlockTypeMerge)) { if (_.current_function().IsBlockType(merge_block, kBlockTypeMerge)) {
return _.diag(SPV_ERROR_INVALID_CFG) return _.diag(SPV_ERROR_INVALID_CFG)
<< "Block " << _.getIdName(merge_block) << "Block " << _.getIdName(merge_block)
<< " is already a merge block for another header"; << " is already a merge block for another header";
@ -245,7 +242,7 @@ spv_result_t MergeBlockAssert(ValidationState_t& _, uint32_t merge_block) {
/// identified in the CFG. /// identified in the CFG.
void UpdateContinueConstructExitBlocks( void UpdateContinueConstructExitBlocks(
Function& function, const vector<pair<uint32_t, uint32_t>>& back_edges) { Function& function, const vector<pair<uint32_t, uint32_t>>& back_edges) {
auto& constructs = function.get_constructs(); auto& constructs = function.constructs();
// TODO(umar): Think of a faster way to do this // TODO(umar): Think of a faster way to do this
for (auto& edge : back_edges) { for (auto& edge : back_edges) {
uint32_t back_edge_block_id; uint32_t back_edge_block_id;
@ -253,15 +250,15 @@ void UpdateContinueConstructExitBlocks(
tie(back_edge_block_id, loop_header_block_id) = edge; tie(back_edge_block_id, loop_header_block_id) = edge;
auto is_this_header = [=](Construct& c) { auto is_this_header = [=](Construct& c) {
return c.get_type() == ConstructType::kLoop && return c.type() == ConstructType::kLoop &&
c.get_entry()->get_id() == loop_header_block_id; c.entry_block()->id() == loop_header_block_id;
}; };
for (auto construct : constructs) { for (auto construct : constructs) {
if (is_this_header(construct)) { if (is_this_header(construct)) {
Construct* continue_construct = Construct* continue_construct =
construct.get_corresponding_constructs().back(); construct.corresponding_constructs().back();
assert(continue_construct->get_type() == ConstructType::kContinue); assert(continue_construct->type() == ConstructType::kContinue);
BasicBlock* back_edge_block; BasicBlock* back_edge_block;
tie(back_edge_block, ignore) = function.GetBlock(back_edge_block_id); tie(back_edge_block, ignore) = function.GetBlock(back_edge_block_id);
@ -286,7 +283,7 @@ string ConstructErrorString(const Construct& construct,
dominate_text = "does not dominate"; dominate_text = "does not dominate";
} }
switch (construct.get_type()) { switch (construct.type()) {
case ConstructType::kSelection: case ConstructType::kSelection:
construct_name = "selection"; construct_name = "selection";
header_name = "selection header"; header_name = "selection header";
@ -344,24 +341,24 @@ spv_result_t StructuredControlFlowChecks(
} }
// Check construct rules // Check construct rules
for (const Construct& construct : function.get_constructs()) { for (const Construct& construct : function.constructs()) {
auto header = construct.get_entry(); auto header = construct.entry_block();
auto merge = construct.get_exit(); auto merge = construct.exit_block();
// if the merge block is reachable then it's dominated by the header // if the merge block is reachable then it's dominated by the header
if (merge->is_reachable() && if (merge->reachable() &&
find(merge->dom_begin(), merge->dom_end(), header) == find(merge->dom_begin(), merge->dom_end(), header) ==
merge->dom_end()) { merge->dom_end()) {
return _.diag(SPV_ERROR_INVALID_CFG) return _.diag(SPV_ERROR_INVALID_CFG)
<< ConstructErrorString(construct, _.getIdName(header->get_id()), << ConstructErrorString(construct, _.getIdName(header->id()),
_.getIdName(merge->get_id())); _.getIdName(merge->id()));
} }
if (construct.get_type() == ConstructType::kContinue) { if (construct.type() == ConstructType::kContinue) {
if (find(header->pdom_begin(), header->pdom_end(), merge) == if (find(header->pdom_begin(), header->pdom_end(), merge) ==
merge->pdom_end()) { merge->pdom_end()) {
return _.diag(SPV_ERROR_INVALID_CFG) return _.diag(SPV_ERROR_INVALID_CFG)
<< ConstructErrorString(construct, _.getIdName(header->get_id()), << ConstructErrorString(construct, _.getIdName(header->id()),
_.getIdName(merge->get_id()), true); _.getIdName(merge->id()), true);
} }
} }
// TODO(umar): an OpSwitch block dominates all its defined case // TODO(umar): an OpSwitch block dominates all its defined case
@ -379,17 +376,17 @@ spv_result_t StructuredControlFlowChecks(
} }
spv_result_t PerformCfgChecks(ValidationState_t& _) { spv_result_t PerformCfgChecks(ValidationState_t& _) {
for (auto& function : _.get_functions()) { for (auto& function : _.functions()) {
// Check all referenced blocks are defined within a function // Check all referenced blocks are defined within a function
if (function.get_undefined_block_count() != 0) { if (function.undefined_block_count() != 0) {
string undef_blocks("{"); string undef_blocks("{");
for (auto undefined_block : function.get_undefined_blocks()) { for (auto undefined_block : function.undefined_blocks()) {
undef_blocks += _.getIdName(undefined_block) + " "; undef_blocks += _.getIdName(undefined_block) + " ";
} }
return _.diag(SPV_ERROR_INVALID_CFG) return _.diag(SPV_ERROR_INVALID_CFG)
<< "Block(s) " << undef_blocks << "\b}" << "Block(s) " << undef_blocks << "\b}"
<< " are referenced but not defined in function " << " are referenced but not defined in function "
<< _.getIdName(function.get_id()); << _.getIdName(function.id());
} }
// Prepare for dominance calculations. We want to analyze all the // Prepare for dominance calculations. We want to analyze all the
@ -405,26 +402,26 @@ spv_result_t PerformCfgChecks(ValidationState_t& _) {
// from the pseudo entry node, and not reachable by following // from the pseudo entry node, and not reachable by following
// predecessors from the pseudo exit node. // predecessors from the pseudo exit node.
auto* pseudo_entry = function.get_pseudo_entry_block(); auto* pseudo_entry = function.pseudo_entry_block();
auto* pseudo_exit = function.get_pseudo_exit_block(); auto* pseudo_exit = function.pseudo_exit_block();
// We need vectors to use as the predecessors (in the augmented CFG) // We need vectors to use as the predecessors (in the augmented CFG)
// for the source nodes of the original CFG. It must have a stable // for the source nodes of the original CFG. It must have a stable
// address for the duration of the calculation. // address for the duration of the calculation.
auto* pseudo_entry_vec = function.get_pseudo_entry_blocks(); auto* pseudo_entry_vec = function.pseudo_entry_blocks();
// Similarly, we need a vector to be used as the successors (in the // Similarly, we need a vector to be used as the successors (in the
// augmented CFG) for sinks in the original CFG. // augmented CFG) for sinks in the original CFG.
auto* pseudo_exit_vec = function.get_pseudo_exit_blocks(); auto* pseudo_exit_vec = function.pseudo_exit_blocks();
// Returns the predecessors of a block in the augmented CFG. // Returns the predecessors of a block in the augmented CFG.
auto augmented_predecessor_fn = [pseudo_entry, pseudo_entry_vec]( auto augmented_predecessor_fn = [pseudo_entry, pseudo_entry_vec](
const BasicBlock* block) { const BasicBlock* block) {
auto predecessors = block->get_predecessors(); auto predecessors = block->predecessors();
return (block != pseudo_entry && predecessors->empty()) ? pseudo_entry_vec return (block != pseudo_entry && predecessors->empty()) ? pseudo_entry_vec
: predecessors; : predecessors;
}; };
// Returns the successors of a block in the augmented CFG. // Returns the successors of a block in the augmented CFG.
auto augmented_successor_fn = [pseudo_exit, auto augmented_successor_fn = [pseudo_exit,
pseudo_exit_vec](const BasicBlock* block) { pseudo_exit_vec](const BasicBlock* block) {
auto successors = block->get_successors(); auto successors = block->successors();
return (block != pseudo_exit && successors->empty()) ? pseudo_exit_vec return (block != pseudo_exit && successors->empty()) ? pseudo_exit_vec
: successors; : successors;
}; };
@ -434,13 +431,12 @@ spv_result_t PerformCfgChecks(ValidationState_t& _) {
vector<const BasicBlock*> postorder; vector<const BasicBlock*> postorder;
vector<const BasicBlock*> postdom_postorder; vector<const BasicBlock*> postdom_postorder;
vector<pair<uint32_t, uint32_t>> back_edges; vector<pair<uint32_t, uint32_t>> back_edges;
if (!function.get_blocks().empty()) { if (!function.ordered_blocks().empty()) {
/// calculate dominators /// calculate dominators
DepthFirstTraversal(pseudo_entry, augmented_successor_fn, [](cbb_ptr) {}, DepthFirstTraversal(pseudo_entry, augmented_successor_fn, [](cbb_ptr) {},
[&](cbb_ptr b) { postorder.push_back(b); }, [&](cbb_ptr b) { postorder.push_back(b); },
[&](cbb_ptr from, cbb_ptr to) { [&](cbb_ptr from, cbb_ptr to) {
back_edges.emplace_back(from->get_id(), back_edges.emplace_back(from->id(), to->id());
to->get_id());
}); });
auto edges = auto edges =
libspirv::CalculateDominators(postorder, augmented_predecessor_fn); libspirv::CalculateDominators(postorder, augmented_predecessor_fn);
@ -462,23 +458,23 @@ spv_result_t PerformCfgChecks(ValidationState_t& _) {
// Check if the order of blocks in the binary appear before the blocks they // Check if the order of blocks in the binary appear before the blocks they
// dominate // dominate
auto& blocks = function.get_blocks(); auto& blocks = function.ordered_blocks();
if (blocks.empty() == false) { if (blocks.empty() == false) {
for (auto block = begin(blocks) + 1; block != end(blocks); ++block) { for (auto block = begin(blocks) + 1; block != end(blocks); ++block) {
if (auto idom = (*block)->GetImmediateDominator()) { if (auto idom = (*block)->immediate_dominator()) {
if (idom != pseudo_entry && if (idom != pseudo_entry &&
block == std::find(begin(blocks), block, idom)) { block == std::find(begin(blocks), block, idom)) {
return _.diag(SPV_ERROR_INVALID_CFG) return _.diag(SPV_ERROR_INVALID_CFG)
<< "Block " << _.getIdName((*block)->get_id()) << "Block " << _.getIdName((*block)->id())
<< " appears in the binary before its dominator " << " appears in the binary before its dominator "
<< _.getIdName(idom->get_id()); << _.getIdName(idom->id());
} }
} }
} }
} }
/// Structured control flow checks are only required for shader capabilities /// Structured control flow checks are only required for shader capabilities
if (_.hasCapability(SpvCapabilityShader)) { if (_.has_capability(SpvCapabilityShader)) {
spvCheckReturn(StructuredControlFlowChecks(_, function, back_edges)); spvCheckReturn(StructuredControlFlowChecks(_, function, back_edges));
} }
} }
@ -490,28 +486,27 @@ spv_result_t CfgPass(ValidationState_t& _,
SpvOp opcode = static_cast<SpvOp>(inst->opcode); SpvOp opcode = static_cast<SpvOp>(inst->opcode);
switch (opcode) { switch (opcode) {
case SpvOpLabel: case SpvOpLabel:
spvCheckReturn(_.get_current_function().RegisterBlock(inst->result_id)); spvCheckReturn(_.current_function().RegisterBlock(inst->result_id));
break; break;
case SpvOpLoopMerge: { case SpvOpLoopMerge: {
uint32_t merge_block = inst->words[inst->operands[0].offset]; uint32_t merge_block = inst->words[inst->operands[0].offset];
uint32_t continue_block = inst->words[inst->operands[1].offset]; uint32_t continue_block = inst->words[inst->operands[1].offset];
CFG_ASSERT(MergeBlockAssert, merge_block); CFG_ASSERT(MergeBlockAssert, merge_block);
spvCheckReturn(_.get_current_function().RegisterLoopMerge( spvCheckReturn(
merge_block, continue_block)); _.current_function().RegisterLoopMerge(merge_block, continue_block));
} break; } break;
case SpvOpSelectionMerge: { case SpvOpSelectionMerge: {
uint32_t merge_block = inst->words[inst->operands[0].offset]; uint32_t merge_block = inst->words[inst->operands[0].offset];
CFG_ASSERT(MergeBlockAssert, merge_block); CFG_ASSERT(MergeBlockAssert, merge_block);
spvCheckReturn( spvCheckReturn(_.current_function().RegisterSelectionMerge(merge_block));
_.get_current_function().RegisterSelectionMerge(merge_block));
} break; } break;
case SpvOpBranch: { case SpvOpBranch: {
uint32_t target = inst->words[inst->operands[0].offset]; uint32_t target = inst->words[inst->operands[0].offset];
CFG_ASSERT(FirstBlockAssert, target); CFG_ASSERT(FirstBlockAssert, target);
_.get_current_function().RegisterBlockEnd({target}, opcode); _.current_function().RegisterBlockEnd({target}, opcode);
} break; } break;
case SpvOpBranchConditional: { case SpvOpBranchConditional: {
uint32_t tlabel = inst->words[inst->operands[1].offset]; uint32_t tlabel = inst->words[inst->operands[1].offset];
@ -519,7 +514,7 @@ spv_result_t CfgPass(ValidationState_t& _,
CFG_ASSERT(FirstBlockAssert, tlabel); CFG_ASSERT(FirstBlockAssert, tlabel);
CFG_ASSERT(FirstBlockAssert, flabel); CFG_ASSERT(FirstBlockAssert, flabel);
_.get_current_function().RegisterBlockEnd({tlabel, flabel}, opcode); _.current_function().RegisterBlockEnd({tlabel, flabel}, opcode);
} break; } break;
case SpvOpSwitch: { case SpvOpSwitch: {
@ -529,13 +524,13 @@ spv_result_t CfgPass(ValidationState_t& _,
CFG_ASSERT(FirstBlockAssert, target); CFG_ASSERT(FirstBlockAssert, target);
cases.push_back(target); cases.push_back(target);
} }
_.get_current_function().RegisterBlockEnd({cases}, opcode); _.current_function().RegisterBlockEnd({cases}, opcode);
} break; } break;
case SpvOpKill: case SpvOpKill:
case SpvOpReturn: case SpvOpReturn:
case SpvOpReturnValue: case SpvOpReturnValue:
case SpvOpUnreachable: case SpvOpUnreachable:
_.get_current_function().RegisterBlockEnd({}, opcode); _.current_function().RegisterBlockEnd({}, opcode);
break; break;
default: default:
break; break;

View File

@ -2349,7 +2349,7 @@ spv_result_t spvValidateInstructionIDs(const spv_instruction_t* pInsts,
spv_position position, spv_position position,
spv_diagnostic* pDiag) { spv_diagnostic* pDiag) {
idUsage idUsage(opcodeTable, operandTable, extInstTable, pInsts, instCount, idUsage idUsage(opcodeTable, operandTable, extInstTable, pInsts, instCount,
state.getMemoryModel(), state.getAddressingModel(), state.memory_model(), state.addressing_model(),
state.usedefs(), state.entry_points(), position, pDiag); state.usedefs(), state.entry_points(), position, pDiag);
for (uint64_t instIndex = 0; instIndex < instCount; ++instIndex) { for (uint64_t instIndex = 0; instIndex < instCount; ++instIndex) {
spvCheck(!idUsage.isValid(&pInsts[instIndex]), return SPV_ERROR_INVALID_ID); spvCheck(!idUsage.isValid(&pInsts[instIndex]), return SPV_ERROR_INVALID_ID);

View File

@ -80,7 +80,7 @@ spv_capability_mask_t RequiredCapabilities(const AssemblyGrammar& grammar,
return 0; return 0;
} }
} // namespace anonymous } // namespace
namespace libspirv { namespace libspirv {
@ -127,9 +127,9 @@ spv_result_t InstructionPass(ValidationState_t& _,
_.RegisterCapability( _.RegisterCapability(
static_cast<SpvCapability>(inst->words[inst->operands[0].offset])); static_cast<SpvCapability>(inst->words[inst->operands[0].offset]));
if (opcode == SpvOpMemoryModel) { if (opcode == SpvOpMemoryModel) {
_.setAddressingModel( _.set_addressing_model(
static_cast<SpvAddressingModel>(inst->words[inst->operands[0].offset])); static_cast<SpvAddressingModel>(inst->words[inst->operands[0].offset]));
_.setMemoryModel( _.set_memory_model(
static_cast<SpvMemoryModel>(inst->words[inst->operands[1].offset])); static_cast<SpvMemoryModel>(inst->words[inst->operands[1].offset]));
} }
if (opcode == SpvOpVariable) { if (opcode == SpvOpVariable) {
@ -138,15 +138,17 @@ spv_result_t InstructionPass(ValidationState_t& _,
if (storage_class == SpvStorageClassGeneric) if (storage_class == SpvStorageClassGeneric)
return _.diag(SPV_ERROR_INVALID_BINARY) return _.diag(SPV_ERROR_INVALID_BINARY)
<< "OpVariable storage class cannot be Generic"; << "OpVariable storage class cannot be Generic";
if (_.getLayoutSection() == kLayoutFunctionDefinitions) { if (_.current_layout_section() == kLayoutFunctionDefinitions) {
if (storage_class != SpvStorageClassFunction) { if (storage_class != SpvStorageClassFunction) {
return _.diag(SPV_ERROR_INVALID_LAYOUT) return _.diag(SPV_ERROR_INVALID_LAYOUT)
<< "Variables must have a function[7] storage class inside" << "Variables must have a function[7] storage class inside"
" of a function"; " of a function";
} }
if(_.get_current_function().IsFirstBlock(_.get_current_function().get_current_block()->get_id()) == false) { if (_.current_function().IsFirstBlock(
return _.diag(SPV_ERROR_INVALID_CFG) _.current_function().current_block()->id()) == false) {
<< "Variables can only be defined in the first block of a function"; return _.diag(SPV_ERROR_INVALID_CFG) << "Variables can only be defined "
"in the first block of a "
"function";
} }
} else { } else {
if (storage_class == SpvStorageClassFunction) { if (storage_class == SpvStorageClassFunction) {

View File

@ -50,10 +50,10 @@ namespace {
spv_result_t ModuleScopedInstructions(ValidationState_t& _, spv_result_t ModuleScopedInstructions(ValidationState_t& _,
const spv_parsed_instruction_t* inst, const spv_parsed_instruction_t* inst,
SpvOp opcode) { SpvOp opcode) {
while (_.isOpcodeInCurrentLayoutSection(opcode) == false) { while (_.IsOpcodeInCurrentLayoutSection(opcode) == false) {
_.progressToNextLayoutSectionOrder(); _.ProgressToNextLayoutSectionOrder();
switch (_.getLayoutSection()) { switch (_.current_layout_section()) {
case kLayoutMemoryModel: case kLayoutMemoryModel:
if (opcode != SpvOpMemoryModel) { if (opcode != SpvOpMemoryModel) {
return _.diag(SPV_ERROR_INVALID_LAYOUT) return _.diag(SPV_ERROR_INVALID_LAYOUT)
@ -80,7 +80,7 @@ spv_result_t ModuleScopedInstructions(ValidationState_t& _,
spv_result_t FunctionScopedInstructions(ValidationState_t& _, spv_result_t FunctionScopedInstructions(ValidationState_t& _,
const spv_parsed_instruction_t* inst, const spv_parsed_instruction_t* inst,
SpvOp opcode) { SpvOp opcode) {
if (_.isOpcodeInCurrentLayoutSection(opcode)) { if (_.IsOpcodeInCurrentLayoutSection(opcode)) {
switch (opcode) { switch (opcode) {
case SpvOpFunction: { case SpvOpFunction: {
if (_.in_function_body()) { if (_.in_function_body()) {
@ -92,8 +92,8 @@ spv_result_t FunctionScopedInstructions(ValidationState_t& _,
spvCheckReturn( spvCheckReturn(
_.RegisterFunction(inst->result_id, inst->type_id, control_mask, _.RegisterFunction(inst->result_id, inst->type_id, control_mask,
inst->words[inst->operands[3].offset])); inst->words[inst->operands[3].offset]));
if (_.getLayoutSection() == kLayoutFunctionDefinitions) if (_.current_layout_section() == kLayoutFunctionDefinitions)
spvCheckReturn(_.get_current_function().RegisterSetFunctionDeclType( spvCheckReturn(_.current_function().RegisterSetFunctionDeclType(
FunctionDecl::kFunctionDeclDefinition)); FunctionDecl::kFunctionDeclDefinition));
} break; } break;
@ -103,13 +103,12 @@ spv_result_t FunctionScopedInstructions(ValidationState_t& _,
"instructions must be in " "instructions must be in "
"a function body"; "a function body";
} }
if (_.get_current_function().get_block_count() != 0) { if (_.current_function().block_count() != 0) {
return _.diag(SPV_ERROR_INVALID_LAYOUT) return _.diag(SPV_ERROR_INVALID_LAYOUT)
<< "Function parameters must only appear immediately after " << "Function parameters must only appear immediately after "
"the " "the function definition";
"function definition";
} }
spvCheckReturn(_.get_current_function().RegisterFunctionParameter( spvCheckReturn(_.current_function().RegisterFunctionParameter(
inst->result_id, inst->type_id)); inst->result_id, inst->type_id));
break; break;
@ -122,14 +121,14 @@ spv_result_t FunctionScopedInstructions(ValidationState_t& _,
return _.diag(SPV_ERROR_INVALID_LAYOUT) return _.diag(SPV_ERROR_INVALID_LAYOUT)
<< "Function end cannot be called in blocks"; << "Function end cannot be called in blocks";
} }
if (_.get_current_function().get_block_count() == 0 && if (_.current_function().block_count() == 0 &&
_.getLayoutSection() == kLayoutFunctionDefinitions) { _.current_layout_section() == kLayoutFunctionDefinitions) {
return _.diag(SPV_ERROR_INVALID_LAYOUT) << "Function declarations " return _.diag(SPV_ERROR_INVALID_LAYOUT) << "Function declarations "
"must appear before " "must appear before "
"function definitions."; "function definitions.";
} }
if (_.getLayoutSection() == kLayoutFunctionDeclarations) { if (_.current_layout_section() == kLayoutFunctionDeclarations) {
spvCheckReturn(_.get_current_function().RegisterSetFunctionDeclType( spvCheckReturn(_.current_function().RegisterSetFunctionDeclType(
FunctionDecl::kFunctionDeclDeclaration)); FunctionDecl::kFunctionDeclDeclaration));
} }
spvCheckReturn(_.RegisterFunctionEnd()); spvCheckReturn(_.RegisterFunctionEnd());
@ -150,15 +149,15 @@ spv_result_t FunctionScopedInstructions(ValidationState_t& _,
return _.diag(SPV_ERROR_INVALID_LAYOUT) return _.diag(SPV_ERROR_INVALID_LAYOUT)
<< "A block must end with a branch instruction."; << "A block must end with a branch instruction.";
} }
if (_.getLayoutSection() == kLayoutFunctionDeclarations) { if (_.current_layout_section() == kLayoutFunctionDeclarations) {
_.progressToNextLayoutSectionOrder(); _.ProgressToNextLayoutSectionOrder();
spvCheckReturn(_.get_current_function().RegisterSetFunctionDeclType( spvCheckReturn(_.current_function().RegisterSetFunctionDeclType(
FunctionDecl::kFunctionDeclDefinition)); FunctionDecl::kFunctionDeclDefinition));
} }
break; break;
default: default:
if (_.getLayoutSection() == kLayoutFunctionDeclarations && if (_.current_layout_section() == kLayoutFunctionDeclarations &&
_.in_function_body()) { _.in_function_body()) {
return _.diag(SPV_ERROR_INVALID_LAYOUT) return _.diag(SPV_ERROR_INVALID_LAYOUT)
<< "A function must begin with a label"; << "A function must begin with a label";
@ -188,7 +187,7 @@ spv_result_t ModuleLayoutPass(ValidationState_t& _,
const spv_parsed_instruction_t* inst) { const spv_parsed_instruction_t* inst) {
const SpvOp opcode = static_cast<SpvOp>(inst->opcode); const SpvOp opcode = static_cast<SpvOp>(inst->opcode);
switch (_.getLayoutSection()) { switch (_.current_layout_section()) {
case kLayoutCapabilities: case kLayoutCapabilities:
case kLayoutExtensions: case kLayoutExtensions:
case kLayoutExtInstImport: case kLayoutExtInstImport:

View File

@ -88,7 +88,7 @@ function<bool(unsigned)> getCanBeForwardDeclaredFunction(SpvOp opcode) {
} }
return out; return out;
} }
} } // namespace
namespace libspirv { namespace libspirv {
@ -112,17 +112,17 @@ spv_result_t SsaPass(ValidationState_t& _,
auto ret = SPV_ERROR_INTERNAL; auto ret = SPV_ERROR_INTERNAL;
switch (type) { switch (type) {
case SPV_OPERAND_TYPE_RESULT_ID: case SPV_OPERAND_TYPE_RESULT_ID:
_.removeIfForwardDeclared(*operand_ptr); _.RemoveIfForwardDeclared(*operand_ptr);
ret = SPV_SUCCESS; ret = SPV_SUCCESS;
break; break;
case SPV_OPERAND_TYPE_ID: case SPV_OPERAND_TYPE_ID:
case SPV_OPERAND_TYPE_TYPE_ID: case SPV_OPERAND_TYPE_TYPE_ID:
case SPV_OPERAND_TYPE_MEMORY_SEMANTICS_ID: case SPV_OPERAND_TYPE_MEMORY_SEMANTICS_ID:
case SPV_OPERAND_TYPE_SCOPE_ID: case SPV_OPERAND_TYPE_SCOPE_ID:
if (_.isDefinedId(*operand_ptr)) { if (_.IsDefinedId(*operand_ptr)) {
ret = SPV_SUCCESS; ret = SPV_SUCCESS;
} else if (can_have_forward_declared_ids(i)) { } else if (can_have_forward_declared_ids(i)) {
ret = _.forwardDeclareId(*operand_ptr); ret = _.ForwardDeclareId(*operand_ptr);
} else { } else {
ret = _.diag(SPV_ERROR_INVALID_ID) << "ID " ret = _.diag(SPV_ERROR_INVALID_ID) << "ID "
<< _.getIdName(*operand_ptr) << _.getIdName(*operand_ptr)
@ -139,4 +139,4 @@ spv_result_t SsaPass(ValidationState_t& _,
} }
return SPV_SUCCESS; return SPV_SUCCESS;
} }
} } // namespace libspirv