1// Copyright (c) 2019 Valve Corporation
2// Copyright (c) 2019 LunarG Inc.
3//
4// Licensed under the Apache License, Version 2.0 (the "License");
5// you may not use this file except in compliance with the License.
6// You may obtain a copy of the License at
7//
8// http://www.apache.org/licenses/LICENSE-2.0
9//
10// Unless required by applicable law or agreed to in writing, software
11// distributed under the License is distributed on an "AS IS" BASIS,
12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13// See the License for the specific language governing permissions and
14// limitations under the License.
15
16#ifndef LIBSPIRV_OPT_RELAX_FLOAT_OPS_PASS_H_
17#define LIBSPIRV_OPT_RELAX_FLOAT_OPS_PASS_H_
18
19#include "source/opt/ir_builder.h"
20#include "source/opt/pass.h"
21
22namespace spvtools {
23namespace opt {
24
25class RelaxFloatOpsPass : public Pass {
26 public:
27 RelaxFloatOpsPass() : Pass() {}
28
29 ~RelaxFloatOpsPass() override = default;
30
31 IRContext::Analysis GetPreservedAnalyses() override {
32 return IRContext::kAnalysisDefUse | IRContext::kAnalysisInstrToBlockMapping;
33 }
34
35 // See optimizer.hpp for pass user documentation.
36 Status Process() override;
37
38 const char* name() const override { return "convert-to-half-pass"; }
39
40 private:
41 // Return true if |inst| can have the RelaxedPrecision decoration applied
42 // to it.
43 bool IsRelaxable(Instruction* inst);
44
45 // Return true if |inst| returns scalar, vector or matrix type with base
46 // float and width 32
47 bool IsFloat32(Instruction* inst);
48
49 // Return true if |r_id| is decorated with RelaxedPrecision
50 bool IsRelaxed(uint32_t r_id);
51
52 // If |inst| is an instruction of float32-based type and is not decorated
53 // RelaxedPrecision, add such a decoration to the module.
54 bool ProcessInst(Instruction* inst);
55
56 // Call ProcessInst on every instruction in |func|.
57 bool ProcessFunction(Function* func);
58
59 Pass::Status ProcessImpl();
60
61 // Initialize state for converting to half
62 void Initialize();
63
64 // Set of float result core operations to be processed
65 std::unordered_set<uint32_t> target_ops_core_f_rslt_;
66
67 // Set of float operand core operations to be processed
68 std::unordered_set<uint32_t> target_ops_core_f_opnd_;
69
70 // Set of 450 extension operations to be processed
71 std::unordered_set<uint32_t> target_ops_450_;
72
73 // Set of sample operations
74 std::unordered_set<uint32_t> sample_ops_;
75};
76
77} // namespace opt
78} // namespace spvtools
79
80#endif // LIBSPIRV_OPT_RELAX_FLOAT_OPS_PASS_H_
81