MCModule.cpp revision 296373
1//===- lib/MC/MCModule.cpp - MCModule implementation ----------------------===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#include "llvm/MC/MCModule.h"
11#include "llvm/MC/MCAtom.h"
12#include "llvm/MC/MCFunction.h"
13#include <algorithm>
14
15using namespace llvm;
16
17static bool AtomComp(const MCAtom *L, uint64_t Addr) {
18  return L->getEndAddr() < Addr;
19}
20
21static bool AtomCompInv(uint64_t Addr, const MCAtom *R) {
22  return Addr < R->getEndAddr();
23}
24
25void MCModule::map(MCAtom *NewAtom) {
26  uint64_t Begin = NewAtom->Begin;
27
28  assert(Begin <= NewAtom->End && "Creating MCAtom with endpoints reversed?");
29
30  // Check for atoms already covering this range.
31  AtomListTy::iterator I = std::lower_bound(atom_begin(), atom_end(),
32                                            Begin, AtomComp);
33  assert((I == atom_end() || (*I)->getBeginAddr() > NewAtom->End)
34         && "Offset range already occupied!");
35
36  // Insert the new atom to the list.
37  Atoms.insert(I, NewAtom);
38}
39
40MCTextAtom *MCModule::createTextAtom(uint64_t Begin, uint64_t End) {
41  MCTextAtom *NewAtom = new MCTextAtom(this, Begin, End);
42  map(NewAtom);
43  return NewAtom;
44}
45
46MCDataAtom *MCModule::createDataAtom(uint64_t Begin, uint64_t End) {
47  MCDataAtom *NewAtom = new MCDataAtom(this, Begin, End);
48  map(NewAtom);
49  return NewAtom;
50}
51
52// remap - Update the interval mapping for an atom.
53void MCModule::remap(MCAtom *Atom, uint64_t NewBegin, uint64_t NewEnd) {
54  // Find and erase the old mapping.
55  AtomListTy::iterator I = std::lower_bound(atom_begin(), atom_end(),
56                                            Atom->Begin, AtomComp);
57  assert(I != atom_end() && "Atom offset not found in module!");
58  assert(*I == Atom && "Previous atom mapping was invalid!");
59  Atoms.erase(I);
60
61  // FIXME: special case NewBegin == Atom->Begin
62
63  // Insert the new mapping.
64  AtomListTy::iterator NewI = std::lower_bound(atom_begin(), atom_end(),
65                                               NewBegin, AtomComp);
66  assert((NewI == atom_end() || (*NewI)->getBeginAddr() > Atom->End)
67         && "Offset range already occupied!");
68  Atoms.insert(NewI, Atom);
69
70  // Update the atom internal bounds.
71  Atom->Begin = NewBegin;
72  Atom->End = NewEnd;
73}
74
75const MCAtom *MCModule::findAtomContaining(uint64_t Addr) const {
76  AtomListTy::const_iterator I = std::lower_bound(atom_begin(), atom_end(),
77                                                  Addr, AtomComp);
78  if (I != atom_end() && (*I)->getBeginAddr() <= Addr)
79    return *I;
80  return 0;
81}
82
83MCAtom *MCModule::findAtomContaining(uint64_t Addr) {
84  return const_cast<MCAtom*>(
85    const_cast<const MCModule *>(this)->findAtomContaining(Addr));
86}
87
88const MCAtom *MCModule::findFirstAtomAfter(uint64_t Addr) const {
89  AtomListTy::const_iterator I = std::upper_bound(atom_begin(), atom_end(),
90                                                  Addr, AtomCompInv);
91  if (I != atom_end())
92    return *I;
93  return 0;
94}
95
96MCAtom *MCModule::findFirstAtomAfter(uint64_t Addr) {
97  return const_cast<MCAtom*>(
98    const_cast<const MCModule *>(this)->findFirstAtomAfter(Addr));
99}
100
101MCFunction *MCModule::createFunction(StringRef Name) {
102  Functions.push_back(new MCFunction(Name, this));
103  return Functions.back();
104}
105
106static bool CompBBToAtom(MCBasicBlock *BB, const MCTextAtom *Atom) {
107  return BB->getInsts() < Atom;
108}
109
110void MCModule::splitBasicBlocksForAtom(const MCTextAtom *TA,
111                                       const MCTextAtom *NewTA) {
112  BBsByAtomTy::iterator
113    I = std::lower_bound(BBsByAtom.begin(), BBsByAtom.end(),
114                         TA, CompBBToAtom);
115  for (; I != BBsByAtom.end() && (*I)->getInsts() == TA; ++I) {
116    MCBasicBlock *BB = *I;
117    MCBasicBlock *NewBB = &BB->getParent()->createBlock(*NewTA);
118    BB->splitBasicBlock(NewBB);
119  }
120}
121
122void MCModule::trackBBForAtom(const MCTextAtom *Atom, MCBasicBlock *BB) {
123  assert(Atom == BB->getInsts() && "Text atom doesn't back the basic block!");
124  BBsByAtomTy::iterator I = std::lower_bound(BBsByAtom.begin(),
125                                             BBsByAtom.end(),
126                                             Atom, CompBBToAtom);
127  for (; I != BBsByAtom.end() && (*I)->getInsts() == Atom; ++I)
128    if (*I == BB)
129      return;
130  BBsByAtom.insert(I, BB);
131}
132
133MCModule::~MCModule() {
134  for (AtomListTy::iterator AI = atom_begin(),
135                            AE = atom_end();
136                            AI != AE; ++AI)
137    delete *AI;
138  for (FunctionListTy::iterator FI = func_begin(),
139                                FE = func_end();
140                                FI != FE; ++FI)
141    delete *FI;
142}
143