summaryrefslogtreecommitdiff
path: root/source/slang/slang-check-overload.cpp
diff options
context:
space:
mode:
authorSai Praveen Bangaru <31557731+saipraveenb25@users.noreply.github.com>2022-06-23 16:02:05 -0400
committerGitHub <noreply@github.com>2022-06-23 16:02:05 -0400
commit6cf3d496005c5635b273d9ce6c110f14541a9492 (patch)
tree91d6480cec20ca88e85fb9b4d437e4661fba229c /source/slang/slang-check-overload.cpp
parent4aa6344f772d31c1f7b0676cbaf315104c4b30a2 (diff)
Added basic syntax to mark and request function derivatives, as well as the framework for passes to process them. (#2297)
* Added a decorator to mark functions for forward-mode differentiation * Fill out support for calls to non-decl values The existing compiler logic has a few places (semantic checking plus AST-to-IR lowering) where it assumes that function calls (`InvokeExpr`) are only ever made to expressions that resolve to a specific `Decl` (`DeclRefExpr`). This assumption allows semantic checking and lowering code to inspect things like the parameter list of an actual declaration, rather than just the type signature of the callee, and that infrastructure is used to support various features (e.g., default argument values on parameters). The AST and IR representations themselves have no matching requirement, and the places where the more general case of call expressions would need to be supported were relatively clear in the code. This change attempts to add suitable logic into each of those places. Note that this change does *not* surface any valid way to form input code that would cause these new code paths to be executed, so it is entirely possible that there are bugs in the logic as written here. The primary goal of this change is simply to get a sketch of the correct code checked in so that we have something to build on once we have language features that will require this support. * fixup: warnings-as-errors * Added parser logic for '__jvp(<fn-name>)' operator * Fixed issue with missing overload candidate item and added basic parsing test for the __jvp syntax * Added a blank JVP Auto-diff pass and a pass that replaces 'JVPDerivativeOf' calls with the differentiated function * Added a couple comments * Added parameter handling for the JVP pass Co-authored-by: Theresa Foley <tfoley@nvidia.com>
Diffstat (limited to 'source/slang/slang-check-overload.cpp')
-rw-r--r--source/slang/slang-check-overload.cpp95
1 files changed, 81 insertions, 14 deletions
diff --git a/source/slang/slang-check-overload.cpp b/source/slang/slang-check-overload.cpp
index f4a1de3d5..bd27c7df2 100644
--- a/source/slang/slang-check-overload.cpp
+++ b/source/slang/slang-check-overload.cpp
@@ -76,6 +76,14 @@ namespace Slang
paramCounts = CountParameters(candidate.item.declRef.as<GenericDecl>());
break;
+ case OverloadCandidate::Flavor::Expr:
+ {
+ auto paramCount = candidate.funcType->getParamCount();
+ paramCounts.allowed = paramCount;
+ paramCounts.required = paramCount;
+ }
+ break;
+
default:
SLANG_UNEXPECTED("unknown flavor of overload candidate");
break;
@@ -312,11 +320,34 @@ namespace Slang
{
Index argCount = context.getArgCount();
- List<DeclRef<ParamDecl>> params;
+ List<Type*> paramTypes;
+// List<DeclRef<ParamDecl>> params;
switch (candidate.flavor)
{
case OverloadCandidate::Flavor::Func:
- params = getParameters(candidate.item.declRef.as<CallableDecl>()).toArray();
+ for (auto param : getParameters(candidate.item.declRef.as<CallableDecl>()))
+ {
+ auto paramType = getType(m_astBuilder, param);
+ paramTypes.add(paramType);
+ }
+ break;
+
+ case OverloadCandidate::Flavor::Expr:
+ {
+ auto funcType = candidate.funcType;
+ Count paramCount = funcType->getParamCount();
+ for (Index i = 0; i < paramCount; ++i)
+ {
+ auto paramType = funcType->getParamType(i);
+
+ if(auto paramDirectionType = as<ParamDirectionType>(paramType))
+ {
+ paramType = paramDirectionType->getValueType();
+ }
+
+ paramTypes.add(paramType);
+ }
+ }
break;
case OverloadCandidate::Flavor::Generic:
@@ -329,13 +360,13 @@ namespace Slang
// Note(tfoley): We might have fewer arguments than parameters in the
// case where one or more parameters had defaults.
- SLANG_RELEASE_ASSERT(argCount <= params.getCount());
+ SLANG_RELEASE_ASSERT(argCount <= paramTypes.getCount());
for (Index ii = 0; ii < argCount; ++ii)
{
auto& arg = context.getArg(ii);
auto argType = context.getArgType(ii);
- auto param = params[ii];
+ auto paramType = paramTypes[ii];
if (context.mode == OverloadResolveContext::Mode::JustTrying)
{
@@ -343,10 +374,10 @@ namespace Slang
if( context.disallowNestedConversions )
{
// We need an exact match in this case.
- if(!getType(m_astBuilder, param)->equals(argType))
+ if(!paramType->equals(argType))
return false;
}
- else if (!canCoerce(getType(m_astBuilder, param), argType, arg, &cost))
+ else if (!canCoerce(paramType, argType, arg, &cost))
{
return false;
}
@@ -354,7 +385,7 @@ namespace Slang
}
else
{
- arg = coerce(getType(m_astBuilder, param), arg);
+ arg = coerce(paramType, arg);
}
}
return true;
@@ -558,11 +589,24 @@ namespace Slang
{
auto originalAppExpr = as<AppExprBase>(context.originalExpr);
- auto baseExpr = ConstructLookupResultExpr(
- candidate.item,
- context.baseExpr,
- context.funcLoc,
- originalAppExpr ? originalAppExpr->functionExpr : nullptr);
+
+
+ Expr* baseExpr;
+ switch(candidate.flavor)
+ {
+ case OverloadCandidate::Flavor::Func:
+ case OverloadCandidate::Flavor::Generic:
+ baseExpr = ConstructLookupResultExpr(
+ candidate.item,
+ context.baseExpr,
+ context.funcLoc,
+ originalAppExpr ? originalAppExpr->functionExpr : nullptr);
+ break;
+ case OverloadCandidate::Flavor::Expr:
+ default:
+ baseExpr = nullptr;
+ break;
+ }
switch(candidate.flavor)
{
@@ -598,6 +642,25 @@ namespace Slang
break;
+ case OverloadCandidate::Flavor::Expr:
+ {
+ AppExprBase* callExpr = as<InvokeExpr>(context.originalExpr);
+ if (!callExpr)
+ {
+ callExpr = m_astBuilder->create<InvokeExpr>();
+ callExpr->loc = context.loc;
+ for (Index aa = 0; aa < context.argCount; ++aa)
+ callExpr->arguments.add(context.getArg(aa));
+ }
+
+ callExpr->originalFunctionExpr = callExpr->functionExpr;
+ callExpr->type = QualType(candidate.resultType);
+
+ return callExpr;
+
+ }
+ break;
+
case OverloadCandidate::Flavor::Generic:
return createGenericDeclRef(
baseExpr,
@@ -996,8 +1059,12 @@ namespace Slang
FuncType* funcType,
OverloadResolveContext& context)
{
- SLANG_UNUSED(funcType);
- getSink()->diagnose(context.loc, Diagnostics::unimplemented, "call on expression of function type");
+ OverloadCandidate candidate;
+ candidate.flavor = OverloadCandidate::Flavor::Expr;
+ candidate.funcType = funcType;
+ candidate.resultType = funcType->getResultType();
+
+ AddOverloadCandidate(context, candidate);
}
void SemanticsVisitor::AddCtorOverloadCandidate(