• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2018 Google LLC
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 SOURCE_OPT_FOLDING_RULES_H_
16 #define SOURCE_OPT_FOLDING_RULES_H_
17 
18 #include <cstdint>
19 #include <unordered_map>
20 #include <vector>
21 
22 #include "source/opt/constants.h"
23 
24 namespace spvtools {
25 namespace opt {
26 
27 // Folding Rules:
28 //
29 // The folding mechanism is built around the concept of a |FoldingRule|.  A
30 // folding rule is a function that implements a method of simplifying an
31 // instruction.
32 //
33 // The inputs to a folding rule are:
34 //     |inst| - the instruction to be simplified.
35 //     |constants| - if an in-operands is an id of a constant, then the
36 //                   corresponding value in |constants| contains that
37 //                   constant value.  Otherwise, the corresponding entry in
38 //                   |constants| is |nullptr|.
39 //
40 // A folding rule returns true if |inst| can be simplified using this rule.  If
41 // the instruction can be simplified, then |inst| is changed to the simplified
42 // instruction.  Otherwise, |inst| remains the same.
43 //
44 // See folding_rules.cpp for examples on how to write a folding rule.  It is
45 // important to note that if |inst| can be folded to the result of an
46 // instruction that feed it, then |inst| should be changed to an OpCopyObject
47 // that copies that id.
48 //
49 // Be sure to add new folding rules to the table of folding rules in the
50 // constructor for FoldingRules.  The new rule should be added to the list for
51 // every opcode that it applies to.  Note that earlier rules in the list are
52 // given priority.  That is, if an earlier rule is able to fold an instruction,
53 // the later rules will not be attempted.
54 
55 using FoldingRule = std::function<bool(
56     IRContext* context, Instruction* inst,
57     const std::vector<const analysis::Constant*>& constants)>;
58 
59 class FoldingRules {
60  public:
61   FoldingRules();
62 
GetRulesForOpcode(SpvOp opcode)63   const std::vector<FoldingRule>& GetRulesForOpcode(SpvOp opcode) const {
64     auto it = rules_.find(opcode);
65     if (it != rules_.end()) {
66       return it->second;
67     }
68     return empty_vector_;
69   }
70 
71  private:
72   std::unordered_map<uint32_t, std::vector<FoldingRule>> rules_;
73   std::vector<FoldingRule> empty_vector_;
74 };
75 
76 }  // namespace opt
77 }  // namespace spvtools
78 
79 #endif  // SOURCE_OPT_FOLDING_RULES_H_
80