• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**
2  * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
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 
16 #ifndef COMPILER_OPTIMIZER_IR_GRAPH_VISITOR_H
17 #define COMPILER_OPTIMIZER_IR_GRAPH_VISITOR_H
18 
19 #include "opcodes.h"
20 #include "basicblock.h"
21 
22 namespace panda::compiler {
23 class Graph;
24 /*
25  * Base visitor class.
26  *
27  * Usage example:
28  *
29  * struct ExampleVisitor: public GraphVisitor {
30  *     using GraphVisitor::GraphVisitor;
31  *
32  *     // Specify blocks to visit and their order
33  *     const ArenaVector<BasicBlock *> &GetBlocksToVisit() const override
34  *     {
35  *         return GetGraph()->GetBlocksRPO();
36  *     }
37  *     // Print special message for Mul instruction
38  *     static void VisitMul(GraphVisitor* v, Inst* inst) {
39  *         std::cerr << "Multiply instruction\n";
40  *     }
41  *     // For all other instructions print its opcode
42  *     void VisitDefault(Inst* inst) override {
43  *         std::cerr << GetOpcodeString(inst->GetOpcode()) << std::endl;
44  *     }
45  *     // Visitor for all instructions which are the instance of the BinaryOperation
46  *     void VisitInst(BinaryOperation* inst) override {
47  *         std::cerr << "Visit binary operation\n";
48  *     }
49  *     #include "visitor.inc"
50  * };
51  *
52  */
53 class GraphVisitor {
54 public:
55     explicit GraphVisitor() = default;
56     virtual ~GraphVisitor() = default;
57 
58     /**
59      * Specify the order of visiting the blocks.
60      * Should return a vector of graph's blocks, for example it could be obtained
61      * from `GetGraph()->GetBlocksRPO()`.
62      */
63     virtual const ArenaVector<BasicBlock *> &GetBlocksToVisit() const = 0;
64 
65     virtual void VisitGraph() = 0;
66     virtual uint64_t VisitGraphAndCount() = 0;
67     virtual void VisitBlock(BasicBlock *bb) = 0;
68     virtual void VisitInstruction(Inst *inst) = 0;
69 
70 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
71 #define GROUP_DEF(BASE) \
72     virtual void VisitInst([[maybe_unused]] BASE *i) {}
73     OPCODE_CLASS_LIST(GROUP_DEF)
74 #undef GROUP_DEF
75 
76     NO_COPY_SEMANTIC(GraphVisitor);
77     NO_MOVE_SEMANTIC(GraphVisitor);
78 
79 protected:
80     using VisitFunc = void (*)(GraphVisitor *, Inst *);
81 
82     /**
83      * Method that will be called if derived class doesn't set handler for opcode
84      */
VisitDefault(Inst * inst)85     virtual void VisitDefault([[maybe_unused]] Inst *inst) {}
86 
87 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
88 #define INST_DEF(OPCODE, ...)                           \
89     static void Visit##OPCODE(GraphVisitor *v, Inst *i) \
90     {                                                   \
91         v->VisitDefault(i);                             \
92     }
93     OPCODE_LIST(INST_DEF)
94 #undef INST_DEF
95 
96     /*
97      * `visitor.inc` include must be in the end of all Visitor classes.
98      * It defines following:
99      * - VisitGraph() method, that aims to iterate over graph.
100      * - VisitBlock() method, that aims to iterate over given basic block.
101      * - VisitFunc table_ - list of methods for all opcodes.
102      */
103 };
104 }  // namespace panda::compiler
105 
106 #endif  // COMPILER_OPTIMIZER_IR_GRAPH_VISITOR_H
107