<feed xmlns='http://www.w3.org/2005/Atom'>
<title>slang.git/source/slang/val-defs.h, branch master</title>
<subtitle>Making it easier to work with shaders</subtitle>
<id>https://git.yummers.dev/slang.git/atom?h=master</id>
<link rel='self' href='https://git.yummers.dev/slang.git/atom?h=master'/>
<link rel='alternate' type='text/html' href='https://git.yummers.dev/slang.git/'/>
<updated>2019-05-31T21:20:37+00:00</updated>
<entry>
<title>Use slang- prefix on slang compiler and core source (#973)</title>
<updated>2019-05-31T21:20:37+00:00</updated>
<author>
<name>jsmall-nvidia</name>
<email>jsmall@nvidia.com</email>
</author>
<published>2019-05-31T21:20:37+00:00</published>
<link rel='alternate' type='text/html' href='https://git.yummers.dev/slang.git/commit/?id=6cbc3929a54d37bd23cb5efa8e3320ba02f78b2f'/>
<id>urn:sha1:6cbc3929a54d37bd23cb5efa8e3320ba02f78b2f</id>
<content type='text'>
* Prefixing source files in source/slang with slang-

* Prefix source in source/slang with slang- prefix.

* Rename core source files with slang- prefix.

* Update project files.

* Fix problems from automatic merge.
</content>
</entry>
<entry>
<title>Initial support for dynamic dispatch using "tagged union" types (#772)</title>
<updated>2019-01-16T20:48:11+00:00</updated>
<author>
<name>Tim Foley</name>
<email>tfoleyNV@users.noreply.github.com</email>
</author>
<published>2019-01-16T20:48:11+00:00</published>
<link rel='alternate' type='text/html' href='https://git.yummers.dev/slang.git/commit/?id=aedf61784606406c090302efd8b7ac668ac997fc'/>
<id>urn:sha1:aedf61784606406c090302efd8b7ac668ac997fc</id>
<content type='text'>
* Initial support for dynamic dispatch using "tagged union" types

Suppose a user declares some generic shader code, like the following:

```hlsl
interface IFrobnicator { ... }
type_param T : IFrobincator;
ParameterBlock&lt;T : IFrobnicator&gt; gFrobnicator;
...
gFrobincator.frobnicate(value);
```

and then they have some concrete implementations of the required interface:

```hlsl
struct A : IFrobnicator { ... }
struct B : IFrobnicator { ... }
```

The current Slang compiler allows them to generate  distinct compiled kernels for the case of `T=A` and the case of `T=B`. This means that the decision of which implementation to use must be made at or before the time when a shader gets bound in the application.

This change adds a new ability where the Slang compiler can generate code to handle the case where `T` might be *either* `A` or `B`, and which case it is will be determined dynamically at runtime. This means a single compiled kernel can handle both cases, and the decision about which code path to run can be made any time before the shader executes.

This new option is supported by defining a *tagged union* type. Via the API, the user specifies that `T` should be specialized to `__TaggedUnion(A,B)` (the double underscore indicates that this is an experimental and unsupported feature at present). We refer to the types `A` and `B` here as the "case" types of the tagged union. Conceptually, the compiler synthesizes a type something like:

```hlsl
struct TU { union { A a; B b; } payload; uint tag; }
```

The user can then allocate a constant buffer to hold their tagged union type, and when they pick a concrete type to use (say `B`), they fill in the first `sizeof(B)` bytes of their buffer with data describing a `B` instance, and then set the `tag` field to the appopriate 0-based index of the case type they chose (in this case the `B` case gets the tag value `1`).

Actually implementing tagged unions takes a few main steps:

* Type parsing was extended to special-case `__TaggedUnion` as a contextual keyword. This is really only intended to be used when parsing types from the API or command-line, and Bad Things are likely to happen if a user ever puts it directly in their code. Eventually construction of tagged unions should be an API feature and not part of the language syntax.

* Semantic checking was extended to recognize that a tagged union like `__TaggedUnion(A,B)` shoud support an interface like `IFrobnicator` whenever all of the case types suport it, as long as the interface is "safe" for use with tagged unions (which means it doesn't use a few of the advancd langauge features like associated types).

* The IR was extended with instructions to represent tagged union types and to extract their tag and the payload for the different cases as needed.

* IR generation was extended to synthesize implementations of interface methods for any interface that a tagged union needs to support. Right now the implementation is simplistic and only handles simple method requirements, which it does by emitting a `switch` instruction to pick between the different cases.

* A new IR pass was introduced to "desugar" any tagged union types used in the code. The downstream HLSL and GLSL compilers don't support `union`s, so we have to instead emit a tagged union as a "bag of bits" and implement loading the data for particular cases from it manually.

* Final code emit mostly Just Works after the above steps, but we had to introduce an explicit IR instruction for bit-casting to handle the output of the desugaring pass.

There are a bunch of gaps and caveats in this implementation, but that seems reasonable for something that is an experimental feature. The various `TODO` comments and assertion failures in unimplemented cases are intended, so that this work can be checked in even if it isn't feature-complete.

* fixup: missing files

* fixup: typos
</content>
</entry>
<entry>
<title>First step toward supporting use of interfaces as existential types (#716)</title>
<updated>2018-12-18T03:26:32+00:00</updated>
<author>
<name>Tim Foley</name>
<email>tfoleyNV@users.noreply.github.com</email>
</author>
<published>2018-12-18T03:26:32+00:00</published>
<link rel='alternate' type='text/html' href='https://git.yummers.dev/slang.git/commit/?id=583c72af28d2dde5c564d5b56d3c5eb4ae4844f6'/>
<id>urn:sha1:583c72af28d2dde5c564d5b56d3c5eb4ae4844f6</id>
<content type='text'>
* First step toward supporting use of interfaces as existential types

Traditional generics involve universal quantification. E.g., a declaration like:

```
void drive&lt;T : IVehicle&gt;(T vehicle);
```

indicates for *for all* types `T` that implement the `IVehicle` interface, the `drive()` function is available.

In contrast, whend directly using an interface type like:

```
IVehicle v = ...;
v.doSomething();
```

we only know that there *exists* some concrete type (we could call it `E`) such that `v` refers to a value of type `E`, and `E` implements the `IVehicle` interface. In order to perform an operation like `v.doSomething()` we need to "open" the existential value so that we can look at the concrete type and how it implements the `IVehicle.doSomething` requirement.

This change adds a very explicit representation of existentials to Slang's IR. An operation like `e = makeExistential(v, w)` creates a value of some existential type (interfaces being our only existential types for now), by wrapping a concrete value `v` (the type of `v` can be seen as an implicit operand) and a witness table `w` showing that the type of `v` implements the requirements of the chosen interface type.

In turn, opening of an existential is handled with operations `extractExistential{Value|Type|WitnessTable}` which pull the corresponding piece of information out of a value of existential type (which somewhere in the code had to have been created with `makeExistential`).

The change includes a trivial simplification pass that can detect cases where an `extractExistential*` operation is applied direclty to a `makeExistential` operation, so that there is only one possible result that could be extracted. This allows for simplification of existential types used in trivial ways for local variables (this is mostly so I can check in a functional test, rather than to actually support useful code involving interfaces right now).

The logic in the semantic checking phase of the compiler is comparatively more complex.
When we are about to perform member lookup given an expression like `obj.member` we will first check if `obj` has an existential type, and if it does we will construct a suitable local context in which we extract the value, type, and witness table from the existential (these all become explicit AST expression nodes), and then use the extracted value as the base of the lookup operation.

The nature of existential values is that two different values with the same existential (interface) type could wrap concrete values with differnt types, so that we need to carefully refer only to the extracted type/value/witness-table of specific *values*. We handle this right now by conceptually moving the existential-type value into a local variable (by introducing a `LetExpr` that amounts to `let v = &lt;init&gt; in &lt;body&gt;`) and then require that the extract expressions must refer to the (immutable) variable declaration from which they are extracting a value.

(Eventually we should expand this so that when using an immutable local variable of existential type we just use that variable as-is rather than introduce a new temporary)

A simple test case is included that uses an interface type in an almost trivial way for a local variable; this test can be run and produces the expected results.
A more complex test case that passes an existential into a function is included, but left disabled because a more aggressive simplification approach is required to generate working code from it.

* Add missing file for expected test output

* Fixups for merge from top-of-tree
</content>
</entry>
<entry>
<title>Introduce an IR-level type system (#481)</title>
<updated>2018-04-11T23:18:29+00:00</updated>
<author>
<name>Tim Foley</name>
<email>tfoleyNV@users.noreply.github.com</email>
</author>
<published>2018-04-11T23:18:29+00:00</published>
<link rel='alternate' type='text/html' href='https://git.yummers.dev/slang.git/commit/?id=baf194e7456ba4568dcf11249896af35b3ce18cc'/>
<id>urn:sha1:baf194e7456ba4568dcf11249896af35b3ce18cc</id>
<content type='text'>
* Introduce an IR-level type system

Up to this point, the Slang IR has used the front-end type system to represent types in the IR.
As a result (but ultimately more importantly) the IR representation of generics and specialization has used AST-level concepts embedded in the IR.
For example, to express the specialization of `vector&lt;T,N&gt;` to a concrete type `float` for `T`, we needed an IR operation that could represent the specialization, with operands that somehow represented the type argument `float`.
The whole thing was very complicated.

The big idea of this change is to introduce a new representation in which types in the IR are just ordinary instructions, so that using them as operands makes sense. The hierarchy of IR types closely mirrors the AST-side hierarchy for now, and that will probably be something we should maintain going forward.

In order to make these changes work, though, I also had to do major overhauls of things like the way substitutions are performed, how we check interface conformances, the way lookup through interface types is done, etc. etc. This is a big change, and unfortunately any attempt to summarize it in the commit message wouldn't do it justice.

* Fix 64-bit build warning

* Fix up some clang warnings/errors
</content>
</entry>
<entry>
<title>bug fixes to get falcor example shader code to compile.</title>
<updated>2018-01-16T20:38:36+00:00</updated>
<author>
<name>Yong He</name>
<email>yonghe@outlook.com</email>
</author>
<published>2018-01-16T20:38:36+00:00</published>
<link rel='alternate' type='text/html' href='https://git.yummers.dev/slang.git/commit/?id=a74a5494b34e2b41a294042ab8b3e7bce115dcba'/>
<id>urn:sha1:a74a5494b34e2b41a294042ab8b3e7bce115dcba</id>
<content type='text'>
1. prevent cyclic lookups when an interface inherits transitively from itself.
2. in `createGlobalGenericParamSubstitution`, create a default substitution for the base type declref before using it to lookup the witness table.
</content>
</entry>
<entry>
<title>Refactor substitution representation in DeclRefBase (#363)</title>
<updated>2018-01-12T22:15:56+00:00</updated>
<author>
<name>Yong He</name>
<email>yonghe@outlook.com</email>
</author>
<published>2018-01-12T22:15:56+00:00</published>
<link rel='alternate' type='text/html' href='https://git.yummers.dev/slang.git/commit/?id=df6eeb93c1718334779ae328db277cdf7a9d7b04'/>
<id>urn:sha1:df6eeb93c1718334779ae328db277cdf7a9d7b04</id>
<content type='text'>
This commit changes the type of `DeclRefBase::substitutions` from `RefPtr&lt;Substitutions&gt;` to `SubstitutionSet`, which is a new type defined as following:
```
struct SubstitutionSet
{
    RefPtr&lt;GenericSubstitution&gt; genericSubstitutions;
    RefPtr&lt;ThisTypeSubstitution&gt; thisTypeSubstitution;
    RefPtr&lt;GlobalGenericParamSubstitution&gt; globalGenParamSubstitutions;
}
```
This change get rid of most helper functions to retreive the substitution of a certain type, as well as surgery operations to insert a `ThisTypeSubstitution` or `GlobalGenericTypeSubstittuion` at top or bottom of the substitution chain. It also simplies type comparison when certain type of substitution should not be considered as part of type definition.</content>
</entry>
<entry>
<title>bruteforce implementation of witness table resolution for associated (#358)</title>
<updated>2018-01-09T18:50:44+00:00</updated>
<author>
<name>Yong He</name>
<email>yonghe@outlook.com</email>
</author>
<published>2018-01-09T18:50:44+00:00</published>
<link rel='alternate' type='text/html' href='https://git.yummers.dev/slang.git/commit/?id=8daafcc2e4bf7b2dfb66d7a3b7ac60c86b2d926c'/>
<id>urn:sha1:8daafcc2e4bf7b2dfb66d7a3b7ac60c86b2d926c</id>
<content type='text'>
</content>
</entry>
<entry>
<title>Support nested generic types (e.g. L&lt;T&lt;S&gt;&gt;)</title>
<updated>2017-12-27T23:50:32+00:00</updated>
<author>
<name>Yong He</name>
<email>yonghe@outlook.com</email>
</author>
<published>2017-12-27T23:47:40+00:00</published>
<link rel='alternate' type='text/html' href='https://git.yummers.dev/slang.git/commit/?id=87cba147d513fcbc4b69a083dc10557a6c1b42ba'/>
<id>urn:sha1:87cba147d513fcbc4b69a083dc10557a6c1b42ba</id>
<content type='text'>
fixes #325

This commit includes following changes:

1. Including a default DeclaredSubtypeWitness argument when creating a default GenericSubstitution for a DeclRefType, so that the witness argument can be successfully replaced with an actual witness table after specialization. (check,cpp)

2. Not emitting full mangled name for struct field members. Since the declref of the member access instruction do not include necessary generic substitutions for its parent generic parameters, so the mangled names of the declaration site and use site mismatches. Instead we just emit the original name for struct fields. (emit.cpp)

3. Allow IRWitnessTable to represent a generic witness table for generic structs. Adds necessary fields to IRWitnessTable for generic specialization. For now, the user field of the IRUse is not used and is nullptr. (ir-inst.h)

4. Make IRProxyVal use an IRUse instead of an IRValue*, so that an IRValue referenced by IRProxyVal (as a substitution argument) can be managed by the def-use chain for easy replacement. This is used for specializing witness tables. (ir.cpp, ir.h)

5. Add a `String dumpIRFunc(IRFunc*)` function for debugging.

6. Add name mangling for generic / specialized witness tables (mangle.cpp)

7. improved natvis file for inspecting witness tables.

8. Add specialization of witness tables:
   1) `findWitnessTable` will simply return the specialize IRInst for a generic witness table.
   2) make `cloneSubstitutionArg` call `cloneValue` to clone the argument instead of calling `context-&gt;maybeCloneValue`, so we can make use of the cloned value lookup machanism to directly return the specialized witness table (which is done when we process the `specialize` instruction on the generic witness table before process the decl ref).
  3) bug fix: the argument in ir.cpp:3338 should be `newArg` instead of `arg`.
  4) add `specializeWitnessTable` function to specailize a generic witness table. It clones the witness table, and recursively calls `getSpecailizedFunc` for the witness table entries.
  5) make `specailizeGenerics` function also handle the case when an operand of the `specialize` instruction is a witness table. We will call `specializeWitnessTable` here and replace the `specialize` instruction with the specialized witness table. The replacement mechanism based on IR def-use chain works here because we have already make IRProxyVal a part of the def-use chain.

9. Add two more test cases for nested generics with constraints. (generic-list.slang and generic-struct-with-constraint.slang)
</content>
</entry>
<entry>
<title>Support for transitive subtype witnesses (#331)</title>
<updated>2017-12-22T20:09:26+00:00</updated>
<author>
<name>Tim Foley</name>
<email>tfoleyNV@users.noreply.github.com</email>
</author>
<published>2017-12-22T20:09:26+00:00</published>
<link rel='alternate' type='text/html' href='https://git.yummers.dev/slang.git/commit/?id=d1c38523d4bfbb6672baca9973013538b549bfae'/>
<id>urn:sha1:d1c38523d4bfbb6672baca9973013538b549bfae</id>
<content type='text'>
* Change stdlib `saturate` to explicitly specialize `clamp`

This exposes issue #329, and so gives us an easy way to see if transitive subtype witnesses have been implemented correctly.

* Fixup: invoke correct `clamp` overloads

When switching the `clamp` calls in the stdlib definition of `saturate` I made two big mistakes:

1. I was passing in `&lt;T&gt;` in all cases, instead of, e.g., `&lt;vector&lt;T,N&gt;&gt;` in the vector case

2. Of course, the overloads don't actually take `&lt;vector&lt;T,N&gt;&gt;` for the vector case, because `vector&lt;T,N&gt;` is not a `__BuiltinArithmeticType` (`T` is), so instead it should be `clamp&lt;T,N&gt;(...)`.

The issue behind (2) is that we don't support "conditional conformances," which would be a way to say that when `T : __BuiltinArithmeticType` then `vector&lt;T,N&gt; : __BuiltinArithmeticType`. That would be a great long-term wish-list feature, but not something I can see us adding in a hurry.

Anyway the fix here is the simple one: change the vector/matrix call sites to invoke the correct overload in each case.

* Add a notion of transitive subtype witnesses

There are two pieces here:

1. Add the `TransitiveSubtypeWitness` class. This is a witness that `A : C` that works by storing nested subtype witnesses that show that `A : B` and `B : C` for some intermediate type `B`. All the basic `Val` operations are easy enough to define on this.

  - The one gotcha case is whether we can ever simplify away a `TransitiveSubtypeWitness` as part of substitution. That is, if we end up substituting so that both `A` and `B` end up as the same type, then we really just need the `B : C` sub-part. Stuff like that is left as future work.

2. Make the logic in `check.cpp` that constructs subtype witnesses based on found inheritance and constraint declarations able to build up transitive chains. Most of the required infrastructure was already there (the search process maintains a trail of "breadcrumbs" that represent all the steps getting from `A : B` to `B : C` to `C : D` ...).

This change does *not* deal with the required changes in the IR to take advantage of transitive witnesses.
</content>
</entry>
<entry>
<title>Support generic interface methods (#251)</title>
<updated>2017-11-08T00:09:40+00:00</updated>
<author>
<name>Yong He</name>
<email>yonghe@outlook.com</email>
</author>
<published>2017-11-08T00:09:40+00:00</published>
<link rel='alternate' type='text/html' href='https://git.yummers.dev/slang.git/commit/?id=6e591ada0eb652c320bba4bd8a46cd579946df01'/>
<id>urn:sha1:6e591ada0eb652c320bba4bd8a46cd579946df01</id>
<content type='text'>
* improve diagnostic messages and prevent fatal errors from crashing the compiler.

* fix top level exception catching.

* spelling fix

* change wording of invalidSwizzleExpr diagnostic

* add speculative GenericsApp expr parsing

* add new test case of cascading generics call.

* Fixing bugs in compiling cascaded generic function calls.

Add implementation of DeclaredSubTypeWitness::SubstituteImpl()

This is not needed by the type checker, but needed by IR specialization. When input source contains cascading generic function call, the arguments to `specialize` instruction is currently represented as a substitution. The arg values of this subsittution can be a `DeclaredSubTypeWitness` when a generic function uses one of its generic parameter to specialize another generic function. When the top level generics function is being specialized, this substitution argument, which is a `DeclaredSubTypeWitness`, needs to be substituted with the witness that used to specialize the top level function in the specialized specialize instruction as well.

* add a test case for cascading generic function call.

* parser bug fix

* fixes #255

* add test case for issue #255

* Generate missing `specialize` instruction when calling a generic method from an interface constraint.

When calling a generic method via an interface, we should be generating the following ir:
...
f = lookup_interface_method(...)
f_s = specailize(f, declRef)
...

This commit fixes this  `emitFuncRef` function to emit the needed `specialize` instruction.

* fixes #260

This fix follows the second apporach in the disucssion. It generated mangled name for specialized functions by appending new substitution type names to the original mangled name.

* Disabling removing and re-inserting specailized functions in getSpecalizeFunc()

I am not sure why it is needed, it seems HLSL and GLSL backends are generating forward declarations anyways, so the order of functions in IRModule shouldn't matter.

* cleanup and complete test cases.

* fix warnings
</content>
</entry>
</feed>
