A few optimizations are updates to handle code that is suppose to be
using the logical addressing mode, but still has variables that contain
pointers as long as the pointer are to opaque objects. This is called
"relaxed logical addressing".
|Instruction::GetBaseAddress| will check that pointers that are use meet
the relaxed logical addressing rules. Optimization that now handle
relaxed logical addressing instead of logical addressing are:
- aggressive dead-code elimination
- local access chain convert
- local store elimination passes.
include: Add target environment enums for OpenCL 1.2 and 2.0
Validator: Validate OpenCL capabilities
Update validate capabilities to handle embedded profiles
Add test for OpenCL capabilities validation
Update messages to mention the OpenCL profile used
Re-format val_capability_test.cpp
This class implements a generic value propagation algorithm based on the
conditional constant propagation algorithm proposed in
Constant propagation with conditional branches,
Wegman and Zadeck, ACM TOPLAS 13(2):181-210.
The implementation is based on
A Propagation Engine for GCC
Diego Novillo, GCC Summit 2005
http://ols.fedoraproject.org/GCC/Reprints-2005/novillo-Reprint.pdf
The purpose of this implementation is to act as a common framework for any
transformation that needs to propagate values from statements producing new
values to statements using those values.
Creates a pass that removes redundant instructions within the same basic
block. This will be implemented using a hash based value numbering
algorithm.
Added a number of functions that check for the Vulkan descriptor types.
These are used to determine if we are variables are read-only or not.
Implemented a function to check if loads and variables are read-only.
Implemented kernel specific and shader specific versions.
A big change is that the Combinator analysis in ADCE is factored out
into the IRContext as an analysis. This was done because it is being
reused in the value number table.
To make the decoration manger available everywhere, and to reduce the
number of times it needs to be build, I add one the IRContext.
As the same time, I move code that modifies decoration instruction into
the IRContext from mempass and the decoration manager. This will make
it easier to keep everything up to date.
This should take care of issue #928.
NFC. This just makes sure every file is formatted following the
formatting definition in .clang-format.
Re-formatted with:
$ clang-format -i $(find source tools include -name '*.cpp')
$ clang-format -i $(find source tools include -name '*.h')
Function static non-POD data causes problems with DLL lifetime.
This pull request turns all static info tables into strict POD
tables. Specifically, the capabilities/extensions field of
opcode/operand/extended-instruction table are turned into two
fields, one for the count and the other a pointer to an array of
capabilities/extensions. CapabilitySet/EnumSet are not used in
the static table anymore, but they are still used for checking
inclusion by constructing on the fly, which should be cheap for
the majority cases.
Also moves all these tables into the global namespace to avoid
C++11 function static thread-safe initialization overhead.
Previously we have several grammar tables defined as global static
variables and these grammar table entries contains non-POD struct
fields (CapabilitySet/ExtensionSet). The initialization of these
non-POD struct fields may require calling operator new. If used
as a library and the caller defines its own operator new, things
can screw up.
This pull request changes all global static variables into
function static variables, which is lazy evaluated in a thread
safe way as guaranteed by C++11.
If the variable_pointer extension is used:
* OpLoad's pointer argument may be the result of any of the following:
* OpSelect
* OpPhi
* OpFunctionCall
* OpPtrAccessChain
* OpCopyObject
* OpLoad
* OpConstantNull
* Return value of a function may be a pointer.
* It is valid to use a pointer as the return value of a function.
* OpStore should allow a variable pointer argument.
- validation_state.cpp uses functions from opcode.h instead of in-place
switches which need to be updated.
- added new spirv 1.1 type declaration opcodes to a 'is op type
declaration' switch in opcode.cpp.
Use libspirv::CapabilitySet instead of a 64-bit mask.
Remove dead function spvOpcodeRequiresCapability and its tests.
The JSON grammar parser is simplified since it just writes the
list of capabilities as a braced list, and takes advantage of
the CapabilitySet intializer-list constructor.
* ValidationState_t and idUsage now store the addressing model and memory model of the SPIR-V module (this is necessary for certain instructions that need different checks depending on if the logical or physical addressing model is used)
* removed SpvOpPtrAccessChain and SpvOpInBoundsPtrAccessChain from spvOpcodeIsPointer again as these are disallowed in logical addressing mode and only allowed in physical addressing mode (which doesn't use/need spvOpcodeIsPointer in the first place)
* added SpvOpImageTexelPointer and SpvOpCopyObject to spvOpcodeIsPointer
* OpLoad/OpStore now only check if the used pointer operand originated from a valid pointer producing opcode in logical addressing mode (as per 2.16.1)
* moved bitcast pointer tests to the kernel / physical addressing model part (+cleanup)
* renamed spvOpcodeIsPointer to spvOpcodeReturnsLogicalPointer to clarify this function is only meant to be used with the logical addressing model
For fulfilling this purpose, the |opcode| field in the
|spv_parsed_instruction_t| struct is changed to of type uint16_t.
Also add functions to query the information of a given SPIR-V
target environment.
This patch uses a Python script to parse the JSON grammar file to
generate the opcode table and operand kind tables.
Now we don't need to do the post-processing (from OperandClass
to spv_operand_type_t) and copying of the opcode info table is
not required anymore!
Previously, the grammar allowed many execution modes for a single
OpExecutionMode instruction.
Removes the variable- and optional- execution mode operand type
enum values.
Issue found by antiagainst@
Recognize SpvOpInBoundsPtrAccessChain and SpvOpPtrAccessChain as opcodes
returning a pointer.
* spvOpcodeIsPointer: recognize SpvOpInBoundsPtrAccessChain and SpvOpPtrAccessChain as opcodes returning a pointer
* isValid<SpvOpEntryPoint>: don't check kernel function signatures (these don't have to be 'void main(void)')
* added tests for kernel OpEntryPoint, OpInBoundsPtrAccessChain and OpPtrAccessChain, as well as facilities to actually test kernel/OpenCL SPIR-V
* fixed pow and pown specification (both should take 2 parameters), spec bug reported at https://www.khronos.org/bugzilla/show_bug.cgi?id=1469
* use ASSERT_TRUE instead of ASSERT_EQ
* added pow and pown test (pow(val, 2.0f) and pown(val, 3))
Revert " * fixed pow and pown specification (both should take 2 parameters), spec bug reported at https://www.khronos.org/bugzilla/show_bug.cgi?id=1469"
This reverts commit c3d5a87e73.
Revert " * added pow and pown test (pow(val, 2.0f) and pown(val, 3))"
This reverts commit 7624aec720.
Now we have public headers arranged as follows:
$SPIRV_TOOLS_ROOT/include/spirv-tools/libspirv.h
$SPIRV_TOOLS_ROOT/include/spirv/spirv.h
$SPIRV_TOOLS_ROOT/include/spirv/GLSL.std.450.h
$SPIRV_TOOLS_ROOT/include/spirv/OpenCL.std.h
A project should use -I$SPIRV_TOOLS_ROOT/include
and then #include "spirv-tools/libspirv.h"
The headers from the SPIR-V Registry can be accessed as "spirv/spirv."
for example.
The install target should also install the headers from the SPIR-V
Registry. The libspirv.h header is broken otherwise.
The SPIRV-Tools library depends on the headers from the SPIR-V Registry.
The util/bitutils.h and util/hex_float.h are pulled into the internal
source tree. Those are not part of the public API to SPIRV-Tools.
- The SPIR-V spec generator has changed how it represents optional
operands. Now it tracks a separate boolean flag indicating optionality.
However, SPIRV-Tools still wants to represent both operand class
and optionality in the same enums space (SPV_OPERAND_TYPE_*).
So there's extra work in the patch.
- In the spec generator, OperandImage is now OperandImageOperands.
This affects enum translation in opcode.cpp.
- In the spec generator, image operands are explicitly followed by
Id, and VariableIds. However, SPIRV-Tools uses the bits set
in the image operand bitmask to control the number and meaning
of the Ids that follow. So in writing the opcode.inc syntax
table, drop all operands after OperandImageOperands.
- Some enums are now more explicitly represented in the generated
opcode.inc:
- AccessQualifier (e.g. on OpTypeImage), in both required and
optional flavours.
- MemoryAccess (e.g. on loads and stores)
- Add SPV_OPERAND_TYPE_OPTIONAL_ACCESS_QUALIFIER
- Add tests for the optional AccessQualifier operand on OpTypeImage.
- Update the AccessQualifier test for OpTypeImage so it's a round
trip test through the disassembler as well.
Also
- Add type_id to spv_id_info_t.
- Use spv_id_info_t::type_id instead of words[1].
Triggered some asserts on tests, where the code incorrectly assumed
words[1] had a type. Remove the asserts and handle gracefully.
- Add tests for OpStore of a label, a void, and a function.
Remove redundant validations of OpConstant and OpConstantComposite.
Binary parser already performs these checks, so the validations can
never be triggered.
Enable bad-constant tests.
If we later add a source/ as an -I include directory,
then avoid confusing other headers that want to include the
standard "endian.h" from /usr/include.
Also rename source/endian.cpp to source/spirv_endian.cpp
This is a grammar fix. The Decoration operand of OpDecorate (and
OpMemberDecorate) determines the remaining operands. Don't just
allow any number of literal numbers as operands.
(The OperandVariableLiterals operand class as the last member
of the OpDecorate and OpMemberDecorate entries in in opcode.inc is
an artifact of how the spec generates the opcode descriptions. It's
not suitable for parsing those instructions.)
Fixes https://github.com/KhronosGroup/SPIRV-Tools/issues/34
The high 16-bits are a registered generator tool.
These are registered at
https://www.khronos.org/registry/spir-v/api/spir-v.xml
The low 16-bits are tool-specific. It might be a version number,
for example, but is not constrained by the spec or by the registration
process.
The disassembler prints the tool name when we know it.
If we don't, print "Unknown" and then the numeric tool number
in parentheses.
In all cases, the disassembler prints lower 16-bit number on the
same line but after the tool name.
Also add newly registered generators:
6: Khronos LLVM/SPIR-V Translator
7: Khronos SPIR-V Tools Assembler
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.
- 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.