Make use of the instruction folder.
[platform/upstream/SPIRV-Tools.git] / source / opt / fold.h
1 // Copyright (c) 2017 Google Inc.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //     http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
15 #ifndef LIBSPIRV_UTIL_FOLD_H_
16 #define LIBSPIRV_UTIL_FOLD_H_
17
18 #include <cstdint>
19 #include <vector>
20
21 #include "constants.h"
22 #include "def_use_manager.h"
23
24 namespace spvtools {
25 namespace opt {
26
27 // Returns the result of folding a scalar instruction with the given |opcode|
28 // and |operands|. Each entry in |operands| is a pointer to an
29 // analysis::Constant instance, which should've been created with the constant
30 // manager (See IRContext::get_constant_mgr).
31 //
32 // It is an error to call this function with an opcode that does not pass the
33 // IsFoldableOpcode test. If any error occurs during folding, the folder will
34 // faill with a call to assert.
35 uint32_t FoldScalars(SpvOp opcode,
36                      const std::vector<const analysis::Constant*>& operands);
37
38 // Returns the result of performing an operation with the given |opcode| over
39 // constant vectors with |num_dims| dimensions.  Each entry in |operands| is a
40 // pointer to an analysis::Constant instance, which should've been created with
41 // the constant manager (See IRContext::get_constant_mgr).
42 //
43 // This function iterates through the given vector type constant operands and
44 // calculates the result for each element of the result vector to return.
45 // Vectors with longer than 32-bit scalar components are not accepted in this
46 // function.
47 //
48 // It is an error to call this function with an opcode that does not pass the
49 // IsFoldableOpcode test. If any error occurs during folding, the folder will
50 // faill with a call to assert.
51 std::vector<uint32_t> FoldVectors(
52     SpvOp opcode, uint32_t num_dims,
53     const std::vector<const analysis::Constant*>& operands);
54
55 // Returns true if |opcode| represents an operation handled by FoldScalars or
56 // FoldVectors.
57 bool IsFoldableOpcode(SpvOp opcode);
58
59 // Returns true if |cst| is supported by FoldScalars and FoldVectors.
60 bool IsFoldableConstant(const analysis::Constant* cst);
61
62 // Returns true if |FoldInstructionToConstant| could fold an instruction whose
63 // result type is |type_inst|.
64 bool IsFoldableType(ir::Instruction* type_inst);
65
66 // Tries to fold |inst| to a single constant, when the input ids to |inst| have
67 // been substituted using |id_map|.  Returns a pointer to the OpConstant*
68 // instruction if successful.  If necessary, a new constant instruction is
69 // created and placed in the global values section.
70 //
71 // |id_map| is a function that takes one result id and returns another.  It can
72 // be used for things like CCP where it is known that some ids contain a
73 // constant, but the instruction itself has not been updated yet.  This can map
74 // those ids to the appropriate constants.
75 ir::Instruction* FoldInstructionToConstant(
76     ir::Instruction* inst, std::function<uint32_t(uint32_t)> id_map);
77
78 // Returns true if |inst| can be folded into a simpler instruction.
79 // If |inst| can be simplified, |inst| is overwritten with the simplified
80 // instruction reusing the same result id.
81 //
82 // If |inst| is simplified, it is possible that the resulting code in invalid
83 // because the instruction is in a bad location.  Callers of this function have
84 // to handle the following cases:
85 //
86 // 1) An OpPhi becomes and OpCopyObject - If there are OpPhi instruction after
87 //    |inst| in a basic block then this is invalid.  The caller must fix this
88 //    up.
89 bool FoldInstruction(ir::Instruction* inst);
90
91 }  // namespace opt
92 }  // namespace spvtools
93
94 #endif  // LIBSPIRV_UTIL_FOLD_H_