summaryrefslogtreecommitdiff
path: root/source/slang/ir.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'source/slang/ir.cpp')
-rw-r--r--source/slang/ir.cpp609
1 files changed, 267 insertions, 342 deletions
diff --git a/source/slang/ir.cpp b/source/slang/ir.cpp
index c0715fca3..bc33527cf 100644
--- a/source/slang/ir.cpp
+++ b/source/slang/ir.cpp
@@ -166,6 +166,19 @@ namespace Slang
}
}
+ // IRInstListBase
+
+ void IRInstListBase::Iterator::operator++()
+ {
+ if (inst)
+ {
+ inst = inst->next;
+ }
+ }
+
+ IRInstListBase::Iterator IRInstListBase::begin() { return Iterator(first); }
+ IRInstListBase::Iterator IRInstListBase::end() { return Iterator(last ? last->next : nullptr); }
+
//
IRUse* IRInst::getOperands()
@@ -180,9 +193,9 @@ namespace Slang
return (IRUse*)(this + 1);
}
- IRDecoration* IRInst::findDecorationImpl(IRDecorationOp decorationOp)
+ IRDecoration* IRInst::findDecorationImpl(IROp decorationOp)
{
- for( auto dd = firstDecoration; dd; dd = dd->next )
+ for(auto dd : getDecorations())
{
if(dd->op == decorationOp)
return dd;
@@ -239,14 +252,31 @@ namespace Slang
void IRBlock::addParam(IRParam* param)
{
- auto lastParam = getLastParam();
- if (lastParam)
+ // If there are any existing parameters,
+ // then insert after the last of them.
+ //
+ if (auto lastParam = getLastParam())
{
param->insertAfter(lastParam);
}
+ //
+ // Otherwise, if there are any existing
+ // "ordinary" instructions, insert before
+ // the first of them.
+ //
+ else if(auto firstOrdinary = getFirstOrdinaryInst())
+ {
+ param->insertBefore(firstOrdinary);
+ }
+ //
+ // Otherwise the block currently has neither
+ // parameters nor orindary instructions,
+ // so we can safely insert at the end of
+ // the list of (raw) children.
+ //
else
{
- param->insertAtStart(this);
+ param->insertAtEnd(this);
}
}
@@ -585,7 +615,7 @@ namespace Slang
}
- void IRBuilder::setInsertInto(IRParentInst* insertInto)
+ void IRBuilder::setInsertInto(IRInst* insertInto)
{
insertIntoParent = insertInto;
insertBeforeInst = nullptr;
@@ -620,7 +650,7 @@ namespace Slang
// Given two parent instructions, pick the better one to use as as
// insertion location for a "hoistable" instruction.
//
- IRParentInst* mergeCandidateParentsForHoistableInst(IRParentInst* left, IRParentInst* right)
+ IRInst* mergeCandidateParentsForHoistableInst(IRInst* left, IRInst* right)
{
// If the candidates are both the same, then who cares?
if(left == right) return left;
@@ -681,7 +711,7 @@ namespace Slang
// If the non-block on the left or right is a descendent of
// the other, then that is what we should use.
//
- IRParentInst* parentNonBlock = nullptr;
+ IRInst* parentNonBlock = nullptr;
for (auto ll = leftNonBlock; ll; ll = ll->getParent())
{
if (ll == rightNonBlock)
@@ -715,7 +745,7 @@ namespace Slang
parentNonBlock = leftNonBlock;
}
- IRParentInst* parent = parentNonBlock;
+ IRInst* parent = parentNonBlock;
// At this point we've found a non-block parent where we
// could stick things, but we have to fix things up in
@@ -791,19 +821,6 @@ namespace Slang
return inst;
}
-
- IRDecoration* createEmptyDecoration(
- IRModule* module,
- IRDecorationOp op,
- size_t sizeInBytes)
- {
- SLANG_ASSERT(sizeInBytes >= sizeof(IRDecoration));
- SLANG_ASSERT(module);
- IRDecoration* decor = (IRDecoration*)module->memoryArena.allocateAndZero(sizeInBytes);
- decor->op = op;
- return decor;
- }
-
// Given an instruction that represents a constant, a type, etc.
// Try to "hoist" it as far toward the global scope as possible
// to insert it at a location where it will be maximally visible.
@@ -814,7 +831,7 @@ namespace Slang
{
// Start with the assumption that we would insert this instruction
// into the global scope (the instruction that represents the module)
- IRParentInst* parent = builder->getModule()->getModuleInst();
+ IRInst* parent = builder->getModule()->getModuleInst();
// The above decision might be invalid, because there might be
// one or more operands of the instruction that are defined in
@@ -1177,13 +1194,14 @@ namespace Slang
return code;
}
- UnownedStringSlice IRConstant::getStringSlice() const
+ UnownedStringSlice IRConstant::getStringSlice()
{
assert(op == kIROp_StringLit);
// If the transitory decoration is set, then this is uses the transitoryStringVal for the text storage.
// This is typically used when we are using a transitory IRInst held on the stack (such that it can be looked up in cached),
// that just points to a string elsewhere, and NOT the typical normal style, where the string is held after the instruction in memory.
- if (firstDecoration && firstDecoration->op == kIRDecorationOp_Transitory)
+ //
+ if(findDecorationImpl(kIROp_TransitoryDecoration))
{
return UnownedStringSlice(value.transitoryStringVal.chars, value.transitoryStringVal.numChars);
}
@@ -1217,6 +1235,10 @@ namespace Slang
// ... we can just compare as bits
return value.intVal == rhs.value.intVal;
}
+ case kIROp_PtrLit:
+ {
+ return value.ptrVal == rhs.value.ptrVal;
+ }
case kIROp_StringLit:
{
return getStringSlice() == rhs.getStringSlice();
@@ -1243,6 +1265,10 @@ namespace Slang
// ... we can just compare as bits
return combineHash(code, Slang::GetHashCode(value.intVal));
}
+ case kIROp_PtrLit:
+ {
+ return combineHash(code, Slang::GetHashCode(value.ptrVal));
+ }
case kIROp_StringLit:
{
const UnownedStringSlice slice = getStringSlice();
@@ -1283,6 +1309,10 @@ namespace Slang
switch (keyInst.op)
{
+ default:
+ SLANG_UNEXPECTED("missing case for IR constant");
+ break;
+
case kIROp_BoolLit:
case kIROp_IntLit:
{
@@ -1296,6 +1326,12 @@ namespace Slang
irValue->value.floatVal = keyInst.value.floatVal;
break;
}
+ case kIROp_PtrLit:
+ {
+ irValue = static_cast<IRConstant*>(createInstWithSizeImpl(builder, keyInst.op, keyInst.getFullType(), prefixSize + sizeof(void*)));
+ irValue->value.ptrVal = keyInst.value.ptrVal;
+ break;
+ }
case kIROp_StringLit:
{
const UnownedStringSlice slice = keyInst.getStringSlice();
@@ -1363,8 +1399,10 @@ namespace Slang
memset(&keyInst, 0, sizeof(keyInst));
// Mark that this is on the stack...
- static IRDecoration stackDecoration = IRDecoration::make(kIRDecorationOp_Transitory);
- keyInst.firstDecoration = &stackDecoration;
+ IRDecoration stackDecoration;
+ memset(&stackDecoration, 0, sizeof(stackDecoration));
+ stackDecoration.op = kIROp_TransitoryDecoration;
+ stackDecoration.insertAtEnd(&keyInst);
keyInst.op = kIROp_StringLit;
keyInst.typeUse.usedValue = getStringType();
@@ -1375,6 +1413,19 @@ namespace Slang
return static_cast<IRStringLit*>(findOrEmitConstant(this, keyInst));
}
+
+ IRPtrLit* IRBuilder::getPtrValue(void* value)
+ {
+ IRType* type = getPtrType(getVoidType());
+
+ IRConstant keyInst;
+ memset(&keyInst, 0, sizeof(keyInst));
+ keyInst.op = kIROp_PtrLit;
+ keyInst.typeUse.usedValue = type;
+ keyInst.value.ptrVal = value;
+ return (IRPtrLit*) findOrEmitConstant(this, keyInst);
+ }
+
IRInst* findOrEmitHoistableInst(
IRBuilder* builder,
@@ -2162,19 +2213,6 @@ namespace Slang
return inst;
}
- IRNotePatchConstantFunc* IRBuilder::emitNotePatchConstantFunc(
- IRInst* func)
- {
- auto inst = createInst<IRNotePatchConstantFunc>(
- this,
- kIROp_NotePatchConstantFunc,
- nullptr,
- func);
-
- addInst(inst);
- return inst;
- }
-
IRInst* IRBuilder::emitFieldExtract(
IRType* type,
IRInst* base,
@@ -2549,18 +2587,40 @@ namespace Slang
return inst;
}
- IRHighLevelDeclDecoration* IRBuilder::addHighLevelDeclDecoration(IRInst* inst, Decl* decl)
+ IRDecoration* IRBuilder::addDecoration(IRInst* value, IROp op, IRInst* const* operands, Int operandCount)
{
- auto decoration = addDecoration<IRHighLevelDeclDecoration>(inst, kIRDecorationOp_HighLevelDecl);
- decoration->decl = decl;
+ auto decoration = createInstWithTrailingArgs<IRDecoration>(
+ this,
+ op,
+ getVoidType(),
+ operandCount,
+ operands);
+
+ // Decoration order should not, in general, be semantically
+ // meaningful, so we will elect to insert a new decoration
+ // at the start of an instruction (constant time) rather
+ // than at the end of any existing list of deocrations
+ // (which would take time linear in the number of decorations).
+ //
+ // TODO: revisit this if maintaining decoration ordering
+ // from input source code is desirable.
+ //
+ decoration->insertAtStart(value);
+
return decoration;
}
- IRLayoutDecoration* IRBuilder::addLayoutDecoration(IRInst* inst, Layout* layout)
+
+ void IRBuilder::addHighLevelDeclDecoration(IRInst* inst, Decl* decl)
{
- auto decoration = addDecoration<IRLayoutDecoration>(inst);
- decoration->layout = addRefObjectToFree(layout);
- return decoration;
+ auto ptrConst = getPtrValue(addRefObjectToFree(decl));
+ addDecoration(inst, kIROp_HighLevelDeclDecoration, ptrConst);
+ }
+
+ void IRBuilder::addLayoutDecoration(IRInst* inst, Layout* layout)
+ {
+ auto ptrConst = getPtrValue(addRefObjectToFree(layout));
+ addDecoration(inst, kIROp_LayoutDecoration, ptrConst);
}
//
@@ -2905,74 +2965,25 @@ namespace Slang
for(; inst; inst = inst->getNextInst())
{
dumpInst(context, inst);
+ dump(context, "\n");
}
}
+ static void dumpInstBody(
+ IRDumpContext* context,
+ IRInst* inst);
+
void dumpIRDecorations(
IRDumpContext* context,
IRInst* inst)
{
- for( auto dd = inst->firstDecoration; dd; dd = dd->next )
+ for(auto dd : inst->getDecorations())
{
- switch( dd->op )
- {
- case kIRDecorationOp_Target:
- {
- auto decoration = (IRTargetDecoration*) dd;
-
- dump(context, "\n");
- dumpIndent(context);
- dump(context, "[target(");
- dump(context, StringRepresentation::getData(decoration->targetName));
- dump(context, ")]");
- }
- break;
+ dump(context, "[");
+ dumpInstBody(context, dd);
+ dump(context, "]\n");
- case kIRDecorationOp_TargetIntrinsic:
- {
- auto decoration = (IRTargetIntrinsicDecoration*) dd;
-
- dump(context, "\n");
- dumpIndent(context);
- dump(context, "[targetIntrinsic(");
- dump(context, StringRepresentation::getData(decoration->targetName));
- dump(context, ", ");
- dump(context, StringRepresentation::getData(decoration->definition));
- dump(context, ")]");
- }
- break;
-
- case kIRDecorationOp_VulkanRayPayload:
- {
- dump(context, "\n[__vulkanRayPayload]");
- }
- break;
- case kIRDecorationOp_VulkanCallablePayload:
- {
- dump(context, "\n[__vulkanCallPayload]");
- }
- break;
- case kIRDecorationOp_VulkanHitAttributes:
- {
- dump(context, "\n[__vulkanHitAttributes]");
- }
- break;
- case kIRDecorationOp_ReadNone:
- {
- dump(context, "\n[__readNone]");
- }
- break;
- case kIRDecorationOp_EarlyDepthStencil:
- {
- dump(context, "\n[earlydepthstencil]");
- }
- break;
- case kIRDecorationOp_GloballyCoherent:
- {
- dump(context, "\n[globallycoherent]");
- }
- break;
- }
+ dumpIndent(context);
}
}
@@ -2982,7 +2993,6 @@ namespace Slang
{
auto opInfo = getIROpInfo(code->op);
- dump(context, "\n");
dumpIndent(context);
dump(context, opInfo.name);
dump(context, " ");
@@ -3038,11 +3048,10 @@ namespace Slang
void dumpIRParentInst(
IRDumpContext* context,
- IRParentInst* inst)
+ IRInst* inst)
{
auto opInfo = getIROpInfo(inst->op);
- dump(context, "\n");
dumpIndent(context);
dump(context, opInfo.name);
dump(context, " ");
@@ -3063,9 +3072,10 @@ namespace Slang
dump(context, "{\n");
context->indent++;
- for (auto child = inst->getFirstChild(); child; child = child->getNextInst())
+ for(auto child : inst->getChildren())
{
dumpInst(context, child);
+ dump(context, "\n");
}
context->indent--;
@@ -3086,19 +3096,19 @@ namespace Slang
for (auto ii : witnessTable->getChildren())
{
dumpInst(context, ii);
+ dump(context, "\n");
}
context->indent--;
dump(context, "}\n");
}
- static void dumpInst(
+ static void dumpInstBody(
IRDumpContext* context,
IRInst* inst)
{
if (!inst)
{
- dumpIndent(context);
dump(context, "<null>");
return;
}
@@ -3121,7 +3131,7 @@ namespace Slang
case kIROp_WitnessTable:
case kIROp_StructType:
- dumpIRParentInst(context, (IRWitnessTable*)inst);
+ dumpIRParentInst(context, inst);
return;
case kIROp_WitnessTableEntry:
@@ -3133,8 +3143,6 @@ namespace Slang
}
// Okay, we have a seemingly "ordinary" op now
- dumpIndent(context);
-
auto opInfo = getIROpInfo(op);
auto dataType = inst->getDataType();
auto rate = inst->getRate();
@@ -3201,8 +3209,14 @@ namespace Slang
}
dump(context, ")");
+ }
- dump(context, "\n");
+ static void dumpInst(
+ IRDumpContext* context,
+ IRInst* inst)
+ {
+ dumpIndent(context);
+ dumpInstBody(context, inst);
}
void dumpIRModule(
@@ -3212,6 +3226,7 @@ namespace Slang
for(auto ii : module->getGlobalInsts())
{
dumpInst(context, ii);
+ dump(context, "\n");
}
}
@@ -3257,6 +3272,57 @@ namespace Slang
//
//
+ IRDecoration* IRInst::getFirstDecoration()
+ {
+ return as<IRDecoration>(getFirstDecorationOrChild());
+ }
+
+ IRDecoration* IRInst::getLastDecoration()
+ {
+ IRDecoration* decoration = getFirstDecoration();
+ if (!decoration) return nullptr;
+
+ while (auto nextDecoration = decoration->getNextDecoration())
+ decoration = nextDecoration;
+
+ return decoration;
+ }
+
+ IRInstList<IRDecoration> IRInst::getDecorations()
+ {
+ return IRInstList<IRDecoration>(
+ getFirstDecoration(),
+ getLastDecoration());
+ }
+
+ IRInst* IRInst::getFirstChild()
+ {
+ // The children come after any decorations,
+ // so if there are any decorations, then the
+ // first child is right after the last decoration.
+ //
+ if(auto lastDecoration = getLastDecoration())
+ return lastDecoration->getNextInst();
+ //
+ // Otherwise, there must be no decorations, so
+ // that the first "child or decoration" is a child.
+ //
+ return getFirstDecorationOrChild();
+ }
+
+ IRInst* IRInst::getLastChild()
+ {
+ // The children come after any decorations, so
+ // that the last item in the list of children
+ // and decorations is the last child *unless*
+ // it is a decoration, in which case there are
+ // no children.
+ //
+ auto lastChild = getLastDecorationOrChild();
+ return as<IRDecoration>(lastChild) ? nullptr : lastChild;
+ }
+
+
IRRate* IRInst::getRate()
{
if(auto rateQualifiedType = as<IRRateQualifiedType>(getFullType()))
@@ -3345,13 +3411,13 @@ namespace Slang
void IRInst::insertBefore(IRInst* other)
{
SLANG_ASSERT(other);
- insertBefore(other, other->parent);
+ _insertAt(other->getPrevInst(), other, other->getParent());
}
- void IRInst::insertAtStart(IRParentInst* newParent)
+ void IRInst::insertAtStart(IRInst* newParent)
{
SLANG_ASSERT(newParent);
- insertBefore(newParent->children.first, newParent);
+ _insertAt(nullptr, newParent->getFirstDecorationOrChild(), newParent);
}
void IRInst::moveToStart()
@@ -3361,52 +3427,49 @@ namespace Slang
insertAtStart(p);
}
- void IRInst::insertBefore(IRInst* other, IRParentInst* newParent)
+ void IRInst::_insertAt(IRInst* inPrev, IRInst* inNext, IRInst* inParent)
{
// Make sure this instruction has been removed from any previous parent
this->removeFromParent();
- SLANG_ASSERT(other || newParent);
- if (!other) other = newParent->children.first;
- if (!newParent) newParent = other->parent;
- SLANG_ASSERT(newParent);
-
- auto nn = other;
- auto pp = other ? other->getPrevInst() : nullptr;
+ SLANG_ASSERT(inParent);
+ SLANG_ASSERT(!inPrev || (inPrev->getNextInst() == inNext) && (inPrev->getParent() == inParent));
+ SLANG_ASSERT(!inNext || (inNext->getPrevInst() == inPrev) && (inNext->getParent() == inParent));
- if( pp )
+ if( inPrev )
{
- pp->next = this;
+ inPrev->next = this;
}
else
{
- newParent->children.first = this;
+ inParent->m_decorationsAndChildren.first = this;
}
- if (nn)
+ if (inNext)
{
- nn->prev = this;
+ inNext->prev = this;
}
else
{
- newParent->children.last = this;
+ inParent->m_decorationsAndChildren.last = this;
}
- this->prev = pp;
- this->next = nn;
- this->parent = newParent;
+ this->prev = inPrev;
+ this->next = inNext;
+ this->parent = inParent;
}
void IRInst::insertAfter(IRInst* other)
{
SLANG_ASSERT(other);
- insertAfter(other, other->parent);
+
+ _insertAt(other, other->getNextInst(), other->getParent());
}
- void IRInst::insertAtEnd(IRParentInst* newParent)
+ void IRInst::insertAtEnd(IRInst* newParent)
{
SLANG_ASSERT(newParent);
- insertAfter(newParent->children.last, newParent);
+ _insertAt(newParent->getLastDecorationOrChild(), nullptr, newParent);
}
void IRInst::moveToEnd()
@@ -3416,42 +3479,6 @@ namespace Slang
insertAtEnd(p);
}
- void IRInst::insertAfter(IRInst* other, IRParentInst* newParent)
- {
- // Make sure this instruction has been removed from any previous parent
- this->removeFromParent();
-
- SLANG_ASSERT(other || newParent);
- if (!other) other = newParent->children.last;
- if (!newParent) newParent = other->parent;
- SLANG_ASSERT(newParent);
-
- auto pp = other;
- auto nn = other ? other->next : nullptr;
-
- if (pp)
- {
- pp->next = this;
- }
- else
- {
- newParent->children.first = this;
- }
-
- if (nn)
- {
- nn->prev = this;
- }
- else
- {
- newParent->children.last = this;
- }
-
- this->prev = pp;
- this->next = nn;
- this->parent = newParent;
- }
-
// Remove this instruction from its parent block,
// and then destroy it (it had better have no uses!)
void IRInst::removeFromParent()
@@ -3473,7 +3500,7 @@ namespace Slang
}
else
{
- oldParent->children.first = nn;
+ oldParent->m_decorationsAndChildren.first = nn;
}
if(nn)
@@ -3483,7 +3510,7 @@ namespace Slang
}
else
{
- oldParent->children.last = pp;
+ oldParent->m_decorationsAndChildren.last = pp;
}
prev = nullptr;
@@ -3507,23 +3534,16 @@ namespace Slang
{
removeFromParent();
removeArguments();
-
- // If this is a parent instruction then we had
- // better remove all its children as well.
- //
- if(auto parentInst = as<IRParentInst>(this))
- {
- parentInst->removeAndDeallocateAllChildren();
- }
+ removeAndDeallocateAllDecorationsAndChildren();
// Run destructor to be sure...
this->~IRInst();
}
- void IRParentInst::removeAndDeallocateAllChildren()
+ void IRInst::removeAndDeallocateAllDecorationsAndChildren()
{
IRInst* nextChild = nullptr;
- for( IRInst* child = getFirstChild(); child; child = nextChild )
+ for( IRInst* child = getFirstDecorationOrChild(); child; child = nextChild )
{
nextChild = child->getNextInst();
child->removeAndDeallocate();
@@ -4153,8 +4173,7 @@ namespace Slang
if(auto outerArrayName = systemValueInfo->outerArrayName)
{
- auto decoration = builder->addDecoration<IRGLSLOuterArrayDecoration>(globalVariable);
- decoration->outerArrayName = outerArrayName;
+ builder->addGLSLOuterArrayDecoration(globalVariable, UnownedTerminatedStringSlice(outerArrayName));
}
}
@@ -4689,13 +4708,13 @@ namespace Slang
IRInst* val,
String const& targetName)
{
- for( auto dd = val->firstDecoration; dd; dd = dd->next )
+ for(auto dd : val->getDecorations())
{
- if(dd->op != kIRDecorationOp_TargetIntrinsic)
+ if(dd->op != kIROp_TargetIntrinsicDecoration)
continue;
auto decoration = (IRTargetIntrinsicDecoration*) dd;
- if(String(decoration->targetName) == targetName)
+ if(String(decoration->getTargetName()) == targetName)
return decoration;
}
@@ -4864,7 +4883,7 @@ namespace Slang
if(!decoration)
continue;
- if(StringRepresentation::asSlice(decoration->definition) != UnownedStringSlice::fromLiteral("EmitVertex()"))
+ if(decoration->getDefinition() != UnownedStringSlice::fromLiteral("EmitVertex()"))
{
continue;
}
@@ -5340,117 +5359,40 @@ namespace Slang
}
}
- void cloneDecorations(
+ IRInst* cloneInst(
+ IRSpecContextBase* context,
+ IRBuilder* builder,
+ IRInst* originalInst,
+ IROriginalValuesForClone const& originalValues);
+
+ IRInst* cloneInst(
IRSpecContextBase* context,
- IRInst* clonedValue,
- IRInst* originalValue)
+ IRBuilder* builder,
+ IRInst* originalInst)
{
- for (auto dd = originalValue->firstDecoration; dd; dd = dd->next)
- {
- switch (dd->op)
- {
- case kIRDecorationOp_HighLevelDecl:
- {
- auto originalDecoration = (IRHighLevelDeclDecoration*)dd;
-
- context->builder->addHighLevelDeclDecoration(clonedValue, originalDecoration->decl);
- }
- break;
-
- case kIRDecorationOp_LoopControl:
- {
- auto originalDecoration = (IRLoopControlDecoration*)dd;
- auto newDecoration = context->builder->addDecoration<IRLoopControlDecoration>(clonedValue);
- newDecoration->mode = originalDecoration->mode;
- }
- break;
-
- case kIRDecorationOp_TargetIntrinsic:
- {
- auto originalDecoration = (IRTargetIntrinsicDecoration*)dd;
- auto newDecoration = context->builder->addDecoration<IRTargetIntrinsicDecoration>(clonedValue);
- newDecoration->targetName = originalDecoration->targetName;
- newDecoration->definition = originalDecoration->definition;
- }
- break;
-
- case kIRDecorationOp_Semantic:
- {
- auto originalDecoration = (IRSemanticDecoration*)dd;
- auto newDecoration = context->builder->addDecoration<IRSemanticDecoration>(clonedValue);
- newDecoration->semanticName = originalDecoration->semanticName;
- }
- break;
-
- case kIRDecorationOp_InterpolationMode:
- {
- auto originalDecoration = (IRInterpolationModeDecoration*)dd;
- auto newDecoration = context->builder->addDecoration<IRInterpolationModeDecoration>(clonedValue);
- newDecoration->mode = originalDecoration->mode;
- }
- break;
-
- case kIRDecorationOp_NameHint:
- {
- auto originalDecoration = (IRNameHintDecoration*)dd;
- auto newDecoration = context->builder->addDecoration<IRNameHintDecoration>(clonedValue);
- newDecoration->name = originalDecoration->name;
- }
- break;
-
- case kIRDecorationOp_VulkanRayPayload:
- {
- context->builder->addDecoration<IRVulkanRayPayloadDecoration>(clonedValue);
- }
- break;
-
- case kIRDecorationOp_VulkanCallablePayload:
- {
- context->builder->addDecoration<IRVulkanCallablePayloadDecoration>(clonedValue);
- }
- break;
- case kIRDecorationOp_EarlyDepthStencil:
- {
- context->builder->addDecoration<IREarlyDepthStencilDecoration>(clonedValue);
- }
- break;
- case kIRDecorationOp_GloballyCoherent:
- {
- context->builder->addDecoration<IRGloballyCoherentDecoration>(clonedValue);
- }
- break;
- case kIRDecorationOp_VulkanHitAttributes:
- {
- context->builder->addDecoration<IRVulkanHitAttributesDecoration>(clonedValue);
- }
- break;
+ return cloneInst(context, builder, originalInst, originalInst);
+ }
- case kIRDecorationOp_RequireGLSLExtension:
- {
- auto originalDecoration = (IRRequireGLSLExtensionDecoration*)dd;
- auto newDecoration = context->builder->addDecoration<IRRequireGLSLExtensionDecoration>(clonedValue);
- newDecoration->extensionName = originalDecoration->extensionName;
- }
- break;
+ /// Clone any decorations from `originalValue` onto `clonedValue`
+ void cloneDecorations(
+ IRSpecContextBase* context,
+ IRInst* clonedValue,
+ IRInst* originalValue)
+ {
+ // TODO: In many cases we might be able to use this as a general-purpose
+ // place to do cloning of *all* the children of an instruction, and
+ // not just its decorations. We should look to refactor this code
+ // later.
- case kIRDecorationOp_RequireGLSLVersion:
- {
- auto originalDecoration = (IRRequireGLSLVersionDecoration*)dd;
- auto newDecoration = context->builder->addDecoration<IRRequireGLSLVersionDecoration>(clonedValue);
- newDecoration->languageVersion = originalDecoration->languageVersion;
- }
- break;
+ IRBuilder builderStorage = *context->builder;
+ IRBuilder* builder = &builderStorage;
+ builder->setInsertInto(clonedValue);
- case kIRDecorationOp_ReadNone:
- {
- context->builder->addDecoration<IRReadNoneDecoration>(clonedValue);
- }
- break;
- default:
- // Don't clone any decorations we don't understand.
- break;
- }
+ SLANG_UNUSED(context);
+ for(auto originalDecoration : originalValue->getDecorations())
+ {
+ cloneInst(context, builder, originalDecoration);
}
// We will also clone the location here, just because this is a convenient bottleneck
@@ -5510,6 +5452,20 @@ namespace Slang
}
break;
+ case kIROp_StringLit:
+ {
+ IRConstant* c = (IRConstant*)originalValue;
+ return builder->getStringValue(c->getStringSlice());
+ }
+ break;
+
+ case kIROp_PtrLit:
+ {
+ IRConstant* c = (IRConstant*)originalValue;
+ return builder->getPtrValue(c->value.ptrVal);
+ }
+ break;
+
default:
{
// In the deafult case, assume that we have some sort of "hoistable"
@@ -5596,20 +5552,6 @@ namespace Slang
return cloneValue(context, originalValue);
}
- IRInst* cloneInst(
- IRSpecContextBase* context,
- IRBuilder* builder,
- IRInst* originalInst,
- IROriginalValuesForClone const& originalValues);
-
- IRInst* cloneInst(
- IRSpecContextBase* context,
- IRBuilder* builder,
- IRInst* originalInst)
- {
- return cloneInst(context, builder, originalInst, originalInst);
- }
-
void cloneGlobalValueWithCodeCommon(
IRSpecContextBase* context,
IRGlobalValueWithCode* clonedValue,
@@ -5652,8 +5594,6 @@ namespace Slang
auto mangledName = originalVar->mangledName;
clonedVar->mangledName = mangledName;
- cloneDecorations(context, clonedVar, originalVar);
-
VarLayout* layout = nullptr;
if (context->globalVarLayouts.TryGetValue(mangledName, layout))
{
@@ -5683,8 +5623,6 @@ namespace Slang
auto mangledName = originalVal->mangledName;
clonedVal->mangledName = mangledName;
- cloneDecorations(context, clonedVal, originalVal);
-
// Clone any code in the body of the constant, since this
// represents the initializer.
cloneGlobalValueWithCodeCommon(
@@ -5707,8 +5645,6 @@ namespace Slang
auto mangledName = originalVal->mangledName;
clonedVal->mangledName = mangledName;
- cloneDecorations(context, clonedVal, originalVal);
-
// Clone any code in the body of the generic, since this
// computes its result value.
cloneGlobalValueWithCodeCommon(
@@ -5732,15 +5668,13 @@ namespace Slang
auto mangledName = originalInst->mangledName;
clonedInst->mangledName = mangledName;
- cloneDecorations(context, clonedInst, originalInst);
-
// Set up an IR builder for inserting into the inst
IRBuilder builderStorage = *context->builder;
IRBuilder* builder = &builderStorage;
builder->setInsertInto(clonedInst);
// Clone any children of the instruction
- for (auto child : originalInst->getChildren())
+ for (auto child : originalInst->getDecorationsAndChildren())
{
cloneInst(context, builder, child);
}
@@ -5812,6 +5746,7 @@ namespace Slang
IRBuilder* builder = &builderStorage;
builder->setInsertInto(clonedValue);
+ cloneDecorations(context, clonedValue, originalValue);
// We will walk through the blocks of the function, and clone each of them.
//
@@ -5864,10 +5799,10 @@ namespace Slang
}
- void checkIRDuplicate(IRInst* inst, IRParentInst* moduleInst, Name* mangledName)
+ void checkIRDuplicate(IRInst* inst, IRInst* moduleInst, Name* mangledName)
{
#ifdef _DEBUG
- for (auto child : moduleInst->getChildren())
+ for (auto child : moduleInst->getDecorationsAndChildren())
{
if (child == inst)
continue;
@@ -5898,8 +5833,6 @@ namespace Slang
clonedFunc->mangledName = originalFunc->mangledName;
clonedFunc->setFullType(cloneType(context, originalFunc->getFullType()));
- cloneDecorations(context, clonedFunc, originalFunc);
-
cloneGlobalValueWithCodeCommon(
context,
clonedFunc,
@@ -6052,13 +5985,13 @@ namespace Slang
}
TargetSpecializationLevel result = TargetSpecializationLevel::notSpecialized;
- for( auto dd = val->firstDecoration; dd; dd = dd->next )
+ for(auto dd : val->getDecorations())
{
- if(dd->op != kIRDecorationOp_Target)
+ if(dd->op != kIROp_TargetDecoration)
continue;
auto decoration = (IRTargetDecoration*) dd;
- if(String(decoration->targetName) == targetName)
+ if(String(decoration->getTargetName()) == targetName)
return TargetSpecializationLevel::specializedForTarget;
result = TargetSpecializationLevel::specializedForOtherTarget;
@@ -6124,7 +6057,7 @@ namespace Slang
case kIROp_GlobalConstant:
case kIROp_Func:
case kIROp_Generic:
- return ((IRParentInst*)val)->getFirstChild() != nullptr;
+ return val->getFirstChild() != nullptr;
case kIROp_StructType:
case kIROp_GlobalVar:
@@ -6704,18 +6637,13 @@ namespace Slang
// We do *not* consider generics, or instructions nested under them.
return;
}
- else if(auto parentInst = as<IRParentInst>(inst))
+ else
{
- // For a parent instruction, we will scan through its contents,
- // since that will be where the `specialize` instructions are
-
- for(auto child : parentInst->children)
+ for(auto child : inst->getChildren())
{
addToSpecializationWorkListRec(sharedContext, child);
}
- }
- else
- {
+
// Default case: consider this instruction for specialization.
sharedContext->addToWorkList(inst);
}
@@ -6806,12 +6734,9 @@ namespace Slang
// We expect a generic to only ever contain a single block.
SLANG_ASSERT(bb == genericVal->getFirstBlock());
- for (auto ii : bb->getChildren())
+ // Iterate over the non-parameter ("ordinary") instructions.
+ for (auto ii : bb->getOrdinaryInsts())
{
- // Skip parameters, since they were handled earlier.
- if (auto param = as<IRParam>(ii))
- continue;
-
// The last block of the generic is expected to end with
// a `return` instruction for the specialized value that
// comes out of the abstraction.