From a12480fe49d5ba7c0a9c2ac63363dc76b599ddbd Mon Sep 17 00:00:00 2001 From: Tim Foley Date: Wed, 18 Oct 2017 11:08:47 -0700 Subject: Work on IR-based cross-compilation (#222) There are two big changes here: - Add logic during the initial IR cloning pass for an entry point + target that tries to pick the best possible version of any target-overloaded function. This allows us to pick the intrinsic version of `saturate()` when compiling for HLSL output, but then pick the non-intrinsic version (that is implemented in terms of `clamp()`) when targetting GLSL. - Add an initial specialization pass that tries to deal with generics. This required some fixing work to IR generation, so that we correctly generate explicit operations to specialize a generic for specific types (this is currently implemented as a `specialize` instruction that takes the generic to specialize plus a declaration-reference that represents the specialized form). With that work in place, we can scan for `specialize` instructions inside of non-generic functions, and use them to trigger generation of specialized code. We rely on the name-mangling scheme to help us find pre-existing specializations when possible. There are also a bunch of cleanups encountered along the way: - Don't use the explicit `layout(offset=...)` for uniforms, because it isn't supported by all current drivers. For now we will just assume that our layout rules compute the same values that the driver would for un-marked-up code. We can come back later and try to implement a workaround in the cases where this doesn't apply (e.g., by re-running the layout logic as part of emission, and dropping layout modifiers from variables that don't need explicit layout). - Fix some issues in IR dump printing so that we print function declarations more nicely. - Testing: print out failing pixel when image-diff fails --- source/slang/syntax.cpp | 46 +++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 45 insertions(+), 1 deletion(-) (limited to 'source/slang/syntax.cpp') diff --git a/source/slang/syntax.cpp b/source/slang/syntax.cpp index b863cb707..54a4a79b6 100644 --- a/source/slang/syntax.cpp +++ b/source/slang/syntax.cpp @@ -628,6 +628,7 @@ void Type::accept(IValVisitor* visitor, void* extra) { SLANG_UNEXPECTED("expected a declaration reference type"); } + declRefType->session = session; declRefType->declRef = declRef; return declRefType; } @@ -800,9 +801,52 @@ void Type::accept(IValVisitor* visitor, void* extra) return false; } + RefPtr FuncType::SubstituteImpl(Substitutions* subst, int* ioDiff) + { + int diff = 0; + + // result type + RefPtr substResultType = resultType->SubstituteImpl(subst, &diff).As(); + + // parameter types + List> substParamTypes; + for( auto pp : paramTypes ) + { + substParamTypes.Add(pp->SubstituteImpl(subst, &diff).As()); + } + + // early exit for no change... + if(!diff) + return this; + + (*ioDiff)++; + RefPtr substType = new FuncType(); + substType->session = session; + substType->resultType = substResultType; + substType->paramTypes = substParamTypes; + return substType; + } + Type* FuncType::CreateCanonicalType() { - return this; + // result type + RefPtr canResultType = resultType->GetCanonicalType(); + + // parameter types + List> canParamTypes; + for( auto pp : paramTypes ) + { + canParamTypes.Add(pp->GetCanonicalType()); + } + + RefPtr canType = new FuncType(); + canType->session = session; + canType->resultType = resultType; + canType->paramTypes = canParamTypes; + + session->canonicalTypes.Add(canType); + + return canType; } int FuncType::GetHashCode() -- cgit v1.2.3