Commit Graph

1018 Commits

Author SHA1 Message Date
Steven Perron
f393b0e480 Don't merge types of resources
When doing reflection users care about the names of the variable, the
name of the type, and the name of the members.  Remove duplicates breaks
this because it removes the names one of the types when merging.

To fix this we have to keep the different types around for each
resource.  This commit adds code to remove duplicates to look for the
types uses to describe resources, and make sure they do not get merged.

However, allow merging of a type used in a resource with something not
used in a resource.  Was done when the non resource type came second.

This could have a negative effect on compile time, but it was not
expected to be much.

Fixes https://github.com/KhronosGroup/SPIRV-Tools/issues/1372.
2018-06-27 13:57:07 -04:00
David Neto
c2e3e67c31 validator: Fix storage buffer layout message 2018-06-27 09:54:40 -04:00
David Neto
8ecd833dbc Block-decorated structs must list members in offset-order
Additionally, implmentes code review feedback.

Adds more detailed messages for Block and BufferBlock layout errors.

Fixes #1638
2018-06-26 23:31:00 -04:00
Ari Suonpaa
29923409e9 Add validation for structs decorated as Block or BufferBlock.
Fixes #937

Stop std140/430 validation when runtime array is encountered.

Check for standard uniform/storage buffer layout instead of std140/430.

Added validator command line switch to skip block layout checking.

Validate structs decorated as Block/BufferBlock only when they
are used as variable with storage class of uniform or push
constant.

Expose --relax-block-layout to command line.

dneto0 modification:
- Use integer arithmetic instead of floor.
2018-06-26 14:23:18 -04:00
Alan Baker
0d43e10b4a Use type id when looking up vector type
Fixes #1634

* Vector components of composite constructs used wrong accessor
2018-06-25 09:47:29 -04:00
Corentin Wallez
ba602c9059 Add a WIP WebGPU environment. It disallows OpUndef
Add SPV_ENV_WEBGPU_0 for work-in-progress WebGPU.

val: Disallow OpUndef in WebGPU env

Silence unused variable warnings when !defined(SPIRV_EFFCE)

Limit visibility of validate_instruction.cpp's symbols
  Only InstructionPass needs to be visible so all other functions are put
  in an anonymous namespace inside the libspirv namespace.
2018-06-21 15:53:15 -04:00
Alan Baker
e7ace1b280 Add Vulkan 1.1 capability sets
Fixes #1597

* Classifies useable capabilities for Vulkan 1.1
* Updates tests
2018-06-21 14:12:02 -04:00
David Neto
8d65c89678 Instruction lookup succeeds if it's enabled by a capability
Also add a corresponding check for capabilities in the validator.

Update previously existing test cases where an instruction used to fail
assembling because of a version check, but now they succeed because the
instruction is also guarded by a capability.  Now it should assemble.
Add tests to ensure that capabilities are checked appropriately.

The explicitly reserved instructions OpImageSparseSampleProj*
now assemble, but they fail validation.

