diff options
author | Thomas Lively <tlively123@gmail.com> | 2024-11-26 17:12:15 -0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-11-27 01:12:15 +0000 |
commit | 6f0f2e00521843118b63f41732dc2eb86d39fa09 (patch) | |
tree | 260d2be13758e3768955ee1f2c684102b6fea39a /src/passes/Flatten.cpp | |
parent | cd3805e31e8f2544d5e32aa505fc5e3abcf93df2 (diff) | |
download | binaryen-6f0f2e00521843118b63f41732dc2eb86d39fa09.tar.gz binaryen-6f0f2e00521843118b63f41732dc2eb86d39fa09.tar.bz2 binaryen-6f0f2e00521843118b63f41732dc2eb86d39fa09.zip |
Make more Ifs unreachable (#7094)
Previously the only Ifs that were typed unreachable were those in which
both arms were unreachable and those in which the condition was
unreachable that would have otherwise been typed none. This caused
problems in IRBuilder because Ifs with unreachable conditions and
value-returning arms would have concrete types, effectively hiding the
unreachable condition from the logic for dropping concretely typed
expressions preceding an unreachable expression when finishing a scope.
Relax the conditions under which an If can be typed unreachable so that
all Ifs with unreachable conditions or two unreachable arms are typed
unreachable. Propagating unreachability more eagerly this way makes
various optimizations of Ifs more powerful. It also requires new
handling for unreachable Ifs with concretely typed arms in the Printer
to ensure that printed wat remains valid.
Also update Unsubtyping, Flatten, and CodeFolding to account for the
newly unreachable Ifs.
Diffstat (limited to 'src/passes/Flatten.cpp')
-rw-r--r-- | src/passes/Flatten.cpp | 16 |
1 files changed, 10 insertions, 6 deletions
diff --git a/src/passes/Flatten.cpp b/src/passes/Flatten.cpp index 37fa15b11..1c2cfbcd5 100644 --- a/src/passes/Flatten.cpp +++ b/src/passes/Flatten.cpp @@ -147,20 +147,24 @@ struct Flatten // arm preludes go in the arms. we must also remove an if value auto* originalIfTrue = iff->ifTrue; auto* originalIfFalse = iff->ifFalse; - auto type = iff->type; + auto type = iff->ifFalse ? Type::getLeastUpperBound(iff->ifTrue->type, + iff->ifFalse->type) + : Type::none; Expression* prelude = nullptr; if (type.isConcrete()) { Index temp = builder.addVar(getFunction(), type); if (iff->ifTrue->type.isConcrete()) { iff->ifTrue = builder.makeLocalSet(temp, iff->ifTrue); } - if (iff->ifFalse && iff->ifFalse->type.isConcrete()) { + if (iff->ifFalse->type.isConcrete()) { iff->ifFalse = builder.makeLocalSet(temp, iff->ifFalse); } - // the whole if (+any preludes from the condition) is now a prelude - prelude = rep; - // and we leave just a get of the value - rep = builder.makeLocalGet(temp, type); + if (curr->type.isConcrete()) { + // the whole if (+any preludes from the condition) is now a prelude + prelude = rep; + // and we leave just a get of the value + rep = builder.makeLocalGet(temp, type); + } } iff->ifTrue = getPreludesWithExpression(originalIfTrue, iff->ifTrue); if (iff->ifFalse) { |