diff options
author | Alon Zakai <azakai@google.com> | 2022-09-28 12:35:28 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-09-28 12:35:28 -0700 |
commit | 524e813891f5957ce9263b909b282b2cbfd1c5be (patch) | |
tree | 75b2caf6f63a550a0e8cc8312c5f6d84f15221a4 /src/ir/possible-contents.cpp | |
parent | 7044da7fe6754c54bd7f4930eaa208e3081cabe3 (diff) | |
download | binaryen-524e813891f5957ce9263b909b282b2cbfd1c5be.tar.gz binaryen-524e813891f5957ce9263b909b282b2cbfd1c5be.tar.bz2 binaryen-524e813891f5957ce9263b909b282b2cbfd1c5be.zip |
[GUFA] Prepare for cone types [NFC] (#5086)
This does not actually add cone types, but it does NFC refactoring towards that.
Specifically it replaces the internal ExactType with ConeType, and the latter
has a depth, so a cone type of depth 0 is the old exact type.
Cone types with depth > 0 are not possible yet, keeping this NFC.
I believe this design with a depth for cone types has little overhead. It does add
to the size of ConeType, but the variant there is larger anyhow (it contains a
Literal). And things like isSubType need to loop anyhow, so looping up to the
depth etc. in checks won't make things slower.
Diffstat (limited to 'src/ir/possible-contents.cpp')
-rw-r--r-- | src/ir/possible-contents.cpp | 26 |
1 files changed, 13 insertions, 13 deletions
diff --git a/src/ir/possible-contents.cpp b/src/ir/possible-contents.cpp index 836f7570d..1b5c5ae0d 100644 --- a/src/ir/possible-contents.cpp +++ b/src/ir/possible-contents.cpp @@ -1411,12 +1411,12 @@ bool Flower::updateContents(LocationIndex locationIndex, // It is not worth sending any more to this location if we are now in the // worst possible case, as no future value could cause any change. // - // Many is always the worst possible case. An exact type of a non-reference is + // Many is always the worst possible case. A cone type of a non-reference is // also the worst case, since subtyping is not relevant there, and so if we - // know only the type then we already know nothing beyond what the type in the - // wasm tells us (and from there we can only go to Many). + // only know something about the type then we already know nothing beyond what + // the type in the wasm tells us (and from there we can only go to Many). bool worthSendingMore = !contents.isMany(); - if (!contents.getType().isRef() && contents.isExactType()) { + if (!contents.getType().isRef() && contents.isConeType()) { worthSendingMore = false; } @@ -1578,9 +1578,10 @@ void Flower::filterGlobalContents(PossibleContents& contents, // "Many", since in the worst case we can just use the immutable value. That // is, we can always replace this value with (global.get $name) which will // get the right value. Likewise, using the immutable global value is often - // better than an exact type, but TODO: we could note both an exact type - // *and* that something is equal to a global, in some cases. - if (contents.isMany() || contents.isExactType()) { + // better than a cone type (even an exact one), but TODO: we could note both + // a cone/exact type *and* that something is equal to a global, in some + // cases. See https://github.com/WebAssembly/binaryen/pull/5083 + if (contents.isMany() || contents.isConeType()) { contents = PossibleContents::global(global->name, global->type); // TODO: We could do better here, to set global->init->type instead of @@ -1603,7 +1604,7 @@ void Flower::readFromData(HeapType declaredHeapType, Expression* read) { // The data that a struct.get reads depends on two things: the reference that // we read from, and the relevant DataLocations. The reference determines - // which DataLocations are relevant: if it is an ExactType then we have a + // which DataLocations are relevant: if it is an exact type then we have a // single DataLocation to read from, the one type that can be read from there. // Otherwise, we might read from any subtype, and so all their DataLocations // are relevant. @@ -1645,22 +1646,21 @@ void Flower::readFromData(HeapType declaredHeapType, std::cout << " add special reads\n"; #endif - if (refContents.isExactType()) { + if (refContents.hasExactType()) { // Add a single link to the exact location the reference points to. connectDuringFlow( DataLocation{refContents.getType().getHeapType(), fieldIndex}, ExpressionLocation{read, 0}); } else { - // Otherwise, this is a cone: the declared type of the reference, or any - // subtype of that, regardless of whether the content is a Many or a Global - // or anything else. + // Otherwise, this is a true cone (i.e., it has a depth > 0): the declared + // type of the reference or some of its subtypes. // TODO: The Global case may have a different cone type than the heapType, // which we could use here. // TODO: A Global may refer to an immutable global, which we can read the // field from potentially (reading it from the struct.new/array.new // in the definition of it, if it is not imported; or, we could track // the contents of immutable fields of allocated objects, and not just - // represent them as ExactType). + // represent them as an exact type). // See the test TODO with text "We optimize some of this, but stop at // reading from the immutable global" assert(refContents.isMany() || refContents.isGlobal()); |