• 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 the given type is concrete.
61 bool spvOperandIsConcrete(spv_operand_type_t type);
62 
63 // Returns true if the given type is concrete and also a mask.
64 bool spvOperandIsConcreteMask(spv_operand_type_t type);
65 
66 // Returns true if an operand of the given type is optional.
67 bool spvOperandIsOptional(spv_operand_type_t type);
68 
69 // Returns true if an operand type represents zero or more logical operands.
70 //
71 // Note that a single logical operand may still be a variable number of words.
72 // For example, a literal string may be many words, but is just one logical
73 // operand.
74 bool spvOperandIsVariable(spv_operand_type_t type);
75 
76 // Append a list of operand types to the end of the pattern vector.
77 // The types parameter specifies the source array of types, ending with
78 // SPV_OPERAND_TYPE_NONE.
79 void spvPushOperandTypes(const spv_operand_type_t* types,
80                          spv_operand_pattern_t* pattern);
81 
82 // Appends the operands expected after the given typed mask onto the
83 // end of the given pattern.
84 //
85 // Each set bit in the mask represents zero or more operand types that should
86 // be appended onto the pattern.  Operands for a less significant bit always
87 // appear after operands for a more significant bit.
88 //
89 // If a set bit is unknown, then we assume it has no operands.
90 void spvPushOperandTypesForMask(spv_target_env,
91                                 const spv_operand_table operand_table,
92                                 const spv_operand_type_t mask_type,
93                                 const uint32_t mask,
94                                 spv_operand_pattern_t* pattern);
95 
96 // Expands an operand type representing zero or more logical operands,
97 // exactly once.
98 //
99 // If the given type represents potentially several logical operands,
100 // then prepend the given pattern with the first expansion of the logical
101 // operands, followed by original type.  Otherwise, don't modify the pattern.
102 //
103 // For example, the SPV_OPERAND_TYPE_VARIABLE_ID represents zero or more
104 // IDs.  In that case we would prepend the pattern with SPV_OPERAND_TYPE_ID
105 // followed by SPV_OPERAND_TYPE_VARIABLE_ID again.
106 //
107 // This also applies to zero or more tuples of logical operands.  In that case
108 // we prepend pattern with for the members of the tuple, followed by the
109 // original type argument.  The pattern must encode the fact that if any part
110 // of the tuple is present, then all tuple members should be.  So the first
111 // member of the tuple must be optional, and the remaining members
112 // non-optional.
113 //
114 // Returns true if we modified the pattern.
115 bool spvExpandOperandSequenceOnce(spv_operand_type_t type,
116                                   spv_operand_pattern_t* pattern);
117 
118 // Expands the first element in the pattern until it is a matchable operand
119 // type, then pops it off the front and returns it.  The pattern must not be
120 // empty.
121 //
122 // A matchable operand type is anything other than a zero-or-more-items
123 // operand type.
124 spv_operand_type_t spvTakeFirstMatchableOperand(spv_operand_pattern_t* pattern);
125 
126 // Calculates the corresponding post-immediate alternate pattern, which allows
127 // a limited set of operand types.
128 spv_operand_pattern_t spvAlternatePatternFollowingImmediate(
129     const spv_operand_pattern_t& pattern);
130 
131 // Is the operand an ID?
132 bool spvIsIdType(spv_operand_type_t type);
133 
134 // Is the operand an input ID?
135 bool spvIsInIdType(spv_operand_type_t type);
136 
137 // Takes the opcode of an instruction and returns
138 // a function object that will return true if the index
139 // of the operand can be forward declared. This function will
140 // used in the SSA validation stage of the pipeline
141 std::function<bool(unsigned)> spvOperandCanBeForwardDeclaredFunction(
142     spv::Op opcode);
143 
144 // Takes the instruction key of a debug info extension instruction
145 // and returns a function object that will return true if the index
146 // of the operand can be forward declared. This function will
147 // used in the SSA validation stage of the pipeline
148 std::function<bool(unsigned)> spvDbgInfoExtOperandCanBeForwardDeclaredFunction(
149     spv_ext_inst_type_t ext_type, uint32_t key);
150 
151 #endif  // SOURCE_OPERAND_H_
152