diff options
Diffstat (limited to 'unittests/IR/CFGBuilder.h')
| -rw-r--r-- | unittests/IR/CFGBuilder.h | 94 |
1 files changed, 94 insertions, 0 deletions
diff --git a/unittests/IR/CFGBuilder.h b/unittests/IR/CFGBuilder.h new file mode 100644 index 0000000000000..d9d9c378e1103 --- /dev/null +++ b/unittests/IR/CFGBuilder.h @@ -0,0 +1,94 @@ +//===- CFGBuilder.h - CFG building and updating utility ----------*- C++ -*-==// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +/// \file +/// CFGBuilders provides utilities fo building and updating CFG for testing +/// purposes. +/// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_UNITTESTS_CFG_BUILDER_H +#define LLVM_UNITTESTS_CFG_BUILDER_H + +#include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/Optional.h" +#include "llvm/ADT/StringMap.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/Support/Debug.h" + +#include <memory> +#include <set> +#include <tuple> +#include <vector> + +namespace llvm { + +class LLVMContext; +class Module; +class Function; +class BasicBlock; +class raw_ostream; + +struct CFGHolder { + std::unique_ptr<LLVMContext> Context; + std::unique_ptr<Module> M; + Function *F; + + CFGHolder(StringRef ModuleName = "m", StringRef FunctionName = "foo"); + ~CFGHolder(); // Defined in the .cpp file so we can use forward declarations. +}; + +/// \brief +/// CFGBuilder builds IR with specific CFG, based on the supplied list of arcs. +/// It's able to apply the provided updates and automatically modify the IR. +/// +/// Internally it makes every basic block end with either SwitchInst or with +/// UnreachableInst. When all arc to a BB are deleted, the BB remains in the +/// function and doesn't get deleted. +/// +class CFGBuilder { +public: + struct Arc { + StringRef From; + StringRef To; + + friend bool operator<(const Arc &LHS, const Arc &RHS) { + return std::tie(LHS.From, LHS.To) < + std::tie(RHS.From, RHS.To); + } + }; + + enum class ActionKind { Insert, Delete }; + struct Update { + ActionKind Action; + Arc Edge; + }; + + CFGBuilder(Function *F, const std::vector<Arc> &InitialArcs, + std::vector<Update> Updates); + + BasicBlock *getOrAddBlock(StringRef BlockName); + Optional<Update> getNextUpdate() const; + Optional<Update> applyUpdate(); + void dump(raw_ostream &OS = dbgs()) const; + +private: + void buildCFG(const std::vector<Arc> &Arcs); + bool connect(const Arc &A); + bool disconnect(const Arc &A); + + Function *F; + unsigned UpdateIdx = 0; + StringMap<BasicBlock *> NameToBlock; + std::set<Arc> Arcs; + std::vector<Update> Updates; +}; + +} // namespace llvm + +#endif |
