chromium/third_party/spirv-tools/src/source/opt/const_folding_rules.cpp

// Copyright (c) 2018 Google LLC
//
// 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.

#include "source/opt/const_folding_rules.h"

#include "source/opt/ir_context.h"

namespace spvtools {
namespace opt {
namespace {
constexpr uint32_t kExtractCompositeIdInIdx =;

// Returns a constants with the value NaN of the given type.  Only works for
// 32-bit and 64-bit float point types.  Returns |nullptr| if an error occurs.
const analysis::Constant* GetNan(const analysis::Type* type,
                                 analysis::ConstantManager* const_mgr) {}

// Returns a constants with the value INF of the given type.  Only works for
// 32-bit and 64-bit float point types.  Returns |nullptr| if an error occurs.
const analysis::Constant* GetInf(const analysis::Type* type,
                                 analysis::ConstantManager* const_mgr) {}

// Returns true if |type| is Float or a vector of Float.
bool HasFloatingPoint(const analysis::Type* type) {}

// Returns a constants with the value |-val| of the given type.  Only works for
// 32-bit and 64-bit float point types.  Returns |nullptr| if an error occurs.
const analysis::Constant* NegateFPConst(const analysis::Type* result_type,
                                        const analysis::Constant* val,
                                        analysis::ConstantManager* const_mgr) {}

// Returns a constants with the value |-val| of the given type.
const analysis::Constant* NegateIntConst(const analysis::Type* result_type,
                                         const analysis::Constant* val,
                                         analysis::ConstantManager* const_mgr) {}

// Folds an OpcompositeExtract where input is a composite constant.
ConstantFoldingRule FoldExtractWithConstants() {}

// Folds an OpcompositeInsert where input is a composite constant.
ConstantFoldingRule FoldInsertWithConstants() {}

ConstantFoldingRule FoldVectorShuffleWithConstants() {}

ConstantFoldingRule FoldVectorTimesScalar() {}

// Returns to the constant that results from tranposing |matrix|. The result
// will have type |result_type|, and |matrix| must exist in |context|. The
// result constant will also exist in |context|.
const analysis::Constant* TransposeMatrix(const analysis::Constant* matrix,
                                          analysis::Matrix* result_type,
                                          IRContext* context) {}

const analysis::Constant* FoldTranspose(
    IRContext* context, Instruction* inst,
    const std::vector<const analysis::Constant*>& constants) {}

ConstantFoldingRule FoldVectorTimesMatrix() {}

ConstantFoldingRule FoldMatrixTimesVector() {}

ConstantFoldingRule FoldCompositeWithConstants() {}

// The interface for a function that returns the result of applying a scalar
// floating-point binary operation on |a| and |b|.  The type of the return value
// will be |type|.  The input constants must also be of type |type|.
UnaryScalarFoldingRule;

// The interface for a function that returns the result of applying a scalar
// floating-point binary operation on |a| and |b|.  The type of the return value
// will be |type|.  The input constants must also be of type |type|.
BinaryScalarFoldingRule;

// Returns a |ConstantFoldingRule| that folds unary scalar ops
// using |scalar_rule| and unary vectors ops by applying
// |scalar_rule| to the elements of the vector.  The |ConstantFoldingRule|
// that is returned assumes that |constants| contains 1 entry.  If they are
// not |nullptr|, then their type is either |Float| or |Integer| or a |Vector|
// whose element type is |Float| or |Integer|.
ConstantFoldingRule FoldUnaryOp(UnaryScalarFoldingRule scalar_rule) {}

// Returns a |ConstantFoldingRule| that folds binary scalar ops
// using |scalar_rule| and binary vectors ops by applying
// |scalar_rule| to the elements of the vector. The folding rule assumes that op
// has two inputs. For regular instruction, those are in operands 0 and 1. For
// extended instruction, they are in operands 1 and 2. If an element in
// |constants| is not nullprt, then the constant's type is |Float|, |Integer|,
// or |Vector| whose element type is |Float| or |Integer|.
ConstantFoldingRule FoldBinaryOp(BinaryScalarFoldingRule scalar_rule) {}

// Returns a |ConstantFoldingRule| that folds unary floating point scalar ops
// using |scalar_rule| and unary float point vectors ops by applying
// |scalar_rule| to the elements of the vector.  The |ConstantFoldingRule|
// that is returned assumes that |constants| contains 1 entry.  If they are
// not |nullptr|, then their type is either |Float| or |Integer| or a |Vector|
// whose element type is |Float| or |Integer|.
ConstantFoldingRule FoldFPUnaryOp(UnaryScalarFoldingRule scalar_rule) {}

// Returns the result of folding the constants in |constants| according the
// |scalar_rule|.  If |result_type| is a vector, then |scalar_rule| is applied
// per component.
const analysis::Constant* FoldFPBinaryOp(
    BinaryScalarFoldingRule scalar_rule, uint32_t result_type_id,
    const std::vector<const analysis::Constant*>& constants,
    IRContext* context) {}

// Returns a |ConstantFoldingRule| that folds floating point scalars using
// |scalar_rule| and vectors of floating point by applying |scalar_rule| to the
// elements of the vector.  The |ConstantFoldingRule| that is returned assumes
// that |constants| contains 2 entries.  If they are not |nullptr|, then their
// type is either |Float| or a |Vector| whose element type is |Float|.
ConstantFoldingRule FoldFPBinaryOp(BinaryScalarFoldingRule scalar_rule) {}

// This macro defines a |UnaryScalarFoldingRule| that performs float to
// integer conversion.
// TODO(greg-lunarg): Support for 64-bit integer types.
UnaryScalarFoldingRule FoldFToIOp() {}

// This function defines a |UnaryScalarFoldingRule| that performs integer to
// float conversion.
// TODO(greg-lunarg): Support for 64-bit integer types.
UnaryScalarFoldingRule FoldIToFOp() {}

// This defines a |UnaryScalarFoldingRule| that performs |OpQuantizeToF16|.
UnaryScalarFoldingRule FoldQuantizeToF16Scalar() {}

// This macro defines a |BinaryScalarFoldingRule| that applies |op|.  The
// operator |op| must work for both float and double, and use syntax "f1 op f2".
#define FOLD_FPARITH_OP(op)

// Define the folding rule for conversion between floating point and integer
ConstantFoldingRule FoldFToI() {}
ConstantFoldingRule FoldIToF() {}
ConstantFoldingRule FoldQuantizeToF16() {}

// Define the folding rules for subtraction, addition, multiplication, and
// division for floating point values.
ConstantFoldingRule FoldFSub() {}
ConstantFoldingRule FoldFAdd() {}
ConstantFoldingRule FoldFMul() {}

// Returns the constant that results from evaluating |numerator| / 0.0.  Returns
// |nullptr| if the result could not be evaluated.
const analysis::Constant* FoldFPScalarDivideByZero(
    const analysis::Type* result_type, const analysis::Constant* numerator,
    analysis::ConstantManager* const_mgr) {}

// Returns the result of folding |numerator| / |denominator|.  Returns |nullptr|
// if it cannot be folded.
const analysis::Constant* FoldScalarFPDivide(
    const analysis::Type* result_type, const analysis::Constant* numerator,
    const analysis::Constant* denominator,
    analysis::ConstantManager* const_mgr) {}

// Returns the constant folding rule to fold |OpFDiv| with two constants.
ConstantFoldingRule FoldFDiv() {}

bool CompareFloatingPoint(bool op_result, bool op_unordered,
                          bool need_ordered) {}

// This macro defines a |BinaryScalarFoldingRule| that applies |op|.  The
// operator |op| must work for both float and double, and use syntax "f1 op f2".
#define FOLD_FPCMP_OP(op, ord)

// Define the folding rules for ordered and unordered comparison for floating
// point values.
ConstantFoldingRule FoldFOrdEqual() {}
ConstantFoldingRule FoldFUnordEqual() {}
ConstantFoldingRule FoldFOrdNotEqual() {}
ConstantFoldingRule FoldFUnordNotEqual() {}
ConstantFoldingRule FoldFOrdLessThan() {}
ConstantFoldingRule FoldFUnordLessThan() {}
ConstantFoldingRule FoldFOrdGreaterThan() {}
ConstantFoldingRule FoldFUnordGreaterThan() {}
ConstantFoldingRule FoldFOrdLessThanEqual() {}
ConstantFoldingRule FoldFUnordLessThanEqual() {}
ConstantFoldingRule FoldFOrdGreaterThanEqual() {}
ConstantFoldingRule FoldFUnordGreaterThanEqual() {}

// Folds an OpDot where all of the inputs are constants to a
// constant.  A new constant is created if necessary.
ConstantFoldingRule FoldOpDotWithConstants() {}

ConstantFoldingRule FoldFNegate() {}
ConstantFoldingRule FoldSNegate() {}

ConstantFoldingRule FoldFClampFeedingCompare(spv::Op cmp_opcode) {}

ConstantFoldingRule FoldFMix() {}

const analysis::Constant* FoldMin(const analysis::Type* result_type,
                                  const analysis::Constant* a,
                                  const analysis::Constant* b,
                                  analysis::ConstantManager*) {}

const analysis::Constant* FoldMax(const analysis::Type* result_type,
                                  const analysis::Constant* a,
                                  const analysis::Constant* b,
                                  analysis::ConstantManager*) {}

// Fold an clamp instruction when all three operands are constant.
const analysis::Constant* FoldClamp1(
    IRContext* context, Instruction* inst,
    const std::vector<const analysis::Constant*>& constants) {}

// Fold a clamp instruction when |x <= min_val|.
const analysis::Constant* FoldClamp2(
    IRContext* context, Instruction* inst,
    const std::vector<const analysis::Constant*>& constants) {}

// Fold a clamp instruction when |x >= max_val|.
const analysis::Constant* FoldClamp3(
    IRContext* context, Instruction* inst,
    const std::vector<const analysis::Constant*>& constants) {}

UnaryScalarFoldingRule FoldFTranscendentalUnary(double (*fp)(double)) {}

BinaryScalarFoldingRule FoldFTranscendentalBinary(double (*fp)(double,
                                                               double)) {}

enum Sign {};

// Returns a BinaryScalarFoldingRule that applies `op` to the scalars.
// The `signedness` is used to determine if the operands should be interpreted
// as signed or unsigned. If the operands are signed, the value will be sign
// extended before the value is passed to `op`. Otherwise the values will be
// zero extended.
template <Sign signedness>
BinaryScalarFoldingRule FoldBinaryIntegerOperation(uint64_t (*op)(uint64_t,
                                                                  uint64_t)) {}

// A scalar folding rule that folds OpSConvert.
const analysis::Constant* FoldScalarSConvert(
    const analysis::Type* result_type, const analysis::Constant* a,
    analysis::ConstantManager* const_mgr) {}

// A scalar folding rule that folds OpUConvert.
const analysis::Constant* FoldScalarUConvert(
    const analysis::Type* result_type, const analysis::Constant* a,
    analysis::ConstantManager* const_mgr) {}
}  // namespace

void ConstantFoldingRules::AddFoldingRules() {}
}  // namespace opt
}  // namespace spvtools