summaryrefslogtreecommitdiffstats
path: root/source
diff options
context:
space:
mode:
authorYong He <yonghe@outlook.com>2024-05-01 17:30:55 -0700
committerGitHub <noreply@github.com>2024-05-01 17:30:55 -0700
commit9043bc5522cc86560ac5d57ddfc6cfa7612c9222 (patch)
tree9804bb8a682386b9f761e8fb164cb43ad5390411 /source
parent0bb826f8b92aec330875d0b966c1f4a6b99988bf (diff)
Fix compile failures when using debug symbol. (#4069)
* Fix compile failures when using debug symbol. * Various fixes. * Fix intrinsic. * Fix test.
Diffstat (limited to 'source')
-rw-r--r--source/slang/glsl.meta.slang61
-rw-r--r--source/slang/slang-compiler-options.cpp7
-rw-r--r--source/slang/slang-ir-insert-debug-value-store.cpp342
-rw-r--r--source/slang/slang-ir-insts.h4
-rw-r--r--source/slang/slang-ir-util.cpp6
-rw-r--r--source/slang/slang-ir-util.h2
-rw-r--r--source/slang/slang-ir.cpp21
-rw-r--r--source/slang/slang.cpp1
8 files changed, 285 insertions, 159 deletions
diff --git a/source/slang/glsl.meta.slang b/source/slang/glsl.meta.slang
index bafd0b947..98770293c 100644
--- a/source/slang/glsl.meta.slang
+++ b/source/slang/glsl.meta.slang
@@ -66,15 +66,15 @@ public typealias mat3 = matrix<float, 3, 3>;
public typealias mat4 = matrix<float, 4, 4>;
public typealias mat2x2 = matrix<float, 2, 2>;
-public typealias mat2x3 = matrix<float, 3, 2>;
-public typealias mat2x4 = matrix<float, 4, 2>;
+public typealias mat2x3 = matrix<float, 2, 3>;
+public typealias mat2x4 = matrix<float, 2, 4>;
-public typealias mat3x2 = matrix<float, 2, 3>;
+public typealias mat3x2 = matrix<float, 3, 2>;
public typealias mat3x3 = matrix<float, 3, 3>;
-public typealias mat3x4 = matrix<float, 4, 3>;
+public typealias mat3x4 = matrix<float, 3, 4>;
-public typealias mat4x2 = matrix<float, 2, 4>;
-public typealias mat4x3 = matrix<float, 3, 4>;
+public typealias mat4x2 = matrix<float, 4, 2>;
+public typealias mat4x3 = matrix<float, 4, 3>;
public typealias mat4x4 = matrix<float, 4, 4>;
public typealias dmat2 = matrix<double, 2, 2>;
@@ -82,15 +82,15 @@ public typealias dmat3 = matrix<double, 3, 3>;
public typealias dmat4 = matrix<double, 4, 4>;
public typealias dmat2x2 = matrix<double, 2, 2>;
-public typealias dmat2x3 = matrix<double, 3, 2>;
-public typealias dmat2x4 = matrix<double, 4, 2>;
+public typealias dmat2x3 = matrix<double, 2, 3>;
+public typealias dmat2x4 = matrix<double, 2, 4>;
-public typealias dmat3x2 = matrix<double, 2, 3>;
+public typealias dmat3x2 = matrix<double, 3, 2>;
public typealias dmat3x3 = matrix<double, 3, 3>;
-public typealias dmat3x4 = matrix<double, 4, 3>;
+public typealias dmat3x4 = matrix<double, 3, 4>;
-public typealias dmat4x2 = matrix<double, 2, 4>;
-public typealias dmat4x3 = matrix<double, 3, 4>;
+public typealias dmat4x2 = matrix<double, 4, 2>;
+public typealias dmat4x3 = matrix<double, 4, 3>;
public typealias dmat4x4 = matrix<double, 4, 4>;
@@ -899,19 +899,18 @@ __generic<T : __BuiltinFloatingPointType, let C : int, let R : int>
[ForceInline]
[OverloadRank(15)]
[require(cpp_cuda_glsl_hlsl_spirv, GLSL_400)]
-public matrix<T, C, R> outerProduct(vector<T, C> c, vector<T, R> r)
+public matrix<T, R, C> outerProduct(vector<T, C> c, vector<T, R> r)
{
__target_switch
{
case glsl: __intrinsic_asm "outerProduct";
default:
- // Column major matrix in GLSL
- matrix<T, C, R> result;
- for (int i = 0; i < C; ++i)
+ matrix<T, R, C> result;
+ for (int j = 0; j < R; ++j)
{
- for (int j = 0; j < R; ++j)
+ for (int i = 0; i < C; ++i)
{
- result[i][j] = c[i] * r[j];
+ result[j][i] = c[i] * r[j];
}
}
return result;
@@ -3884,10 +3883,9 @@ public property mat4x3 gl_ObjectToWorldEXT
}
case spirv:
{
- return spirv_asm
+ return spirv_asm
{
- %mat:$$mat3x4 = OpLoad builtin(ObjectToWorldKHR:mat3x4);
- result:$$mat4x3 = OpTranspose %mat
+ result:$$mat4x3 = OpLoad builtin(ObjectToWorldKHR:mat4x3);
};
}
}
@@ -3910,7 +3908,8 @@ public property mat3x4 gl_ObjectToWorld3x4EXT
{
return spirv_asm
{
- result:$$mat3x4 = OpLoad builtin(ObjectToWorldKHR:mat3x4)
+ %mat:$$mat4x3 = OpLoad builtin(ObjectToWorldKHR:mat4x3);
+ result:$$mat3x4 = OpTranspose %mat
};
}
}
@@ -3933,8 +3932,7 @@ public property mat4x3 gl_WorldToObjectEXT
{
return spirv_asm
{
- %mat:$$mat3x4 = OpLoad builtin(WorldToObjectKHR:mat3x4);
- result:$$mat4x3 = OpTranspose %mat
+ result:$$mat4x3 = OpLoad builtin(WorldToObjectKHR:mat4x3);
};
}
}
@@ -3957,7 +3955,8 @@ public property mat3x4 gl_WorldToObject3x4EXT
{
return spirv_asm
{
- result:$$mat3x4 = OpLoad builtin(WorldToObjectKHR:mat3x4)
+ %mat:$$mat4x3 = OpLoad builtin(WorldToObjectKHR:mat4x3);
+ result:$$mat3x4 = OpTranspose %mat
};
}
}
@@ -4336,11 +4335,11 @@ public mat4x3 rayQueryGetIntersectionObjectToWorldEXT(rayQueryEXT q, bool commit
{
if (committed)
{
- return transpose(q.CommittedRayObjectToWorld());
+ return q.CommittedRayObjectToWorld();
}
else
{
- return transpose(q.CandidateRayObjectToWorld());
+ return q.CandidateRayObjectToWorld();
}
}
@@ -4351,11 +4350,11 @@ public mat4x3 rayQueryGetIntersectionWorldToObjectEXT(rayQueryEXT q, bool commit
{
if (committed)
{
- return transpose(q.CommittedRayWorldToObject());
+ return q.CommittedRayWorldToObject();
}
else
{
- return transpose(q.CandidateRayWorldToObject());
+ return q.CandidateRayWorldToObject();
}
}
@@ -4910,7 +4909,7 @@ __glsl_extension(GLSL_EXT_buffer_reference_uvec2)
[require(glsl_spirv, ser_raygen_closesthit_miss)]
public mat4x3 hitObjectGetObjectToWorldNV(hitObjectNV hitObject)
{
- return transpose(hitObject.GetObjectToWorld());
+ return hitObject.GetObjectToWorld();
}
__glsl_extension(GL_EXT_ray_tracing)
@@ -4920,7 +4919,7 @@ __glsl_extension(GLSL_EXT_buffer_reference_uvec2)
[require(glsl_spirv, ser_raygen_closesthit_miss)]
public mat4x3 hitObjectGetWorldToObjectNV(hitObjectNV hitObject)
{
- return transpose(hitObject.GetWorldToObject());
+ return hitObject.GetWorldToObject();
}
__glsl_extension(GL_EXT_ray_tracing)
diff --git a/source/slang/slang-compiler-options.cpp b/source/slang/slang-compiler-options.cpp
index 974fbaaaa..ea2593713 100644
--- a/source/slang/slang-compiler-options.cpp
+++ b/source/slang/slang-compiler-options.cpp
@@ -186,7 +186,7 @@ namespace Slang
result |= SLANG_TARGET_FLAG_DUMP_IR;
if (getBoolOption(CompilerOptionName::GenerateWholeProgram))
result |= SLANG_TARGET_FLAG_GENERATE_WHOLE_PROGRAM;
- if (getBoolOption(CompilerOptionName::EmitSpirvDirectly))
+ if (!getBoolOption(CompilerOptionName::EmitSpirvViaGLSL))
result |= SLANG_TARGET_FLAG_GENERATE_SPIRV_DIRECTLY;
if (getBoolOption(CompilerOptionName::ParameterBlocksUseRegisterSpaces))
result |= SLANG_TARGET_FLAG_PARAMETER_BLOCKS_USE_REGISTER_SPACES;
@@ -197,7 +197,10 @@ namespace Slang
{
set(CompilerOptionName::DumpIr, (flags & SLANG_TARGET_FLAG_DUMP_IR) != 0);
set(CompilerOptionName::GenerateWholeProgram, (flags & SLANG_TARGET_FLAG_GENERATE_WHOLE_PROGRAM) != 0);
- set(CompilerOptionName::EmitSpirvDirectly, (flags & SLANG_TARGET_FLAG_GENERATE_SPIRV_DIRECTLY) != 0);
+ if ((flags & SLANG_TARGET_FLAG_GENERATE_SPIRV_DIRECTLY) != 0)
+ set(CompilerOptionName::EmitSpirvViaGLSL, false);
+ else
+ set(CompilerOptionName::EmitSpirvViaGLSL, true);
set(CompilerOptionName::ParameterBlocksUseRegisterSpaces, (flags & SLANG_TARGET_FLAG_PARAMETER_BLOCKS_USE_REGISTER_SPACES) != 0);
}
diff --git a/source/slang/slang-ir-insert-debug-value-store.cpp b/source/slang/slang-ir-insert-debug-value-store.cpp
index 004598b5d..46116d660 100644
--- a/source/slang/slang-ir-insert-debug-value-store.cpp
+++ b/source/slang/slang-ir-insert-debug-value-store.cpp
@@ -6,181 +6,277 @@
namespace Slang
{
- void insertDebugValueStore(IRFunc* func)
+ struct DebugValueStoreContext
{
- IRBuilder builder(func);
- Dictionary<IRInst*, IRInst*> mapVarToDebugVar;
- auto firstBlock = func->getFirstBlock();
- if (!firstBlock)
- return;
- auto funcDebugLoc = func->findDecoration<IRDebugLocationDecoration>();
- if (!funcDebugLoc)
- return;
- List<IRInst*> params;
- for (auto param : firstBlock->getParams())
+ Dictionary<IRType*, bool> m_mapTypeToDebugability;
+ bool isTypeKind(IRInst* inst)
{
- params.add(param);
+ if (!inst)
+ return true;
+ switch (inst->getOp())
+ {
+ case kIROp_TypeKind:
+ case kIROp_TypeType:
+ return true;
+ default:
+ return false;
+ }
}
- Index paramIndex = 0;
- for (auto param : params)
+ bool isDebuggableType(IRType* type)
{
- builder.setInsertBefore(firstBlock->getFirstOrdinaryInst());
- auto paramType = param->getDataType();
- bool isRefParam = false;
- if (auto outType = as<IROutTypeBase>(paramType))
+ if (bool* result = m_mapTypeToDebugability.tryGetValue(type))
+ return *result;
+
+ bool debuggable = false;
+ switch (type->getOp())
+ {
+ case kIROp_VoidType:
+ break;
+ case kIROp_StructType:
{
- isRefParam = true;
- paramType = outType->getValueType();
+ auto structType = static_cast<IRStructType*>(type);
+ bool structDebuggable = true;
+ for (auto field : structType->getFields())
+ {
+ if (!isDebuggableType(field->getFieldType()))
+ {
+ structDebuggable = false;
+ break;
+ }
+ }
+ debuggable = structDebuggable;
+ break;
}
- auto debugVar = builder.emitDebugVar(
- paramType,
- funcDebugLoc->getSource(),
- funcDebugLoc->getLine(),
- funcDebugLoc->getCol(),
- builder.getIntValue(builder.getUIntType(), paramIndex));
- copyNameHintAndDebugDecorations(debugVar, param);
-
- mapVarToDebugVar[param] = debugVar;
-
- // Store the initial value of the parameter into the debug var.
- IRInst* paramVal = nullptr;
- if (!isRefParam)
- paramVal = param;
- else if (as<IRInOutType>(param->getDataType()))
- paramVal = builder.emitLoad(param);
- if (paramVal)
+ case kIROp_ArrayType:
+ case kIROp_UnsizedArrayType:
{
- ArrayView<IRInst*> accessChain;
- builder.emitDebugValue(debugVar, paramVal, accessChain);
+ auto arrayType = static_cast<IRArrayTypeBase*>(type);
+ debuggable = isDebuggableType(arrayType->getElementType());
+ break;
}
- paramIndex++;
- }
-
- for (auto block : func->getBlocks())
- {
- IRInst* nextInst = nullptr;
- for (auto inst = block->getFirstInst(); inst; inst = nextInst)
+ case kIROp_VectorType:
+ case kIROp_MatrixType:
+ case kIROp_PtrType:
+ debuggable = true;
+ break;
+ case kIROp_Param:
+ // Assume generic parameters are debuggable.
+ debuggable = true;
+ break;
+ case kIROp_Specialize:
{
- nextInst = inst->getNextInst();
- if (auto varInst = as<IRVar>(inst))
+ auto specType = as<IRSpecialize>(type);
+ auto specTypeDebuggable = isDebuggableType((IRType*)getResolvedInstForDecorations(specType));
+ if (!specTypeDebuggable)
+ break;
+ for (UInt i = 0; i < specType->getArgCount(); i++)
{
- if (auto debugLoc = varInst->findDecoration<IRDebugLocationDecoration>())
+ auto arg = specType->getArg(i);
+ if (isTypeKind(arg->getDataType()) && !isDebuggableType((IRType*)specType->getArg(i)))
{
- builder.setInsertBefore(varInst);
- auto debugVar = builder.emitDebugVar(
- tryGetPointedToType(&builder, varInst->getDataType()),
- debugLoc->getSource(),
- debugLoc->getLine(),
- debugLoc->getCol());
- copyNameHintAndDebugDecorations(debugVar, varInst);
- mapVarToDebugVar[varInst] = debugVar;
- }
+ specTypeDebuggable = false;
+ break;
+ }
}
+ debuggable = false;// specTypeDebuggable;
+ break;
}
+ default:
+ if (as<IRBasicType>(type))
+ debuggable = true;
+ break;
+ }
+ m_mapTypeToDebugability[type] = debuggable;
+ return debuggable;
}
- // Collect all stores and insert debug value insts to update debug vars.
-
- // Helper func to insert debugValue updates.
- auto setDebugValue = [&](IRInst* debugVar, IRInst* rootVar, IRInst* newValue, ArrayView<IRInst*> accessChain)
+ void insertDebugValueStore(IRFunc* func)
+ {
+ IRBuilder builder(func);
+ Dictionary<IRInst*, IRInst*> mapVarToDebugVar;
+ auto firstBlock = func->getFirstBlock();
+ if (!firstBlock)
+ return;
+ auto funcDebugLoc = func->findDecoration<IRDebugLocationDecoration>();
+ if (!funcDebugLoc)
+ return;
+ List<IRInst*> params;
+ for (auto param : firstBlock->getParams())
+ {
+ params.add(param);
+ }
+ Index paramIndex = 0;
+ for (auto param : params)
{
- // SPIRV does not allow dynamic indices in DebugValue,
- // so we need to stop the access chain at the first dynamic index.
- Index i = 0;
- for (; i < accessChain.getCount(); i++)
+ builder.setInsertBefore(firstBlock->getFirstOrdinaryInst());
+ auto paramType = param->getDataType();
+ bool isRefParam = false;
+ if (auto outType = as<IROutTypeBase>(paramType))
{
- if (auto key = as<IRStructKey>(accessChain[i]))
- {
- continue;
- }
- if (as<IRIntLit>(accessChain[i]))
- {
- continue;
- }
- break;
+ isRefParam = true;
+ paramType = outType->getValueType();
}
- // If everything is static on the access chain, we can simply emit a DebugValue.
- if (i == accessChain.getCount())
+ if (!isDebuggableType(paramType))
+ continue;
+ auto debugVar = builder.emitDebugVar(
+ paramType,
+ funcDebugLoc->getSource(),
+ funcDebugLoc->getLine(),
+ funcDebugLoc->getCol(),
+ builder.getIntValue(builder.getUIntType(), paramIndex));
+ copyNameHintAndDebugDecorations(debugVar, param);
+
+ mapVarToDebugVar[param] = debugVar;
+
+ // Store the initial value of the parameter into the debug var.
+ IRInst* paramVal = nullptr;
+ if (!isRefParam)
+ paramVal = param;
+ else if (as<IRInOutType>(param->getDataType()))
+ paramVal = builder.emitLoad(param);
+ if (paramVal)
{
- builder.emitDebugValue(debugVar, newValue, accessChain);
- return;
+ ArrayView<IRInst*> accessChain;
+ builder.emitDebugValue(debugVar, paramVal, accessChain);
}
-
- // Otherwise we need to load the entire composite value starting at the dynamic index access chain
- // and set it.
- auto compositePtr = builder.emitElementAddress(rootVar, accessChain.head(i));
- auto compositeVal = builder.emitLoad(compositePtr);
- builder.emitDebugValue(debugVar, compositeVal, accessChain.head(i));
- };
- for (auto block : func->getBlocks())
- {
- IRInst* nextInst = nullptr;
- for (auto inst = block->getFirstInst(); inst; inst = nextInst)
- {
- nextInst = inst->getNextInst();
+ paramIndex++;
+ }
- if (auto storeInst = as<IRStore>(inst))
+ for (auto block : func->getBlocks())
+ {
+ IRInst* nextInst = nullptr;
+ for (auto inst = block->getFirstInst(); inst; inst = nextInst)
{
- List<IRInst*> accessChain;
- auto varInst = getRootAddr(storeInst->getPtr(), accessChain);
- IRInst* debugVar = nullptr;
- if (mapVarToDebugVar.tryGetValue(varInst, debugVar))
+ nextInst = inst->getNextInst();
+ if (auto varInst = as<IRVar>(inst))
{
- builder.setInsertAfter(storeInst);
- setDebugValue(debugVar, varInst, storeInst->getVal(), accessChain.getArrayView());
+ if (auto debugLoc = varInst->findDecoration<IRDebugLocationDecoration>())
+ {
+ auto varType = tryGetPointedToType(&builder, varInst->getDataType());
+ builder.setInsertBefore(varInst);
+ if (!isDebuggableType(varType))
+ continue;
+ auto debugVar = builder.emitDebugVar(
+ varType,
+ debugLoc->getSource(),
+ debugLoc->getLine(),
+ debugLoc->getCol());
+ copyNameHintAndDebugDecorations(debugVar, varInst);
+ mapVarToDebugVar[varInst] = debugVar;
+ }
}
}
- else if (auto swizzledStore = as<IRSwizzledStore>(inst))
+ }
+
+ // Collect all stores and insert debug value insts to update debug vars.
+
+ // Helper func to insert debugValue updates.
+ auto setDebugValue = [&](
+ IRInst* debugVar, IRInst* rootVar, IRInst* newValue,
+ ArrayView<IRInst*> accessChain, ArrayView<IRInst*> types)
{
- List<IRInst*> accessChain;
- auto varInst = getRootAddr(swizzledStore->getDest(), accessChain);
- IRInst* debugVar = nullptr;
- if (mapVarToDebugVar.tryGetValue(varInst, debugVar))
+ // SPIRV does not allow dynamic indices in DebugValue,
+ // so we need to stop the access chain at the first dynamic index.
+ Index i = 0;
+ for (; i < accessChain.getCount(); i++)
{
- builder.setInsertAfter(swizzledStore);
- auto loadVal = builder.emitLoad(swizzledStore->getDest());
- setDebugValue(debugVar, varInst, loadVal, accessChain.getArrayView());
+ if (auto key = as<IRStructKey>(accessChain[i]))
+ {
+ continue;
+ }
+ if (as<IRIntLit>(accessChain[i]))
+ {
+ continue;
+ }
+ break;
}
- }
- else if (auto callInst = as<IRCall>(inst))
+ // If everything is static on the access chain, we can simply emit a DebugValue.
+ if (i == accessChain.getCount())
+ {
+ builder.emitDebugValue(debugVar, newValue, accessChain);
+ return;
+ }
+
+ // Otherwise we need to load the entire composite value starting at the dynamic index access chain
+ // and set it.
+ auto compositePtr = builder.emitElementAddress(rootVar, accessChain.head(i), types.head(i));
+ auto compositeVal = builder.emitLoad(compositePtr);
+ builder.emitDebugValue(debugVar, compositeVal, accessChain.head(i));
+ };
+ for (auto block : func->getBlocks())
+ {
+ IRInst* nextInst = nullptr;
+ for (auto inst = block->getFirstInst(); inst; inst = nextInst)
{
- auto funcValue = getResolvedInstForDecorations(callInst->getCallee());
- if (!funcValue)
- continue;
- for (UInt i = 0; i < callInst->getArgCount(); i++)
+ nextInst = inst->getNextInst();
+
+ if (auto storeInst = as<IRStore>(inst))
{
- auto arg = callInst->getArg(i);
- if (!as<IRPtrTypeBase>(arg->getDataType()))
- continue;
List<IRInst*> accessChain;
- auto varInst = getRootAddr(arg, accessChain);
+ List<IRInst*> types;
+ auto varInst = getRootAddr(storeInst->getPtr(), accessChain, &types);
IRInst* debugVar = nullptr;
if (mapVarToDebugVar.tryGetValue(varInst, debugVar))
{
- builder.setInsertAfter(callInst);
- auto loadVal = builder.emitLoad(arg);
- setDebugValue(debugVar, varInst, loadVal, accessChain.getArrayView());
+ builder.setInsertAfter(storeInst);
+ setDebugValue(debugVar, varInst, storeInst->getVal(), accessChain.getArrayView(), types.getArrayView());
+ }
+ }
+ else if (auto swizzledStore = as<IRSwizzledStore>(inst))
+ {
+ List<IRInst*> accessChain;
+ List<IRInst*> types;
+ auto varInst = getRootAddr(swizzledStore->getDest(), accessChain, &types);
+ IRInst* debugVar = nullptr;
+ if (mapVarToDebugVar.tryGetValue(varInst, debugVar))
+ {
+ builder.setInsertAfter(swizzledStore);
+ auto loadVal = builder.emitLoad(swizzledStore->getDest());
+ setDebugValue(debugVar, varInst, loadVal, accessChain.getArrayView(), types.getArrayView());
+ }
+ }
+ else if (auto callInst = as<IRCall>(inst))
+ {
+ auto funcValue = getResolvedInstForDecorations(callInst->getCallee());
+ if (!funcValue)
+ continue;
+ for (UInt i = 0; i < callInst->getArgCount(); i++)
+ {
+ auto arg = callInst->getArg(i);
+ if (!as<IRPtrTypeBase>(arg->getDataType()))
+ continue;
+ List<IRInst*> accessChain;
+ List<IRInst*> types;
+ auto varInst = getRootAddr(arg, accessChain, &types);
+ IRInst* debugVar = nullptr;
+ if (mapVarToDebugVar.tryGetValue(varInst, debugVar))
+ {
+ builder.setInsertAfter(callInst);
+ auto loadVal = builder.emitLoad(arg);
+ setDebugValue(debugVar, varInst, loadVal, accessChain.getArrayView(), types.getArrayView());
+ }
}
}
}
}
}
- }
+ };
void insertDebugValueStore(IRModule* module)
{
+ DebugValueStoreContext context;
for (auto globalInst : module->getGlobalInsts())
{
if (auto genericInst = as<IRGeneric>(globalInst))
{
if (auto func = as<IRFunc>(findGenericReturnVal(genericInst)))
{
- insertDebugValueStore(func);
+ context.insertDebugValueStore(func);
}
}
else if (auto func = as<IRFunc>(globalInst))
{
- insertDebugValueStore(func);
+ context.insertDebugValueStore(func);
}
}
}
diff --git a/source/slang/slang-ir-insts.h b/source/slang/slang-ir-insts.h
index 0f41f9bd9..9329e3806 100644
--- a/source/slang/slang-ir-insts.h
+++ b/source/slang/slang-ir-insts.h
@@ -4042,6 +4042,10 @@ public:
IRInst* emitElementAddress(
IRInst* basePtr,
const ArrayView<IRInst*>& accessChain);
+ IRInst* emitElementAddress(
+ IRInst* basePtr,
+ const ArrayView<IRInst*>& accessChain,
+ const ArrayView<IRInst*>& types);
IRInst* emitUpdateElement(IRInst* base, IRInst* index, IRInst* newElement);
IRInst* emitUpdateElement(IRInst* base, IRIntegerValue index, IRInst* newElement);
diff --git a/source/slang/slang-ir-util.cpp b/source/slang/slang-ir-util.cpp
index bcb9439fb..1fccf3e27 100644
--- a/source/slang/slang-ir-util.cpp
+++ b/source/slang/slang-ir-util.cpp
@@ -652,7 +652,7 @@ IRInst* getRootAddr(IRInst* addr)
return addr;
}
-IRInst* getRootAddr(IRInst* addr, List<IRInst*>& outAccessChain)
+IRInst* getRootAddr(IRInst* addr, List<IRInst*>& outAccessChain, List<IRInst*>* outTypes)
{
for (;;)
{
@@ -661,6 +661,8 @@ IRInst* getRootAddr(IRInst* addr, List<IRInst*>& outAccessChain)
case kIROp_GetElementPtr:
case kIROp_FieldAddress:
outAccessChain.add(addr->getOperand(1));
+ if (outTypes)
+ outTypes->add(addr->getFullType());
addr = addr->getOperand(0);
continue;
default:
@@ -669,6 +671,8 @@ IRInst* getRootAddr(IRInst* addr, List<IRInst*>& outAccessChain)
break;
}
outAccessChain.reverse();
+ if (outTypes)
+ outTypes->reverse();
return addr;
}
diff --git a/source/slang/slang-ir-util.h b/source/slang/slang-ir-util.h
index 3b3df27ef..03a45746d 100644
--- a/source/slang/slang-ir-util.h
+++ b/source/slang/slang-ir-util.h
@@ -180,7 +180,7 @@ IRType* dropNormAttributes(IRType* const t);
void getTypeNameHint(StringBuilder& sb, IRInst* type);
void copyNameHintAndDebugDecorations(IRInst* dest, IRInst* src);
IRInst* getRootAddr(IRInst* addrInst);
-IRInst* getRootAddr(IRInst* addrInst, List<IRInst*>& outAccessChain);
+IRInst* getRootAddr(IRInst* addrInst, List<IRInst*>& outAccessChain, List<IRInst*>* outTypes = nullptr);
bool canAddressesPotentiallyAlias(IRGlobalValueWithCode* func, IRInst* addr1, IRInst* addr2);
diff --git a/source/slang/slang-ir.cpp b/source/slang/slang-ir.cpp
index 5f49d1966..11f8cdb87 100644
--- a/source/slang/slang-ir.cpp
+++ b/source/slang/slang-ir.cpp
@@ -5032,6 +5032,27 @@ namespace Slang
return basePtr;
}
+ IRInst* IRBuilder::emitElementAddress(
+ IRInst* basePtr,
+ const ArrayView<IRInst*>& accessChain,
+ const ArrayView<IRInst*>& types)
+ {
+ for (Index i = 0; i < accessChain.getCount(); i++)
+ {
+ auto access = accessChain[i];
+ auto type = (IRType*)types[i];
+ if (auto structKey = as<IRStructKey>(access))
+ {
+ basePtr = emitFieldAddress(type, basePtr, structKey);
+ }
+ else
+ {
+ basePtr = emitElementAddress(type, basePtr, access);
+ }
+ }
+ return basePtr;
+ }
+
IRInst* IRBuilder::emitUpdateElement(IRInst* base, IRInst* index, IRInst* newElement)
{
auto inst = createInst<IRUpdateElement>(
diff --git a/source/slang/slang.cpp b/source/slang/slang.cpp
index 654295211..5974656df 100644
--- a/source/slang/slang.cpp
+++ b/source/slang/slang.cpp
@@ -3796,7 +3796,6 @@ Linkage::IncludeResult Linkage::findAndIncludeFile(Module* module, TranslationUn
IncludeSystem includeSystem;
auto sourceFile = findFile(name, loc, includeSystem);
-
if (!sourceFile)
{
sink->diagnose(loc, Diagnostics::cannotOpenFile, getText(name));