1// Copyright (c) 2016 Google Inc.
2//
3// Permission is hereby granted, free of charge, to any person obtaining a
4// copy of this software and/or associated documentation files (the
5// "Materials"), to deal in the Materials without restriction, including
6// without limitation the rights to use, copy, modify, merge, publish,
7// distribute, sublicense, and/or sell copies of the Materials, and to
8// permit persons to whom the Materials are furnished to do so, subject to
9// the following conditions:
10//
11// The above copyright notice and this permission notice shall be included
12// in all copies or substantial portions of the Materials.
13//
14// MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS
15// KHRONOS STANDARDS. THE UNMODIFIED, NORMATIVE VERSIONS OF KHRONOS
16// SPECIFICATIONS AND HEADER INFORMATION ARE LOCATED AT
17//    https://www.khronos.org/registry/
18//
19// THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
20// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
22// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
23// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
24// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
25// MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
26
27#ifndef LIBSPIRV_OPT_IR_LOADER_H_
28#define LIBSPIRV_OPT_IR_LOADER_H_
29
30#include <memory>
31
32#include "basic_block.h"
33#include "instruction.h"
34#include "module.h"
35#include "spirv-tools/libspirv.h"
36
37namespace spvtools {
38namespace ir {
39
40// Loader class for constructing SPIR-V in-memory IR representation. Methods in
41// this class are designed to work with the interface for spvBinaryParse() in
42// libspirv.h so that we can leverage the syntax checks implemented behind it.
43//
44// The user is expected to call SetModuleHeader() to fill in the module's
45// header, and then AddInstruction() for each decoded instruction, and finally
46// EndModule() to finalize the module. The instructions processed in sequence
47// by AddInstruction() should comprise a valid SPIR-V module.
48class IrLoader {
49 public:
50  // Instantiates a builder to construct the given |module| gradually.
51  IrLoader(Module* module) : module_(module) {}
52
53  // Sets the fields in the module's header to the given parameters.
54  void SetModuleHeader(uint32_t magic, uint32_t version, uint32_t generator,
55                       uint32_t bound, uint32_t reserved) {
56    module_->SetHeader({magic, version, generator, bound, reserved});
57  }
58  // Adds an instruction to the module. This method will properly capture and
59  // store the data provided in |inst| so that |inst| is no longer needed after
60  // returning.
61  void AddInstruction(const spv_parsed_instruction_t* inst);
62  // Finalizes the module construction. This must be called after the module
63  // header has been set and all instructions have been added.
64  // Resolves internal bookkeeping.
65  void EndModule();
66
67 private:
68  // The module to be built.
69  Module* module_;
70  // The current Function under construction.
71  std::unique_ptr<Function> function_;
72  // The current BasicBlock under construction.
73  std::unique_ptr<BasicBlock> block_;
74  // Line related debug instructions accumulated thus far.
75  std::vector<Instruction> dbg_line_info_;
76};
77
78}  // namespace ir
79}  // namespace spvtools
80
81#endif  // LIBSPIRV_OPT_IR_LOADER_H_
82