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/DenseMap.h" 18 #include "llvm/ADT/Optional.h" 19 #include "llvm/ADT/StringMap.h" 20 #include "llvm/ADT/StringRef.h" 21 #include "llvm/Support/Debug.h" 22 23 #include <memory> 24 #include <set> 25 #include <tuple> 26 #include <vector> 27 28 namespace llvm { 29 30 class LLVMContext; 31 class Module; 32 class Function; 33 class BasicBlock; 34 class raw_ostream; 35 36 struct CFGHolder { 37 std::unique_ptr<LLVMContext> Context; 38 std::unique_ptr<Module> M; 39 Function *F; 40 41 CFGHolder(StringRef ModuleName = "m", StringRef FunctionName = "foo"); 42 ~CFGHolder(); // Defined in the .cpp file so we can use forward declarations. 43 }; 44 45 /// \brief 46 /// CFGBuilder builds IR with specific CFG, based on the supplied list of arcs. 47 /// It's able to apply the provided updates and automatically modify the IR. 48 /// 49 /// Internally it makes every basic block end with either SwitchInst or with 50 /// UnreachableInst. When all arc to a BB are deleted, the BB remains in the 51 /// function and doesn't get deleted. 52 /// 53 class CFGBuilder { 54 public: 55 struct Arc { 56 StringRef From; 57 StringRef To; 58 59 friend bool operator<(const Arc &LHS, const Arc &RHS) { 60 return std::tie(LHS.From, LHS.To) < 61 std::tie(RHS.From, RHS.To); 62 } 63 }; 64 65 enum class ActionKind { Insert, Delete }; 66 struct Update { 67 ActionKind Action; 68 Arc Edge; 69 }; 70 71 CFGBuilder(Function *F, const std::vector<Arc> &InitialArcs, 72 std::vector<Update> Updates); 73 74 BasicBlock *getOrAddBlock(StringRef BlockName); 75 Optional<Update> getNextUpdate() const; 76 Optional<Update> applyUpdate(); 77 void dump(raw_ostream &OS = dbgs()) const; 78 79 private: 80 void buildCFG(const std::vector<Arc> &Arcs); 81 bool connect(const Arc &A); 82 bool disconnect(const Arc &A); 83 84 Function *F; 85 unsigned UpdateIdx = 0; 86 StringMap<BasicBlock *> NameToBlock; 87 std::set<Arc> Arcs; 88 std::vector<Update> Updates; 89 }; 90 91 } // namespace llvm 92 93 #endif 94