Skip to content

Commit d06f09b

Browse files
authored
[Custom Descriptors] GUFA support for descriptor fields (#7869)
Represent them as index -1, which lets us very easily reuse all the existing struct field logic.
1 parent 4b1e557 commit d06f09b

File tree

3 files changed

+666
-3
lines changed

3 files changed

+666
-3
lines changed

src/ir/possible-contents.cpp

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -704,8 +704,12 @@ struct InfoCollector
704704
void visitRefCast(RefCast* curr) { receiveChildValue(curr->ref, curr); }
705705
void visitRefTest(RefTest* curr) { addRoot(curr); }
706706
void visitRefGetDesc(RefGetDesc* curr) {
707-
// TODO: Do something more similar to struct.get here
708-
addRoot(curr);
707+
// Parallel to StructGet.
708+
if (!isRelevant(curr->ref)) {
709+
addRoot(curr);
710+
return;
711+
}
712+
addChildParentLink(curr->ref, curr);
709713
}
710714
void visitBrOn(BrOn* curr) {
711715
// TODO: optimize when possible
@@ -939,6 +943,10 @@ struct InfoCollector
939943
return DataLocation{type, i};
940944
});
941945
}
946+
if (curr->desc) {
947+
info.links.push_back({ExpressionLocation{curr->desc, 0},
948+
DataLocation{type, DataLocation::DescriptorIndex}});
949+
}
942950
addRoot(curr, PossibleContents::exactType(curr->type));
943951
}
944952
void visitArrayNew(ArrayNew* curr) {
@@ -2679,6 +2687,11 @@ void Flower::flowAfterUpdate(LocationIndex locationIndex) {
26792687
} else if (auto* set = parent->dynCast<ArraySet>()) {
26802688
assert(set->ref == child || set->value == child);
26812689
writeToData(set->ref, set->value, 0);
2690+
} else if (auto* get = parent->dynCast<RefGetDesc>()) {
2691+
// Similar to struct.get.
2692+
assert(get->ref == child);
2693+
readFromData(
2694+
get->ref->type, DataLocation::DescriptorIndex, contents, get);
26822695
} else {
26832696
// TODO: ref.test and all other casts can be optimized (see the cast
26842697
// helper code used in OptimizeInstructions and RemoveUnusedBrs)
@@ -2839,6 +2852,10 @@ void Flower::filterGlobalContents(PossibleContents& contents,
28392852

28402853
void Flower::filterDataContents(PossibleContents& contents,
28412854
const DataLocation& dataLoc) {
2855+
if (dataLoc.index == DataLocation::DescriptorIndex) {
2856+
// Nothing to filter (packing is not relevant for a descriptor).
2857+
return;
2858+
}
28422859
auto field = GCTypeUtils::getField(dataLoc.type, dataLoc.index);
28432860
if (!field) {
28442861
// This is a bottom type; nothing will be written here.

src/ir/possible-contents.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -481,7 +481,9 @@ struct SignatureResultLocation {
481481
struct DataLocation {
482482
HeapType type;
483483
// The index of the field in a struct, or 0 for an array (where we do not
484-
// attempt to differentiate by index).
484+
// attempt to differentiate by index). A special index is used for the
485+
// descriptor field.
486+
static const Index DescriptorIndex = -1;
485487
Index index;
486488
bool operator==(const DataLocation& other) const {
487489
return type == other.type && index == other.index;

0 commit comments

Comments
 (0)