aboutsummaryrefslogtreecommitdiff
path: root/source/operand.h
blob: 7c73c6f5607e744a63f19cb0803f906318133aad (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
// Copyright (c) 2015-2016 The Khronos Group Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#ifndef SOURCE_OPERAND_H_
#define SOURCE_OPERAND_H_

#include <functional>
#include <vector>

#include "source/table.h"
#include "spirv-tools/libspirv.h"

// A sequence of operand types.
//
// A SPIR-V parser uses an operand pattern to describe what is expected
// next on the input.
//
// As we parse an instruction in text or binary form from left to right,
// we pop and push at the end of the pattern vector. Symbols later in the
// pattern vector are matched against the input before symbols earlier in the
// pattern vector are matched.

// Using a vector in this way reduces memory traffic, which is good for
// performance.
using spv_operand_pattern_t = std::vector<spv_operand_type_t>;

// Finds the named operand in the table. The type parameter specifies the
// operand's group. A handle of the operand table entry for this operand will
// be written into *entry.
spv_result_t spvOperandTableNameLookup(spv_target_env,
                                       const spv_operand_table table,
                                       const spv_operand_type_t type,
                                       const char* name,
                                       const size_t name_length,
                                       spv_operand_desc* entry);

// Finds the operand with value in the table. The type parameter specifies the
// operand's group. A handle of the operand table entry for this operand will
// be written into *entry.
spv_result_t spvOperandTableValueLookup(spv_target_env,
                                        const spv_operand_table table,
                                        const spv_operand_type_t type,
                                        const uint32_t value,
                                        spv_operand_desc* entry);

// Gets the name string of the non-variable operand type.
const char* spvOperandTypeStr(spv_operand_type_t type);

// Returns true if the given type is concrete.
bool spvOperandIsConcrete(spv_operand_type_t type);

// Returns true if the given type is concrete and also a mask.
bool spvOperandIsConcreteMask(spv_operand_type_t type);

// Returns true if an operand of the given type is optional.
bool spvOperandIsOptional(spv_operand_type_t type);

// Returns true if an operand type represents zero or more logical operands.
//
// Note that a single logical operand may still be a variable number of words.
// For example, a literal string may be many words, but is just one logical
// operand.
bool spvOperandIsVariable(spv_operand_type_t type);

// Append a list of operand types to the end of the pattern vector.
// The types parameter specifies the source array of types, ending with
// SPV_OPERAND_TYPE_NONE.
void spvPushOperandTypes(const spv_operand_type_t* types,
                         spv_operand_pattern_t* pattern);

// Appends the operands expected after the given typed mask onto the
// end of the given pattern.
//
// Each set bit in the mask represents zero or more operand types that should
// be appended onto the pattern.  Operands for a less significant bit always
// appear after operands for a more significant bit.
//
// If a set bit is unknown, then we assume it has no operands.
void spvPushOperandTypesForMask(spv_target_env,
                                const spv_operand_table operand_table,
                                const spv_operand_type_t mask_type,
                                const uint32_t mask,
                                spv_operand_pattern_t* pattern);

// Expands an operand type representing zero or more logical operands,
// exactly once.
//
// If the given type represents potentially several logical operands,
// then prepend the given pattern with the first expansion of the logical
// operands, followed by original type.  Otherwise, don't modify the pattern.
//
// For example, the SPV_OPERAND_TYPE_VARIABLE_ID represents zero or more
// IDs.  In that case we would prepend the pattern with SPV_OPERAND_TYPE_ID
// followed by SPV_OPERAND_TYPE_VARIABLE_ID again.
//
// This also applies to zero or more tuples of logical operands.  In that case
// we prepend pattern with for the members of the tuple, followed by the
// original type argument.  The pattern must encode the fact that if any part
// of the tuple is present, then all tuple members should be.  So the first
// member of the tuple must be optional, and the remaining members
// non-optional.
//
// Returns true if we modified the pattern.
bool spvExpandOperandSequenceOnce(spv_operand_type_t type,
                                  spv_operand_pattern_t* pattern);

// Expands the first element in the pattern until it is a matchable operand
// type, then pops it off the front and returns it.  The pattern must not be
// empty.
//
// A matchable operand type is anything other than a zero-or-more-items
// operand type.
spv_operand_type_t spvTakeFirstMatchableOperand(spv_operand_pattern_t* pattern);

// Calculates the corresponding post-immediate alternate pattern, which allows
// a limited set of operand types.
spv_operand_pattern_t spvAlternatePatternFollowingImmediate(
    const spv_operand_pattern_t& pattern);

// Is the operand an ID?
bool spvIsIdType(spv_operand_type_t type);

// Is the operand an input ID?
bool spvIsInIdType(spv_operand_type_t type);

// Takes the opcode of an instruction and returns
// a function object that will return true if the index
// of the operand can be forward declared. This function will
// used in the SSA validation stage of the pipeline
std::function<bool(unsigned)> spvOperandCanBeForwardDeclaredFunction(
    SpvOp opcode);

// Takes the instruction key of a debug info extension instruction
// and returns a function object that will return true if the index
// of the operand can be forward declared. This function will
// used in the SSA validation stage of the pipeline
std::function<bool(unsigned)> spvDbgInfoExtOperandCanBeForwardDeclaredFunction(
    spv_ext_inst_type_t ext_type, uint32_t key);

#endif  // SOURCE_OPERAND_H_