1cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines//===-- MCFunction.h --------------------------------------------*- C++ -*-===//
2ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha//
3ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha//                     The LLVM Compiler Infrastructure
4ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha//
5ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha// This file is distributed under the University of Illinois Open Source
6ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha// License. See LICENSE.TXT for details.
7ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha//
8ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha//===----------------------------------------------------------------------===//
9ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha//
10ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha// This file defines the data structures to hold a CFG reconstructed from
11ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha// machine code.
12ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha//
13ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha//===----------------------------------------------------------------------===//
14ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha
15cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines#ifndef LLVM_MC_MCANALYSIS_MCFUNCTION_H
16cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines#define LLVM_MC_MCANALYSIS_MCFUNCTION_H
17ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha
18ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha#include "llvm/ADT/StringRef.h"
19ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha#include "llvm/MC/MCInst.h"
20dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines#include <memory>
21ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha#include <string>
22ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha#include <vector>
23ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha
24ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougachanamespace llvm {
25ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha
26ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougachaclass MCFunction;
27ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougachaclass MCModule;
28ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougachaclass MCTextAtom;
29ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha
30ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha/// \brief Basic block containing a sequence of disassembled instructions.
31ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha/// The basic block is backed by an MCTextAtom, which holds the instructions,
32ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha/// and the address range it covers.
33ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha/// Create a basic block using MCFunction::createBlock.
34ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougachaclass MCBasicBlock {
35ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha  const MCTextAtom *Insts;
36ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha
37ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha  // MCFunction owns the basic block.
38ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha  MCFunction *Parent;
39ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha  friend class MCFunction;
40ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha  MCBasicBlock(const MCTextAtom &Insts, MCFunction *Parent);
41ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha
42ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha  /// \name Predecessors/Successors, to represent the CFG.
43ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha  /// @{
44ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha  typedef std::vector<const MCBasicBlock *> BasicBlockListTy;
45ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha  BasicBlockListTy Successors;
46ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha  BasicBlockListTy Predecessors;
47ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha  /// @}
48ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougachapublic:
49ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha
50ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha  /// \brief Get the backing MCTextAtom, containing the instruction sequence.
51ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha  const MCTextAtom *getInsts() const { return Insts; }
52ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha
53ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha  /// \name Get the owning MCFunction.
54ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha  /// @{
55ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha  const MCFunction *getParent() const { return Parent; }
56ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha        MCFunction *getParent()       { return Parent; }
57ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha  /// @}
58ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha
59ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha  /// MC CFG access: Predecessors/Successors.
60ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha  /// @{
61ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha  typedef BasicBlockListTy::const_iterator succ_const_iterator;
62ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha  succ_const_iterator succ_begin() const { return Successors.begin(); }
63ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha  succ_const_iterator succ_end()   const { return Successors.end(); }
64ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha
65ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha  typedef BasicBlockListTy::const_iterator pred_const_iterator;
66ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha  pred_const_iterator pred_begin() const { return Predecessors.begin(); }
67ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha  pred_const_iterator pred_end()   const { return Predecessors.end(); }
68ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha
69ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha  void addSuccessor(const MCBasicBlock *MCBB);
70ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha  bool isSuccessor(const MCBasicBlock *MCBB) const;
71ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha
72ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha  void addPredecessor(const MCBasicBlock *MCBB);
73ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha  bool isPredecessor(const MCBasicBlock *MCBB) const;
74aeb2bbcb6d4f13d0032d57fd1cb1a92da2acd01eAhmed Bougacha
75aeb2bbcb6d4f13d0032d57fd1cb1a92da2acd01eAhmed Bougacha  /// \brief Split block, mirrorring NewAtom = Insts->split(..).
76aeb2bbcb6d4f13d0032d57fd1cb1a92da2acd01eAhmed Bougacha  /// This moves all successors to \p SplitBB, and
77aeb2bbcb6d4f13d0032d57fd1cb1a92da2acd01eAhmed Bougacha  /// adds a fallthrough to it.
78aeb2bbcb6d4f13d0032d57fd1cb1a92da2acd01eAhmed Bougacha  /// \p SplitBB The result of splitting Insts, a basic block directly following
79aeb2bbcb6d4f13d0032d57fd1cb1a92da2acd01eAhmed Bougacha  /// this basic block.
80aeb2bbcb6d4f13d0032d57fd1cb1a92da2acd01eAhmed Bougacha  void splitBasicBlock(MCBasicBlock *SplitBB);
81ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha  /// @}
82ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha};
83ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha
84ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha/// \brief Represents a function in machine code, containing MCBasicBlocks.
857dac32d07d54231ba203f7c32f3a9f8e6730810fAhmed Bougacha/// MCFunctions are created by MCModule.
86ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougachaclass MCFunction {
87ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha  MCFunction           (const MCFunction&) LLVM_DELETED_FUNCTION;
88ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha  MCFunction& operator=(const MCFunction&) LLVM_DELETED_FUNCTION;
89ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha
90ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha  std::string Name;
917dac32d07d54231ba203f7c32f3a9f8e6730810fAhmed Bougacha  MCModule *ParentModule;
92dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  typedef std::vector<std::unique_ptr<MCBasicBlock>> BasicBlockListTy;
93ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha  BasicBlockListTy Blocks;
94ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha
95ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha  // MCModule owns the function.
96ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha  friend class MCModule;
977dac32d07d54231ba203f7c32f3a9f8e6730810fAhmed Bougacha  MCFunction(StringRef Name, MCModule *Parent);
98ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha
997dac32d07d54231ba203f7c32f3a9f8e6730810fAhmed Bougachapublic:
100ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha  /// \brief Create an MCBasicBlock backed by Insts and add it to this function.
101ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha  /// \param Insts Sequence of straight-line code backing the basic block.
102ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha  /// \returns The newly created basic block.
103ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha  MCBasicBlock &createBlock(const MCTextAtom &Insts);
104ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha
105ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha  StringRef getName() const { return Name; }
106ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha
10746d353f8e8a2bbe02e8aa6a2292eae930dd3b7e6Ahmed Bougacha  /// \name Get the owning MC Module.
10846d353f8e8a2bbe02e8aa6a2292eae930dd3b7e6Ahmed Bougacha  /// @{
10946d353f8e8a2bbe02e8aa6a2292eae930dd3b7e6Ahmed Bougacha  const MCModule *getParent() const { return ParentModule; }
11046d353f8e8a2bbe02e8aa6a2292eae930dd3b7e6Ahmed Bougacha        MCModule *getParent()       { return ParentModule; }
11146d353f8e8a2bbe02e8aa6a2292eae930dd3b7e6Ahmed Bougacha  /// @}
11246d353f8e8a2bbe02e8aa6a2292eae930dd3b7e6Ahmed Bougacha
113f9e2348e948451d30e4e0593e0beb3bcc31da8daAhmed Bougacha  /// \name Access to the function's basic blocks. No ordering is enforced,
114f9e2348e948451d30e4e0593e0beb3bcc31da8daAhmed Bougacha  /// except that the first block is the entry block.
115ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha  /// @{
116ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha  /// \brief Get the entry point basic block.
117ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha  const MCBasicBlock *getEntryBlock() const { return front(); }
118ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha        MCBasicBlock *getEntryBlock()       { return front(); }
119ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha
120f9e2348e948451d30e4e0593e0beb3bcc31da8daAhmed Bougacha  bool empty() const { return Blocks.empty(); }
121f9e2348e948451d30e4e0593e0beb3bcc31da8daAhmed Bougacha
122ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha  typedef BasicBlockListTy::const_iterator const_iterator;
123ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha  typedef BasicBlockListTy::      iterator       iterator;
124ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha  const_iterator begin() const { return Blocks.begin(); }
125ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha        iterator begin()       { return Blocks.begin(); }
126ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha  const_iterator   end() const { return Blocks.end(); }
127ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha        iterator   end()       { return Blocks.end(); }
128ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha
129dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  const MCBasicBlock* front() const { return Blocks.front().get(); }
130dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        MCBasicBlock* front()       { return Blocks.front().get(); }
131dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  const MCBasicBlock*  back() const { return Blocks.back().get(); }
132dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        MCBasicBlock*  back()       { return Blocks.back().get(); }
133f9e2348e948451d30e4e0593e0beb3bcc31da8daAhmed Bougacha
134f9e2348e948451d30e4e0593e0beb3bcc31da8daAhmed Bougacha  /// \brief Find the basic block, if any, that starts at \p StartAddr.
135f9e2348e948451d30e4e0593e0beb3bcc31da8daAhmed Bougacha  const MCBasicBlock *find(uint64_t StartAddr) const;
136f9e2348e948451d30e4e0593e0beb3bcc31da8daAhmed Bougacha        MCBasicBlock *find(uint64_t StartAddr);
137ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha  /// @}
138ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha};
139ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha
140ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha}
141ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha
142ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha#endif
143