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 27 namespace llvm { 28 29 class LLVMContext; 30 class Module; 31 class Function; 32 class BasicBlock; 33 class raw_ostream; 34 35 struct 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 /// 52 class CFGBuilder { 53 public: 54 struct Arc { 55 StringRef From; 56 StringRef To; 57 58 friend bool operator<(const Arc &LHS, const Arc &RHS) { 59 return std::tie(LHS.From, LHS.To) < 60 std::tie(RHS.From, 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 78 private: 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