• 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#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