| /* |
| * 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 "wasm.h" |
| |
| namespace wasm { |
| |
| struct PassOptions; |
| |
| // Given an expression, returns a new expression that drops the given |
| // expression's unconditional 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). |
| // |
| // This function only operates on children that executes unconditionally. That |
| // is the case in almost all expressions, except for those with conditional |
| // execution, like if, which unconditionally executes the condition but then |
| // conditionally executes one of the two arms. The above function simply returns |
| // all children in order, so it does this to if: |
| // |
| // (if |
| // (condition) |
| // (arm-A) |
| // (arm-B) |
| // ) |
| // => |
| // (drop |
| // (condition) |
| // ) |
| // (drop |
| // (arm-A) |
| // ) |
| // (drop |
| // (arm-B) |
| // ) |
| // (appended last item) |
| // |
| // This is dangerous as it executes what were conditional children in an |
| // unconditional way. To avoid that issue, this function will only operate on |
| // unconditional children, and keep conditional ones as they were. That means |
| // it will not split up and drop the children of an if, for example. All we do |
| // in that case is drop the entire if and append the last item: |
| // |
| // (drop |
| // (if |
| // (condition) |
| // (arm-A) |
| // (arm-B) |
| // ) |
| // ) |
| // (appended last item) |
| // |
| // Also this function preserves other unremovable expressions like trys, pops, |
| // and named blocks. |
| Expression* getDroppedChildrenAndAppend(Expression* curr, |
| Module& wasm, |
| const PassOptions& options, |
| Expression* last); |
| |
| } // namespace wasm |
| |
| #endif // wasm_ir_drop_h |