1 // Copyright (c) 2016 Google Inc. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 #ifndef SOURCE_OPT_IR_LOADER_H_ 16 #define SOURCE_OPT_IR_LOADER_H_ 17 18 #include <memory> 19 #include <string> 20 #include <vector> 21 22 #include "source/opt/basic_block.h" 23 #include "source/opt/instruction.h" 24 #include "source/opt/module.h" 25 #include "spirv-tools/libspirv.hpp" 26 27 namespace spvtools { 28 namespace opt { 29 30 // Loader class for constructing SPIR-V in-memory IR representation. Methods in 31 // this class are designed to work with the interface for spvBinaryParse() in 32 // libspirv.h so that we can leverage the syntax checks implemented behind it. 33 // 34 // The user is expected to call SetModuleHeader() to fill in the module's 35 // header, and then AddInstruction() for each decoded instruction, and finally 36 // EndModule() to finalize the module. The instructions processed in sequence 37 // by AddInstruction() should comprise a valid SPIR-V module. 38 class IrLoader { 39 public: 40 // Instantiates a builder to construct the given |module| gradually. 41 // All internal messages will be communicated to the outside via the given 42 // message |consumer|. This instance only keeps a reference to the |consumer|, 43 // so the |consumer| should outlive this instance. 44 IrLoader(const MessageConsumer& consumer, Module* m); 45 46 // Sets the source name of the module. SetSource(const std::string & src)47 void SetSource(const std::string& src) { source_ = src; } 48 module()49 Module* module() const { return module_; } 50 51 // Sets the fields in the module's header to the given parameters. SetModuleHeader(uint32_t magic,uint32_t version,uint32_t generator,uint32_t bound,uint32_t reserved)52 void SetModuleHeader(uint32_t magic, uint32_t version, uint32_t generator, 53 uint32_t bound, uint32_t reserved) { 54 module_->SetHeader({magic, version, generator, bound, reserved}); 55 } 56 // Adds an instruction to the module. Returns true if no error occurs. This 57 // method will properly capture and store the data provided in |inst| so that 58 // |inst| is no longer needed after returning. 59 bool AddInstruction(const spv_parsed_instruction_t* inst); 60 // Finalizes the module construction. This must be called after the module 61 // header has been set and all instructions have been added. This is 62 // forgiving in the case of a missing terminator instruction on a basic block, 63 // or a missing OpFunctionEnd. Resolves internal bookkeeping. 64 void EndModule(); 65 66 // Sets whether extra OpLine instructions should be injected to better 67 // track line information. SetExtraLineTracking(bool flag)68 void SetExtraLineTracking(bool flag) { extra_line_tracking_ = flag; } 69 70 private: 71 // Consumer for communicating messages to outside. 72 const MessageConsumer& consumer_; 73 // The module to be built. 74 Module* module_; 75 // The source name of the module. 76 std::string source_; 77 // The last used instruction index. 78 uint32_t inst_index_; 79 // The current Function under construction. 80 std::unique_ptr<Function> function_; 81 // The current BasicBlock under construction. 82 std::unique_ptr<BasicBlock> block_; 83 // Line related debug instructions accumulated thus far. 84 std::vector<Instruction> dbg_line_info_; 85 // If doing extra line tracking, this is the line instruction that should be 86 // applied to the next instruction. Otherwise it always contains null. 87 std::unique_ptr<Instruction> last_line_inst_; 88 89 // The last DebugScope information that IrLoader::AddInstruction() handled. 90 DebugScope last_dbg_scope_; 91 92 // When true, do extra line information tracking: Additional OpLine 93 // instructions will be injected to help track line info more robustly during 94 // transformations. 95 bool extra_line_tracking_ = true; 96 }; 97 98 } // namespace opt 99 } // namespace spvtools 100 101 #endif // SOURCE_OPT_IR_LOADER_H_ 102