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