* Validates module level instructions for logical layout
conformance
* Does not validate:
1. Function logical layout
2. Minor cases with OpVariable
3. Missing MemoryModel instruction in module
4. Order of function definition and function declaration
* 782 unit tests for logical layout
Addressed feedback
Most uses of an ID must occur after the definition
of the ID. Forward references are allowed for
things like OpName, OpDecorate, and various cases
of control-flow instructions such as OpBranch, OpPhi,
and OpFunctionCall.
TODO: Use CFG analysis for SSA checks. In particular,
an ID defined inside a function body is only usable inside
that function body. Also, use dominator info to catch
some failing cases.
Also:
* Validator test cases use (standard) assignment form.
* Update style to more closely follow the Google C++ style guide
* Remove color-diagnostics flag.
This is enabled by default on terminals with color. Prints
hidden ASCII for terminals that can't handle color(Emacs)
* Pass functors to SSAPass to check if the
operand can be forward referenced based on its index value
* Return SPV_ERROR_INVALID_ID for ID related errors
spvBinaryParse returned SPV_ERROR_INVALID_BINARY for all types of
errors. Since spvBinaryParse does some ID validation, this was
returning inappropriate error codes for some tests.
* Common fixture for validation tests.
It only runs certian validation passes.
* Add a SPV_VALIDATE_SSA_BIT for testing purposes
* Fixtures now return error codes
* Add OpName support in diag message and unit tests
* Binary parsing can fail with invalid ID or invalid binary error code
Tests include:
* OpDecorate
* OpName
* OpMemberName
* OpBranchConditional
* OpSelectionMerge
* OpMemberDecorate
* OpGroupDecorate
* OpDeviceEnqueue
* Enable several tests failing in ID validation.
Add unit tests for all diagnostics issued by spvBinaryParse.
Handle image format operands in the binary parser and the
disassembler.
Document that the callback function pointers can be null,
in which case they are ignored.
Detect exhaustion of input when parsing an operand,
to avoid buffer overruns on some invalid input cases.
Fix the description strings for some operand types.
Make the diagnostic messages for those operand types
consistent between the assembler and binary parser.
Fixes https://github.com/KhronosGroup/SPIRV-Tools/issues/29
When a callback returns something other than SPV_SUCCESS,
then no futher callbacks are issued (parsing terminates early),
and no additional diagnostics are emitted.
The unit tests already check this behaviour.
Add a non-zero spv_result_t value SPV_REQUESTED_TERMINATION
which should be used to signal an ok result, but signals
early termination for a process, such as binary parsing.
Tests include:
- correct contents sent to header and instruction callbacks
- non-zero status from a callback should terminate parsing,
but the parser should not generate its own diagnostic.
TODO: Check diagnostics generated by the parser itself.
Add members:
- words: a pointer to an array of words in the instruction,
in host native endianness.
- num_words: sizes the words member
Remove member:
- offset
This simplifies clients of spvBinaryParse, because they don't
have to handle endianness translation.
Also, it makes the binary parse API more composable, allowing
for easy chaining of binary parse clients. A binary parse client
is handed the array of words directly instead of having to reference
some external array of all the words in the SPIR-V binary. It also
allows a binary parse client to mutate the instruction stream before
handing off to a downstream consumer.
TODO(dneto): Still need to write the unit tests for spvBinaryParse
Fixes: https://github.com/KhronosGroup/SPIRV-Tools/issues/1
Don't use SYSTEM attribute on include_directories directive
for the SPIR-V standard header files. When you do, object files
are not considered dependent on those headers.
Checked by looking at the dependency file source/disassemble.cpp.o.d,
and by trying to compile after a trivial edit to spirv.h
Fixes https://github.com/KhronosGroup/SPIRV-Tools/issues/7
Also, use "" inclusion instead of <> inclusion for standard SPIR-V
headers.
Bits 24-31: 0
Bits 16-23: SPIR-V major number (1)
Bits 8-15: SPIR-V minor number (0)
Bits 0-7: SPIR-V minor number (2)
The assembler will construct the word appropriately,
and the disassemble will print it in major.minor.revision form.
Previously the opcode table is declared as an global array and we
have spvOpcodeTableInitialize() modifying it. That can result in
race condition. Now spvOpcodeTabelGet() copies the whole underlying
array.
Replaced uint64_t with size_t in the places that make sense and
added spv_const_binary{,_t} to allow the interface to accept non
modifiable spirv where appropriate.
- Concrete operand types are never optional.
Split them to make this so, e.g. add SPV_OPERAND_TYPE_IMAGE
since there was SPV_OPERAND_TYPE_OPTIONAL_IMAGE.
Similarly for SPV_OPERAND_TYPE_MEMORY_ACCESS.
This entails duplicating two operand table entries.
- The above, plus some rearranging of enums, allows us to define
first and last optional operand types, and first and last
variable operand types.
This lets us simplify the code for spvOperandIsOptional, and
spvOperandIsVariable.
- Replace SPV_OPERAND_TYPE_MULTIWORD_LITERAL_NUMBER with the
more accurately named SPV_OPERAND_TYPE_TYPED_LITERAL_NUMBER.
Its special characteristic is that the type of the literal
number is determined by some previous operand in the instruction.
This is used for literals in OpSwitch, OpConstant, and OpSpecConstant.
This lets us refactor operand parsing cases in the assembler.
- Remove the special required-thing-in-optional-tuple in favour of
the corresponding concrete operand type:
SPV_OPERAND_TYPE_ID_IN_OPTIONAL_TUPLE
--> SPV_OPERAND_TYPE_ID
SPV_OPERAND_TYPE_INTEGER_LITERAL_IN_OPTIONAL_TUPLE
--> SPV_OPERAND_TYPE_INTEGER_LITERAL
- Constrain spvOpeandTypeStr to only have to work for non-variable
operand types. Add a test for this.
The binary parser has a C API, described in binary.h.
Eventually we will make it public in libspirv.h.
The API is event-driven in the sense that a callback is called
when a valid header is parsed, and for each parsed instruction.
Classify some operand types as "concrete". The binary parser uses
only concrete operand types to describe parsed instructions.
The old disassembler APIs are moved into disassemble.cpp
TODO: Add unit tests for spvBinaryParse.
Note that we are more strict than Google style for one aspect:
pointer/reference indicators are adjacent to their types, not
their variables.
find . -name "*.h" -exec clang-format -i {} \;
find . -name "*.cpp" -exec clang-format -i {} \;
This is required to support extended instructions that
have literal numbers as operands. An example is OpenCL's
vloadn.
The previous code in the assembler assumed that *any* literal
number argument in any part of an OpExtInst must be the name
of the extended instruction. That's true only for the first
literal number argument.
Versions 1.2, 2.0, and 2.1 all use the same
extended instruction list.
Updated the source code patch for the SPIR-V doc generator,
so it can both generate the core syntax table, and also the
OpenCL extended instructions table.
Tested the Math and Common functions.
TODO: test the remaining entries.
Except for OpConstant and OpSpecConstant, all other literal number
operands are indeed unsigned integers. So,
* Rename all *LITERAL_NUMBER* operand types to *LITERAL_INTEGER*.
* Expect unsigned integers for *LITERAL_INTEGER* operands.
* Keep MULITPLE_WORD_LITERAL untouched since it is only used by
OpConstant and OpSpecConstant.
And we want to provide the capability to specify floating-point
numbers after !<integer> in the alternate parsing mode. So,
OPTIONAL_LITERAL_NUMBER is reserved for OPTIONAL_CIV.
We need to know how to generate correct SPIRV for cases like
OpConstant %int64 42 since the current parser will encode the 42 as a
32-bit value incorrectly.
This change is the first of a pair. This one tracks types, and makes
sure that OpConstant and OpSpecConstant are only ever called with
Integer or Float types, and OpSwitch is only called with integer
generating values.
Move the definition of spv_instruction_t to an internal
header file, since it now depends on C++ and is not
used by the external interface.
Use a std::vector<uint32_t> in spv_instruction_t
instead of a fixed size array.
Fixes dependencies among capabilities. (The table should store
the mask of capabilites, not the capability enum.)
Remove the old spot check test for capabilities of enums.