1// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
2// for details. All rights reserved. Use of this source code is governed by a
3// BSD-style license that can be found in the LICENSE file.
4
5#ifndef RUNTIME_VM_COMPILER_BACKEND_FLOW_GRAPH_CHECKER_H_
6#define RUNTIME_VM_COMPILER_BACKEND_FLOW_GRAPH_CHECKER_H_
7
8#if defined(DART_PRECOMPILED_RUNTIME)
9#error "AOT runtime should not use compiler sources (including header files)"
10#endif // defined(DART_PRECOMPILED_RUNTIME)
11
12#if defined(DEBUG)
13
14#include "vm/compiler/backend/flow_graph.h"
15#include "vm/compiler/backend/il.h"
16
17namespace dart {
18
19// Class responsible for performing sanity checks on the flow graph.
20// The intended use is running the checks after each compiler pass
21// in debug mode in order to detect graph inconsistencies as soon
22// as possible. This way, culprit passes are more easily identified.
23//
24// All important assumptions on the flow graph structure that can be
25// verified in reasonable time should be made explicit in this pass
26// so that we no longer rely on asserts that are dispersed throughout
27// the passes or, worse, unwritten assumptions once agreed upon but
28// so easily forgotten. Since the graph checker runs only in debug
29// mode, it is acceptable to perform slightly elaborate tests.
30class FlowGraphChecker : public FlowGraphVisitor {
31 public:
32 // Constructs graph checker. The checker uses some custom-made
33 // visitation to perform additional checks, and uses the
34 // FlowGraphVisitor structure for anything else.
35 explicit FlowGraphChecker(FlowGraph* flow_graph)
36 : FlowGraphVisitor(flow_graph->preorder()),
37 flow_graph_(flow_graph),
38 current_block_(nullptr) {}
39
40 // Performs a sanity check on the flow graph.
41 void Check(const char* pass_name);
42
43 private:
44 // Custom-made visitors.
45 void VisitBlocks() override;
46 void VisitInstructions(BlockEntryInstr* block);
47 void VisitInstruction(Instruction* instruction);
48 void VisitDefinition(Definition* def);
49 void VisitUseDef(Instruction* instruction,
50 Value* use,
51 intptr_t index,
52 bool is_env);
53 void VisitDefUse(Definition* def, Value* use, Value* prev, bool is_env);
54
55 // Instruction visitors.
56 void VisitConstant(ConstantInstr* constant) override;
57 void VisitPhi(PhiInstr* phi) override;
58 void VisitGoto(GotoInstr* jmp) override;
59 void VisitIndirectGoto(IndirectGotoInstr* jmp) override;
60 void VisitBranch(BranchInstr* branch) override;
61 void VisitRedefinition(RedefinitionInstr* def) override;
62 void VisitClosureCall(ClosureCallInstr* call) override;
63 void VisitStaticCall(StaticCallInstr* call) override;
64 void VisitInstanceCall(InstanceCallInstr* call) override;
65 void VisitPolymorphicInstanceCall(
66 PolymorphicInstanceCallInstr* call) override;
67
68 FlowGraph* const flow_graph_;
69 BlockEntryInstr* current_block_;
70};
71
72} // namespace dart
73
74#endif // defined(DEBUG)
75
76#endif // RUNTIME_VM_COMPILER_BACKEND_FLOW_GRAPH_CHECKER_H_
77