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