Fixes #1624
2018-06-20 10:44:03 -04:00
dan sinclair
f80696eaf6
[val] Add extra context to error messages. (#1600)
[val] Add extra context to error messages.

This CL extends the error messages produced by the validator to output the
disassembly of the errored line.

The validation_id messages have also been updated to print the line number of
the error instead of the word number. Note, the error number is from the start
of the SPIR-V, it does not include any headers printed in the disassembled code.

Fixes #670, #1581
2018-06-19 16:02:44 -04:00
dan sinclair
c4304ea0ac Reland "Disallow array-of-arrays with DescriptorSets when validating. (#1586)"
This CL reverts the revert of 'Disallow array-of-arrays with DescriptorSets when
validating." Other changes have been committed which should aleviate the
AppVeryor resource constraints.

This reverts commit f2c93c6e12.

This CL adds validation to disallow using an array-of-arrays when attached to a
DescriptorSet.

Fixes #1522
2018-06-19 15:14:17 -04:00
dan sinclair
d3ed998222
Validate Ids before DataRules. (#1622)
Validate Ids before DataRules.

The DataRule validators call FindDefs with the assumption that they
definitions being looked at can be found. This may not be true if we
have not validated identifiers first.

This CL flips the IdPass and DataRulesPass to fix this issue.
2018-06-19 09:32:20 -04:00
Alan Baker
ea7239fa73 Structured switch checks
Fixes #491

* Basic blocks now have a link to the terminator
* Check all case sepecific rules
* Missing check for branching into the middle of a case (#1618)
2018-06-13 15:04:47 -04:00
Alan Baker
4f866abfd8 Validate static uses of interfaces
Fixes #1120

Checks that all static uses of the Input and Output variables are listed
as interfaces in each corresponding entry point declaration.
 * Changed validation state to track interface lists
 * updated many tests
* Modified validation state to store entry point names
 * Combined with interface list and called EntryPointDescription
 * Updated uses
* Changed interface validation error messages to output entry point name
in addtion to ID
2018-06-13 10:56:14 -04:00
David Neto
b49cbf09c2 Fix buffer read overrun in linker
Fixes an ASAN failure.

Was occuring when generating the OpModuleProcessed instruction declaring
that this module was processed by the linker.
2018-06-13 10:18:04 -04:00
Steven Perron
1f7b1f1bf7 Small vector optimization for operands.
We replace the std::vector in the Operand class by a new class that does
a small size optimization.  This helps improve compile time on Windows.

Tested on three sets of shaders.  Trying various values for the small
vector.  The optimal value for the operand class was 2.  However, for
the Instruction class, using an std::vector was optimal.  Size of "0"
means that an std::vector was used.

                Instruction size
	        0      4      8
Operand Size

0               489    544    684
1               593    487
2               469    570
4               473
8               505

This is a single thread run of ~120 shaders.  For the multithreaded run
the results were the similar.  The basline time was ~62sec.  The
optimal configuration was an 2 for the OperandData and an
std::vector for the OperandList with a compile time of ~38sec.  Similar
expiriments were done with other sets of shaders.  The compile time still
improved, but not as much.

Contributes to https://github.com/KhronosGroup/SPIRV-Tools/issues/1609.
2018-06-12 13:41:08 -04:00
David Neto
363bfca2ed Operand lookup succeeds if it's enabled by a capability
- Fix tests for basic group operations (e.g. Reduce) to allow for
new capabilities in SPIR-V 1.3 that enable them.
- Refactor operand capability check to avoid code duplication and
to put all checks that don't need table lookup before any table
lookup.
- Test round trip assembly/disassembly support for extension
SPV_NV_viewport_array2
- Test assembly and validation of decoration ViewportRelativeNV

Fixes #1596
2018-06-11 19:27:52 -04:00
Alan Baker
06de86863b Check for invalid branches into construct body.
Fixes #1281

* New structured cfg check: all non-construct header blocks'
predecessors must come from within the construct
* New function to calculate blocks in a construct

* Fixed a bug in BasicBlock type bitset

Relaxing check to not consider unreachable predecessors

* Fixing broken common uniform elim test
2018-06-11 19:23:44 -04:00
dan sinclair
63c9bba59d
[val] Output id names along with numbers in validate_id (#1601)
This CL updates the validate_id code to output the name of the object along with
the id number. There were a few instances which already output the name, this
just extends to all of them. Now, the output should say 123[obj] instead of just
123.

Issue #1581
2018-06-06 22:08:27 -04:00
dan sinclair
f2c93c6e12
Revert "Disallow array-of-arrays with DescriptorSets when validating. (#1586)" (#1607)
This reverts commit e3f1f3bda5.
2018-06-06 20:27:43 -04:00
dan sinclair
e3f1f3bda5
Disallow array-of-arrays with DescriptorSets when validating. (#1586)
* Disallow array-of-arrays with DescriptorSets when validating.

This CL adds validation to disallow using an array-of-arrays when attached to a
DescriptorSet.

Fixes #1522
2018-06-05 09:11:35 -04:00
Steven Perron
a1f9e1342e Preserve inst-to-block and def-use in passes.
The following passes are updated to preserve the inst-to-block and
def-use analysies:

	private-to-local
	aggressive dead-code elimination
	dead branch elimination
	local-single-block elimination
	local-single-store elimination
	reduce load size
	compact ids (inst-to-block only)
	merge block
	dead-insert elimination
	ccp

The one execption is that compact ids still kills the def-use manager.
This is because it changes so many ids it is faster to kill and rebuild.

Does everything in
https://github.com/KhronosGroup/SPIRV-Tools/issues/1593 except for the
changes to merge return.
2018-06-04 13:48:30 -04:00
Steven Perron
fe2fbee294 Delete the insert-extract-elim pass.
Replaces anything that creates an insert-extract-elim pass and create
a simplifiation pass instead.  Then delete the implementation of the
pass.

Fixes https://github.com/KhronosGroup/SPIRV-Tools/issues/1570.
2018-06-01 10:13:39 -04:00
Steven Perron
9a008835f4 Add store for var initializer in inlining.
Fixes https://github.com/KhronosGroup/SPIRV-Tools/issues/1591.
2018-06-01 09:44:42 -04:00
Alan Baker
badcf73d00 Allow duplicate pointer types
Fixes #1577

* Remove validation requiring unique pointer types unless variable
pointers extension enabled
* Modified scalar replacement to always look for an undecorated pointer
2018-05-31 09:14:38 -04:00
Steven Perron
93c4c184d5 Handle types with self references.
By using forward pointers, we are able to define a struct that has a
pointer to itself.  This could be directly or indirectly.  The current
implementation of the type manager did not handle this case.  There are
three changes that are made in this commit inorder to handle this case:

1) Change the handling of OpTypeForwardPointer

The current handling of OpTypeForwardsPointer is broken if there is a
reference to the pointer before the real definition.  When build the
type that contain the forward delared pointer, the type manager will ask
for the type for that ID, and will get a nullptr because it does not
exists.  This nullptr is not handleded very well.

The change is to keep track of the incomplete types the first time
through all of the types.  An incomplete type is a ForwardPointer or any
type that references an incomplete type.

Then we implement a second pass through the incomplete types that will
complete them.

2) Hashing types.

When hashing a type, we want to uses all of the subtypes as part of the
hash.  However, with types that reference them selves, this creates an
infinite recursion.  To get around this, we keep track of which types
have been seen on the path from the root type.  If we have see the
current type already then we can stop the recursion.

3) Comparing types.

In order to check if two types are the same, we must check that all of
their subtypes are the same as well.  This also causes an infinit
recursion.  The solution is to stop comparing the subtypes if we are
trying to compare two pointer types that we are already in the middle of
comparing.  The ideas is that if the two pointer are different, then in
progress compare will return false itself.

Fixes https://github.com/KhronosGroup/SPIRV-Tools/issues/1578.
2018-05-30 15:48:38 -04:00
Steven Perron
745dd00af9 Fold FMix feeding Extract, and use the simplification pass.
We add a new rule to the folding rules to fold an FMix feeding an
extract when the alpha value for the element being extracted is either
0 or 1.  In those case, we can simple extract from one of the operands
to the FMix.

With that change the simplification pass completely subsumes the
insert-extract elimination pass.  So we remove the insert-extract
elimination passes and replce them with calls to the simplification
pass.

In a follow up PR, we should delete the insert-extract elimination pass.

Contributes to https://github.com/KhronosGroup/SPIRV-Tools/issues/1570.
2018-05-25 14:42:59 -04:00
Arseny Kapoulkine
f765d16bd9 Add external interface for creating a pass token
Currently it's impossible for external code to register a pass because
the only source file that can create pass tokens is optimizer.cpp. This
makes it hard to add passes that can't be upstreamed since you can't run
them from the usual pass sequence without reimplementing Optimizer.

This change adds a PassToken constructor that takes unique_ptr to
opt::Pass; if out-of-tree code implements opt::Pass it can register a
custom pass without having to add it to SPIRV-Tools source code.
2018-05-25 09:19:43 -04:00
dan sinclair
0a14a1f748 Validate that only a single OpMemoryModel is provided.
This CL adds validation that only a single OpMemoryModel is provided in the
SPIR-V binary.

Fixes #1574
2018-05-24 08:43:14 -04:00
dan sinclair
3b87dac56b Validate presence of OpMemoryModel.
According to the SPIR-V Spec, section 2.4 Logical Layout of a Module there
should be a single required OpMemoryModel instruction provided. This CL adds
validation that OpMemoryModel is provided to the SPIR-V validator.

Fixes #1207
2018-05-23 08:17:39 -04:00
Steven Perron
a579e720a8 Remove the limit on struct size in SROA.
Removes the limit on scalar replacement for the lagalization passes.
This is done by adding an option to the pass (and command line option)
to set the limit on maximum size of the composite that scalar
replacement is willing to divide.

Fixes #1494.
2018-05-18 10:03:46 -04:00
Steven Perron
f1f7cc870e Get ADCE to handle OpCopyMemory
ADCE does not treat OpCopyMemory as an instruction that references
memory.  Because of that stores are removed that should not be.

This change teaches ADCE that OpCopyMemory and OpCopyMemorySize both
loads from and stores to memory.  This will keep other stores live when
needed, and will allows ADCE to remove OpCopyMemory instructions as
well.

Fixes https://github.com/KhronosGroup/SPIRV-Tools/issues/1556.
2018-05-16 13:50:47 -04:00
Lei Zhang
b09e3ce842
Allow ViewportIndex & Layer to be used in VS/DS with extension
SPV_EXT_shader_viewport_index_layer enables using ViewportIndex
and Layer in vertex and tessellation shaders.

Also, as per the Vulkan spec:

> The ViewportIndex decoration must be used only within vertex,
> tessellation evaluation, geometry, and fragment shaders.

> In a vertex, tessellation evaluation, or geometry shader, any
> variable decorated with ViewportIndex must be declared using
> the Output storage class.

> In a fragment shader, any variable decorated with ViewportIndex
> must be declared using the Input storage class.

Similarly for Layer.
2018-05-16 13:16:27 -04:00
Steven Perron
9b1a938ea1 SROA: Only create symbols that are loaded.
Currently in scalar replacement, we create a new variable for every
memeber of the composite being divided.  It is often overkill, because
not all of those members will be used.  This change will check which
elements are used and only create variable for the members that are
used.

This reduces the compile time for one set of shader from 248s to 165s.

Part of https://github.com/KhronosGroup/SPIRV-Tools/issues/1494.
2018-05-16 10:48:25 -04:00
Steven Perron
0e1b7e5aef Fix getting operand without checking opcode.
Fixes https://github.com/KhronosGhttps://github.com/KhronosGroup/SPIRV-Tools/issues/1559roup/SPIRV-Tools/issues/1559.

There is an load of an operand of an instruction that was suppose to be
only for the OpCompositeExtract case.  However, an error caused it to
be loaded for every opcode, even those that do not have an operand in
that position.

We fix up that bug, and a couple other things noticed that the same
time.
2018-05-16 09:34:43 -04:00
Lei Zhang
efcc33e8a9
Support SpvOpExecutionModeId in SPIR-V logical layout 2018-05-16 08:43:50 -04:00
Steven Perron
f46f2d3e5d Remove redundant stores.
The code patterns generated by DXC around function calls can cause many
store to be storing the same value that was just loaded from the same
location:

```
%10 = OpLoad %type %var
OpStore %var %10
```

We want to clean these up very early on because they can cause other
transformations to do a lot of work.  For the cases I see, they can be
removed during local-single-block-elim.

For one set of shaders the compile time goes from 248s to 182s.  A 26%
improvement.

Part of https://github.com/KhronosGroup/SPIRV-Tools/issues/1494.
2018-05-15 10:24:05 -04:00
Steven Perron
af430ec822 Add pass to fold a load feeding an extract.
We have already disabled common uniform elimination because it created
sequences of loads an entire uniform object, then we extract just a
single element.  This caused problems in some drivers, and is just
generally slow because it loads more memory than needed.

However, there are other way to get into this situation, so I've added
a pass that looks specifically for this pattern and removes it when only
a portion of the load is used.

Fixes #1547.
2018-05-14 15:40:34 -04:00
Steven Perron
804e8884c4 Fold fclamp feeding compare.
An FClamp instruction forces a values to be within a certain interval.
When the upper or lower bound of the FClamp is a constant and the value
being compared with is a constant, then in some case we can fold the
compared because the entire range is say less than the value.

Fixes https://github.com/KhronosGroup/SPIRV-Tools/issues/1549.
2018-05-14 10:27:49 -04:00
Steven Perron
9ec3f81e5c Remove dead Workgroup variables in ADCE.
If there is a shader with a variable in the workgroup storage class that
is stored to, but not loadeds, then we know nothing will read those
loads.  It should be safe to remove them.

This is implemented in ADCE by treating workgroup variables the same
way that private variables are treated.

Fixes https://github.com/KhronosGroup/SPIRV-Tools/issues/1550.
2018-05-09 16:07:26 -04:00
Steven Perron
0856997df6 Allow ADCE to remove more instructions.
At this time, DCE will only remove an instruction if it is a combinator.
However, there are certain non-combinator instructions that can be
safely removed if their results are not used.  The derivative
instructions are on example.

We are also missing some instructions from the list of combinators
those are added as the same time.
2018-05-05 09:15:28 -04:00
Steven Perron
7d01643132 Allow hoisting code in if-conversion.
When doing if-conversion, we do not currently move code out of the side
nodes.  The reason for this is that it can increase the number of
instructions that get executed because both side nods will have to be
executed now.

In this commit, we add code to move an instruction, and all of the
instructions it depends on, out of a side node and into the header of
the selection construct.  However to keep the cost down, we only do it
when the two values in the OpPhi node compute the same value.  This way
we have to move only one of the instructions and the other becomes
unused most of the time.  So no real extra cost.

Makes the value number table an alalysis in the ir context.

Added more opcodes to list of code motion safe opcodes.

Fixes #1526.
2018-05-04 12:56:29 -04:00
Stephen McGroarty
1c2cbaf569 Add GetContinueBlock to loop class.
Previously, the loop class used the terms latch and continue block
interchangeably. This patch splits the two and corrects and tests some
uses of the old uses of GetLatchBlock.
2018-05-03 14:30:41 -04:00
Steven Perron
70bb3c1cc2 Fold divide and multiply by same value.
We want to fold code like (x*y)/x and other permutations of this.

Fixes #1531.
2018-05-02 10:18:37 -04:00
Toomas Remmelg
1dc2458060 Add a loop fusion pass.
This pass will look for adjacent loops that are compatible and legal to
be fused.

Loops are compatible if:

- they both have one induction variable
- they have the same upper and lower bounds
    - same initial value
    - same condition
- they have the same update step
- they are adjacent
- there are no break/continue in either of them

Fusion is legal if:

- fused loops do not have any dependencies with dependence distance
  greater than 0 that did not exist in the original loops.
- there are no function calls in the loops (could have side-effects)
- there are no barriers in the loops

It will fuse all such loops as long as the number of registers used for
the fused loop stays under the threshold defined by
max_registers_per_loop.
2018-05-01 15:40:37 -04:00
Stephen McGroarty
9a5dd6fe88 Support loop fission.
Adds support for spliting loops whose register pressure exceeds a user
provided level. This pass will split a loop into two or more loops given
that the loop is a top level loop and that spliting the loop is legal.
Control flow is left intact for dead code elimination to remove.

This pass is enabled with the --loop-fission flag to spirv-opt.
2018-05-01 15:15:10 -04:00
Steven Perron
9ba0879ddf Improve Vector DCE
Track live scalars in VDCE as if they were single element vectors.

Handle the extended instructions for GLSL in VDCE.

Handle composite construct instructions in VDCE.
2018-04-30 11:55:50 -04:00
Steven Perron
a00a0a09ae Revert "Improvements to vector dce."
This reverts commit 2813722993.

A regression was found.  Undoing the change until it is fixed.
2018-04-27 10:33:19 -04:00
Alan Baker
4246abdc74 Fixes handling of kill and unreachable ops in inlining.
Fixes #1527

* Adds handling for copying OpKill and OpUnreachable and forces the
generation of a new basic block
* Adds tests to check
2018-04-27 09:42:37 -04:00
Steven Perron
e1bcd2b2d8 Fold OpVectorTimesScalar and OpPhi better.
If one of the operands to an OpVectorTimesScalar instruction is zero,
then the result will be the 0 vector. Currently we do not fold the
insturction unless both operands are constants. This change fixes that.

We also allow folding of OpPhi instructions where the incoming values
are either an OpUndef or the OpPhi instruction itself. As with other
cases, this can be simplified to the OpUndef.
2018-04-26 12:41:16 -04:00
Steven Perron
2813722993 Improvements to vector dce.
Track live scalars in VDCE as if they were single element vectors.

Handle the extended instructions for GLSL in VDCE.

Handle composite construct instructions in VDCE.

Fixes #1511.
2018-04-26 11:07:48 -04:00
Cort Stratton
72524db2de Fixes #1521: PadToWord() should use std::move() in && variant 2018-04-25 22:03:14 -04:00
Greg Fischer
268be6143d LocalSingleBlockElim: Add store-store elimination
Eliminate unused store to variable if followed by store to same
variable in same block.

Most significantly, this cleans up stores made unused by this pass.
These useless stores can inhibit subsequent optimizations, specifically
LocalSingleStoreElim. Eliminating them makes subsequent optimization more
effective.

The main effect of this pass is to simplify the work done by the SSA
rewriter.  It catches many local loads/stores that help speeding up the
work done by the main rewriter.
2018-04-25 10:30:18 -04:00
Steven Perron
ee8cd5c847 Add Dead insert elmination back in. 2018-04-24 10:10:30 -04:00
Steven Perron
2c0ce87210
Vector DCE (#1512)
Introduce a pass that does a DCE type analysis for vector elements
instead of the whole vector as a single element.

It will then rewrite instructions that are not used with something else.
For example, an instruction whose value are not used, even though it is
referenced, is replaced with an OpUndef.
2018-04-23 11:13:07 -04:00
Victor Lomuller
efc5061929 Dominator analysis interface clean.
Remove the CFG requirement when querying a dominator/post-dominator from an IRContext.

Updated all uses of the function and tests.
2018-04-20 15:41:59 -04:00
Jaebaek Seo
48802bad72 Constant folding for OpVectorTimesScalar 2018-04-20 13:43:04 -04:00
Victor Lomuller
0ec08c28c1 Add register liveness analysis.
For each function, the analysis determine which SSA registers are live
at the beginning of each basic block and which one are killed at
the end of the basic block.

It also includes utilities to simulate the register pressure for loop
fusion and fission.

The implementation is based on the paper "A non-iterative data-flow
algorithm for computing liveness sets in strict ssa programs" from
Boissinot et al.
2018-04-20 09:45:15 -04:00
Alan Baker
09c206b6fb Fixes #1480. Validate group non-uniform scopes.
* Adds new pass for validating non-uniform group instructions
 * Currently on checks execution scope for Vulkan 1.1 and SPIR-V 1.3
* Added test framework
2018-04-20 09:25:00 -04:00
David Neto
e7c2e91ded Fix for old XCode: std::set has explicit ctor 2018-04-19 16:33:12 -04:00
Greg Fischer
df7f00f60e DeadInsertElim: Don't revisit select phi nodes during MarkInsertChain
Fixes #1487.
2018-04-19 14:40:00 -04:00
Jaebaek Seo
430a29335e Fix broken pointer of CommonUniformElimPass 2018-04-19 09:36:10 -04:00
Steven Perron
c20a718e00 Rewrite local-single-store-elim to not create large data structures.
The local-single-store-elim algorithm is not fundamentally bad.
However, when there are a large number of variables, some of the
maps that are used can become very large.  These large data structures
then take a very long time to be destroyed.  I've seen cases around 40%
if the time.

I've rewritten that algorithm to not use as much memory.  This give a
significant improvement when running a large number of shader through
DXC.

I've also made a small change to local-single-block-elim to delete the
loads that is has replaced.  That way local-single-store-elim will not
have to look at those.  local-single-store-elim now does the same thing.

The time for one set goes from 309s down to 126s.  For another set, the
time goes from 102s down to 88s.
2018-04-18 16:38:18 -04:00
Jaebaek Seo
0fa42996b5
Merge pull request #1461 from jaebaek/fnegate
Add constant folding for OpFNegate

Contributes to #709
2018-04-18 13:46:10 -04:00
Toomas Remmelg
0f335cf87e Add support for MIV and Delta test dependence analysis.
GCD MIV test as described in Chapter 3 of "Optimizing Compilers for
Modern Architectures: A Dependence-Based Approach" by Randy Allen, and
Ken Kennedy.

Delta test as described in Figure 3 of "Practical Dependence Testing" by
Gina Goff, Ken Kennedy, and Chau-Wen Tseng from PLDI '91.
2018-04-17 13:57:02 -04:00
Jaebaek Seo
d8b9306a4f Add more unit tests 2018-04-17 12:08:45 -04:00
Jaebaek Seo
79491259e0 Add constant folding for FNegate 2018-04-17 12:08:45 -04:00
Alan Baker
38359ba800 Fixes #1483. Validating Vulkan 1.1 barrier execution scopes
* Reworked how execution model limitations are checked
 * Now OpFunction checks which entry points call it and checks its
 registered limitations instead of building a call stack in the entry
 point
* New tests
* Moving function to entry point mapping into VState
2018-04-17 10:26:38 -04:00
David Neto
152b9a681e ADCE: Remove OpDecorateStringGOOGLE
Also fix a few failures to set "modified" status when removing
global values.

Add OpDecorateStringGOOGLE to decoration ordering

Fixes #1492
2018-04-17 10:24:30 -04:00
Alan Baker
0e80b86dbe Fixes #1472. Per-vertex variable validation fixes.
Relaxs checks for per-vertex builtin variables. If the builtin
decoration is applied to a variable, then those checks now allow a level
of arraying on the variable before checking the type consistency.

* Allows arrays of variables to be present for the per-vertex variables:
 * Position
 * PointSize
 * ClipDistance
 * CullDistance
* Updated tests
2018-04-16 12:58:35 -04:00
Rex Xu
7fe186476a Fix validation issues relevant to SPV_AMD_gpu_shader_int16.
Frexp/FrexpStruct allows exp to be either 16-bit or 32 bit integer if
SPV_AMD_gpu_shader_int16 is enabled.
2018-04-16 10:49:01 -04:00
David Neto
e8814be732 Add validator test for OpBranch
Add test for case where OpBranch branches to a value (a function value).
Previous tests only checked a label value (name of a block.).

Update validate_id.cpp to remove the TODO for OpBranch and say that it
is already checked in validate_cfg.cpp
2018-04-16 10:27:51 -04:00
Steven Perron
d42f65e7c1 Use a bit vector in ADCE
The unordered_set in ADCE that holds all of the live instructions takes
a very long time to be destroyed.  In some shaders, it takes over 40% of
the time.

If we look at the unique ids of the live instructions, I believe they
are dense enough make a simple bit vector a good choice for to hold that
data.  When I check the density of the bit vector for larger shaders, we
are usually using less than 4 bytes per element in the vector, and
almost always less than 16.

So, in this commit, I introduce a simple bit vector class, and
use it in ADCE.

This help improve the compile time for some shaders on windows by the
40% mentioned above.

Contributes to https://github.com/KhronosGroup/SPIRV-Tools/issues/1328.
2018-04-13 16:38:02 -04:00
Steven Perron
8190c26270 Change parameter to Mempass::RemovePhiOperands
Pass a hashtable by const ref instead of by value.  Big impact on
compile time.
2018-04-13 09:53:37 -04:00
Alan Baker
e805d1f8d7 Fixes #1469. Allow subgroup memory scope for Vulkan 1.1
* New error that prevents CrossDevice memory scope for all vulkan
* Old error specifically references Vulkan 1.0
* New tests
2018-04-12 13:16:04 -04:00
Alan Baker
c522b697bf Fixes #1470. Don't restrict WGS storage class
* Removed restriction that workgroup size can only be on Input storage
class
* added test
2018-04-12 09:22:34 -04:00
Steven Perron
bc648fd76a Delete unused code in MemPass
Since the SSA rewriter was added, the code old phi insertion code is no
longer used.  It is going stale and should be deleted.
2018-04-11 15:40:33 -04:00
Steven Perron
c584ac4fc6 Don't allow an instance of a pass to be run multiple times. 2018-04-11 12:02:30 -04:00
Victor Lomuller
10e5d7cf13 Add a loop peeling pass.
For each loop in a function, the pass walks the loops from inner to outer most loop
and tries to peel loop for which a certain amount of iteration can be done before or after the loop.

To limit code growth, peeling will not happen if the growth in code size goes above a configurable threshold.
2018-04-11 15:41:29 +01:00
Alexander Johnston
61b50b3bfa ZIV and SIV loop dependence analysis.
Provides functionality to perform ZIV and SIV dependency analysis tests
between a load and store within the same loop.

Dependency tests rely on scalar analysis to prove and disprove dependencies
with regard to the loop being analysed.

Based on the 1990 paper Practical Dependence Testing by Goff, Kennedy, Tseng

Adds support for marking loops in the loop nest as IRRELEVANT.
Loops are marked IRRELEVANT if the analysed instructions contain
no induction variables for the loops, i.e. the loops induction
variable is not relevent to the dependence of the store and load.
2018-04-11 09:32:42 -04:00
Steven Perron
53bc1623ec Fold OpDot
Adding three rules to fold OpDot (implemented as two).

- When an OpDot has two constants, then fold to the resulting const.

- When one of the inputs is the 0 vector, then fold to zero.

- When one of the inputs is a single 1 with 0s, then rewrite to an
OpCompositeExtract of the appropriate element.  This will help find
even more folding opportunities.

Contributes to #709.
2018-04-10 13:09:37 -04:00
Alan Baker
42840d15e4 Fixes #1433. Validate binary version
* Validates SPIR-V binary version against target environment
2018-04-06 22:41:50 -04:00
Lei Zhang
26a698c347 Fix PrimitiveId builtin check for Vulkan
According to Vulkan spec 1.1.72:

> The PrimitiveId decoration must be used only within fragment,
> tessellation control, tessellation evaluation, and geometry shaders.

> In a tessellation control or tessellation evaluation shader, any
> variable decorated with PrimitiveId must be declared using the Input
> storage class.

We were enforcing that PrimitiveId can only be used with Output
storage class for TCS and TES before.
2018-04-06 22:38:32 -04:00
David Neto
a91cbfbf75 Optimizer: update extension whitelists
Add two new extensions:
- SPV_NV_shader_subgroup_partitioned
- SPV_EXT_descriptor_indexing
2018-04-06 15:56:20 -04:00
GregF
6fbfe1c016 Fix SSA rewrite for nested loops.
From the test case, the slice of the CFG that is interesting for the bug
is

25
|
v
30
|
v
31<-+
|   |
v   |
34--+

1. In block 25, we have a Phi candidate for %f with arguments
   %47 = Phi[%float_0, %0]. This merges %float_0 and a yet unknown
   argument from the external loop backedge.
2. We are now processing block 34:
   i. The load %35 = OpLoad %f triggers a Phi candidate to be placed in
      block 31.
  ii. The Phi candidate %50 = Phi needs two arguments. The one coming
      from block 30 is %47. But the one coming from block 34 (which we
      are now processing and have marked sealed), finds %50 itself as
      the reaching def for %f.
3. This wrongfully marks %50 as a copy-of Phi, which ultimately makes
   both %47 and %50 copy-of Phis that get eliminated.
2018-04-06 15:17:52 -04:00
Alan Baker
e66e305b46 Re-enabled checks for UConvert 2018-04-06 10:51:57 -04:00
Pierre Moreau
caf7da87e1 linker: Properly remove FuncParamAttr from imported symbols
Fixes https://github.com/KhronosGroup/SPIRV-Tools/issues/898
2018-04-06 09:55:54 -04:00
Lei Zhang
43ca2112b8 Stop asking for extensions if feature avaiable in core SPIR-V
Migrating to unified grammar means we sometimes have two fields
for a certain feature: version and extensions. It means the feature
in question can be used either in SPIR-V of advanced-enough
versions or in any SPIR-V with with the specified extensions.

Validator now respects the above rules.
2018-04-05 15:14:07 -04:00
Andrey Tuganov
d7fff408e3 Fix bug validate_builtins (additional def checks)
At every definition of a builtin id, run at-reference-check rules on the
defining instruction as well.

Previosly the validation was missing the case when invalid storage class
was defined in the instruction which defines the built-in, and not in
the instruction which references the built-in.
2018-04-05 13:55:18 -04:00
Andrey Tuganov
691eed92cb Fix major bug in validate_builtins
Fixed an early return in the loop, resulting in only one decoration
being checked.
2018-04-05 13:45:45 -04:00
Andrey Tuganov
da332cf332 Execution mode/model available in validation state
Refactored validate built-ins to make
GetExecutionModels(entry_point)
and
GetExecutionModes(entry_point)
available in validation state.

Entry points are allowed to have multiple execution modes and execution
models.

Finished the last missing feature in Vulkan built-ins validation:
FragDepth requires DepthReplacing.
2018-04-05 11:55:42 -04:00
Steven Perron
742454968d OpName and decorations should not stop array copy prop. 2018-04-04 22:24:10 -04:00
Steven Perron
7c5d49bf2a Teach ADCE about OpImageTexelPointer
Currently OpImageTexelPointer operations are treat like a use of the
pointer, but it does
not look for the memory being referenced to make sure stores are not
removed.

This change teaches it so identify the memory being accessed, and
treats it as if that memory is loaded.

Fixes to #1445.
2018-04-04 13:45:29 -04:00
Steven Perron
c33af63264 Teach array copy propagation about OpImageTexelPointer.
OpImageTexelPointer acts like a special kind of load.  It is not an
array load, but it also cannot be removed the same way a regular
load can.  The type of propagation that needs to be done is similar
to what we do for arrays, so I want to merge that code into that
optmization.

Contributers to #1445.
2018-04-04 13:42:51 -04:00
Steven Perron
e64a4656b3 Teach the private to local about OpImageTexelPointer.
OpImageTexelPointer acts like a special kind of load.  It is still
safe to change the storage class of a variable used in a
OpImageTexalPointer instruction.

Contributes to #1445.
2018-04-04 13:42:35 -04:00
Neil Roberts
57a2441791 hex_float: Use max_digits10 for the float precision
CPPreference.com has this description of digits10:

“The value of std::numeric_limits<T>::digits10 is the number of
 base-10 digits that can be represented by the type T without change,
 that is, any number with this many significant decimal digits can be
 converted to a value of type T and back to decimal form, without
 change due to rounding or overflow.”

This means that any number with this many digits can be represented
accurately in the corresponding type. A change in any digit in a
number after that may or may not cause it a different bitwise
representation. Therefore this isn’t necessarily enough precision to
accurately represent the value in text. Instead we need max_digits10
which has the following description:

“The value of std::numeric_limits<T>::max_digits10 is the number of
 base-10 digits that are necessary to uniquely represent all distinct
 values of the type T, such as necessary for
 serialization/deserialization to text.”

The patch includes a test case in hex_float_test which tries to do a
round-robin conversion of a number that requires more than 6 decimal
places to be accurately represented. This would fail without the
patch.

Sadly this also breaks a bunch of other tests. Some of the tests in
hex_float_test use ldexp and then compare it with a value which is not
the same as the one returned by ldexp but instead is the value rounded
to 6 decimals. Others use values that are not evenly representable as
a binary floating fraction but then happened to generate the same
value when rounded to 6 decimals. Where the actual value didn’t seem
to matter these have been changed with different values that can be
represented as a binary fraction.
2018-04-03 12:53:10 -04:00
James Jones
6dd5e955f5 Add missing function parameters in libspirv.h
When building C code with gcc and the
-Wstrict-prototypes option, function declarations
and definitions that don't specify their argument
types generate warnings.  Functions that don't
take parameters need to specify (void) as their
parameter list, rather than leaving it empty.

Note this only applies to C, so only the functions
exported in C-compatible headers need fixing.  In
C++ functions can't be declared/defined without a
parameter list, so C++ can safely allow an empty
parameter list to imply (void).
2018-04-03 10:10:43 -04:00
Lei Zhang
fc9f621e8b Add missing <iterator> header for std::back_inserter 2018-03-30 11:30:25 -04:00
Lei Zhang
ddbaf32460 Use standard SPIR-V version scheme for version requirement
Previously we use symbols in spv_target_env as the minimum version
requirements for features. That makes version check implicitly
relies on the order of entries in the spv_target_env enum, which
also contains client APIs. Instead, we should use the standard
scheme for constructing SPIR-V version; and by doing that we can
also map client API entries to universial SPIR-V versions.
2018-03-29 12:06:54 -04:00
Steven Perron
cbceeceab4 In copy-prop-arrays, indentify copies via OpCompositeInsert
When the original code copies an entire array or struct one element at a
time, this turns into a series of OpCompositeInsert instruction followed
by a store of the whole array.  We currently miss opportunities in copy
propagate arrays because we do not recognize this as a copy.

This commit adds code to copy propagate arrays to identify this code
pattern.

Also updates the performance passed to run array copy propagation.
2018-03-29 09:39:55 -04:00
Steven Perron
d8ca09821d Handle non-constant accesses in memory objects (copy prop arrays)
The first implementation of MemroyObject, which is used in copy
propagate arrays, forced the access chain to be like the access chains
in OpCompositeExtract.  This excluded the possibility of the memory
object from representing an array element that was extracted with a
variable index.   Looking at the code, that restriction is not
neccessary.  I also see some opportunities for doing this in some real
shaders.

Contributes to #1430.
2018-03-28 20:23:47 -04:00