Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
85 changes: 52 additions & 33 deletions src/ir/child-typer.h
Original file line number Diff line number Diff line change
Expand Up @@ -867,11 +867,11 @@ template<typename Subtype> struct ChildTyper : OverriddenVisitor<Subtype> {

void visitCallRef(CallRef* curr, std::optional<HeapType> ht = std::nullopt) {
if (!ht) {
if (!curr->target->type.isRef()) {
if (!curr->target->type.isSignature()) {
self().noteUnknown();
return;
}
ht = curr->target->type.getHeapType().getSignature();
ht = curr->target->type.getHeapType();
}
auto params = ht->getSignature().params;
handleCall(curr, params);
Expand All @@ -891,19 +891,25 @@ template<typename Subtype> struct ChildTyper : OverriddenVisitor<Subtype> {
}
target = curr->type;
}
std::optional<HeapType> desc;
if (curr->desc) {
desc = target->getHeapType().getDescriptorType();
if (!desc) {
self().noteUnknown();
return;
}
}
auto top = target->getHeapType().getTop();
note(&curr->ref, Type(top, Nullable));
if (curr->desc) {
auto desc = target->getHeapType().getDescriptorType();
assert(desc);
note(&curr->desc, Type(*desc, Nullable, target->getExactness()));
}
}

void visitRefGetDesc(RefGetDesc* curr,
std::optional<HeapType> ht = std::nullopt) {
if (!ht) {
if (!curr->ref->type.isRef()) {
if (!curr->ref->type.isRef() || curr->ref->type.isBottomRef()) {
self().noteUnknown();
return;
}
Expand Down Expand Up @@ -936,11 +942,17 @@ template<typename Subtype> struct ChildTyper : OverriddenVisitor<Subtype> {
out = curr->castType;
in = Type(out->getHeapType().getTop(), Nullable);
}
note(&curr->ref, *in);
std::optional<HeapType> desc;
if (curr->op == BrOnCastDescEq || curr->op == BrOnCastDescEqFail) {
auto desc = out->getHeapType().getDescriptorType();
assert(desc);
note(&curr->desc, Type(*desc, Nullable));
desc = out->getHeapType().getDescriptorType();
if (!desc) {
self().noteUnknown();
return;
}
}
note(&curr->ref, *in);
if (desc) {
note(&curr->desc, Type(*desc, Nullable, out->getExactness()));
}
return;
}
Expand All @@ -949,7 +961,7 @@ template<typename Subtype> struct ChildTyper : OverriddenVisitor<Subtype> {
}

void visitStructNew(StructNew* curr) {
if (!curr->type.isRef()) {
if (!curr->type.isStruct()) {
self().noteUnknown();
return;
}
Expand All @@ -968,7 +980,7 @@ template<typename Subtype> struct ChildTyper : OverriddenVisitor<Subtype> {
void visitStructGet(StructGet* curr,
std::optional<HeapType> ht = std::nullopt) {
if (!ht) {
if (!curr->ref->type.isRef()) {
if (!curr->ref->type.isStruct()) {
self().noteUnknown();
return;
}
Expand All @@ -980,7 +992,7 @@ template<typename Subtype> struct ChildTyper : OverriddenVisitor<Subtype> {
void visitStructSet(StructSet* curr,
std::optional<HeapType> ht = std::nullopt) {
if (!ht) {
if (!curr->ref->type.isRef()) {
if (!curr->ref->type.isStruct()) {
self().noteUnknown();
return;
}
Expand All @@ -995,7 +1007,7 @@ template<typename Subtype> struct ChildTyper : OverriddenVisitor<Subtype> {
void visitStructRMW(StructRMW* curr,
std::optional<HeapType> ht = std::nullopt) {
if (!ht) {
if (!curr->ref->type.isRef()) {
if (!curr->ref->type.isStruct()) {
self().noteUnknown();
return;
}
Expand All @@ -1010,7 +1022,7 @@ template<typename Subtype> struct ChildTyper : OverriddenVisitor<Subtype> {
void visitStructCmpxchg(StructCmpxchg* curr,
std::optional<HeapType> ht = std::nullopt) {
if (!ht) {
if (!curr->ref->type.isRef()) {
if (!curr->ref->type.isStruct()) {
self().noteUnknown();
return;
}
Expand Down Expand Up @@ -1063,7 +1075,7 @@ template<typename Subtype> struct ChildTyper : OverriddenVisitor<Subtype> {

void visitArrayNew(ArrayNew* curr) {
if (!curr->isWithDefault()) {
if (!curr->type.isRef()) {
if (!curr->type.isArray()) {
self().noteUnknown();
return;
}
Expand All @@ -1083,7 +1095,7 @@ template<typename Subtype> struct ChildTyper : OverriddenVisitor<Subtype> {
}

void visitArrayNewFixed(ArrayNewFixed* curr) {
if (!curr->type.isRef()) {
if (!curr->type.isArray()) {
self().noteUnknown();
return;
}
Expand All @@ -1096,7 +1108,7 @@ template<typename Subtype> struct ChildTyper : OverriddenVisitor<Subtype> {
void visitArrayGet(ArrayGet* curr,
std::optional<HeapType> ht = std::nullopt) {
if (!ht) {
if (!curr->ref->type.isRef()) {
if (!curr->ref->type.isArray()) {
self().noteUnknown();
return;
}
Expand All @@ -1109,7 +1121,7 @@ template<typename Subtype> struct ChildTyper : OverriddenVisitor<Subtype> {
void visitArraySet(ArraySet* curr,
std::optional<HeapType> ht = std::nullopt) {
if (!ht) {
if (!curr->ref->type.isRef()) {
if (!curr->ref->type.isArray()) {
self().noteUnknown();
return;
}
Expand All @@ -1124,7 +1136,7 @@ template<typename Subtype> struct ChildTyper : OverriddenVisitor<Subtype> {
void visitArrayLoad(ArrayLoad* curr,
std::optional<HeapType> ht = std::nullopt) {
if (!ht) {
if (!curr->ref->type.isRef()) {
if (!curr->ref->type.isArray()) {
self().noteUnknown();
return;
}
Expand All @@ -1138,7 +1150,7 @@ template<typename Subtype> struct ChildTyper : OverriddenVisitor<Subtype> {
std::optional<HeapType> ht = std::nullopt,
std::optional<Type> valueType = std::nullopt) {
if (!ht) {
if (!curr->ref->type.isRef()) {
if (!curr->ref->type.isArray()) {
self().noteUnknown();
return;
}
Expand All @@ -1162,14 +1174,14 @@ template<typename Subtype> struct ChildTyper : OverriddenVisitor<Subtype> {
std::optional<HeapType> dest = std::nullopt,
std::optional<HeapType> src = std::nullopt) {
if (!dest) {
if (!curr->destRef->type.isRef()) {
if (!curr->destRef->type.isArray()) {
self().noteUnknown();
return;
}
dest = curr->destRef->type.getHeapType();
}
if (!src) {
if (!curr->srcRef->type.isRef()) {
if (!curr->srcRef->type.isArray()) {
self().noteUnknown();
return;
}
Expand All @@ -1185,7 +1197,7 @@ template<typename Subtype> struct ChildTyper : OverriddenVisitor<Subtype> {
void visitArrayFill(ArrayFill* curr,
std::optional<HeapType> ht = std::nullopt) {
if (!ht) {
if (!curr->ref->type.isRef()) {
if (!curr->ref->type.isArray()) {
self().noteUnknown();
return;
}
Expand All @@ -1201,7 +1213,7 @@ template<typename Subtype> struct ChildTyper : OverriddenVisitor<Subtype> {
void visitArrayInitData(ArrayInitData* curr,
std::optional<HeapType> ht = std::nullopt) {
if (!ht) {
if (!curr->ref->type.isRef()) {
if (!curr->ref->type.isArray()) {
self().noteUnknown();
return;
}
Expand All @@ -1216,7 +1228,7 @@ template<typename Subtype> struct ChildTyper : OverriddenVisitor<Subtype> {
void visitArrayInitElem(ArrayInitElem* curr,
std::optional<HeapType> ht = std::nullopt) {
if (!ht) {
if (!curr->ref->type.isRef()) {
if (!curr->ref->type.isArray()) {
self().noteUnknown();
return;
}
Expand All @@ -1231,7 +1243,7 @@ template<typename Subtype> struct ChildTyper : OverriddenVisitor<Subtype> {
void visitArrayRMW(ArrayRMW* curr,
std::optional<HeapType> ht = std::nullopt) {
if (!ht) {
if (!curr->ref->type.isRef()) {
if (!curr->ref->type.isArray()) {
self().noteUnknown();
return;
}
Expand All @@ -1246,7 +1258,7 @@ template<typename Subtype> struct ChildTyper : OverriddenVisitor<Subtype> {
void visitArrayCmpxchg(ArrayCmpxchg* curr,
std::optional<HeapType> ht = std::nullopt) {
if (!ht) {
if (!curr->ref->type.isRef()) {
if (!curr->ref->type.isArray()) {
self().noteUnknown();
return;
}
Expand Down Expand Up @@ -1350,20 +1362,27 @@ template<typename Subtype> struct ChildTyper : OverriddenVisitor<Subtype> {
note(&curr->end, Type::i32);
}

void visitContNew(ContNew* curr) { note(&curr->func, curr->type); }
void visitContNew(ContNew* curr) {
if (!curr->type.isContinuation()) {
self().noteUnknown();
return;
}
note(&curr->func,
Type(curr->type.getHeapType().getContinuation().type, Nullable));
}

void visitContBind(ContBind* curr,
std::optional<HeapType> src = std::nullopt,
std::optional<HeapType> dest = std::nullopt) {
if (!src) {
if (!curr->cont->type.isRef()) {
if (!curr->cont->type.isContinuation()) {
self().noteUnknown();
return;
}
src = curr->cont->type.getHeapType();
}
if (!dest) {
if (!curr->type.isRef()) {
if (!curr->type.isContinuation()) {
self().noteUnknown();
return;
}
Expand All @@ -1390,7 +1409,7 @@ template<typename Subtype> struct ChildTyper : OverriddenVisitor<Subtype> {

void visitResume(Resume* curr, std::optional<HeapType> ct = std::nullopt) {
if (!ct) {
if (!curr->cont->type.isRef()) {
if (!curr->cont->type.isContinuation()) {
self().noteUnknown();
return;
}
Expand All @@ -1408,7 +1427,7 @@ template<typename Subtype> struct ChildTyper : OverriddenVisitor<Subtype> {
void visitResumeThrow(ResumeThrow* curr,
std::optional<HeapType> ct = std::nullopt) {
if (!ct) {
if (!curr->cont->type.isRef()) {
if (!curr->cont->type.isContinuation()) {
self().noteUnknown();
return;
}
Expand All @@ -1432,7 +1451,7 @@ template<typename Subtype> struct ChildTyper : OverriddenVisitor<Subtype> {
void visitStackSwitch(StackSwitch* curr,
std::optional<HeapType> ct = std::nullopt) {
if (!ct) {
if (!curr->cont->type.isRef()) {
if (!curr->cont->type.isContinuation()) {
self().noteUnknown();
return;
}
Expand Down
19 changes: 10 additions & 9 deletions src/passes/TypeSSA.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@
#include "ir/module-utils.h"
#include "ir/names.h"
#include "ir/possible-constant.h"
#include "ir/properties.h"
#include "ir/utils.h"
#include "pass.h"
#include "support/hash.h"
Expand Down Expand Up @@ -136,26 +137,26 @@ struct Analyzer
}
}
void visitRefTest(RefTest* curr) { visitCast(curr); }
void visitRefCast(RefCast* curr) { visitCast(curr); }
void visitRefCast(RefCast* curr) {
visitCast(curr);
visitExpression(curr);
}
void visitBrOn(BrOn* curr) {
if (curr->op == BrOnCast || curr->op == BrOnCastFail) {
if (curr->op != BrOnNull && curr->op != BrOnNonNull) {
visitCast(curr);
}
visitExpression(curr);
}

void visitExpression(Expression* curr) {
// Look at the constraints on this expression's operands to see if it
// requires an exact operand. If it does, we cannot optimize allocations of
// that type. As an optimization, do not let control flow structures or
// branches inhibit optimization since they can safely be refinalized to use
// branches inhibit optimization. They can safely be refinalized to use
// new types as long as no other instruction expected the original exact
// type. Also allow optimizing if the instruction that would inhibit
// optimizing will not be written in the final output. Skipping further
// analysis for these instructions also ensures that the ChildTyper below
// sees the type information it expects in the instructions it analyzes.
// type.
if (Properties::isControlFlowStructure(curr) ||
Properties::isBranch(curr) ||
Properties::hasUnwritableTypeImmediate(curr)) {
Properties::isBranch(curr)) {
return;
}

Expand Down
Loading
Loading