diff options
Diffstat (limited to 'src/ir/properties.h')
-rw-r--r-- | src/ir/properties.h | 36 |
1 files changed, 36 insertions, 0 deletions
diff --git a/src/ir/properties.h b/src/ir/properties.h index 7cbbe73f0..6848e9481 100644 --- a/src/ir/properties.h +++ b/src/ir/properties.h @@ -146,6 +146,42 @@ inline Index getZeroExtBits(Expression* curr) { return Bits::getMaskedBits(curr->cast<Binary>()->right->cast<Const>()->value.geti32()); } +// Returns a falling-through value, that is, it looks through a tee_local +// and other operations that receive a value and let it flow through them. +inline Expression* getFallthrough(Expression* curr) { + // If the current node is unreachable, there is no value + // falling through. + if (curr->type == unreachable) { + return curr; + } + if (auto* set = curr->dynCast<SetLocal>()) { + if (set->isTee()) { + return getFallthrough(set->value); + } + } else if (auto* block = curr->dynCast<Block>()) { + // if no name, we can't be broken to, and then can look at the fallthrough + if (!block->name.is() && block->list.size() > 0) { + return getFallthrough(block->list.back()); + } + } else if (auto* loop = curr->dynCast<Loop>()) { + return getFallthrough(loop->body); + } else if (auto* iff = curr->dynCast<If>()) { + if (iff->ifFalse) { + // Perhaps just one of the two actually returns. + if (iff->ifTrue->type == unreachable) { + return getFallthrough(iff->ifFalse); + } else if (iff->ifFalse->type == unreachable) { + return getFallthrough(iff->ifTrue); + } + } + } else if (auto* br = curr->dynCast<Break>()) { + if (br->condition && br->value) { + return getFallthrough(br->value); + } + } + return curr; +} + } // Properties } // wasm |