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. |
47 | void SetSource(const std::string& src) { source_ = src; } |
48 | |
49 | Module* module() const { return module_; } |
50 | |
51 | // Sets the fields in the module's header to the given parameters. |
52 | void (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 | private: |
67 | // Consumer for communicating messages to outside. |
68 | const MessageConsumer& consumer_; |
69 | // The module to be built. |
70 | Module* module_; |
71 | // The source name of the module. |
72 | std::string source_; |
73 | // The last used instruction index. |
74 | uint32_t inst_index_; |
75 | // The current Function under construction. |
76 | std::unique_ptr<Function> function_; |
77 | // The current BasicBlock under construction. |
78 | std::unique_ptr<BasicBlock> block_; |
79 | // Line related debug instructions accumulated thus far. |
80 | std::vector<Instruction> dbg_line_info_; |
81 | |
82 | // The last DebugScope information that IrLoader::AddInstruction() handled. |
83 | DebugScope last_dbg_scope_; |
84 | }; |
85 | |
86 | } // namespace opt |
87 | } // namespace spvtools |
88 | |
89 | #endif // SOURCE_OPT_IR_LOADER_H_ |
90 | |