/* * Copyright 2022 WebAssembly Community Group participants * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef wasm_ir_drop_h #define wasm_ir_drop_h #include "ir/effects.h" #include "ir/iteration.h" #include "wasm-builder.h" #include "wasm.h" namespace wasm { // Given an expression, returns a new expression that drops the given // expression's children that cannot be removed outright due to their side // effects. This is useful if we know the node is not needed but may need to // keep the children around; this utility will automatically remove any children // we do not actually need to keep, based on their effects. // // The caller must also pass in a last item to append to the output (which is // typically what the original expression is replaced with). Expression* getDroppedChildrenAndAppend(Expression* curr, Module& wasm, const PassOptions& options, Expression* last) { Builder builder(wasm); std::vector contents; for (auto* child : ChildIterator(curr)) { if (!EffectAnalyzer(options, wasm, child).hasUnremovableSideEffects()) { continue; } if (child->type.isConcrete()) { contents.push_back(builder.makeDrop(child)); } else { // The child is unreachable, or none (none is possible as a child of a // block or loop, etc.); in both cases we do not need a drop. contents.push_back(child); } } contents.push_back(last); if (contents.size() == 1) { return contents[0]; } return builder.makeBlock(contents); } } // namespace wasm #endif // wasm_ir_drop_h