| //===-- MCFunction.h --------------------------------------------*- C++ -*-===// |
| // |
| // The LLVM Compiler Infrastructure |
| // |
| // This file is distributed under the University of Illinois Open Source |
| // License. See LICENSE.TXT for details. |
| // |
| //===----------------------------------------------------------------------===// |
| // |
| // This file defines the data structures to hold a CFG reconstructed from |
| // machine code. |
| // |
| //===----------------------------------------------------------------------===// |
| |
| #ifndef LLVM_MC_MCANALYSIS_MCFUNCTION_H |
| #define LLVM_MC_MCANALYSIS_MCFUNCTION_H |
| |
| #include "llvm/ADT/StringRef.h" |
| #include "llvm/MC/MCInst.h" |
| #include <memory> |
| #include <string> |
| #include <vector> |
| |
| namespace llvm { |
| |
| class MCFunction; |
| class MCModule; |
| class MCTextAtom; |
| |
| /// \brief Basic block containing a sequence of disassembled instructions. |
| /// The basic block is backed by an MCTextAtom, which holds the instructions, |
| /// and the address range it covers. |
| /// Create a basic block using MCFunction::createBlock. |
| class MCBasicBlock { |
| const MCTextAtom *Insts; |
| |
| // MCFunction owns the basic block. |
| MCFunction *Parent; |
| friend class MCFunction; |
| MCBasicBlock(const MCTextAtom &Insts, MCFunction *Parent); |
| |
| /// \name Predecessors/Successors, to represent the CFG. |
| /// @{ |
| typedef std::vector<const MCBasicBlock *> BasicBlockListTy; |
| BasicBlockListTy Successors; |
| BasicBlockListTy Predecessors; |
| /// @} |
| public: |
| |
| /// \brief Get the backing MCTextAtom, containing the instruction sequence. |
| const MCTextAtom *getInsts() const { return Insts; } |
| |
| /// \name Get the owning MCFunction. |
| /// @{ |
| const MCFunction *getParent() const { return Parent; } |
| MCFunction *getParent() { return Parent; } |
| /// @} |
| |
| /// MC CFG access: Predecessors/Successors. |
| /// @{ |
| typedef BasicBlockListTy::const_iterator succ_const_iterator; |
| succ_const_iterator succ_begin() const { return Successors.begin(); } |
| succ_const_iterator succ_end() const { return Successors.end(); } |
| |
| typedef BasicBlockListTy::const_iterator pred_const_iterator; |
| pred_const_iterator pred_begin() const { return Predecessors.begin(); } |
| pred_const_iterator pred_end() const { return Predecessors.end(); } |
| |
| void addSuccessor(const MCBasicBlock *MCBB); |
| bool isSuccessor(const MCBasicBlock *MCBB) const; |
| |
| void addPredecessor(const MCBasicBlock *MCBB); |
| bool isPredecessor(const MCBasicBlock *MCBB) const; |
| |
| /// \brief Split block, mirrorring NewAtom = Insts->split(..). |
| /// This moves all successors to \p SplitBB, and |
| /// adds a fallthrough to it. |
| /// \p SplitBB The result of splitting Insts, a basic block directly following |
| /// this basic block. |
| void splitBasicBlock(MCBasicBlock *SplitBB); |
| /// @} |
| }; |
| |
| /// \brief Represents a function in machine code, containing MCBasicBlocks. |
| /// MCFunctions are created by MCModule. |
| class MCFunction { |
| MCFunction (const MCFunction&) LLVM_DELETED_FUNCTION; |
| MCFunction& operator=(const MCFunction&) LLVM_DELETED_FUNCTION; |
| |
| std::string Name; |
| MCModule *ParentModule; |
| typedef std::vector<std::unique_ptr<MCBasicBlock>> BasicBlockListTy; |
| BasicBlockListTy Blocks; |
| |
| // MCModule owns the function. |
| friend class MCModule; |
| MCFunction(StringRef Name, MCModule *Parent); |
| |
| public: |
| /// \brief Create an MCBasicBlock backed by Insts and add it to this function. |
| /// \param Insts Sequence of straight-line code backing the basic block. |
| /// \returns The newly created basic block. |
| MCBasicBlock &createBlock(const MCTextAtom &Insts); |
| |
| StringRef getName() const { return Name; } |
| |
| /// \name Get the owning MC Module. |
| /// @{ |
| const MCModule *getParent() const { return ParentModule; } |
| MCModule *getParent() { return ParentModule; } |
| /// @} |
| |
| /// \name Access to the function's basic blocks. No ordering is enforced, |
| /// except that the first block is the entry block. |
| /// @{ |
| /// \brief Get the entry point basic block. |
| const MCBasicBlock *getEntryBlock() const { return front(); } |
| MCBasicBlock *getEntryBlock() { return front(); } |
| |
| bool empty() const { return Blocks.empty(); } |
| |
| typedef BasicBlockListTy::const_iterator const_iterator; |
| typedef BasicBlockListTy:: iterator iterator; |
| const_iterator begin() const { return Blocks.begin(); } |
| iterator begin() { return Blocks.begin(); } |
| const_iterator end() const { return Blocks.end(); } |
| iterator end() { return Blocks.end(); } |
| |
| const MCBasicBlock* front() const { return Blocks.front().get(); } |
| MCBasicBlock* front() { return Blocks.front().get(); } |
| const MCBasicBlock* back() const { return Blocks.back().get(); } |
| MCBasicBlock* back() { return Blocks.back().get(); } |
| |
| /// \brief Find the basic block, if any, that starts at \p StartAddr. |
| const MCBasicBlock *find(uint64_t StartAddr) const; |
| MCBasicBlock *find(uint64_t StartAddr); |
| /// @} |
| }; |
| |
| } |
| |
| #endif |