From 3c3513ab501277333d1062ad2737ac4a60dac6f7 Mon Sep 17 00:00:00 2001 From: Tim Foley Date: Mon, 28 Jan 2019 14:20:44 -0800 Subject: Support function parameters of existential (interface) type (#802) * Support function parameters of existential (interface) type The basic idea here is that you can define a function that takes an interface-type parameter: ```hlsl interface IThing { void doSOmething(); } void coolFunction(IThing thing) { ... thing.doSomething() ... } ``` and call it with a concrete value that implements the given interface: ```hlsl struct Stuff : IThing { void doSomething() { /* secret sauce */ } } ... Stuff stuff; coolFunction(stuff); ``` The compiler implementation will specialize `coolFunction` based on the concrete type that was actually passed in, resulting in output code along the lines of: ```hlsl struct Stuff { ... } void Stuff_doSomething(Stuff this) { /* secret sauce */ } void coolFunction_Stuff(Stuff thing) { ... Stuff_doSomething(thing); } ``` In terms of implementation the new specialization approach has been integrated into the existing pass for generic specialization (which has been refactored significantly along the way), because generic specialization can open up opportunities for existential/interface simplification and vice versa, so there is no fixed interleaving of the two passes that can clean up everything. The new logic therefore subsumes the old code for simplifying existential types (which only worked on local variables) in `ir-existential.{h,cpp}`. The local simplification rules from that implementation have become part of the core specialization pass instead, so that they can open up further transformation opportunities enabled by existential-type simplifications. This code in place right now only handles the basic case of a function parameter that directly uses an interface type, and not one that wraps up an interface type in an array, structure, etc. Additional simplifications need to be introduced to deal with those cases as well. * fixup: typos --- source/slang/emit.cpp | 33 ++++++++++++--------------------- 1 file changed, 12 insertions(+), 21 deletions(-) (limited to 'source/slang/emit.cpp') diff --git a/source/slang/emit.cpp b/source/slang/emit.cpp index dd6feb50d..887a62974 100644 --- a/source/slang/emit.cpp +++ b/source/slang/emit.cpp @@ -3,7 +3,6 @@ #include "../core/slang-writer.h" #include "ir-dce.h" -#include "ir-existential.h" #include "ir-glsl-legalize.h" #include "ir-insts.h" #include "ir-link.h" @@ -6667,34 +6666,26 @@ String emitEntryPoint( #endif validateIRModuleIfEnabled(compileRequest, irModule); - - // Any code that makes use of existential (interface) types - // needs to be simplified to use concrete types instead, - // wherever this is possible. - // - // Note: we are applying this *before* doing specialization - // of generics because this pass could expose concrete - // types and/or witness tables that allow for further - // specialization. + // Next, we need to ensure that the code we emit for + // the target doesn't contain any operations that would + // be illegal on the target platform. For example, + // none of our target supports generics, or interfaces, + // so we need to specialize those away. // - // TODO: Simplification of existential-based and generics-based + // Simplification of existential-based and generics-based // code may each open up opportunities for the other, so - // in the long run these will need to be merged into a + // the relevant specialization transformations are handled in a // single pass that looks for all simplification opportunities. // - // TODO: We also need a legalization pass that will "expose" + // TODO: We also need to extend this pass so that it will "expose" // existential values that are nested inside of other types, // so that the simplifications can be applied. // - simplifyExistentialTypes(irModule); - - // Next, we need to ensure that the code we emit for - // the target doesn't contain any operations that would - // be illegal on the target platform. For example, - // none of our target supports generics, or interfaces, - // so we need to specialize those away. + // TODO: This pass is *also* likely to be the place where we + // perform specialization of functions based on parameter + // values that need to be compile-time constants. // - specializeGenerics(irModule); + specializeModule(irModule); // Debugging code for IR transformations... #if 0 -- cgit v1.2.3