SPIRV-Tools/source/opt/ir_loader.h

102 lines
4.0 KiB
C
Raw Normal View History

// 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 SOURCE_OPT_IR_LOADER_H_
#define SOURCE_OPT_IR_LOADER_H_
#include <memory>
#include <string>
#include <vector>
#include "source/opt/basic_block.h"
#include "source/opt/instruction.h"
#include "source/opt/module.h"
2016-09-21 21:16:31 +00:00
#include "spirv-tools/libspirv.hpp"
namespace spvtools {
namespace opt {
// Loader class for constructing SPIR-V in-memory IR representation. Methods in
// this class are designed to work with the interface for spvBinaryParse() in
// libspirv.h so that we can leverage the syntax checks implemented behind it.
//
// The user is expected to call SetModuleHeader() to fill in the module's
// header, and then AddInstruction() for each decoded instruction, and finally
// EndModule() to finalize the module. The instructions processed in sequence
// by AddInstruction() should comprise a valid SPIR-V module.
class IrLoader {
public:
// Instantiates a builder to construct the given |module| gradually.
// All internal messages will be communicated to the outside via the given
// message |consumer|. This instance only keeps a reference to the |consumer|,
// so the |consumer| should outlive this instance.
Adding an unique id to Instruction generated by IRContext Each instruction is given an unique id that can be used for ordering purposes. The ids are generated via the IRContext. Major changes: * Instructions now contain a uint32_t for unique id and a cached context pointer * Most constructors have been modified to take a context as input * unfortunately I cannot remove the default and copy constructors, but developers should avoid these * Added accessors to parents of basic block and function * Removed the copy constructors for BasicBlock and Function and replaced them with Clone functions * Reworked BuildModule to return an IRContext owning the built module * Since all instructions require a context, the context now becomes the basic unit for IR * Added a constructor to context to create an owned module internally * Replaced uses of Instruction's copy constructor with Clone whereever I found them * Reworked the linker functionality to perform clones into a different context instead of moves * Updated many tests to be consistent with the above changes * Still need to add new tests to cover added functionality * Added comparison operators to Instruction * Added an internal option to LinkerOptions to verify merged ids are unique * Added a test for the linker to verify merged ids are unique * Updated MergeReturnPass to supply a context * Updated DecorationManager to supply a context for cloned decorations * Reworked several portions of the def use tests in anticipation of next set of changes
2017-11-14 19:11:50 +00:00
IrLoader(const MessageConsumer& consumer, Module* m);
// Sets the source name of the module.
void SetSource(const std::string& src) { source_ = src; }
Adding an unique id to Instruction generated by IRContext Each instruction is given an unique id that can be used for ordering purposes. The ids are generated via the IRContext. Major changes: * Instructions now contain a uint32_t for unique id and a cached context pointer * Most constructors have been modified to take a context as input * unfortunately I cannot remove the default and copy constructors, but developers should avoid these * Added accessors to parents of basic block and function * Removed the copy constructors for BasicBlock and Function and replaced them with Clone functions * Reworked BuildModule to return an IRContext owning the built module * Since all instructions require a context, the context now becomes the basic unit for IR * Added a constructor to context to create an owned module internally * Replaced uses of Instruction's copy constructor with Clone whereever I found them * Reworked the linker functionality to perform clones into a different context instead of moves * Updated many tests to be consistent with the above changes * Still need to add new tests to cover added functionality * Added comparison operators to Instruction * Added an internal option to LinkerOptions to verify merged ids are unique * Added a test for the linker to verify merged ids are unique * Updated MergeReturnPass to supply a context * Updated DecorationManager to supply a context for cloned decorations * Reworked several portions of the def use tests in anticipation of next set of changes
2017-11-14 19:11:50 +00:00
Module* module() const { return module_; }
// Sets the fields in the module's header to the given parameters.
void SetModuleHeader(uint32_t magic, uint32_t version, uint32_t generator,
uint32_t bound, uint32_t reserved) {
module_->SetHeader({magic, version, generator, bound, reserved});
}
// Adds an instruction to the module. Returns true if no error occurs. This
// method will properly capture and store the data provided in |inst| so that
// |inst| is no longer needed after returning.
bool AddInstruction(const spv_parsed_instruction_t* inst);
// Finalizes the module construction. This must be called after the module
// header has been set and all instructions have been added. This is
// forgiving in the case of a missing terminator instruction on a basic block,
// or a missing OpFunctionEnd. Resolves internal bookkeeping.
void EndModule();
// Sets whether extra OpLine instructions should be injected to better
// track line information.
void SetExtraLineTracking(bool flag) { extra_line_tracking_ = flag; }
private:
// Consumer for communicating messages to outside.
const MessageConsumer& consumer_;
// The module to be built.
Module* module_;
// The source name of the module.
std::string source_;
// The last used instruction index.
uint32_t inst_index_;
// The current Function under construction.
std::unique_ptr<Function> function_;
// The current BasicBlock under construction.
std::unique_ptr<BasicBlock> block_;
// Line related debug instructions accumulated thus far.
std::vector<Instruction> dbg_line_info_;
// If doing extra line tracking, this is the line instruction that should be
// applied to the next instruction. Otherwise it always contains null.
Propagate OpLine to all applied instructions in spirv-opt (#3951) Based on the OpLine spec, an OpLine instruction must be applied to the instructions physically following it up to the first occurrence of the next end of block, the next OpLine instruction, or the next OpNoLine instruction. ``` OpLine %file 0 0 OpNoLine OpLine %file 1 1 OpStore %foo %int_1 %value = OpLoad %int %foo OpLine %file 2 2 ``` For the above code, the current spirv-opt keeps three line instructions `OpLine %file 0 0`, `OpNoLine`, and `OpLine %file 1 1` in `std::vector<Instruction> dbg_line_insts_` of Instruction class for `OpStore %foo %int_1`. It does not put any line instruction to `std::vector<Instruction> dbg_line_insts_` of `%value = OpLoad %int %foo` even though `OpLine %file 1 1` must be applied to `%value = OpLoad %int %foo` based on the spec. This results in the missing line information for `%value = OpLoad %int %foo` while each spirv-opt pass optimizes the code. We have to put `OpLine %file 1 1` to `std::vector<Instruction> dbg_line_insts_` of both `%value = OpLoad %int %foo` and `OpStore %foo %int_1`. This commit conducts the line instruction propagation and skips emitting the eliminated line instructions at the end, which are the same with PropagateLineInfoPass and RedundantLineInfoElimPass. This commit removes PropagateLineInfoPass and RedundantLineInfoElimPass. KhronosGroup/glslang#2440 is a related PR that stop using PropagateLineInfoPass and RedundantLineInfoElimPass from glslang. When the code in this PR applied, the glslang tests will pass.
2020-10-29 17:06:30 +00:00
std::unique_ptr<Instruction> last_line_inst_;
// The last DebugScope information that IrLoader::AddInstruction() handled.
DebugScope last_dbg_scope_;
// When true, do extra line information tracking: Additional OpLine
// instructions will be injected to help track line info more robustly during
// transformations.
bool extra_line_tracking_ = true;
};
} // namespace opt
} // namespace spvtools
#endif // SOURCE_OPT_IR_LOADER_H_