summaryrefslogtreecommitdiffstats
path: root/source/slang
diff options
context:
space:
mode:
Diffstat (limited to 'source/slang')
-rw-r--r--source/slang/emit.cpp18
-rw-r--r--source/slang/ir-insts.h36
-rw-r--r--source/slang/ir-legalize-types.cpp2
-rw-r--r--source/slang/ir-ssa.cpp19
-rw-r--r--source/slang/ir.cpp144
-rw-r--r--source/slang/ir.h23
-rw-r--r--source/slang/syntax.cpp4
7 files changed, 152 insertions, 94 deletions
diff --git a/source/slang/emit.cpp b/source/slang/emit.cpp
index 335662ab3..a27492c0b 100644
--- a/source/slang/emit.cpp
+++ b/source/slang/emit.cpp
@@ -5183,7 +5183,7 @@ emitDeclImpl(decl, nullptr);
for(UInt aa = 0; aa < argCount; ++aa)
{
if(aa != 0) emit(", ");
- emitIROperand(ctx, args[aa].usedValue, mode);
+ emitIROperand(ctx, args[aa].get(), mode);
}
emit(")");
}
@@ -5488,7 +5488,7 @@ emitDeclImpl(decl, nullptr);
for (UInt aa = 0; aa < argCount; ++aa)
{
if (aa != 0) Emit(", ");
- emitIROperand(ctx, args[aa].usedValue, mode);
+ emitIROperand(ctx, args[aa].get(), mode);
}
Emit(")");
return;
@@ -5524,7 +5524,7 @@ emitDeclImpl(decl, nullptr);
UInt argIndex = d - '0';
SLANG_RELEASE_ASSERT((0 <= argIndex) && (argIndex < argCount));
Emit("(");
- emitIROperand(ctx, args[argIndex].usedValue, mode);
+ emitIROperand(ctx, args[argIndex].get(), mode);
Emit(")");
}
break;
@@ -5536,8 +5536,8 @@ emitDeclImpl(decl, nullptr);
// texturing operation.
SLANG_RELEASE_ASSERT(argCount >= 2);
- auto textureArg = args[0].usedValue;
- auto samplerArg = args[1].usedValue;
+ auto textureArg = args[0].get();
+ auto samplerArg = args[1].get();
if (auto baseTextureType = textureArg->type->As<TextureType>())
{
@@ -5576,7 +5576,7 @@ emitDeclImpl(decl, nullptr);
//
// We are going to hack this *hard* for now.
- auto textureArg = args[0].usedValue;
+ auto textureArg = args[0].get();
if (auto baseTextureType = textureArg->type->As<TextureType>())
{
emitGLSLTextureOrTextureSamplerType(baseTextureType, "sampler");
@@ -5602,7 +5602,7 @@ emitDeclImpl(decl, nullptr);
// shape.
SLANG_RELEASE_ASSERT(argCount >= 1);
- auto textureArg = args[0].usedValue;
+ auto textureArg = args[0].get();
if (auto baseTextureType = textureArg->type->As<TextureType>())
{
auto elementType = baseTextureType->elementType;
@@ -6269,7 +6269,7 @@ emitDeclImpl(decl, nullptr);
break;
}
- IRValue* arg = args[argIndex].usedValue;
+ IRValue* arg = args[argIndex].get();
emitIROperand(ctx, pp, IREmitMode::Default);
emit(" = ");
@@ -7142,7 +7142,7 @@ emitDeclImpl(decl, nullptr);
if(value->op == kIROp_specialize)
{
- value = ((IRSpecialize*) value)->genericVal.usedValue;
+ value = ((IRSpecialize*) value)->genericVal.get();
}
if(value->op != kIROp_Func)
diff --git a/source/slang/ir-insts.h b/source/slang/ir-insts.h
index eec42d59a..f53004ae4 100644
--- a/source/slang/ir-insts.h
+++ b/source/slang/ir-insts.h
@@ -124,8 +124,8 @@ struct IRFieldExtract : IRInst
IRUse base;
IRUse field;
- IRValue* getBase() { return base.usedValue; }
- IRValue* getField() { return field.usedValue; }
+ IRValue* getBase() { return base.get(); }
+ IRValue* getField() { return field.get(); }
};
struct IRFieldAddress : IRInst
@@ -133,8 +133,8 @@ struct IRFieldAddress : IRInst
IRUse base;
IRUse field;
- IRValue* getBase() { return base.usedValue; }
- IRValue* getField() { return field.usedValue; }
+ IRValue* getBase() { return base.get(); }
+ IRValue* getField() { return field.get(); }
};
// Terminators
@@ -146,7 +146,7 @@ struct IRReturnVal : IRReturn
{
IRUse val;
- IRValue* getVal() { return val.usedValue; }
+ IRValue* getVal() { return val.get(); }
};
struct IRReturnVoid : IRReturn
@@ -168,7 +168,7 @@ struct IRUnconditionalBranch : IRTerminatorInst
{
IRUse block;
- IRBlock* getTargetBlock() { return (IRBlock*)block.usedValue; }
+ IRBlock* getTargetBlock() { return (IRBlock*)block.get(); }
};
// Special cases of unconditional branch, to handle
@@ -191,8 +191,8 @@ struct IRLoop : IRUnconditionalBranch
// on a `continue`.
IRUse continueBlock;
- IRBlock* getBreakBlock() { return (IRBlock*)breakBlock.usedValue; }
- IRBlock* getContinueBlock() { return (IRBlock*)continueBlock.usedValue; }
+ IRBlock* getBreakBlock() { return (IRBlock*)breakBlock.get(); }
+ IRBlock* getContinueBlock() { return (IRBlock*)continueBlock.get(); }
};
struct IRConditionalBranch : IRTerminatorInst
@@ -201,9 +201,9 @@ struct IRConditionalBranch : IRTerminatorInst
IRUse trueBlock;
IRUse falseBlock;
- IRValue* getCondition() { return condition.usedValue; }
- IRBlock* getTrueBlock() { return (IRBlock*)trueBlock.usedValue; }
- IRBlock* getFalseBlock() { return (IRBlock*)falseBlock.usedValue; }
+ IRValue* getCondition() { return condition.get(); }
+ IRBlock* getTrueBlock() { return (IRBlock*)trueBlock.get(); }
+ IRBlock* getFalseBlock() { return (IRBlock*)falseBlock.get(); }
};
// A conditional branch that represent the test inside a loop
@@ -230,7 +230,7 @@ struct IRIfElse : IRConditionalBranch
{
IRUse afterBlock;
- IRBlock* getAfterBlock() { return (IRBlock*)afterBlock.usedValue; }
+ IRBlock* getAfterBlock() { return (IRBlock*)afterBlock.get(); }
};
// A multi-way branch that represents a source-level `switch`
@@ -240,9 +240,9 @@ struct IRSwitch : IRTerminatorInst
IRUse breakLabel;
IRUse defaultLabel;
- IRValue* getCondition() { return condition.usedValue; }
- IRBlock* getBreakLabel() { return (IRBlock*) breakLabel.usedValue; }
- IRBlock* getDefaultLabel() { return (IRBlock*) defaultLabel.usedValue; }
+ IRValue* getCondition() { return condition.get(); }
+ IRBlock* getBreakLabel() { return (IRBlock*) breakLabel.get(); }
+ IRBlock* getDefaultLabel() { return (IRBlock*) defaultLabel.get(); }
// remaining args are: caseVal, caseLabel, ...
@@ -255,7 +255,7 @@ struct IRSwizzle : IRReturn
{
IRUse base;
- IRValue* getBase() { return base.usedValue; }
+ IRValue* getBase() { return base.get(); }
UInt getElementCount()
{
return getArgCount() - 1;
@@ -271,8 +271,8 @@ struct IRSwizzleSet : IRReturn
IRUse base;
IRUse source;
- IRValue* getBase() { return base.usedValue; }
- IRValue* getSource() { return source.usedValue; }
+ IRValue* getBase() { return base.get(); }
+ IRValue* getSource() { return source.get(); }
UInt getElementCount()
{
return getArgCount() - 2;
diff --git a/source/slang/ir-legalize-types.cpp b/source/slang/ir-legalize-types.cpp
index 4e3bafd31..2e69898e5 100644
--- a/source/slang/ir-legalize-types.cpp
+++ b/source/slang/ir-legalize-types.cpp
@@ -232,7 +232,7 @@ static LegalVal legalizeCall(
return LegalVal::simple(context->builder->emitCallInst(
callInst->type,
- callInst->func.usedValue,
+ callInst->func.get(),
instArgs.Count(),
instArgs.Buffer()));
}
diff --git a/source/slang/ir-ssa.cpp b/source/slang/ir-ssa.cpp
index d58fd22e4..432dfc1b1 100644
--- a/source/slang/ir-ssa.cpp
+++ b/source/slang/ir-ssa.cpp
@@ -110,7 +110,7 @@ bool isPromotableVar(
for (auto u = var->firstUse; u; u = u->nextUse)
{
- auto user = u->user;
+ auto user = u->getUser();
switch (user->op)
{
default:
@@ -231,7 +231,7 @@ IRValue* tryRemoveTrivialPhi(
IRValue* same = nullptr;
for (auto u : phiInfo->operands)
{
- auto usedVal = u.usedValue;
+ auto usedVal = u.get();
assert(usedVal);
if (usedVal == same || usedVal == phi)
@@ -542,8 +542,8 @@ void processBlock(
case kIROp_Store:
{
auto storeInst = (IRStore*)ii;
- auto ptrArg = storeInst->ptr.usedValue;
- auto valArg = storeInst->val.usedValue;
+ auto ptrArg = storeInst->ptr.get();
+ auto valArg = storeInst->val.get();
if (auto var = asPromotableVar(context, ptrArg))
{
@@ -563,7 +563,7 @@ void processBlock(
case kIROp_Load:
{
IRLoad* loadInst = (IRLoad*)ii;
- auto ptrArg = loadInst->ptr.usedValue;
+ auto ptrArg = loadInst->ptr.get();
if (auto var = asPromotableVar(context, ptrArg))
{
@@ -669,10 +669,10 @@ static void breakCriticalEdges(
for (auto edgeUse : criticalEdges)
{
- auto pred = (IRBlock*) edgeUse->user->parent;
+ auto pred = (IRBlock*) edgeUse->getUser()->parent;
assert(pred->op == kIROp_Block);
- auto succ = (IRBlock*)edgeUse->usedValue;
+ auto succ = (IRBlock*)edgeUse->get();
assert(succ->op == kIROp_Block);
IRBuilder builder;
@@ -683,6 +683,8 @@ static void breakCriticalEdges(
// Create a new block that will sit "along" the edge
IRBlock* edgeBlock = builder.createBlock();
+ edgeUse->debugValidate();
+
// The predecessor block should now branch to
// the edge block.
edgeUse->set(edgeBlock);
@@ -709,7 +711,6 @@ void constructSSA(ConstructSSAContext* context)
// because our representation of SSA form doesn't allow for them.
breakCriticalEdges(context);
-
// Figure out what variables we can promote to
// SSA temporaries.
identifyPromotableVars(context);
@@ -766,7 +767,7 @@ void constructSSA(ConstructSSAContext* context)
UInt predIndex = predCounter++;
auto predInfo = *context->blockInfos.TryGetValue(pp);
- IRValue* operandVal = phiInfo->operands[predIndex].usedValue;
+ IRValue* operandVal = phiInfo->operands[predIndex].get();
phiInfo->operands[predIndex].clear();
diff --git a/source/slang/ir.cpp b/source/slang/ir.cpp
index 40c7e20d5..50b0b83e9 100644
--- a/source/slang/ir.cpp
+++ b/source/slang/ir.cpp
@@ -59,41 +59,81 @@ namespace Slang
//
+ void IRUse::debugValidate()
+ {
+#ifdef _DEBUG
+ auto uv = this->usedValue;
+ if(!uv)
+ {
+ assert(!user);
+ assert(!nextUse);
+ assert(!prevLink);
+ return;
+ }
+
+ auto pp = &uv->firstUse;
+ for(auto u = uv->firstUse; u;)
+ {
+ assert(u->prevLink == pp);
+
+ pp = &u->nextUse;
+ u = u->nextUse;
+ }
+#endif
+ }
+
void IRUse::init(IRUser* u, IRValue* v)
{
+ clear();
+
user = u;
usedValue = v;
-
if(v)
{
nextUse = v->firstUse;
prevLink = &v->firstUse;
+ if(nextUse)
+ {
+ nextUse->prevLink = &this->nextUse;
+ }
+
v->firstUse = this;
}
+
+ debugValidate();
}
- void IRUse::set(IRValue* usedVal)
+ void IRUse::set(IRValue* uv)
{
- // clear out the old value
- if (usedVal)
- {
- if (prevLink)
- *prevLink = nextUse;
- }
-
- init(user, usedVal);
+ init(user, uv);
}
void IRUse::clear()
{
+ // This `IRUse` is part of the linked list
+ // of uses for `usedValue`.
+
+ debugValidate();
+
if (usedValue)
{
+ auto uv = usedValue;
+
*prevLink = nextUse;
- }
+ if(nextUse)
+ {
+ nextUse->prevLink = prevLink;
+ }
+
+ user = nullptr;
+ usedValue = nullptr;
+ nextUse = nullptr;
+ prevLink = nullptr;
- user = nullptr;
- usedValue = nullptr;
+ if(uv->firstUse)
+ uv->firstUse->debugValidate();
+ }
}
//
@@ -250,7 +290,7 @@ namespace Slang
// We will re-use the logic for getting the successor
// list from such an instruction.
- auto successorList = getSuccessors((IRInst*) use->user);
+ auto successorList = getSuccessors((IRInst*) use->getUser());
if(use >= successorList.begin_
&& use < successorList.end_)
@@ -315,7 +355,7 @@ namespace Slang
IRBlock* IRBlock::PredecessorList::Iterator::operator*()
{
if (!use) return nullptr;
- return (IRBlock*)use->user->parent;
+ return (IRBlock*)use->getUser()->parent;
}
IRBlock::SuccessorList IRBlock::getSuccessors()
@@ -351,7 +391,7 @@ namespace Slang
IRBlock* IRBlock::SuccessorList::Iterator::operator*()
{
- return (IRBlock*)use->usedValue;
+ return (IRBlock*)use->get();
}
// IRFunc
@@ -714,7 +754,7 @@ namespace Slang
auto rightArgs = right.inst->getArgs();
for( UInt aa = 0; aa < argCount; ++aa )
{
- if(leftArgs[aa].usedValue != rightArgs[aa].usedValue)
+ if(leftArgs[aa].get() != rightArgs[aa].get())
return false;
}
@@ -731,7 +771,7 @@ namespace Slang
auto args = inst->getArgs();
for( UInt aa = 0; aa < argCount; ++aa )
{
- code = combineHash(code, Slang::GetHashCode(args[aa].usedValue));
+ code = combineHash(code, Slang::GetHashCode(args[aa].get()));
}
return code;
}
@@ -1894,7 +1934,7 @@ namespace Slang
}
else if (auto proxyVal = dynamic_cast<IRProxyVal*>(val))
{
- dumpOperand(context, proxyVal->inst.usedValue);
+ dumpOperand(context, proxyVal->inst.get());
}
else
{
@@ -2283,7 +2323,7 @@ namespace Slang
if (ii != 0)
dump(context, ", ");
- auto argVal = inst->getArgs()[ii].usedValue;
+ auto argVal = inst->getArgs()[ii].get();
dumpOperand(context, argVal);
}
@@ -2449,9 +2489,9 @@ namespace Slang
IRWitnessTableEntry* entry)
{
dump(context, "witness_table_entry(");
- dumpOperand(context, entry->requirementKey.usedValue);
+ dumpOperand(context, entry->requirementKey.get());
dump(context, ",");
- dumpOperand(context, entry->satisfyingVal.usedValue);
+ dumpOperand(context, entry->satisfyingVal.get());
dump(context, ")\n");
}
@@ -2522,6 +2562,20 @@ namespace Slang
dumpIRModule(&context, module);
}
+ void dumpIR(IRGlobalValue* globalVal)
+ {
+ StringBuilder sb;
+
+ IRDumpContext context;
+ context.builder = &sb;
+ context.indent = 0;
+
+ dumpIRGlobalValue(&context, globalVal);
+
+ fprintf(stderr, "%s\n", sb.Buffer());
+ fflush(stderr);
+ }
+
String getSlangIRAssembly(IRModule* module)
{
StringBuilder sb;
@@ -2551,12 +2605,14 @@ namespace Slang
if(!ff)
return;
+ ff->debugValidate();
+
IRUse* uu = ff;
for(;;)
{
// The uses had better all be uses of this
// instruction, or invariants are broken.
- assert(uu->usedValue == this);
+ assert(uu->get() == this);
// Swap this use over to use the other value.
uu->usedValue = other;
@@ -2597,6 +2653,8 @@ namespace Slang
// And `this` will have no uses any more.
this->firstUse = nullptr;
+
+ ff->debugValidate();
}
void IRValue::deallocate()
@@ -2684,15 +2742,7 @@ namespace Slang
for( UInt aa = 0; aa < argCount; ++aa )
{
IRUse& use = getArgs()[aa];
-
- if(!use.usedValue)
- continue;
-
- // Need to unlink this use from the appropriate linked list.
- use.usedValue = nullptr;
- *use.prevLink = use.nextUse;
- use.prevLink = nullptr;
- use.nextUse = nullptr;
+ use.clear();
}
}
@@ -3616,7 +3666,7 @@ namespace Slang
{
auto proxyVal = witness.Value.As<IRProxyVal>();
SLANG_ASSERT(proxyVal);
- return proxyVal->inst.usedValue;
+ return proxyVal->inst.get();
}
}
}
@@ -3651,7 +3701,7 @@ namespace Slang
{
if (auto proxyVal = dynamic_cast<IRProxyVal*>(val))
{
- auto newIRVal = cloneValue(context, proxyVal->inst.usedValue);
+ auto newIRVal = cloneValue(context, proxyVal->inst.get());
RefPtr<IRProxyVal> newProxyVal = new IRProxyVal();
newProxyVal->inst.init(nullptr, newIRVal);
@@ -3879,10 +3929,10 @@ namespace Slang
// Clone the entries in the witness table as well
for( auto originalEntry : originalTable->entries )
{
- auto clonedKey = cloneValue(context, originalEntry->requirementKey.usedValue);
+ auto clonedKey = cloneValue(context, originalEntry->requirementKey.get());
// if a global val with the mangled name already exists, don't clone again
- auto clonedVal = maybeCloneValueWithMangledName(context, (IRGlobalValue*)(originalEntry->satisfyingVal.usedValue));
+ auto clonedVal = maybeCloneValueWithMangledName(context, (IRGlobalValue*)(originalEntry->satisfyingVal.get()));
/*auto clonedEntry = */context->builder->createWitnessTableEntry(
clonedTable,
@@ -4643,7 +4693,7 @@ namespace Slang
// the pointed-to value and not the proxy type-level `Val`
// instead.
- return context->maybeCloneValue(proxyVal->inst.usedValue);
+ return context->maybeCloneValue(proxyVal->inst.get());
}
else
{
@@ -4905,9 +4955,9 @@ namespace Slang
// of involved functions.
for (auto entry : specTable->entries)
{
- if (entry->satisfyingVal.usedValue->op == kIROp_Func)
+ if (entry->satisfyingVal.get()->op == kIROp_Func)
{
- IRFunc* func = (IRFunc*)entry->satisfyingVal.usedValue;
+ IRFunc* func = (IRFunc*)entry->satisfyingVal.get();
auto specFunc = getSpecializedFunc(sharedContext, func, specDeclRef);
entry->satisfyingVal.set(specFunc);
insertGlobalValueSymbol(sharedContext, specFunc);
@@ -5016,7 +5066,7 @@ namespace Slang
{
// We expect the key on the entry to be a decl-ref,
// but lets go ahead and check, just to be sure.
- auto requirementKey = entry->requirementKey.usedValue;
+ auto requirementKey = entry->requirementKey.get();
if(requirementKey->op != kIROp_decl_ref)
continue;
auto keyDeclRef = ((IRDeclRef*) requirementKey)->declRef;
@@ -5039,7 +5089,7 @@ namespace Slang
// If the keys matched, then we use the value from
// this entry.
- auto satisfyingVal = entry->satisfyingVal.usedValue;
+ auto satisfyingVal = entry->satisfyingVal.get();
return satisfyingVal;
}
@@ -5147,11 +5197,11 @@ namespace Slang
// Now we extract the specialized decl-ref that will
// tell us how to specialize things.
- auto specDeclRefVal = (IRDeclRef*)specInst->specDeclRefVal.usedValue;
+ auto specDeclRefVal = (IRDeclRef*)specInst->specDeclRefVal.get();
auto specDeclRef = specDeclRefVal->declRef;
// We need to specialize functions and witness tables
- auto genericVal = specInst->genericVal.usedValue;
+ auto genericVal = specInst->genericVal.get();
if (genericVal->op == kIROp_Func)
{
auto genericFunc = (IRFunc*)genericVal;
@@ -5187,8 +5237,8 @@ namespace Slang
// try find concrete witness table from global scope
IRLookupWitnessTable* lookupInst = (IRLookupWitnessTable*)ii;
IRWitnessTable* witnessTable = nullptr;
- auto srcDeclRef = ((IRDeclRef*)lookupInst->sourceType.usedValue)->declRef;
- auto interfaceDeclRef = ((IRDeclRef*)lookupInst->interfaceType.usedValue)->declRef;
+ auto srcDeclRef = ((IRDeclRef*)lookupInst->sourceType.get())->declRef;
+ auto interfaceDeclRef = ((IRDeclRef*)lookupInst->interfaceType.get())->declRef;
auto mangledName = getMangledNameForConformanceWitness(srcDeclRef, interfaceDeclRef);
witnessTables.TryGetValue(mangledName, witnessTable);
@@ -5221,14 +5271,14 @@ namespace Slang
// We only want to deal with the case where the witness-table
// argument points to a concrete global table.
- auto witnessTableArg = lookupInst->witnessTable.usedValue;
+ auto witnessTableArg = lookupInst->witnessTable.get();
if(witnessTableArg->op != kIROp_witness_table)
continue;
IRWitnessTable* witnessTable = (IRWitnessTable*)witnessTableArg;
// We also need to be sure that the requirement we
// are trying to look up is identified via a decl-ref:
- auto requirementArg = lookupInst->requirementDeclRef.usedValue;
+ auto requirementArg = lookupInst->requirementDeclRef.get();
if(requirementArg->op != kIROp_decl_ref)
continue;
auto requirementDeclRef = ((IRDeclRef*) requirementArg)->declRef;
diff --git a/source/slang/ir.h b/source/slang/ir.h
index 028468308..407506116 100644
--- a/source/slang/ir.h
+++ b/source/slang/ir.h
@@ -82,22 +82,27 @@ IROpInfo getIROpInfo(IROp op);
// A use of another value/inst within an IR operation
struct IRUse
{
+ IRValue* get() { return usedValue; }
+ IRUser* getUser() { return user; }
+
+ void init(IRUser* user, IRValue* usedValue);
+ void set(IRValue* usedValue);
+ void clear();
+
// The value that is being used
- IRValue* usedValue;
+ IRValue* usedValue = nullptr;
// The value that is doing the using.
- IRUser* user;
+ IRUser* user = nullptr;
// The next use of the same value
- IRUse* nextUse;
+ IRUse* nextUse = nullptr;
// A "link" back to where this use is referenced,
// so that we can simplify updates.
- IRUse** prevLink;
+ IRUse** prevLink = nullptr;
- void init(IRUser* user, IRValue* usedValue);
- void set(IRValue* usedValue);
- void clear();
+ void debugValidate();
};
enum IRDecorationOp : uint16_t
@@ -262,7 +267,7 @@ struct IRUser : IRChildValue
IRValue* getArg(UInt index)
{
- return getArgs()[index].usedValue;
+ return getArgs()[index].get();
}
void setArg(UInt index, IRValue* value)
@@ -542,6 +547,8 @@ void printSlangIRAssembly(StringBuilder& builder, IRModule* module);
String getSlangIRAssembly(IRModule* module);
void dumpIR(IRModule* module);
+void dumpIR(IRGlobalValue* globalVal);
+
String dumpIRFunc(IRFunc* func);
}
diff --git a/source/slang/syntax.cpp b/source/slang/syntax.cpp
index d83a91938..e050fc977 100644
--- a/source/slang/syntax.cpp
+++ b/source/slang/syntax.cpp
@@ -1888,7 +1888,7 @@ void Type::accept(IValVisitor* visitor, void* extra)
if(!otherProxy)
return false;
- return this->inst.usedValue == otherProxy->inst.usedValue;
+ return this->inst.get() == otherProxy->inst.get();
}
String IRProxyVal::ToString()
@@ -1898,7 +1898,7 @@ void Type::accept(IValVisitor* visitor, void* extra)
int IRProxyVal::GetHashCode()
{
- auto hash = Slang::GetHashCode(inst.usedValue);
+ auto hash = Slang::GetHashCode(inst.get());
return hash;
}