1//===- CFGBuilder.h - CFG building and updating utility ----------*- C++ -*-==//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8/// \file
9/// CFGBuilders provides utilities fo building and updating CFG for testing
10/// purposes.
11///
12//===----------------------------------------------------------------------===//
13
14#ifndef LLVM_UNITTESTS_CFG_BUILDER_H
15#define LLVM_UNITTESTS_CFG_BUILDER_H
16
17#include "llvm/ADT/StringMap.h"
18#include "llvm/ADT/StringRef.h"
19#include "llvm/Support/Debug.h"
20
21#include <memory>
22#include <optional>
23#include <set>
24#include <tuple>
25#include <vector>
26
27namespace llvm {
28
29class LLVMContext;
30class Module;
31class Function;
32class BasicBlock;
33class raw_ostream;
34
35struct CFGHolder {
36 std::unique_ptr<LLVMContext> Context;
37 std::unique_ptr<Module> M;
38 Function *F;
39
40 CFGHolder(StringRef ModuleName = "m", StringRef FunctionName = "foo");
41 ~CFGHolder(); // Defined in the .cpp file so we can use forward declarations.
42};
43
44/// \brief
45/// CFGBuilder builds IR with specific CFG, based on the supplied list of arcs.
46/// It's able to apply the provided updates and automatically modify the IR.
47///
48/// Internally it makes every basic block end with either SwitchInst or with
49/// UnreachableInst. When all arc to a BB are deleted, the BB remains in the
50/// function and doesn't get deleted.
51///
52class CFGBuilder {
53public:
54 struct Arc {
55 StringRef From;
56 StringRef To;
57
58 friend bool operator<(const Arc &LHS, const Arc &RHS) {
59 return std::tie(args: LHS.From, args: LHS.To) <
60 std::tie(args: RHS.From, args: RHS.To);
61 }
62 };
63
64 enum class ActionKind { Insert, Delete };
65 struct Update {
66 ActionKind Action;
67 Arc Edge;
68 };
69
70 CFGBuilder(Function *F, const std::vector<Arc> &InitialArcs,
71 std::vector<Update> Updates);
72
73 BasicBlock *getOrAddBlock(StringRef BlockName);
74 std::optional<Update> getNextUpdate() const;
75 std::optional<Update> applyUpdate();
76 void dump(raw_ostream &OS = dbgs()) const;
77
78private:
79 void buildCFG(const std::vector<Arc> &Arcs);
80 bool connect(const Arc &A);
81 bool disconnect(const Arc &A);
82
83 Function *F;
84 unsigned UpdateIdx = 0;
85 StringMap<BasicBlock *> NameToBlock;
86 std::set<Arc> Arcs;
87 std::vector<Update> Updates;
88};
89
90} // namespace llvm
91
92#endif
93

source code of llvm/unittests/IR/CFGBuilder.h