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
27namespace spvtools {
28namespace 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.
38class 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 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 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