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#include "compiler/optimizer/ir/graph_visitor.h" 17#include "compiler/optimizer/ir/graph.h" 18 19namespace panda::compiler { 20 21class InstChecker : public GraphVisitor { 22public: 23 explicit InstChecker(const Graph *graph) : graph_(graph) {} 24 25 const ArenaVector<BasicBlock *> &GetBlocksToVisit() const override 26 { 27 return graph_->GetBlocksRPO(); 28 } 29 30 template<typename... Args> 31 static bool CheckType(DataType::Type type, Args... types) { 32 return ((types == type) || ...); 33 } 34 35 static DataType::Type GetInputType(Inst* inst, size_t input) 36 { 37 return inst->GetInput(input).GetInst()->GetType(); 38 } 39 40 static void Run(const Graph *graph) 41 { 42 InstChecker(graph).VisitGraph(); 43 } 44 45% IR::instructions.each do |inst| 46 static void Visit<%= inst.opcode %>([[maybe_unused]] GraphVisitor *v, [[maybe_unused]] Inst *inst) 47 { 48% if !inst.has_dst? 49 ASSERT(!inst->HasUsers()); 50% elsif !inst.dst.pseudo? 51 ASSERT_DO(CheckType(inst->GetType(), <%= inst.dst.types.map { |x| Operand::cpp_type(x) }.join(', ') %>), 52 std::cerr << "Wrong dst type '" << DataType::ToString(inst->GetType()) << "' for inst:\n" << *inst << std::endl); 53% end 54% if inst.inputs.any? { |x| x.is_dyn? } 55 } 56% next 57% end 58 CHECK_EQ(inst->GetInputsCount(), <%= inst.inputs.size %>U); 59% inst.inputs.each_with_index do |operand, i| 60% if operand.has('save_state') 61 ASSERT(inst->GetInput(<%= i %>).GetInst()->IsSaveState()); 62% else 63 ASSERT_DO(CheckType(GetInputType(inst, <%= i %>), <%= operand.types.map { |x| Operand::cpp_type(x) }.join(', ') %>), 64 std::cerr << "Wrong input <%= i %> type '" << DataType::ToString(GetInputType(inst, <%= i %>)) << "' for inst:\n" << *inst << std::endl); 65% end 66% end 67 } 68% end 69 70#include "optimizer/ir/visitor.inc" 71 72private: 73 const Graph *graph_{nullptr}; 74}; 75 76} // namespace panda::compiler 77