| //===- lib/MC/MCModule.cpp - MCModule implementation ----------------------===// |
| // |
| // The LLVM Compiler Infrastructure |
| // |
| // This file is distributed under the University of Illinois Open Source |
| // License. See LICENSE.TXT for details. |
| // |
| //===----------------------------------------------------------------------===// |
| |
| #include "llvm/MC/MCModule.h" |
| #include "llvm/MC/MCAtom.h" |
| #include "llvm/MC/MCFunction.h" |
| #include <algorithm> |
| |
| using namespace llvm; |
| |
| static bool AtomComp(const MCAtom *L, uint64_t Addr) { |
| return L->getEndAddr() < Addr; |
| } |
| |
| static bool AtomCompInv(uint64_t Addr, const MCAtom *R) { |
| return Addr < R->getEndAddr(); |
| } |
| |
| void MCModule::map(MCAtom *NewAtom) { |
| uint64_t Begin = NewAtom->Begin; |
| |
| assert(Begin <= NewAtom->End && "Creating MCAtom with endpoints reversed?"); |
| |
| // Check for atoms already covering this range. |
| AtomListTy::iterator I = std::lower_bound(atom_begin(), atom_end(), |
| Begin, AtomComp); |
| assert((I == atom_end() || (*I)->getBeginAddr() > NewAtom->End) |
| && "Offset range already occupied!"); |
| |
| // Insert the new atom to the list. |
| Atoms.insert(I, NewAtom); |
| } |
| |
| MCTextAtom *MCModule::createTextAtom(uint64_t Begin, uint64_t End) { |
| MCTextAtom *NewAtom = new MCTextAtom(this, Begin, End); |
| map(NewAtom); |
| return NewAtom; |
| } |
| |
| MCDataAtom *MCModule::createDataAtom(uint64_t Begin, uint64_t End) { |
| MCDataAtom *NewAtom = new MCDataAtom(this, Begin, End); |
| map(NewAtom); |
| return NewAtom; |
| } |
| |
| // remap - Update the interval mapping for an atom. |
| void MCModule::remap(MCAtom *Atom, uint64_t NewBegin, uint64_t NewEnd) { |
| // Find and erase the old mapping. |
| AtomListTy::iterator I = std::lower_bound(atom_begin(), atom_end(), |
| Atom->Begin, AtomComp); |
| assert(I != atom_end() && "Atom offset not found in module!"); |
| assert(*I == Atom && "Previous atom mapping was invalid!"); |
| Atoms.erase(I); |
| |
| // FIXME: special case NewBegin == Atom->Begin |
| |
| // Insert the new mapping. |
| AtomListTy::iterator NewI = std::lower_bound(atom_begin(), atom_end(), |
| NewBegin, AtomComp); |
| assert((NewI == atom_end() || (*NewI)->getBeginAddr() > Atom->End) |
| && "Offset range already occupied!"); |
| Atoms.insert(NewI, Atom); |
| |
| // Update the atom internal bounds. |
| Atom->Begin = NewBegin; |
| Atom->End = NewEnd; |
| } |
| |
| const MCAtom *MCModule::findAtomContaining(uint64_t Addr) const { |
| AtomListTy::const_iterator I = std::lower_bound(atom_begin(), atom_end(), |
| Addr, AtomComp); |
| if (I != atom_end() && (*I)->getBeginAddr() <= Addr) |
| return *I; |
| return 0; |
| } |
| |
| MCAtom *MCModule::findAtomContaining(uint64_t Addr) { |
| return const_cast<MCAtom*>( |
| const_cast<const MCModule *>(this)->findAtomContaining(Addr)); |
| } |
| |
| const MCAtom *MCModule::findFirstAtomAfter(uint64_t Addr) const { |
| AtomListTy::const_iterator I = std::upper_bound(atom_begin(), atom_end(), |
| Addr, AtomCompInv); |
| if (I != atom_end()) |
| return *I; |
| return 0; |
| } |
| |
| MCAtom *MCModule::findFirstAtomAfter(uint64_t Addr) { |
| return const_cast<MCAtom*>( |
| const_cast<const MCModule *>(this)->findFirstAtomAfter(Addr)); |
| } |
| |
| MCFunction *MCModule::createFunction(StringRef Name) { |
| Functions.push_back(new MCFunction(Name, this)); |
| return Functions.back(); |
| } |
| |
| static bool CompBBToAtom(MCBasicBlock *BB, const MCTextAtom *Atom) { |
| return BB->getInsts() < Atom; |
| } |
| |
| void MCModule::splitBasicBlocksForAtom(const MCTextAtom *TA, |
| const MCTextAtom *NewTA) { |
| BBsByAtomTy::iterator |
| I = std::lower_bound(BBsByAtom.begin(), BBsByAtom.end(), |
| TA, CompBBToAtom); |
| for (; I != BBsByAtom.end() && (*I)->getInsts() == TA; ++I) { |
| MCBasicBlock *BB = *I; |
| MCBasicBlock *NewBB = &BB->getParent()->createBlock(*NewTA); |
| BB->splitBasicBlock(NewBB); |
| } |
| } |
| |
| void MCModule::trackBBForAtom(const MCTextAtom *Atom, MCBasicBlock *BB) { |
| assert(Atom == BB->getInsts() && "Text atom doesn't back the basic block!"); |
| BBsByAtomTy::iterator I = std::lower_bound(BBsByAtom.begin(), |
| BBsByAtom.end(), |
| Atom, CompBBToAtom); |
| for (; I != BBsByAtom.end() && (*I)->getInsts() == Atom; ++I) |
| if (*I == BB) |
| return; |
| BBsByAtom.insert(I, BB); |
| } |
| |
| MCModule::~MCModule() { |
| for (AtomListTy::iterator AI = atom_begin(), |
| AE = atom_end(); |
| AI != AE; ++AI) |
| delete *AI; |
| for (FunctionListTy::iterator FI = func_begin(), |
| FE = func_end(); |
| FI != FE; ++FI) |
| delete *FI; |
| } |