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_VAL_VALIDATE_H_
16#define SOURCE_VAL_VALIDATE_H_
17
18#include <functional>
19#include <memory>
20#include <utility>
21#include <vector>
22
23#include "source/instruction.h"
24#include "source/table.h"
25#include "spirv-tools/libspirv.h"
26
27namespace spvtools {
28namespace val {
29
30class ValidationState_t;
31class BasicBlock;
32class Instruction;
33
34/// A function that returns a vector of BasicBlocks given a BasicBlock. Used to
35/// get the successor and predecessor nodes of a CFG block
36using get_blocks_func =
37 std::function<const std::vector<BasicBlock*>*(const BasicBlock*)>;
38
39/// @brief Performs the Control Flow Graph checks
40///
41/// @param[in] _ the validation state of the module
42///
43/// @return SPV_SUCCESS if no errors are found. SPV_ERROR_INVALID_CFG otherwise
44spv_result_t PerformCfgChecks(ValidationState_t& _);
45
46/// @brief Updates the use vectors of all instructions that can be referenced
47///
48/// This function will update the vector which define where an instruction was
49/// referenced in the binary.
50///
51/// @param[in] _ the validation state of the module
52///
53/// @return SPV_SUCCESS if no errors are found.
54spv_result_t UpdateIdUse(ValidationState_t& _, const Instruction* inst);
55
56/// @brief This function checks all ID definitions dominate their use in the
57/// CFG.
58///
59/// This function will iterate over all ID definitions that are defined in the
60/// functions of a module and make sure that the definitions appear in a
61/// block that dominates their use.
62///
63/// @param[in] _ the validation state of the module
64///
65/// @return SPV_SUCCESS if no errors are found. SPV_ERROR_INVALID_ID otherwise
66spv_result_t CheckIdDefinitionDominateUse(ValidationState_t& _);
67
68/// @brief This function checks for preconditions involving the adjacent
69/// instructions.
70///
71/// This function will iterate over all instructions and check for any required
72/// predecessor and/or successor instructions. e.g. SpvOpPhi must only be
73/// preceeded by SpvOpLabel, SpvOpPhi, or SpvOpLine.
74///
75/// @param[in] _ the validation state of the module
76///
77/// @return SPV_SUCCESS if no errors are found. SPV_ERROR_INVALID_DATA otherwise
78spv_result_t ValidateAdjacency(ValidationState_t& _);
79
80/// @brief Validates static uses of input and output variables
81///
82/// Checks that any entry point that uses a input or output variable lists that
83/// variable in its interface.
84///
85/// @param[in] _ the validation state of the module
86///
87/// @return SPV_SUCCESS if no errors are found.
88spv_result_t ValidateInterfaces(ValidationState_t& _);
89
90/// @brief Validates memory instructions
91///
92/// @param[in] _ the validation state of the module
93/// @return SPV_SUCCESS if no errors are found.
94spv_result_t MemoryPass(ValidationState_t& _, const Instruction* inst);
95
96/// @brief Updates the immediate dominator for each of the block edges
97///
98/// Updates the immediate dominator of the blocks for each of the edges
99/// provided by the @p dom_edges parameter
100///
101/// @param[in,out] dom_edges The edges of the dominator tree
102/// @param[in] set_func This function will be called to updated the Immediate
103/// dominator
104void UpdateImmediateDominators(
105 const std::vector<std::pair<BasicBlock*, BasicBlock*>>& dom_edges,
106 std::function<void(BasicBlock*, BasicBlock*)> set_func);
107
108/// @brief Prints all of the dominators of a BasicBlock
109///
110/// @param[in] block The dominators of this block will be printed
111void printDominatorList(BasicBlock& block);
112
113/// Performs logical layout validation as described in section 2.4 of the SPIR-V
114/// spec.
115spv_result_t ModuleLayoutPass(ValidationState_t& _, const Instruction* inst);
116
117/// Performs Control Flow Graph validation and construction.
118spv_result_t CfgPass(ValidationState_t& _, const Instruction* inst);
119
120/// Validates Control Flow Graph instructions.
121spv_result_t ControlFlowPass(ValidationState_t& _, const Instruction* inst);
122
123/// Performs Id and SSA validation of a module
124spv_result_t IdPass(ValidationState_t& _, Instruction* inst);
125
126/// Performs instruction validation.
127spv_result_t InstructionPass(ValidationState_t& _, const Instruction* inst);
128
129/// Performs decoration validation. Assumes each decoration on a group
130/// has been propagated down to the group members.
131spv_result_t ValidateDecorations(ValidationState_t& _);
132
133/// Performs validation of built-in variables.
134spv_result_t ValidateBuiltIns(ValidationState_t& _);
135
136/// Validates type instructions.
137spv_result_t TypePass(ValidationState_t& _, const Instruction* inst);
138
139/// Validates constant instructions.
140spv_result_t ConstantPass(ValidationState_t& _, const Instruction* inst);
141
142/// Validates correctness of arithmetic instructions.
143spv_result_t ArithmeticsPass(ValidationState_t& _, const Instruction* inst);
144
145/// Validates correctness of composite instructions.
146spv_result_t CompositesPass(ValidationState_t& _, const Instruction* inst);
147
148/// Validates correctness of conversion instructions.
149spv_result_t ConversionPass(ValidationState_t& _, const Instruction* inst);
150
151/// Validates correctness of derivative instructions.
152spv_result_t DerivativesPass(ValidationState_t& _, const Instruction* inst);
153
154/// Validates correctness of logical instructions.
155spv_result_t LogicalsPass(ValidationState_t& _, const Instruction* inst);
156
157/// Validates correctness of bitwise instructions.
158spv_result_t BitwisePass(ValidationState_t& _, const Instruction* inst);
159
160/// Validates correctness of image instructions.
161spv_result_t ImagePass(ValidationState_t& _, const Instruction* inst);
162
163/// Validates correctness of atomic instructions.
164spv_result_t AtomicsPass(ValidationState_t& _, const Instruction* inst);
165
166/// Validates correctness of barrier instructions.
167spv_result_t BarriersPass(ValidationState_t& _, const Instruction* inst);
168
169/// Validates correctness of literal numbers.
170spv_result_t LiteralsPass(ValidationState_t& _, const Instruction* inst);
171
172/// Validates correctness of extension instructions.
173spv_result_t ExtensionPass(ValidationState_t& _, const Instruction* inst);
174
175/// Validates correctness of annotation instructions.
176spv_result_t AnnotationPass(ValidationState_t& _, const Instruction* inst);
177
178/// Validates correctness of non-uniform group instructions.
179spv_result_t NonUniformPass(ValidationState_t& _, const Instruction* inst);
180
181/// Validates correctness of debug instructions.
182spv_result_t DebugPass(ValidationState_t& _, const Instruction* inst);
183
184// Validates that capability declarations use operands allowed in the current
185// context.
186spv_result_t CapabilityPass(ValidationState_t& _, const Instruction* inst);
187
188/// Validates correctness of primitive instructions.
189spv_result_t PrimitivesPass(ValidationState_t& _, const Instruction* inst);
190
191/// Validates correctness of mode setting instructions.
192spv_result_t ModeSettingPass(ValidationState_t& _, const Instruction* inst);
193
194/// Validates correctness of function instructions.
195spv_result_t FunctionPass(ValidationState_t& _, const Instruction* inst);
196
197/// Validates correctness of miscellaneous instructions.
198spv_result_t MiscPass(ValidationState_t& _, const Instruction* inst);
199
200/// Validates execution limitations.
201///
202/// Verifies execution models are allowed for all functionality they contain.
203spv_result_t ValidateExecutionLimitations(ValidationState_t& _,
204 const Instruction* inst);
205
206/// Validates restricted uses of 8- and 16-bit types.
207///
208/// Validates shaders that uses 8- or 16-bit storage capabilities, but not full
209/// capabilities only have appropriate uses of those types.
210spv_result_t ValidateSmallTypeUses(ValidationState_t& _,
211 const Instruction* inst);
212
213/// @brief Validate the ID's within a SPIR-V binary
214///
215/// @param[in] pInstructions array of instructions
216/// @param[in] count number of elements in instruction array
217/// @param[in] bound the binary header
218/// @param[in,out] position current word in the binary
219/// @param[in] consumer message consumer callback
220///
221/// @return result code
222spv_result_t spvValidateIDs(const spv_instruction_t* pInstructions,
223 const uint64_t count, const uint32_t bound,
224 spv_position position,
225 const MessageConsumer& consumer);
226
227// Performs validation for the SPIRV-V module binary.
228// The main difference between this API and spvValidateBinary is that the
229// "Validation State" is not destroyed upon function return; it lives on and is
230// pointed to by the vstate unique_ptr.
231spv_result_t ValidateBinaryAndKeepValidationState(
232 const spv_const_context context, spv_const_validator_options options,
233 const uint32_t* words, const size_t num_words, spv_diagnostic* pDiagnostic,
234 std::unique_ptr<ValidationState_t>* vstate);
235
236} // namespace val
237} // namespace spvtools
238
239#endif // SOURCE_VAL_VALIDATE_H_
240