summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAlon Zakai <azakai@google.com>2023-07-07 12:25:42 -0700
committerGitHub <noreply@github.com>2023-07-07 12:25:42 -0700
commit0d3bb31a37e151a7d4dcf32575f5789f0a3818ce (patch)
tree9f2bb746054460d4fe7efd8a28087edb5e094e5d /src
parentcdb7aeab40b4c522de20b242019f7e88641445d5 (diff)
downloadbinaryen-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.cpp19
-rw-r--r--src/passes/Heap2Local.cpp4
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) {