93 lines · c
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-exception6//7//===----------------------------------------------------------------------===//8/// \file9/// CFGBuilders provides utilities fo building and updating CFG for testing10/// purposes.11///12//===----------------------------------------------------------------------===//13 14#ifndef LLVM_UNITTESTS_CFG_BUILDER_H15#define LLVM_UNITTESTS_CFG_BUILDER_H16 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/// \brief45/// 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 with49/// UnreachableInst. When all arc to a BB are deleted, the BB remains in the50/// 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(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 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 llvm91 92#endif93