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