// Copyright (c) 2019 Valve Corporation
// Copyright (c) 2019 LunarG Inc.
//
// 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 LIBSPIRV_OPT_CONVERT_TO_HALF_PASS_H_
#define LIBSPIRV_OPT_CONVERT_TO_HALF_PASS_H_

#include "source/opt/ir_builder.h"
#include "source/opt/pass.h"

namespace spvtools {
namespace opt {

class ConvertToHalfPass : public Pass {
 public:
  ConvertToHalfPass() : Pass() {}

  ~ConvertToHalfPass() override = default;

  IRContext::Analysis GetPreservedAnalyses() override {
    return IRContext::kAnalysisDefUse | IRContext::kAnalysisInstrToBlockMapping;
  }

  // See optimizer.hpp for pass user documentation.
  Status Process() override;

  const char* name() const override { return "convert-to-half-pass"; }

 private:
  // Return true if |inst| is an arithmetic, composite or phi op that can be
  // of type float16
  bool IsArithmetic(Instruction* inst);

  // Return true if |inst| returns scalar, vector or matrix type with base
  // float and |width|
  bool IsFloat(Instruction* inst, uint32_t width);

  // Return true if |inst| is decorated with RelaxedPrecision
  bool IsDecoratedRelaxed(Instruction* inst);

  // Return true if |id| has been added to the relaxed id set
  bool IsRelaxed(uint32_t id);

  // Add |id| to the relaxed id set
  void AddRelaxed(uint32_t id);

  // Return type id for float with |width|
  analysis::Type* FloatScalarType(uint32_t width);

  // Return type id for vector of length |vlen| of float of |width|
  analysis::Type* FloatVectorType(uint32_t v_len, uint32_t width);

  // Return type id for matrix of |v_cnt| vectors of length identical to
  // |vty_id| of float of |width|
  analysis::Type* FloatMatrixType(uint32_t v_cnt, uint32_t vty_id,
                                  uint32_t width);

  // Return equivalent to float type |ty_id| with |width|
  uint32_t EquivFloatTypeId(uint32_t ty_id, uint32_t width);

  // Append instructions to builder to convert value |*val_idp| to type
  // |ty_id| but with |width|. Set |*val_idp| to the new id.
  void GenConvert(uint32_t* val_idp, uint32_t width, Instruction* inst);

  // Remove RelaxedPrecision decoration of |id|.
  bool RemoveRelaxedDecoration(uint32_t id);

  // Add |inst| to relaxed instruction set if warranted. Specifically, if
  // it is float32 and either decorated relaxed or a composite or phi
  // instruction where all operands are relaxed or all uses are relaxed.
  bool CloseRelaxInst(Instruction* inst);

  // If |inst| is an arithmetic, phi, extract or convert instruction of float32
  // base type and decorated with RelaxedPrecision, change it to the equivalent
  // float16 based type instruction. Specifically, insert instructions to
  // convert all operands to float16 (if needed) and change its type to the
  // equivalent float16 type. Otherwise, insert instructions to convert its
  // operands back to their original types, if needed.
  bool GenHalfInst(Instruction* inst);

  // Gen code for relaxed arithmetic |inst|
  bool GenHalfArith(Instruction* inst);

  // Gen code for relaxed phi |inst|
  bool ProcessPhi(Instruction* inst);

  // Gen code for relaxed convert |inst|
  bool ProcessConvert(Instruction* inst);

  // Gen code for image reference |inst|
  bool ProcessImageRef(Instruction* inst);

  // Process default non-relaxed |inst|
  bool ProcessDefault(Instruction* inst);

  // If |inst| is an FConvert of a matrix type, decompose it to a series
  // of vector extracts, converts and inserts into an Undef. These are
  // generated by GenHalfInst because they are easier to manipulate, but are
  // invalid so we need to clean them up.
  bool MatConvertCleanup(Instruction* inst);

  // Call GenHalfInst on every instruction in |func|.
  // If code is generated for an instruction, replace the instruction
  // with the new instructions that are generated.
  bool ProcessFunction(Function* func);

  Pass::Status ProcessImpl();

  // Initialize state for converting to half
  void Initialize();

  // Set of core operations to be processed
  std::unordered_set<uint32_t> target_ops_core_;

  // Set of 450 extension operations to be processed
  std::unordered_set<uint32_t> target_ops_450_;

  // Set of sample operations
  std::unordered_set<uint32_t> image_ops_;

  // Set of dref sample operations
  std::unordered_set<uint32_t> dref_image_ops_;

  // Set of dref sample operations
  std::unordered_set<uint32_t> closure_ops_;

  // Set of ids of all relaxed instructions
  std::unordered_set<uint32_t> relaxed_ids_set_;

  // Ids of all converted instructions
  std::unordered_set<uint32_t> converted_ids_;
};

}  // namespace opt
}  // namespace spvtools

#endif  // LIBSPIRV_OPT_CONVERT_TO_HALF_PASS_H_
