blob: 63a77bd4ca389115193e536a33d2a0e6ec0ef29a [file] [log] [blame]
// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
#ifndef RUNTIME_VM_COMPILER_BACKEND_FLOW_GRAPH_CHECKER_H_
#define RUNTIME_VM_COMPILER_BACKEND_FLOW_GRAPH_CHECKER_H_
#if !defined(DART_PRECOMPILED_RUNTIME)
#if defined(DEBUG)
#include "vm/compiler/backend/flow_graph.h"
#include "vm/compiler/backend/il.h"
namespace dart {
// Class responsible for performing sanity checks on the flow graph.
// The intended use is running the checks after each compiler pass
// in debug mode in order to detect graph inconsistencies as soon
// as possible. This way, culprit passes are more easily identified.
//
// All important assumptions on the flow graph structure that can be
// verified in reasonable time should be made explicit in this pass
// so that we no longer rely on asserts that are dispersed throughout
// the passes or, worse, unwritten assumptions once agreed upon but
// so easily forgotten. Since the graph checker runs only in debug
// mode, it is acceptable to perform slightly elaborate tests.
class FlowGraphChecker : public FlowGraphVisitor {
public:
// Constructs graph checker. The checker uses some custom-made
// visitation to perform additional checks, and uses the
// FlowGraphVisitor structure for anything else.
explicit FlowGraphChecker(FlowGraph* flow_graph)
: FlowGraphVisitor(flow_graph->preorder()),
flow_graph_(flow_graph),
current_block_(nullptr) {}
// Performs a sanity check on the flow graph.
void Check(const char* pass_name);
private:
// Custom-made visitors.
void VisitBlocks() override;
void VisitInstructions(BlockEntryInstr* block);
void VisitInstruction(Instruction* instruction);
void VisitDefinition(Definition* def);
void VisitUseDef(Instruction* instruction,
Value* use,
intptr_t index,
bool is_env);
void VisitDefUse(Definition* def, Value* use, Value* prev, bool is_env);
// Instruction visitors.
void VisitConstant(ConstantInstr* constant) override;
void VisitPhi(PhiInstr* phi) override;
void VisitGoto(GotoInstr* jmp) override;
void VisitIndirectGoto(IndirectGotoInstr* jmp) override;
void VisitBranch(BranchInstr* branch) override;
void VisitRedefinition(RedefinitionInstr* def) override;
void VisitInstanceCall(InstanceCallInstr* instr) override;
void VisitPolymorphicInstanceCall(
PolymorphicInstanceCallInstr* instr) override;
FlowGraph* const flow_graph_;
BlockEntryInstr* current_block_;
};
} // namespace dart
#endif // defined(DEBUG)
#endif // !defined(DART_PRECOMPILED_RUNTIME)
#endif // RUNTIME_VM_COMPILER_BACKEND_FLOW_GRAPH_CHECKER_H_