This change adds a folding rule which transforms x * y - a and a - x * y
into FMA(x, y, -a) and FMA(-x, y, a), respectively.
While the SPIR-V instruction count remains the same, target instruction
sets typically feature FMA instruction variants that can negate an
operand. Also this transformation may unlock further optimizations which
eliminate the negation.
(Google bug: b/226145988)
* Add move folding for composite instructions
Fold chains of insert into construct
If a chain of OpCompositeInsert instruction write to every element of a
composite object, then we can replace it with an OpCompositeConstruct.
Fold a construct fed by extracts to a single extract
We already fold an OpCompositeConstruct when it is simlpy reconstructing
an object that was decomposed by a series of OpCompositeExtract
instructions. However, we do not do that if that object is an element
of a larger object.
I have updated the rule, so that if the original object is a an element
of a larger object, then the OpCompositeConstruct is replaced with a
single OpCompositeExtract from the larger object.
Fixes#4371.
* Handle 64-bit integers in local access chain convert
The local access chain convert pass does on run on module that have
64-bit integers, even if they have nothing to to with access chains.
This is very limiting because other passes rely on the access chains
being removed. So this commit will add this functionality to the pass.
spirv validation require OpFunctionCall with memory object, usually this
is non issue as all the functions are inlined.
This pass deal with some case for
DontInline function. accesschain input operand would be replaced new
created variable
- Add assembler/disassembler support
- Add validator support
Signed-off-by: Kevin Petit <kevin.petit@arm.com>
Change-Id: Iffcedd5d5e636a0e128a5906ffe634dd85727de1
This reverts commit 671f6e633f.
PR #4783 was reverted because it caused OpenCL CTS failures for clvk.
The was in clspv, which was not adding the no contract decoration when
it was required. This has been fixed in
https://github.com/google/clspv/pull/845. We can now reapply #4783.
* linker: Recalculate interface variables
By resolving extern symbols Entry Points might access variables they
hadn't declared before.
* test/linker: add test to verify linked spir-vs importing functions validate
Without the fix Validate will complain about:
"ERROR: 9: Interface variable id <5> is used by entry point 'bar' id <1>, but is not listed as an interface\n %5 = OpVariable %_ptr_Input_v3uint Input\n"
Adding Fma instruction can speed up the code. This was requested by
swiftshader, so they do not have to do this analysis themselves. It can
also help reduce the code size, and the work the ICD compilers have to
do.
In the installed file
/usr/lib64/cmake/SPIRV-Tools/SPIRV-ToolsTarget.cmake, occurences of
librt in the INTERFACE_LINK_LIBRARIES property are incorrect. The
property contains the absolute path to librt. In most situations, this
produces no problem. But when building in a sysroot, which is commonly
done when cross-compiling, the absolute path breaks dependent projects.
For example, when building spirv-tools using the Chrome OS SDK, and
targeting the board 'volteer', where the build sysroot is
'/build/volteer', the file includes this line
INTERFACE_LINK_LIBRARIES "/build/volteer/usr/lib64/librt.so"
when it should instead say
INTERFACE_LINK_LIBRARIES "rt"
The CMake documentation agrees [1]:
Note that it is not advisable to populate the
INTERFACE_LINK_LIBRARIES of a target with absolute paths to
dependencies. That would hard-code into installed packages the
library file paths for dependencies as found on the machine the
package was made on.
[1] https://cmake.org/cmake/help/latest/prop_tgt/INTERFACE_LINK_LIBRARIES.html
* Fix gen_build_version on Windows
The paths used in the gen_build_version script are causing some failures
in downstream builds. Switch to using the location of the CHANGES file
rather than the ".." parent directory workaround.
* Update other build files
The code accidentally expected OpTypeFunction operand count to match.
This is fixed so that OpTypeFunction instructions with different operand
counts are considered not matching.
Currently, the diff tool matches types bottom up, so on every
instruction it expects to know if its operands are already matched or
not. With cyclical references, it cannot know that. Type matching
would need significant rework to be able to support such a use case; for
example, it may need to maintain a set of plausable matches between type
pointers that are forward-referenced, and potentially back track when
later the types turn out to be incompatible.
In this change, OpTypeForwardPointer is supported in the more common and
trivial case. Firstly, forwarded type pointers are only matched if they
have they have the same storage class and point to the same type opcode:
- In the presence of debug info, matching is done only if the names are
unique in both src and dst.
- In the absence of debug info, matching is done only if there is only
one possible matching.
Fixes: #4754
spread-volatile-semantics pass spreads Volatile semantics for builtin
variables used by certain execution models based on
VUID-StandaloneSpirv-VulkanMemoryModel-04678 and
VUID-StandaloneSpirv-VulkanMemoryModel-04679 (See "Standalone SPIR-V
Validation" section of Vulkan spec "Appendix A: Vulkan Environment for
SPIR-V"). Therefore, shaders without execution model (e.g., used only
for linkage) are not the target of the pass. This commit lets the pass
just return SuccessWithoutChange in that case.
In preparation for supporting OpTypeForwardPointer, which adds more
usages like this. This change refactors common code used to group
instructions and match the groups.
Clang added -Wunqualified-std-cast-call in
https://reviews.llvm.org/D119670, which warns on unqualified std::move
and std::forward calls. This change qualifies these calls to allow the
project to build on HEAD Clang -Werror.
If the body of the module does not have any ids change, compact ids will
not change the id bound. This can cause problems because the id bound
could be much higher than the largest id in that is used. It should be
reset any time it is not the larger id used + 1.
Fixes#4604
When folding a vector shuffle feeding a vector shuffle, we do not
propagate an 0xFFFFFFFF, which has a special meaning, correctly. We
adjust the value making it lose it meaning as an undefined value.
Fixes#4581
CCP does not want to fold an instruction unless it folds to a constant.
There is an asser to check for this. The question if a spec constant
counts as a constant. The constant folder considers a spec constant a
constand, but CCP does not. I've fixed the assert in CCP to match what
the folder does. It should not require any new changes to CCP.
Swift shader needs a way to inline all functions, even those marked as
DontInline. See https://github.com/KhronosGroup/SPIRV-Tools/pull/4471.
This implements the suggestion I made in the PR. We add a pass that
will remove the DontInline function control, so that the inlining passes
will inline them.
SwiftShader will still have to modify their code to add this pass before
the other passes are run.
The function `BuildInvalideAnalyses` will be rebuilt for every analysis that
has been requested, but it is not necessary. It also can cause problems
because if the CFG needs to be rebuilt, so do the dominator trees.
This change will make the functionality match the description of the
function.
* Optimize DefUseManager allocations
Saves around 30-35% of compilation time.
For inst->use_ids, use a pool linked list instead of allocating vectors for every instruction. For inst->uses, use a "PooledLinkedList"' -- a linked list that has shared storage for all nodes. Neither re-use nodes, instead we do a bulk compaction operation when too much memory is being wasted (tuneable).
Includes separate PooledLinkedList templated datastructure, a very special case construct, but split out to make the code a little easier to understand.