blob: 78ff98c6644c33f4c1bfa9bc610b34acc620cbde [file] [log] [blame] [edit]
/*
* 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