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 LIBSPIRV_OPT_CONSTRUCTS_H_
16 #define LIBSPIRV_OPT_CONSTRUCTS_H_
17
18 #include <functional>
19 #include <memory>
20 #include <utility>
21 #include <vector>
22
23 #include "basic_block.h"
24 #include "instruction.h"
25 #include "iterator.h"
26
27 namespace spvtools {
28 namespace ir {
29
30 class Module;
31
32 // A SPIR-V function.
33 class Function {
34 public:
35 using iterator = UptrVectorIterator<BasicBlock>;
36 using const_iterator = UptrVectorIterator<BasicBlock, true>;
37
38 // Creates a function instance declared by the given OpFunction instruction
39 // |def_inst|.
40 inline explicit Function(std::unique_ptr<Instruction> def_inst);
41 // The OpFunction instruction that begins the definition of this function.
DefInst()42 Instruction& DefInst() { return *def_inst_; }
43
44 // Sets the enclosing module for this function.
SetParent(Module * module)45 void SetParent(Module* module) { module_ = module; }
46 // Appends a parameter to this function.
47 inline void AddParameter(std::unique_ptr<Instruction> p);
48 // Appends a basic block to this function.
49 inline void AddBasicBlock(std::unique_ptr<BasicBlock> b);
50
51 // Saves the given function end instruction.
52 inline void SetFunctionEnd(std::unique_ptr<Instruction> end_inst);
53
54 // Returns function's id
result_id()55 inline uint32_t result_id() const { return def_inst_->result_id(); }
56
57 // Returns function's type id
type_id()58 inline uint32_t type_id() const { return def_inst_->type_id(); }
59
begin()60 iterator begin() { return iterator(&blocks_, blocks_.begin()); }
end()61 iterator end() { return iterator(&blocks_, blocks_.end()); }
cbegin()62 const_iterator cbegin() const {
63 return const_iterator(&blocks_, blocks_.cbegin());
64 }
cend()65 const_iterator cend() const {
66 return const_iterator(&blocks_, blocks_.cend());
67 }
68
69 // Runs the given function |f| on each instruction in this function, and
70 // optionally on debug line instructions that might precede them.
71 void ForEachInst(const std::function<void(Instruction*)>& f,
72 bool run_on_debug_line_insts = false);
73 void ForEachInst(const std::function<void(const Instruction*)>& f,
74 bool run_on_debug_line_insts = false) const;
75
76 // Runs the given function |f| on each parameter instruction in this function,
77 // and optionally on debug line instructions that might precede them.
78 void ForEachParam(const std::function<void(const Instruction*)>& f,
79 bool run_on_debug_line_insts = false) const;
80
81 private:
82 // The enclosing module.
83 Module* module_;
84 // The OpFunction instruction that begins the definition of this function.
85 std::unique_ptr<Instruction> def_inst_;
86 // All parameters to this function.
87 std::vector<std::unique_ptr<Instruction>> params_;
88 // All basic blocks inside this function in specification order
89 std::vector<std::unique_ptr<BasicBlock>> blocks_;
90 // The OpFunctionEnd instruction.
91 std::unique_ptr<Instruction> end_inst_;
92 };
93
Function(std::unique_ptr<Instruction> def_inst)94 inline Function::Function(std::unique_ptr<Instruction> def_inst)
95 : module_(nullptr), def_inst_(std::move(def_inst)), end_inst_() {}
96
AddParameter(std::unique_ptr<Instruction> p)97 inline void Function::AddParameter(std::unique_ptr<Instruction> p) {
98 params_.emplace_back(std::move(p));
99 }
100
AddBasicBlock(std::unique_ptr<BasicBlock> b)101 inline void Function::AddBasicBlock(std::unique_ptr<BasicBlock> b) {
102 blocks_.emplace_back(std::move(b));
103 }
104
SetFunctionEnd(std::unique_ptr<Instruction> end_inst)105 inline void Function::SetFunctionEnd(std::unique_ptr<Instruction> end_inst) {
106 end_inst_ = std::move(end_inst);
107 }
108
109 } // namespace ir
110 } // namespace spvtools
111
112 #endif // LIBSPIRV_OPT_CONSTRUCTS_H_
113