/src/spirv-tools/source/opt/instruction_list.h
Line | Count | Source (jump to first uncovered line) |
1 | | |
2 | | // Copyright (c) 2017 Google Inc. |
3 | | // |
4 | | // Licensed under the Apache License, Version 2.0 (the "License"); |
5 | | // you may not use this file except in compliance with the License. |
6 | | // You may obtain a copy of the License at |
7 | | // |
8 | | // http://www.apache.org/licenses/LICENSE-2.0 |
9 | | // |
10 | | // Unless required by applicable law or agreed to in writing, software |
11 | | // distributed under the License is distributed on an "AS IS" BASIS, |
12 | | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
13 | | // See the License for the specific language governing permissions and |
14 | | // limitations under the License. |
15 | | |
16 | | #ifndef SOURCE_OPT_INSTRUCTION_LIST_H_ |
17 | | #define SOURCE_OPT_INSTRUCTION_LIST_H_ |
18 | | |
19 | | #include <cassert> |
20 | | #include <functional> |
21 | | #include <memory> |
22 | | #include <utility> |
23 | | #include <vector> |
24 | | |
25 | | #include "source/latest_version_spirv_header.h" |
26 | | #include "source/operand.h" |
27 | | #include "source/opt/instruction.h" |
28 | | #include "source/util/ilist.h" |
29 | | #include "spirv-tools/libspirv.h" |
30 | | |
31 | | namespace spvtools { |
32 | | namespace opt { |
33 | | |
34 | | // This class is intended to be the container for Instructions. This container |
35 | | // owns the instructions that are in it. When removing an Instruction from the |
36 | | // list, the caller is assuming responsibility for deleting the storage. |
37 | | // |
38 | | // TODO: Because there are a number of other data structures that will want |
39 | | // pointers to instruction, ownership should probably be moved to the module. |
40 | | // Because of that I have not made the ownership passing in this class fully |
41 | | // explicit. For example, RemoveFromList takes ownership from the list, but |
42 | | // does not return an std::unique_ptr to signal that. When we fully decide on |
43 | | // ownership, this will have to be fixed up one way or the other. |
44 | | class InstructionList : public utils::IntrusiveList<Instruction> { |
45 | | public: |
46 | 3.65M | InstructionList() = default; |
47 | | InstructionList(InstructionList&& that) |
48 | 0 | : utils::IntrusiveList<Instruction>(std::move(that)) {} |
49 | 0 | InstructionList& operator=(InstructionList&& that) { |
50 | 0 | auto p = static_cast<utils::IntrusiveList<Instruction>*>(this); |
51 | 0 | *p = std::move(that); |
52 | 0 | return *this; |
53 | 0 | } |
54 | | |
55 | | // Destroy this list and any instructions in the list. |
56 | | inline ~InstructionList() override; |
57 | | |
58 | | class iterator : public utils::IntrusiveList<Instruction>::iterator { |
59 | | public: |
60 | | iterator(const utils::IntrusiveList<Instruction>::iterator& i) |
61 | 414M | : utils::IntrusiveList<Instruction>::iterator(i) {} |
62 | 1.39M | iterator(Instruction* i) : utils::IntrusiveList<Instruction>::iterator(i) {} |
63 | | |
64 | 274M | iterator& operator++() { |
65 | 274M | utils::IntrusiveList<Instruction>::iterator::operator++(); |
66 | 274M | return *this; |
67 | 274M | } |
68 | | |
69 | 121M | iterator& operator--() { |
70 | 121M | utils::IntrusiveList<Instruction>::iterator::operator--(); |
71 | 121M | return *this; |
72 | 121M | } |
73 | | |
74 | | // DEPRECATED: Please use MoveBefore with an InstructionList instead. |
75 | | // |
76 | | // Moves the nodes in |list| to the list that |this| points to. The |
77 | | // positions of the nodes will be immediately before the element pointed to |
78 | | // by the iterator. The return value will be an iterator pointing to the |
79 | | // first of the newly inserted elements. Ownership of the elements in |
80 | | // |list| is now passed on to |*this|. |
81 | | iterator InsertBefore(std::vector<std::unique_ptr<Instruction>>&& list); |
82 | | |
83 | | // The node |i| will be inserted immediately before |this|. The return value |
84 | | // will be an iterator pointing to the newly inserted node. The owner of |
85 | | // |*i| becomes |*this| |
86 | | iterator InsertBefore(std::unique_ptr<Instruction>&& i); |
87 | | |
88 | | // Removes the node from the list, and deletes the storage. Returns a valid |
89 | | // iterator to the next node. |
90 | 0 | iterator Erase() { |
91 | 0 | iterator_template next_node = *this; |
92 | 0 | ++next_node; |
93 | 0 | node_->RemoveFromList(); |
94 | 0 | delete node_; |
95 | 0 | return next_node; |
96 | 0 | } |
97 | | }; |
98 | | |
99 | 110M | iterator begin() { return utils::IntrusiveList<Instruction>::begin(); } |
100 | 303M | iterator end() { return utils::IntrusiveList<Instruction>::end(); } |
101 | 4.22M | const_iterator begin() const { |
102 | 4.22M | return utils::IntrusiveList<Instruction>::begin(); |
103 | 4.22M | } |
104 | 4.22M | const_iterator end() const { |
105 | 4.22M | return utils::IntrusiveList<Instruction>::end(); |
106 | 4.22M | } |
107 | | |
108 | 32.9M | void push_back(std::unique_ptr<Instruction>&& inst) { |
109 | 32.9M | utils::IntrusiveList<Instruction>::push_back(inst.release()); |
110 | 32.9M | } |
111 | | |
112 | | // Same as in the base class, except it will delete the data as well. |
113 | | inline void clear(); |
114 | | |
115 | | // Runs the given function |f| on the instructions in the list and optionally |
116 | | // on the preceding debug line instructions. |
117 | | inline void ForEachInst(const std::function<void(Instruction*)>& f, |
118 | 6.96M | bool run_on_debug_line_insts) { |
119 | 6.96M | auto next = begin(); |
120 | 34.0M | for (auto i = next; i != end(); i = next) { |
121 | 27.0M | ++next; |
122 | 27.0M | i->ForEachInst(f, run_on_debug_line_insts); |
123 | 27.0M | } |
124 | 6.96M | } |
125 | | }; |
126 | | |
127 | 3.65M | InstructionList::~InstructionList() { clear(); } |
128 | | |
129 | 3.65M | void InstructionList::clear() { |
130 | 15.9M | while (!empty()) { |
131 | 12.3M | Instruction* inst = &front(); |
132 | 12.3M | inst->RemoveFromList(); |
133 | 12.3M | delete inst; |
134 | 12.3M | } |
135 | 3.65M | } |
136 | | |
137 | | } // namespace opt |
138 | | } // namespace spvtools |
139 | | |
140 | | #endif // SOURCE_OPT_INSTRUCTION_LIST_H_ |