1259698Sdim//===-- lib/MC/MCFunction.cpp -----------------------------------*- C++ -*-===//
2259698Sdim//
3259698Sdim//                     The LLVM Compiler Infrastructure
4259698Sdim//
5259698Sdim// This file is distributed under the University of Illinois Open Source
6259698Sdim// License. See LICENSE.TXT for details.
7259698Sdim//
8259698Sdim//===----------------------------------------------------------------------===//
9259698Sdim
10259698Sdim#include "llvm/MC/MCFunction.h"
11259698Sdim#include "llvm/MC/MCAtom.h"
12259698Sdim#include "llvm/MC/MCModule.h"
13259698Sdim#include <algorithm>
14259698Sdim
15259698Sdimusing namespace llvm;
16259698Sdim
17259698Sdim// MCFunction
18259698Sdim
19259698SdimMCFunction::MCFunction(StringRef Name, MCModule *Parent)
20259698Sdim  : Name(Name), ParentModule(Parent)
21259698Sdim{}
22259698Sdim
23259698SdimMCFunction::~MCFunction() {
24259698Sdim  for (iterator I = begin(), E = end(); I != E; ++I)
25259698Sdim    delete *I;
26259698Sdim}
27259698Sdim
28259698SdimMCBasicBlock &MCFunction::createBlock(const MCTextAtom &TA) {
29259698Sdim  MCBasicBlock *MCBB = new MCBasicBlock(TA, this);
30259698Sdim  Blocks.push_back(MCBB);
31259698Sdim  return *MCBB;
32259698Sdim}
33259698Sdim
34259698SdimMCBasicBlock *MCFunction::find(uint64_t StartAddr) {
35259698Sdim  for (const_iterator I = begin(), E = end(); I != E; ++I)
36259698Sdim    if ((*I)->getInsts()->getBeginAddr() == StartAddr)
37259698Sdim      return *I;
38259698Sdim  return 0;
39259698Sdim}
40259698Sdim
41259698Sdimconst MCBasicBlock *MCFunction::find(uint64_t StartAddr) const {
42259698Sdim  return const_cast<MCFunction *>(this)->find(StartAddr);
43259698Sdim}
44259698Sdim
45259698Sdim// MCBasicBlock
46259698Sdim
47259698SdimMCBasicBlock::MCBasicBlock(const MCTextAtom &Insts, MCFunction *Parent)
48259698Sdim  : Insts(&Insts), Parent(Parent) {
49259698Sdim  getParent()->getParent()->trackBBForAtom(&Insts, this);
50259698Sdim}
51259698Sdim
52259698Sdimvoid MCBasicBlock::addSuccessor(const MCBasicBlock *MCBB) {
53259698Sdim  if (!isSuccessor(MCBB))
54259698Sdim    Successors.push_back(MCBB);
55259698Sdim}
56259698Sdim
57259698Sdimbool MCBasicBlock::isSuccessor(const MCBasicBlock *MCBB) const {
58259698Sdim  return std::find(Successors.begin(), Successors.end(),
59259698Sdim                   MCBB) != Successors.end();
60259698Sdim}
61259698Sdim
62259698Sdimvoid MCBasicBlock::addPredecessor(const MCBasicBlock *MCBB) {
63259698Sdim  if (!isPredecessor(MCBB))
64259698Sdim    Predecessors.push_back(MCBB);
65259698Sdim}
66259698Sdim
67259698Sdimbool MCBasicBlock::isPredecessor(const MCBasicBlock *MCBB) const {
68259698Sdim  return std::find(Predecessors.begin(), Predecessors.end(),
69259698Sdim                   MCBB) != Predecessors.end();
70259698Sdim}
71259698Sdim
72259698Sdimvoid MCBasicBlock::splitBasicBlock(MCBasicBlock *SplitBB) {
73259698Sdim  assert(Insts->getEndAddr() + 1 == SplitBB->Insts->getBeginAddr() &&
74259698Sdim         "Splitting unrelated basic blocks!");
75259698Sdim  SplitBB->addPredecessor(this);
76259698Sdim  assert(SplitBB->Successors.empty() &&
77259698Sdim         "Split basic block shouldn't already have successors!");
78259698Sdim  SplitBB->Successors = Successors;
79259698Sdim  Successors.clear();
80259698Sdim  addSuccessor(SplitBB);
81259698Sdim}
82