Skip to content

Commit 342d386

Browse files
committed
Fix the order changing issue
1 parent 19700df commit 342d386

File tree

3 files changed

+39
-59
lines changed

3 files changed

+39
-59
lines changed

source/slang/slang-ir-specialize.cpp

+1-55
Original file line numberDiff line numberDiff line change
@@ -3121,61 +3121,7 @@ IRInst* specializeGenericImpl(
31213121
// instructions only, because parameters were dealt
31223122
// with explictly at an earlier point.
31233123
//
3124-
IRInstList<IRInst> ordinaryInsts = bb->getOrdinaryInsts();
3125-
3126-
// After IRWitnessTable became Hoistable, they are removed and insered back by
3127-
// `addHoistableInst()`. But when they are re-inserted, the order it appears in the block is
3128-
// changed. When IRWitnessTable refers to IRSpecialize, as an example, IRSpecialize must be
3129-
// cloned before the cloning of IRWitnessTable. It is because the operands are assumed to be
3130-
// cloned before the cloning of IRInst.
3131-
//
3132-
// We need to resolve the dependency problem by changing the order of them.
3133-
//
3134-
List<IRInst*> insts;
3135-
int instCount = 0;
3136-
for (IRInst* ii : ordinaryInsts)
3137-
{
3138-
SLANG_UNUSED(ii);
3139-
instCount++;
3140-
}
3141-
insts.reserve(instCount);
3142-
3143-
// First, add all instructions in their original order
3144-
for (IRInst* ii : ordinaryInsts)
3145-
{
3146-
insts.add(ii);
3147-
}
3148-
3149-
// We'll need multiple passes to handle complex dependency chains
3150-
bool madeChanges = true;
3151-
while (madeChanges)
3152-
{
3153-
madeChanges = false;
3154-
3155-
for (int i = 0; i < instCount; i++)
3156-
{
3157-
IRInst* current = insts[i];
3158-
3159-
// Find all instructions that `current` depends on
3160-
for (int j = i + 1; j < instCount; j++)
3161-
{
3162-
IRInst* later = insts[j];
3163-
3164-
if (IsIRInstDependOn(current, later))
3165-
{
3166-
// `current` depends on `later`, so `later` must come before `current`.
3167-
insts.removeAt(j);
3168-
insts.insert(i, later);
3169-
3170-
// mark the change, and continue to the next.
3171-
madeChanges = true;
3172-
i++;
3173-
}
3174-
}
3175-
}
3176-
}
3177-
3178-
for (auto ii : insts)
3124+
for (auto ii : bb->getOrdinaryInsts())
31793125
{
31803126
// The last block of the generic is expected to end with
31813127
// a `return` instruction for the specialized value that

source/slang/slang-ir.cpp

+34
Original file line numberDiff line numberDiff line change
@@ -1694,6 +1694,30 @@ void addHoistableInst(IRBuilder* builder, IRInst* inst)
16941694
while (insertBeforeInst && insertBeforeInst->getOp() == kIROp_Param)
16951695
insertBeforeInst = insertBeforeInst->getNextInst();
16961696

1697+
if (inst->getOp() == kIROp_WitnessTable)
1698+
{
1699+
// WitnessTable can refer to IRSpecialize from its WitnessTableEntry
1700+
// children. In this case, specialize insts must be cloned before the
1701+
// WitnessTable. Similar an WitnessTables can have depdency to another
1702+
// WitnessTable.
1703+
//
1704+
for (IRInst* iter = insertBeforeInst; iter;)
1705+
{
1706+
bool mayHaveDependency = false;
1707+
switch (iter->getOp())
1708+
{
1709+
case kIROp_Specialize:
1710+
case kIROp_WitnessTable:
1711+
mayHaveDependency = true;
1712+
break;
1713+
}
1714+
1715+
iter = iter->getNextInst();
1716+
if (mayHaveDependency)
1717+
insertBeforeInst = iter;
1718+
}
1719+
}
1720+
16971721
// For instructions that will be placed at module scope,
16981722
// we don't care about relative ordering, but for everything
16991723
// else, we want to ensure that an instruction comes after
@@ -4609,6 +4633,16 @@ void addGlobalValue(IRBuilder* builder, IRInst* value)
46094633
parent = builder->getModule()->getModuleInst();
46104634
}
46114635

4636+
// If the value is already in the parent, keep it as it. Because WitnessTable is Hoistable, the
4637+
// parent can have only one instance of this WitnessTable. The order among siblings should
4638+
// remain because the later siblings may have dependency to the earlier siblings.
4639+
//
4640+
if (parent == value->parent)
4641+
{
4642+
SLANG_ASSERT(getIROpInfo(kIROp_WitnessTable).isHoistable());
4643+
return;
4644+
}
4645+
46124646
// If it turns out that we are inserting into the
46134647
// current "insert into" parent for the builder, then
46144648
// we need to respect its "insert before" setting

source/slang/slang-lower-to-ir.cpp

+4-4
Original file line numberDiff line numberDiff line change
@@ -8040,9 +8040,9 @@ struct DeclLoweringVisitor : DeclVisitor<DeclLoweringVisitor, LoweredValInfo>
80408040
astReqWitnessTable,
80418041
irSatisfyingWitnessTable,
80428042
mapASTToIRWitnessTable);
8043-
}
80448043

8045-
irSatisfyingWitnessTable->moveToEnd();
8044+
irSatisfyingWitnessTable->moveToEnd();
8045+
}
80468046
}
80478047
irSatisfyingVal = irSatisfyingWitnessTable;
80488048
}
@@ -8214,9 +8214,9 @@ struct DeclLoweringVisitor : DeclVisitor<DeclLoweringVisitor, LoweredValInfo>
82148214
irWitnessTable,
82158215
mapASTToIRWitnessTable);
82168216
}
8217-
}
82188217

8219-
irWitnessTable->moveToEnd();
8218+
irWitnessTable->moveToEnd();
8219+
}
82208220

82218221
return LoweredValInfo::simple(
82228222
finishOuterGenerics(subBuilder, irWitnessTable, outerGeneric));

0 commit comments

Comments
 (0)