Skip to content

Commit

Permalink
Delete wrap-global-context pass. (shader-slang#4114)
Browse files Browse the repository at this point in the history
* Delete `wrap-global-context` pass.

The pass was added for the metal backend without realizing that the existing `explicit-global-context` does 99% of the job. Instead of duplicating the logic in a different pass for metal, we extend same explicit-global-context pass to work for metal.

* Fix build.
  • Loading branch information
csyonghe authored May 6, 2024
1 parent 2220d26 commit 618428a
Show file tree
Hide file tree
Showing 6 changed files with 54 additions and 366 deletions.
2 changes: 0 additions & 2 deletions build/visual-studio/slang/slang.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -487,7 +487,6 @@ IF EXIST ..\..\..\external\slang-glslang\bin\windows-aarch64\release\slang-glsla
<ClInclude Include="..\..\..\source\slang\slang-ir-variable-scope-correction.h" />
<ClInclude Include="..\..\..\source\slang\slang-ir-vk-invert-y.h" />
<ClInclude Include="..\..\..\source\slang\slang-ir-witness-table-wrapper.h" />
<ClInclude Include="..\..\..\source\slang\slang-ir-wrap-global-context.h" />
<ClInclude Include="..\..\..\source\slang\slang-ir-wrap-structured-buffers.h" />
<ClInclude Include="..\..\..\source\slang\slang-ir.h" />
<ClInclude Include="..\..\..\source\slang\slang-language-server-ast-lookup.h" />
Expand Down Expand Up @@ -720,7 +719,6 @@ IF EXIST ..\..\..\external\slang-glslang\bin\windows-aarch64\release\slang-glsla
<ClCompile Include="..\..\..\source\slang\slang-ir-variable-scope-correction.cpp" />
<ClCompile Include="..\..\..\source\slang\slang-ir-vk-invert-y.cpp" />
<ClCompile Include="..\..\..\source\slang\slang-ir-witness-table-wrapper.cpp" />
<ClCompile Include="..\..\..\source\slang\slang-ir-wrap-global-context.cpp" />
<ClCompile Include="..\..\..\source\slang\slang-ir-wrap-structured-buffers.cpp" />
<ClCompile Include="..\..\..\source\slang\slang-ir.cpp" />
<ClCompile Include="..\..\..\source\slang\slang-language-server-ast-lookup.cpp" />
Expand Down
6 changes: 0 additions & 6 deletions build/visual-studio/slang/slang.vcxproj.filters
Original file line number Diff line number Diff line change
Expand Up @@ -549,9 +549,6 @@
<ClInclude Include="..\..\..\source\slang\slang-ir-witness-table-wrapper.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\..\source\slang\slang-ir-wrap-global-context.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\..\source\slang\slang-ir-wrap-structured-buffers.h">
<Filter>Header Files</Filter>
</ClInclude>
Expand Down Expand Up @@ -1244,9 +1241,6 @@
<ClCompile Include="..\..\..\source\slang\slang-ir-witness-table-wrapper.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\..\source\slang\slang-ir-wrap-global-context.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\..\source\slang\slang-ir-wrap-structured-buffers.cpp">
<Filter>Source Files</Filter>
</ClCompile>
Expand Down
9 changes: 1 addition & 8 deletions source/slang/slang-emit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,6 @@
#include "slang-ir-synthesize-active-mask.h"
#include "slang-ir-validate.h"
#include "slang-ir-wrap-structured-buffers.h"
#include "slang-ir-wrap-global-context.h"
#include "slang-ir-liveness.h"
#include "slang-ir-glsl-liveness.h"
#include "slang-ir-translate-glsl-global-var.h"
Expand Down Expand Up @@ -886,9 +885,9 @@ Result linkAndOptimizeIR(
case CodeGenTarget::GLSL:
case CodeGenTarget::SPIRV:
case CodeGenTarget::SPIRVAssembly:
case CodeGenTarget::Metal:
moveGlobalVarInitializationToEntryPoints(irModule);
break;
case CodeGenTarget::Metal:
case CodeGenTarget::CPPSource:
case CodeGenTarget::CUDASource:
moveGlobalVarInitializationToEntryPoints(irModule);
Expand Down Expand Up @@ -1097,12 +1096,6 @@ Result linkAndOptimizeIR(
validateIRModuleIfEnabled(codeGenContext, irModule);
}

// Metal does not allow global variables and global parameters, so
// we need to convert them into an explicit global context parameter
// passed around through a function parameter.
if (target == CodeGenTarget::Metal)
wrapGlobalScopeInContextType(irModule);

auto metadata = new ArtifactPostEmitMetadata;
outLinkedIR.metadata = metadata;

Expand Down
103 changes: 53 additions & 50 deletions source/slang/slang-ir-explicit-global-context.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#include "slang-ir-explicit-global-context.h"

#include "slang-ir-insts.h"
#include "slang-ir-clone.h"

namespace Slang
{
Expand All @@ -19,7 +20,7 @@ struct IntroduceExplicitGlobalContextPass
IRStructType* m_contextStructType = nullptr;
IRPtrType* m_contextStructPtrType = nullptr;

IRGlobalParam* m_globalUniformsParam = nullptr;
List<IRGlobalParam*> m_globalParams;
List<IRGlobalVar*> m_globalVars;
List<IRFunc*> m_entryPoints;

Expand Down Expand Up @@ -80,17 +81,26 @@ struct IntroduceExplicitGlobalContextPass


// One detail we need to be careful about is that as a result
// of legalizing the varying parameters of kernels, we can end
// up with global parameters for varying parameters on CUDA
// (e.g., to represent `threadIdx`. We thus skip any global-scope
// parameters that are varying instead of uniform.
// of legalizing the varying parameters of compute kernels to
// CPU or CUDA, we can end up with global parameters for varying
// parameters on CUDA (e.g., to represent `threadIdx`. We thus
// skip any global-scope parameters that are varying instead of
// uniform.
//
auto layoutDecor = globalParam->findDecoration<IRLayoutDecoration>();
SLANG_ASSERT(layoutDecor);
auto layout = as<IRVarLayout>(layoutDecor->getLayout());
SLANG_ASSERT(layout);
if(isVaryingParameter(layout))
continue;
switch (m_target)
{
case CodeGenTarget::CUDASource:
case CodeGenTarget::CPPSource:
{
auto layoutDecor = globalParam->findDecoration<IRLayoutDecoration>();
SLANG_ASSERT(layoutDecor);
auto layout = as<IRVarLayout>(layoutDecor->getLayout());
SLANG_ASSERT(layout);
if (isVaryingParameter(layout))
continue;
}
break;
}

// Because of upstream passes, we expect there to be only a
// single global uniform parameter (at most).
Expand All @@ -105,8 +115,7 @@ struct IntroduceExplicitGlobalContextPass
if(m_target == CodeGenTarget::CUDASource)
continue;

SLANG_ASSERT(!m_globalUniformsParam);
m_globalUniformsParam = globalParam;
m_globalParams.add(globalParam);
}
break;

Expand All @@ -130,15 +139,15 @@ struct IntroduceExplicitGlobalContextPass
}

// If there are no global-scope entities that require processing,
// then we can completely skip the work of this pass for CUDA.
// then we can completely skip the work of this pass for CUDA/Metal.
//
// Note: We cannot skip the rest of the pass for CPU, because
// it is responsible for introducing the explicit entry-point
// parameter that is used for passing in the global param(s).
//
if( m_target == CodeGenTarget::CUDASource )
if( m_target != CodeGenTarget::CPPSource )
{
if( !m_globalUniformsParam && (m_globalVars.getCount() == 0) )
if (m_globalParams.getCount() == 0 && m_globalVars.getCount() == 0)
{
return;
}
Expand All @@ -156,7 +165,7 @@ struct IntroduceExplicitGlobalContextPass
// The context will usually be passed around by pointer,
// so we get and cache that pointer type up front.
//
m_contextStructPtrType = builder.getPtrType(m_contextStructType);
m_contextStructPtrType = builder.getPtrType(kIROp_PtrType, m_contextStructType, (IRIntegerValue)AddressSpace::ThreadLocal);


// The first step will be to create fields in the `KernelContext`
Expand All @@ -166,12 +175,13 @@ struct IntroduceExplicitGlobalContextPass
// in a dictionary, so that we can find them later based on
// the global parameter/variable.
//
if( m_globalUniformsParam )
for (auto globalParam : m_globalParams)
{
// For the parameter representing all the global uniform shader
// parameters, we create a field that exactly matches its type.
//
createContextStructField(m_globalUniformsParam, m_globalUniformsParam->getFullType());

createContextStructField(globalParam, globalParam->getFullType());
}
for( auto globalVar : m_globalVars )
{
Expand Down Expand Up @@ -204,9 +214,9 @@ struct IntroduceExplicitGlobalContextPass
// above, but other functions will have an explicit context parameter
// added on demand.
//
if( m_globalUniformsParam )
for (auto globalParam : m_globalParams)
{
replaceUsesOfGlobalParam(m_globalUniformsParam);
replaceUsesOfGlobalParam(globalParam);
}
for( auto globalVar : m_globalVars )
{
Expand Down Expand Up @@ -234,23 +244,11 @@ struct IntroduceExplicitGlobalContextPass
// of the appropraite type.
//
auto key = builder.createStructKey();
auto field = builder.createStructField(m_contextStructType, key, type);
builder.createStructField(m_contextStructType, key, type);

// If the original instruction had a name hint on it,
// then we transfer that name hint over to the key,
// so that the field will have the name of the former
// global variable/parameter.
//
if( auto nameHint = originalInst->findDecoration<IRNameHintDecoration>() )
{
nameHint->insertAtStart(key);
}

// Any other decorations on the original instruction
// (e.g., pertaining to layout) need to be transferred
// over to the field (not the key).
//
originalInst->transferDecorationsTo(field);
// Clone all original decorations to the new struct key.
IRCloneEnv cloneEnv;
cloneInstDecorationsAndChildren(&cloneEnv, m_module, originalInst, key);

// We end by making note of the key that was created
// for the instruction, so that we can use the key
Expand Down Expand Up @@ -280,21 +278,26 @@ struct IntroduceExplicitGlobalContextPass
// then we need to introduce an explicit parameter onto
// each entry-point function to represent it.
//
IRParam* globalUniformsParam = nullptr;
if( m_globalUniformsParam )
struct GlobalParamInfo
{
globalUniformsParam = builder.createParam(m_globalUniformsParam->getFullType());
if( auto nameHint = m_globalUniformsParam->findDecoration<IRNameHintDecoration>() )
{
builder.addNameHintDecoration(globalUniformsParam, nameHint->getNameOperand());
}
IRGlobalParam* globalParam;
IRParam* entryPointParam;
};
List<GlobalParamInfo> entryPointParams;
for (auto globalParam : m_globalParams)
{
auto entryPointParam = builder.createParam(globalParam->getFullType());
IRCloneEnv cloneEnv;
cloneInstDecorationsAndChildren(&cloneEnv, m_module, globalParam, entryPointParam);
entryPointParams.add({globalParam, entryPointParam});

// The new parameter will be the last one in the
// parameter list of the entry point.
//
globalUniformsParam->insertBefore(firstOrdinary);
entryPointParam->insertBefore(firstOrdinary);
}
else if(m_target == CodeGenTarget::CPPSource)

if (m_target == CodeGenTarget::CPPSource && m_globalParams.getCount() == 0)
{
// The nature of our current ABI for entry points on CPU
// means that we need an explicit parameter to be *declared*
Expand All @@ -316,17 +319,17 @@ struct IntroduceExplicitGlobalContextPass
// to inialize the corresponding field of the `KernelContext`
// before moving on with execution of the kernel body.
//
if(m_globalUniformsParam)
for (auto entryPointParam : entryPointParams)
{
auto fieldKey = m_mapInstToContextFieldKey[m_globalUniformsParam];
auto fieldType = globalUniformsParam->getFullType();
auto fieldKey = m_mapInstToContextFieldKey[entryPointParam.globalParam];
auto fieldType = entryPointParam.globalParam->getFullType();
auto fieldPtrType = builder.getPtrType(fieldType);

// We compute the addrress of the field and store the
// value of the parameter into it.
//
auto fieldPtr = builder.emitFieldAddress(fieldPtrType, contextVarPtr, fieldKey);
builder.emitStore(fieldPtr, globalUniformsParam);
builder.emitStore(fieldPtr, entryPointParam.entryPointParam);
}

// Note: at this point the `KernelContext` has additional
Expand Down
Loading

0 comments on commit 618428a

Please sign in to comment.