• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2015-2016 The Khronos Group 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_OPERAND_H_
16 #define SOURCE_OPERAND_H_
17 
18 #include <functional>
19 #include <vector>
20 
21 #include "source/table.h"
22 #include "spirv-tools/libspirv.h"
23 
24 // A sequence of operand types.
25 //
26 // A SPIR-V parser uses an operand pattern to describe what is expected
27 // next on the input.
28 //
29 // As we parse an instruction in text or binary form from left to right,
30 // we pop and push at the end of the pattern vector. Symbols later in the
31 // pattern vector are matched against the input before symbols earlier in the
32 // pattern vector are matched.
33 
34 // Using a vector in this way reduces memory traffic, which is good for
35 // performance.
36 using spv_operand_pattern_t = std::vector<spv_operand_type_t>;
37 
38 // Finds the named operand in the table. The type parameter specifies the
39 // operand's group. A handle of the operand table entry for this operand will
40 // be written into *entry.
41 spv_result_t spvOperandTableNameLookup(spv_target_env,
42                                        const spv_operand_table table,
43                                        const spv_operand_type_t type,
44                                        const char* name,
45                                        const size_t name_length,
46                                        spv_operand_desc* entry);
47 
48 // Finds the operand with value in the table. The type parameter specifies the
49 // operand's group. A handle of the operand table entry for this operand will
50 // be written into *entry.
51 spv_result_t spvOperandTableValueLookup(spv_target_env,
52                                         const spv_operand_table table,
53                                         const spv_operand_type_t type,
54                                         const uint32_t value,
55                                         spv_operand_desc* entry);
56 
57 // Gets the name string of the non-variable operand type.
58 const char* spvOperandTypeStr(spv_operand_type_t type);
59 
60 // Returns true if an operand of the given type is optional.
61 bool spvOperandIsOptional(spv_operand_type_t type);
62 
63 // Returns true if an operand type represents zero or more logical operands.
64 //
65 // Note that a single logical operand may still be a variable number of words.
66 // For example, a literal string may be many words, but is just one logical
67 // operand.
68 bool spvOperandIsVariable(spv_operand_type_t type);
69 
70 // Append a list of operand types to the end of the pattern vector.
71 // The types parameter specifies the source array of types, ending with
72 // SPV_OPERAND_TYPE_NONE.
73 void spvPushOperandTypes(const spv_operand_type_t* types,
74                          spv_operand_pattern_t* pattern);
75 
76 // Appends the operands expected after the given typed mask onto the
77 // end of the given pattern.
78 //
79 // Each set bit in the mask represents zero or more operand types that should
80 // be appended onto the pattern.  Operands for a less significant bit always
81 // appear after operands for a more significant bit.
82 //
83 // If a set bit is unknown, then we assume it has no operands.
84 void spvPushOperandTypesForMask(spv_target_env,
85                                 const spv_operand_table operand_table,
86                                 const spv_operand_type_t mask_type,
87                                 const uint32_t mask,
88                                 spv_operand_pattern_t* pattern);
89 
90 // Expands an operand type representing zero or more logical operands,
91 // exactly once.
92 //
93 // If the given type represents potentially several logical operands,
94 // then prepend the given pattern with the first expansion of the logical
95 // operands, followed by original type.  Otherwise, don't modify the pattern.
96 //
97 // For example, the SPV_OPERAND_TYPE_VARIABLE_ID represents zero or more
98 // IDs.  In that case we would prepend the pattern with SPV_OPERAND_TYPE_ID
99 // followed by SPV_OPERAND_TYPE_VARIABLE_ID again.
100 //
101 // This also applies to zero or more tuples of logical operands.  In that case
102 // we prepend pattern with for the members of the tuple, followed by the
103 // original type argument.  The pattern must encode the fact that if any part
104 // of the tuple is present, then all tuple members should be.  So the first
105 // member of the tuple must be optional, and the remaining members
106 // non-optional.
107 //
108 // Returns true if we modified the pattern.
109 bool spvExpandOperandSequenceOnce(spv_operand_type_t type,
110                                   spv_operand_pattern_t* pattern);
111 
112 // Expands the first element in the pattern until it is a matchable operand
113 // type, then pops it off the front and returns it.  The pattern must not be
114 // empty.
115 //
116 // A matchable operand type is anything other than a zero-or-more-items
117 // operand type.
118 spv_operand_type_t spvTakeFirstMatchableOperand(spv_operand_pattern_t* pattern);
119 
120 // Calculates the corresponding post-immediate alternate pattern, which allows
121 // a limited set of operand types.
122 spv_operand_pattern_t spvAlternatePatternFollowingImmediate(
123     const spv_operand_pattern_t& pattern);
124 
125 // Is the operand an ID?
126 bool spvIsIdType(spv_operand_type_t type);
127 
128 // Is the operand an input ID?
129 bool spvIsInIdType(spv_operand_type_t type);
130 
131 // Takes the opcode of an instruction and returns
132 // a function object that will return true if the index
133 // of the operand can be forward declared. This function will
134 // used in the SSA validation stage of the pipeline
135 std::function<bool(unsigned)> spvOperandCanBeForwardDeclaredFunction(
136     spv::Op opcode);
137 
138 // Takes the instruction key of a debug info extension instruction
139 // and returns a function object that will return true if the index
140 // of the operand can be forward declared. This function will
141 // used in the SSA validation stage of the pipeline
142 std::function<bool(unsigned)> spvDbgInfoExtOperandCanBeForwardDeclaredFunction(
143     spv::Op opcode, spv_ext_inst_type_t ext_type, uint32_t key);
144 
145 #endif  // SOURCE_OPERAND_H_
146