mirror of
https://github.com/KhronosGroup/SPIRV-Tools
synced 2024-12-28 10:41:04 +00:00
9fc8658ef3
Fixes https://github.com/KhronosGroup/SPIRV-Tools/issues/383 Finalize v2016.4
241 lines
8.6 KiB
C++
241 lines
8.6 KiB
C++
// Copyright (c) 2016 Google Inc.
|
|
//
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
// you may not use this file except in compliance with the License.
|
|
// You may obtain a copy of the License at
|
|
//
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
|
|
#ifndef LIBSPIRV_OPT_MODULE_H_
|
|
#define LIBSPIRV_OPT_MODULE_H_
|
|
|
|
#include <functional>
|
|
#include <memory>
|
|
#include <utility>
|
|
#include <vector>
|
|
|
|
#include "function.h"
|
|
#include "instruction.h"
|
|
#include "iterator.h"
|
|
|
|
namespace spvtools {
|
|
namespace ir {
|
|
|
|
// A struct for containing the module header information.
|
|
struct ModuleHeader {
|
|
uint32_t magic_number;
|
|
uint32_t version;
|
|
uint32_t generator;
|
|
uint32_t bound;
|
|
uint32_t reserved;
|
|
};
|
|
|
|
// A SPIR-V module. It contains all the information for a SPIR-V module and
|
|
// serves as the backbone of optimization transformations.
|
|
class Module {
|
|
public:
|
|
using iterator = UptrVectorIterator<Function>;
|
|
using const_iterator = UptrVectorIterator<Function, true>;
|
|
using inst_iterator = UptrVectorIterator<Instruction>;
|
|
using const_inst_iterator = UptrVectorIterator<Instruction, true>;
|
|
|
|
// Creates an empty module with zero'd header.
|
|
Module() : header_({}) {}
|
|
|
|
// Sets the header to the given |header|.
|
|
void SetHeader(const ModuleHeader& header) { header_ = header; }
|
|
// Sets the Id bound.
|
|
void SetIdBound(uint32_t bound) { header_.bound = bound; }
|
|
// Appends a capability instruction to this module.
|
|
inline void AddCapability(std::unique_ptr<Instruction> c);
|
|
// Appends an extension instruction to this module.
|
|
inline void AddExtension(std::unique_ptr<Instruction> e);
|
|
// Appends an extended instruction set instruction to this module.
|
|
inline void AddExtInstImport(std::unique_ptr<Instruction> e);
|
|
// Set the memory model for this module.
|
|
inline void SetMemoryModel(std::unique_ptr<Instruction> m);
|
|
// Appends an entry point instruction to this module.
|
|
inline void AddEntryPoint(std::unique_ptr<Instruction> e);
|
|
// Appends an execution mode instruction to this module.
|
|
inline void AddExecutionMode(std::unique_ptr<Instruction> e);
|
|
// Appends a debug instruction (excluding OpLine & OpNoLine) to this module.
|
|
inline void AddDebugInst(std::unique_ptr<Instruction> d);
|
|
// Appends an annotation instruction to this module.
|
|
inline void AddAnnotationInst(std::unique_ptr<Instruction> a);
|
|
// Appends a type-declaration instruction to this module.
|
|
inline void AddType(std::unique_ptr<Instruction> t);
|
|
// Appends a constant, global variable, or OpUndef instruction to this module.
|
|
inline void AddGlobalValue(std::unique_ptr<Instruction> v);
|
|
// Appends a function to this module.
|
|
inline void AddFunction(std::unique_ptr<Function> f);
|
|
|
|
// Returns a vector of pointers to type-declaration instructions in this
|
|
// module.
|
|
std::vector<Instruction*> GetTypes();
|
|
std::vector<const Instruction*> GetTypes() const;
|
|
// Returns a vector of pointers to constant-creation instructions in this
|
|
// module.
|
|
std::vector<Instruction*> GetConstants();
|
|
std::vector<const Instruction*> GetConstants() const;
|
|
|
|
// Iterators for debug instructions (excluding OpLine & OpNoLine) contained in
|
|
// this module.
|
|
inline inst_iterator debug_begin();
|
|
inline inst_iterator debug_end();
|
|
inline IteratorRange<inst_iterator> debugs();
|
|
inline IteratorRange<const_inst_iterator> debugs() const;
|
|
|
|
// Clears all debug instructions (excluding OpLine & OpNoLine).
|
|
void debug_clear() { debugs_.clear(); }
|
|
|
|
// Iterators for annotation instructions contained in this module.
|
|
IteratorRange<inst_iterator> annotations();
|
|
IteratorRange<const_inst_iterator> annotations() const;
|
|
|
|
// Iterators for types, constants and global variables instructions.
|
|
inline inst_iterator types_values_begin();
|
|
inline inst_iterator types_values_end();
|
|
inline IteratorRange<inst_iterator> types_values();
|
|
inline IteratorRange<const_inst_iterator> types_values() const;
|
|
|
|
// Iterators for functions contained in this module.
|
|
iterator begin() { return iterator(&functions_, functions_.begin()); }
|
|
iterator end() { return iterator(&functions_, functions_.end()); }
|
|
inline const_iterator cbegin() const;
|
|
inline const_iterator cend() const;
|
|
|
|
// Invokes function |f| on all instructions in this module, and optionally on
|
|
// the debug line instructions that precede them.
|
|
void ForEachInst(const std::function<void(Instruction*)>& f,
|
|
bool run_on_debug_line_insts = false);
|
|
void ForEachInst(const std::function<void(const Instruction*)>& f,
|
|
bool run_on_debug_line_insts = false) const;
|
|
|
|
// Pushes the binary segments for this instruction into the back of *|binary|.
|
|
// If |skip_nop| is true and this is a OpNop, do nothing.
|
|
void ToBinary(std::vector<uint32_t>* binary, bool skip_nop) const;
|
|
|
|
// Returns 1 more than the maximum Id value mentioned in the module.
|
|
uint32_t ComputeIdBound() const;
|
|
|
|
private:
|
|
ModuleHeader header_; // Module header
|
|
|
|
// The following fields respect the "Logical Layout of a Module" in
|
|
// Section 2.4 of the SPIR-V specification.
|
|
std::vector<std::unique_ptr<Instruction>> capabilities_;
|
|
std::vector<std::unique_ptr<Instruction>> extensions_;
|
|
std::vector<std::unique_ptr<Instruction>> ext_inst_imports_;
|
|
// A module only has one memory model instruction.
|
|
std::unique_ptr<Instruction> memory_model_;
|
|
std::vector<std::unique_ptr<Instruction>> entry_points_;
|
|
std::vector<std::unique_ptr<Instruction>> execution_modes_;
|
|
std::vector<std::unique_ptr<Instruction>> debugs_;
|
|
std::vector<std::unique_ptr<Instruction>> annotations_;
|
|
// Type declarations, constants, and global variable declarations.
|
|
std::vector<std::unique_ptr<Instruction>> types_values_;
|
|
std::vector<std::unique_ptr<Function>> functions_;
|
|
};
|
|
|
|
inline void Module::AddCapability(std::unique_ptr<Instruction> c) {
|
|
capabilities_.emplace_back(std::move(c));
|
|
}
|
|
|
|
inline void Module::AddExtension(std::unique_ptr<Instruction> e) {
|
|
extensions_.emplace_back(std::move(e));
|
|
}
|
|
|
|
inline void Module::AddExtInstImport(std::unique_ptr<Instruction> e) {
|
|
ext_inst_imports_.emplace_back(std::move(e));
|
|
}
|
|
|
|
inline void Module::SetMemoryModel(std::unique_ptr<Instruction> m) {
|
|
memory_model_ = std::move(m);
|
|
}
|
|
|
|
inline void Module::AddEntryPoint(std::unique_ptr<Instruction> e) {
|
|
entry_points_.emplace_back(std::move(e));
|
|
}
|
|
|
|
inline void Module::AddExecutionMode(std::unique_ptr<Instruction> e) {
|
|
execution_modes_.emplace_back(std::move(e));
|
|
}
|
|
|
|
inline void Module::AddDebugInst(std::unique_ptr<Instruction> d) {
|
|
debugs_.emplace_back(std::move(d));
|
|
}
|
|
|
|
inline void Module::AddAnnotationInst(std::unique_ptr<Instruction> a) {
|
|
annotations_.emplace_back(std::move(a));
|
|
}
|
|
|
|
inline void Module::AddType(std::unique_ptr<Instruction> t) {
|
|
types_values_.emplace_back(std::move(t));
|
|
}
|
|
|
|
inline void Module::AddGlobalValue(std::unique_ptr<Instruction> v) {
|
|
types_values_.emplace_back(std::move(v));
|
|
}
|
|
|
|
inline void Module::AddFunction(std::unique_ptr<Function> f) {
|
|
functions_.emplace_back(std::move(f));
|
|
}
|
|
|
|
inline Module::inst_iterator Module::debug_begin() {
|
|
return inst_iterator(&debugs_, debugs_.begin());
|
|
}
|
|
inline Module::inst_iterator Module::debug_end() {
|
|
return inst_iterator(&debugs_, debugs_.end());
|
|
}
|
|
|
|
inline IteratorRange<Module::inst_iterator> Module::debugs() {
|
|
return make_range(debugs_);
|
|
}
|
|
|
|
inline IteratorRange<Module::const_inst_iterator> Module::debugs() const {
|
|
return make_const_range(debugs_);
|
|
}
|
|
|
|
inline IteratorRange<Module::inst_iterator> Module::annotations() {
|
|
return make_range(annotations_);
|
|
}
|
|
|
|
inline IteratorRange<Module::const_inst_iterator> Module::annotations() const {
|
|
return make_const_range(annotations_);
|
|
}
|
|
|
|
inline Module::inst_iterator Module::types_values_begin() {
|
|
return inst_iterator(&types_values_, types_values_.begin());
|
|
}
|
|
|
|
inline Module::inst_iterator Module::types_values_end() {
|
|
return inst_iterator(&types_values_, types_values_.end());
|
|
}
|
|
|
|
inline IteratorRange<Module::inst_iterator> Module::types_values() {
|
|
return make_range(types_values_);
|
|
}
|
|
|
|
inline IteratorRange<Module::const_inst_iterator> Module::types_values() const {
|
|
return make_const_range(types_values_);
|
|
}
|
|
|
|
inline Module::const_iterator Module::cbegin() const {
|
|
return const_iterator(&functions_, functions_.cbegin());
|
|
}
|
|
|
|
inline Module::const_iterator Module::cend() const {
|
|
return const_iterator(&functions_, functions_.cend());
|
|
}
|
|
|
|
} // namespace ir
|
|
} // namespace spvtools
|
|
|
|
#endif // LIBSPIRV_OPT_MODULE_H_
|