/*
 * 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_pass_param_utils_h
#define wasm_pass_param_utils_h

#include "pass.h"
#include "support/sorted_vector.h"
#include "wasm.h"

// Helper code for passes that manipulate function parameters, specifically
// checking if they are used and removing them if so. This is closely tied to
// the internals of those passes, and so is not in /ir/ (it would be inside the
// pass .cpp file, but there is more than one).

namespace wasm::ParamUtils {

// Find which parameters are actually used in the function, that is, that the
// values arriving in the parameter are read. This ignores values set in the
// function, like this:
//
// function foo(x) {
//   x = 10;
//   bar(x); // read of a param index, but not the param value passed in.
// }
//
// This is an actual use:
//
// function foo(x) {
//   bar(x); // read of a param value
// }
std::unordered_set<Index> getUsedParams(Function* func);

// The outcome of an attempt to remove a parameter(s).
enum RemovalOutcome {
  // We removed successfully.
  Success = 0,
  // We failed, but only because of fixable nested effects. The caller can move
  // those effects out (e.g. using ChildLocalizer, or the helper localizeCallsTo
  // below) and repeat.
  Failure = 1,
};

// Try to remove a parameter from a set of functions and replace it with a local
// instead. This may not succeed if the parameter type cannot be used in a
// local, or if we hit another limitation, in which case this returns false and
// does nothing. If we succeed then the parameter is removed both from the
// functions and from the calls to it, which are passed in (the caller must
// ensure to pass in all relevant calls and call_refs).
//
// This does not check if removing the parameter would change the semantics
// (say, if the parameter's value is used), which the caller is assumed to do.
//
// This assumes that the set of functions all have the same signature. The main
// use cases are either to send a single function, or to send a set of functions
// that all have the same heap type (and so if they all do not use some
// parameter, it can be removed from them all).
//
// This does *not* update the types in call_refs. It is assumed that the caller
// will be updating types, which is simpler as there may be other locations that
// need adjusting and it is easier to do it all in one place. Also, the caller
// can update all the types at once throughout the program after making
// multiple calls to removeParameter().
RemovalOutcome removeParameter(const std::vector<Function*>& funcs,
                               Index index,
                               const std::vector<Call*>& calls,
                               const std::vector<CallRef*>& callRefs,
                               Module* module,
                               PassRunner* runner);

// The same as removeParameter, but gets a sorted list of indexes. It tries to
// remove them all, and returns which we removed, as well as an indication as
// to whether we might remove more if effects were not in the way (specifically,
// we return Success if we removed any index, Failure if we removed none, and
// FailureDueToEffects if at least one index could have been removed but for
// effects).
std::pair<SortedVector, RemovalOutcome>
removeParameters(const std::vector<Function*>& funcs,
                 SortedVector indexes,
                 const std::vector<Call*>& calls,
                 const std::vector<CallRef*>& callRefs,
                 Module* module,
                 PassRunner* runner);

// Given a set of functions and the calls and call_refs that reach them, find
// which parameters are passed the same constant value in all the calls. For
// each such parameter, apply it inside the function, that is, do a local.set of
// that value in the function. The parameter's incoming value is then ignored,
// which allows other optimizations to remove it.
//
// Returns the indexes that were optimized.
SortedVector applyConstantValues(const std::vector<Function*>& funcs,
                                 const std::vector<Call*>& calls,
                                 const std::vector<CallRef*>& callRefs,
                                 Module* module);

// Helper that localizes all calls to a set of targets, in an entire module.
// This basically calls ChildLocalizer in each function, on the relevant calls.
// This is useful when we get FailureDueToEffects, see above.
//
// The set of targets can be function names (the individual functions we want to
// handle calls towards) or heap types (which will then include all functions
// with those types).
void localizeCallsTo(const std::unordered_set<Name>& callTargets,
                     Module& wasm,
                     PassRunner* runner);
void localizeCallsTo(const std::unordered_set<HeapType>& callTargets,
                     Module& wasm,
                     PassRunner* runner);

} // namespace wasm::ParamUtils

#endif // wasm_pass_param_utils_h
