summaryrefslogtreecommitdiffstats
path: root/source
diff options
context:
space:
mode:
authorYong He <yonghe@outlook.com>2017-11-22 17:32:15 -0500
committerGitHub <noreply@github.com>2017-11-22 17:32:15 -0500
commit83d49ce376185f7dc3f40eb531f01ee350220959 (patch)
tree7e96f26c6b6e6bf6a8b15ba1820e844e78a31394 /source
parent56e49feea3956d66e41b819c26628c65b3c28197 (diff)
parent581b30dd5a4263c90539a8c5cc6063b2485885cd (diff)
Merge pull request #293 from csyonghe/generic-param-fix
Fixup global generic parameters
Diffstat (limited to 'source')
-rw-r--r--source/slang/ir.cpp31
-rw-r--r--source/slang/parameter-binding.cpp38
-rw-r--r--source/slang/syntax.cpp47
-rw-r--r--source/slang/syntax.h1
-rw-r--r--source/slang/type-layout.h2
5 files changed, 104 insertions, 15 deletions
diff --git a/source/slang/ir.cpp b/source/slang/ir.cpp
index 0f34d5585..598445fcd 100644
--- a/source/slang/ir.cpp
+++ b/source/slang/ir.cpp
@@ -3103,10 +3103,30 @@ namespace Slang
IRGlobalVar* cloneGlobalVar(IRSpecContext* context, IRGlobalVar* originalVar);
IRFunc* cloneFunc(IRSpecContext* context, IRFunc* originalFunc);
IRWitnessTable* cloneWitnessTable(IRSpecContext* context, IRWitnessTable* originalVar);
+ RefPtr<Substitutions> cloneSubstitutions(
+ IRSpecContext* context,
+ Substitutions* subst);
RefPtr<Type> IRSpecContext::maybeCloneType(Type* originalType)
{
- return originalType->Substitute(subst).As<Type>();
+ auto rsType = originalType->GetCanonicalType()->Substitute(subst).As<Type>();
+ if (auto declRefType = rsType.As<DeclRefType>())
+ {
+ if (subst)
+ {
+ auto newSubst = cloneSubstitutions(this, subst);
+ insertSubstAtBottom(declRefType->declRef.substitutions, newSubst);
+ }
+ }
+ else if (auto funcType = rsType.As<FuncType>())
+ {
+ RefPtr<FuncType> newFuncType = new FuncType();
+ newFuncType->setSession(funcType->getSession());
+ newFuncType->resultType = maybeCloneType(funcType->resultType);
+ for (auto paramType : funcType->paramTypes)
+ newFuncType->paramTypes.Add(maybeCloneType(paramType));
+ }
+ return rsType;
}
IRValue* IRSpecContext::maybeCloneValue(IRValue* originalValue)
@@ -3243,6 +3263,15 @@ namespace Slang
newSubst->outer = cloneSubstitutions(context, subst->outer);
return newSubst;
}
+ else if (auto genTypeSubst = dynamic_cast<GlobalGenericParamSubstitution*>(subst))
+ {
+ RefPtr<GlobalGenericParamSubstitution> newSubst = new GlobalGenericParamSubstitution();
+ newSubst->actualType = genTypeSubst->actualType;
+ newSubst->paramDecl = genTypeSubst->paramDecl;
+ newSubst->witnessTables = genTypeSubst->witnessTables;
+ newSubst->outer = cloneSubstitutions(context, subst->outer);
+ return newSubst;
+ }
else
SLANG_UNREACHABLE("unimplemented cloneSubstitution");
UNREACHABLE_RETURN(nullptr);
diff --git a/source/slang/parameter-binding.cpp b/source/slang/parameter-binding.cpp
index 836ed254f..0daa2abc7 100644
--- a/source/slang/parameter-binding.cpp
+++ b/source/slang/parameter-binding.cpp
@@ -1425,6 +1425,16 @@ static RefPtr<TypeLayout> processEntryPointParameter(
return structLayout;
}
+ else if (auto globalGenericParam = declRef.As<GlobalGenericParamDecl>())
+ {
+ auto genParamTypeLayout = new GenericParamTypeLayout();
+ // we should have already populated ProgramLayout::genericEntryPointParams list at this point,
+ // so we can find the index of this generic param decl in the list
+ genParamTypeLayout->type = type;
+ genParamTypeLayout->paramIndex = findGenericParam(context->shared->programLayout->globalGenericParams, globalGenericParam.getDecl());
+ genParamTypeLayout->findOrAddResourceInfo(LayoutResourceKind::GenericResource)->count++;
+ return genParamTypeLayout;
+ }
else
{
SLANG_UNEXPECTED("unhandled type kind");
@@ -1442,7 +1452,8 @@ static RefPtr<TypeLayout> processEntryPointParameter(
static void collectEntryPointParameters(
ParameterBindingContext* context,
- EntryPointRequest* entryPoint)
+ EntryPointRequest* entryPoint,
+ Substitutions* typeSubst)
{
FuncDecl* entryPointFuncDecl = entryPoint->decl;
if (!entryPointFuncDecl)
@@ -1507,7 +1518,7 @@ static void collectEntryPointParameters(
auto paramTypeLayout = processEntryPointParameterWithPossibleSemantic(
context,
paramDecl.Ptr(),
- paramDecl->type.type,
+ paramDecl->type.type->Substitute(typeSubst).As<Type>(),
state,
paramVarLayout);
@@ -1539,7 +1550,7 @@ static void collectEntryPointParameters(
auto resultTypeLayout = processEntryPointParameterWithPossibleSemantic(
context,
entryPointFuncDecl,
- resultType,
+ resultType->Substitute(typeSubst).As<Type>(),
state,
resultLayout);
@@ -1632,7 +1643,7 @@ static void collectParameters(
for( auto& entryPoint : translationUnit->entryPoints )
{
context->stage = entryPoint->profile.GetStage();
- collectEntryPointParameters(context, entryPoint.Ptr());
+ collectEntryPointParameters(context, entryPoint.Ptr(), nullptr);
}
}
@@ -1891,13 +1902,7 @@ RefPtr<ProgramLayout> specializeProgramLayout(
newProgramLayout = new ProgramLayout();
newProgramLayout->bindingForHackSampler = programLayout->bindingForHackSampler;
newProgramLayout->hackSamplerVar = programLayout->hackSamplerVar;
- for (auto & entryPoint : programLayout->entryPoints)
- {
- RefPtr<EntryPointLayout> newEntryPoint = new EntryPointLayout(*entryPoint);
- // TODO: for now just copy existing entry point layouts, but we eventually need to
- // specialize these as well...
- newProgramLayout->entryPoints.Add(newEntryPoint);
- }
+ newProgramLayout->globalGenericParams = programLayout->globalGenericParams;
List<RefPtr<TypeLayout>> paramTypeLayouts;
auto globalStructLayout = getGlobalStructLayout(programLayout);
@@ -1919,7 +1924,7 @@ RefPtr<ProgramLayout> specializeProgramLayout(
SharedParameterBindingContext sharedContext;
sharedContext.compileRequest = targetReq->compileRequest;
sharedContext.defaultLayoutRules = layoutContext.getRulesFamily();
- sharedContext.programLayout = programLayout;
+ sharedContext.programLayout = newProgramLayout;
// Create a sub-context to collect parameters that get
// declared into the global scope
@@ -1928,6 +1933,15 @@ RefPtr<ProgramLayout> specializeProgramLayout(
context.translationUnit = nullptr;
context.layoutContext = layoutContext;
+
+ for (auto & translationUnit : targetReq->compileRequest->translationUnits)
+ {
+ for (auto & entryPoint : translationUnit->entryPoints)
+ {
+ collectEntryPointParameters(&context, entryPoint, typeSubst);
+ }
+ }
+
auto constantBufferRules = context.getRulesFamily()->getConstantBufferRules();
structLayout->rules = constantBufferRules;
diff --git a/source/slang/syntax.cpp b/source/slang/syntax.cpp
index e43dd9074..2c214a332 100644
--- a/source/slang/syntax.cpp
+++ b/source/slang/syntax.cpp
@@ -1309,9 +1309,39 @@ void Type::accept(IValVisitor* visitor, void* extra)
UNREACHABLE_RETURN(expr);
}
+ bool hasGlobalGenericSubst(Substitutions * destSubst, GlobalGenericParamSubstitution * genSubst)
+ {
+ while (destSubst)
+ {
+ if (auto globalParamSubst = dynamic_cast<GlobalGenericParamSubstitution*>(destSubst))
+ {
+ if (globalParamSubst->paramDecl == genSubst->paramDecl)
+ return true;
+ }
+ destSubst = destSubst->outer;
+ }
+ return false;
+ }
+ void insertGlobalGenericSubstitutions(RefPtr<Substitutions> & destSubst, Substitutions * srcSubst)
+ {
+ while (srcSubst)
+ {
+ if (auto globalGenSubst = dynamic_cast<GlobalGenericParamSubstitution*>(srcSubst))
+ {
+ if (!hasGlobalGenericSubst(destSubst, globalGenSubst))
+ {
+ RefPtr<GlobalGenericParamSubstitution> cpyGlobalGenSubst = new GlobalGenericParamSubstitution(*globalGenSubst);
+ cpyGlobalGenSubst->outer = nullptr;
+ insertSubstAtBottom(destSubst, cpyGlobalGenSubst);
+ }
+ }
+ srcSubst = srcSubst->outer;
+ }
+ }
DeclRefBase DeclRefBase::SubstituteImpl(Substitutions* subst, int* ioDiff)
{
+ insertGlobalGenericSubstitutions(substitutions, subst);
if (!substitutions) return *this;
int diff = 0;
@@ -1709,7 +1739,22 @@ void Type::accept(IValVisitor* visitor, void* extra)
return sb.ProduceString();
}
-
+ void insertSubstAtBottom(RefPtr<Substitutions> & substHead, RefPtr<Substitutions> substToInsert)
+ {
+ if (!substHead)
+ {
+ substHead = substToInsert;
+ return;
+ }
+ auto subst = substHead;
+ RefPtr<Substitutions> lastSubst = subst;
+ while (subst->outer)
+ {
+ lastSubst = subst;
+ subst = subst->outer;
+ }
+ lastSubst->outer = substToInsert;
+ }
void insertSubstAtTop(DeclRefBase & declRef, RefPtr<Substitutions> substToInsert)
{
diff --git a/source/slang/syntax.h b/source/slang/syntax.h
index b4d550ef5..f3690d9ae 100644
--- a/source/slang/syntax.h
+++ b/source/slang/syntax.h
@@ -1156,6 +1156,7 @@ namespace Slang
Session* session,
Decl* decl);
+ void insertSubstAtBottom(RefPtr<Substitutions> & substHead, RefPtr<Substitutions> substToInsert);
RefPtr<ThisTypeSubstitution> getNewThisTypeSubst(DeclRefBase & declRef);
RefPtr<ThisTypeSubstitution> getThisTypeSubst(DeclRefBase & declRef, bool insertSubstEntry);
void removeSubstitution(DeclRefBase & declRef, RefPtr<Substitutions> subst);
diff --git a/source/slang/type-layout.h b/source/slang/type-layout.h
index 4ce6dc355..07530bdfc 100644
--- a/source/slang/type-layout.h
+++ b/source/slang/type-layout.h
@@ -676,7 +676,7 @@ createStructuredBufferTypeLayout(
RefPtr<Type> structuredBufferType,
RefPtr<Type> elementType);
-
+int findGenericParam(List<RefPtr<GenericParamLayout>> & genericParameters, GlobalGenericParamDecl * decl);
//
}