diff options
author | Alon Zakai <azakai@google.com> | 2023-07-07 12:25:42 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-07-07 12:25:42 -0700 |
commit | 0d3bb31a37e151a7d4dcf32575f5789f0a3818ce (patch) | |
tree | 9f2bb746054460d4fe7efd8a28087edb5e094e5d /src | |
parent | cdb7aeab40b4c522de20b242019f7e88641445d5 (diff) | |
download | binaryen-0d3bb31a37e151a7d4dcf32575f5789f0a3818ce.tar.gz binaryen-0d3bb31a37e151a7d4dcf32575f5789f0a3818ce.tar.bz2 binaryen-0d3bb31a37e151a7d4dcf32575f5789f0a3818ce.zip |
GUFA: Refine casts (#5805)
If we see (ref.cast $A) but we have inferred that a more refined type will
be present there at runtime $B then we can refine the cast to (ref.cast $B).
We could do the same even when a cast is not present, but that would
increase code size. This optimization keeps code size constant.
Diffstat (limited to 'src')
-rw-r--r-- | src/passes/GUFA.cpp | 19 | ||||
-rw-r--r-- | src/passes/Heap2Local.cpp | 4 |
2 files changed, 22 insertions, 1 deletions
diff --git a/src/passes/GUFA.cpp b/src/passes/GUFA.cpp index 137ffda17..8f58eaf8a 100644 --- a/src/passes/GUFA.cpp +++ b/src/passes/GUFA.cpp @@ -255,6 +255,25 @@ struct GUFAOptimizer } } + void visitRefCast(RefCast* curr) { + auto currType = curr->type; + auto inferredType = getContents(curr).getType(); + if (inferredType.isRef() && inferredType != currType && + Type::isSubType(inferredType, currType)) { + // We have inferred that this will only contain something of a more + // refined type, so we might as well cast to that more refined type. + // + // Note that we could in principle apply this in all expressions by adding + // a cast. However, to be careful with code size, we only refine existing + // casts for now. + curr->type = inferredType; + } + + // Apply the usual optimizations as well, such as potentially replacing this + // with a constant. + visitExpression(curr); + } + // TODO: If an instruction would trap on null, like struct.get, we could // remove it here if it has no possible contents and if we are in // traps-never-happen mode (that is, we'd have proven it can only trap, diff --git a/src/passes/Heap2Local.cpp b/src/passes/Heap2Local.cpp index 91298106d..fccbc3321 100644 --- a/src/passes/Heap2Local.cpp +++ b/src/passes/Heap2Local.cpp @@ -191,7 +191,9 @@ struct Heap2LocalOptimizer { localGraph.computeSetInfluences(); // All the allocations in the function. - // TODO: Arrays (of constant size) as well. + // TODO: Arrays (of constant size) as well, if all element accesses use + // constant indexes. One option might be to first convert such + // nonescaping arrays into structs. FindAll<StructNew> allocations(func->body); for (auto* allocation : allocations.list) { |