blob: 4b2f5b28251cb10d135e9b71062e432720041fc8 [file] [edit]
// Copyright 2024 The Dawn & Tint Authors
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice, this
// list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// 3. Neither the name of the copyright holder nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef SRC_TINT_LANG_CORE_IR_ANALYSIS_INTEGER_RANGE_ANALYSIS_H_
#define SRC_TINT_LANG_CORE_IR_ANALYSIS_INTEGER_RANGE_ANALYSIS_H_
#include <cstdint>
#include <memory>
#include <variant>
namespace tint::core::ir {
class Binary;
class Function;
class FunctionParam;
class Loop;
class Var;
} // namespace tint::core::ir
namespace tint::core::ir::analysis {
/// The result of a integer range analysis: the upper and lower bound of a given integer variable.
/// The bound is inclusive, which means the value x being bound satisfies:
/// min_bound <= x <= max_bound.
struct IntegerRangeInfo {
IntegerRangeInfo() = default;
IntegerRangeInfo(int64_t min_bound, int64_t max_bound);
IntegerRangeInfo(uint64_t min_bound, uint64_t max_bound);
struct SignedIntegerRange {
int64_t min_bound;
int64_t max_bound;
};
struct UnsignedIntegerRange {
uint64_t min_bound;
uint64_t max_bound;
};
std::variant<std::monostate, SignedIntegerRange, UnsignedIntegerRange> range;
};
struct IntegerRangeAnalysisImpl;
/// IntegerRangeAnalysis is a helper used to analyze integer ranges.
class IntegerRangeAnalysis {
public:
/// Constructor
/// @param func the function to cache analyses for
explicit IntegerRangeAnalysis(Function* func);
~IntegerRangeAnalysis();
/// Returns the integer range info of a given parameter with given index, if it is an integer
/// or an integer vector parameter. The index must not be over the maximum size of the vector
/// and must be 0 if the parameter is an integer.
/// Otherwise is not analyzable and returns nullptr. If it is the first time to query the info,
/// the result will also be stored into a cache for future queries.
/// @param param the variable to get information about
/// @param index the vector component index when the parameter is a vector type. if the
/// parameter is a scalar, then `index` must be zero.
/// @returns the integer range info
const IntegerRangeInfo* GetInfo(const FunctionParam* param, uint32_t index = 0);
/// Returns the integer range info of a given variable with given index, if it is an integer
/// variable.
/// @param var the variable to get information about
/// @returns the integer range info
const IntegerRangeInfo* GetInfo(const Var* var);
/// Note: This function is only for tests.
/// Returns the pointer of the loop control variable in the given loop when its initializer
/// meets the below requirements.
/// - There are only two instructions in the loop initializer block.
/// - The first instruction is to initialize the loop control variable
/// with a constant integer (signed or unsigned) value.
/// - The second instruction is `next_iteration`.
/// @param loop the Loop variable to investigate
/// @returns the pointer of the loop control variable when its loop initializer meets the
/// requirements, return nullptr otherwise.
const Var* GetLoopControlVariableFromConstantInitializerForTest(const Loop* loop);
/// Note: This function is only for tests.
/// Returns the pointer of the binary operation that updates the loop control variable in the
/// continuing block of the given loop if the loop meets the below requirements.
/// - There are only 4 instructions in the loop initializer block.
/// - The first instruction is to load the loop control variable into a temporary variable.
/// - The second instruction is to add one or minus one to the temporary variable.
/// - The third instruction is to store the value of the temporary variable into the loop
/// control variable.
/// - The fourth instruction is `next_iteration`.
/// @param loop the Loop variable to investigate.
/// @param loop_control_variable the loop control variable to investigate.
/// @returns the pointer of the binary operation that updates the loop control variable in the
/// continuing block of the given loop if the loop meets all the requirements, return nullptr
/// otherwise.
const Binary* GetBinaryToUpdateLoopControlVariableInContinuingBlockForTest(
const Loop* loop,
const Var* loop_control_variable);
/// Note: This function is only for tests
/// Returns the pointer of the binary operation that compares the loop control variable with its
/// limitations in the body block of the loop if the loop meets the below requirements:
/// - The loop control variable is only used as the parameter of the load instruction.
/// - The first instruction is to load the loop control variable into a temporary variable.
/// - The second instruction is to compare the temporary variable with a constant value and save
/// the result to a boolean variable.
/// - The second instruction cannot be a comparison that will never return true.
/// - The third instruction is an `ifelse` expression that uses the boolean variable got in the
/// second instruction as the condition.
// - The true block of the above `ifelse` expression doesn't contain `exit_loop`.
// - The false block of the above `ifelse` expression only contains `exit_loop`.
/// @param loop the Loop variable to investigate.
/// @param loop_control_variable the loop control variable to investigate.
/// @returns the pointer of the binary operation that compares the loop control variable with
/// its limitations in the body block of the loop if the loop meets the below requirements,
/// return nullptr otherwise.
const Binary* GetBinaryToCompareLoopControlVariableInLoopBodyForTest(
const Loop* loop,
const Var* loop_control_variable);
private:
IntegerRangeAnalysis(const IntegerRangeAnalysis&) = delete;
IntegerRangeAnalysis(IntegerRangeAnalysis&&) = delete;
std::unique_ptr<IntegerRangeAnalysisImpl> impl_;
};
} // namespace tint::core::ir::analysis
#endif // SRC_TINT_LANG_CORE_IR_ANALYSIS_INTEGER_RANGE_ANALYSIS_H_