MC: Track section layout order explicitly, and use to simplify.

llvm-svn: 103616
This commit is contained in:
Daniel Dunbar 2010-05-12 15:42:59 +00:00
parent 0856bf7b13
commit e02c1f6834
2 changed files with 35 additions and 32 deletions

View File

@ -10,6 +10,8 @@
#ifndef LLVM_MC_MCASMLAYOUT_H
#define LLVM_MC_MCASMLAYOUT_H
#include "llvm/ADT/SmallVector.h"
namespace llvm {
class MCAssembler;
class MCFragment;
@ -24,11 +26,18 @@ class MCSymbolData;
/// efficiently compute the exact addresses of any symbol in the assembly file,
/// even during the relaxation process.
class MCAsmLayout {
public:
typedef llvm::SmallVectorImpl<MCSectionData*>::const_iterator const_iterator;
typedef llvm::SmallVectorImpl<MCSectionData*>::iterator iterator;
private:
MCAssembler &Assembler;
/// List of sections in layout order.
llvm::SmallVector<MCSectionData*, 16> SectionOrder;
public:
MCAsmLayout(MCAssembler &_Assembler) : Assembler(_Assembler) {}
MCAsmLayout(MCAssembler &_Assembler);
/// Get the assembler object this is a layout for.
MCAssembler &getAssembler() const { return Assembler; }
@ -38,6 +47,16 @@ public:
/// the delta from the old size.
void UpdateForSlide(MCFragment *F, int SlideAmount);
/// @name Section Access (in layout order)
/// @{
iterator begin() { return SectionOrder.begin(); }
const_iterator begin() const { return SectionOrder.begin(); }
iterator end() {return SectionOrder.end();}
const_iterator end() const {return SectionOrder.end();}
/// @}
/// @name Fragment Layout Data
/// @{

View File

@ -47,6 +47,16 @@ STATISTIC(SectionLayouts, "Number of section layouts");
/* *** */
MCAsmLayout::MCAsmLayout(MCAssembler &Asm) : Assembler(Asm) {
// Compute the section layout order. Virtual sections must go last.
for (MCAssembler::iterator it = Asm.begin(), ie = Asm.end(); it != ie; ++it)
if (!Asm.getBackend().isVirtualSection(it->getSection()))
SectionOrder.push_back(&*it);
for (MCAssembler::iterator it = Asm.begin(), ie = Asm.end(); it != ie; ++it)
if (Asm.getBackend().isVirtualSection(it->getSection()))
SectionOrder.push_back(&*it);
}
void MCAsmLayout::UpdateForSlide(MCFragment *F, int SlideAmount) {
// We shouldn't have to do anything special to support negative slides, and it
// is a perfectly valid thing to do as long as other parts of the system can
@ -59,24 +69,10 @@ void MCAsmLayout::UpdateForSlide(MCFragment *F, int SlideAmount) {
// FIXME-PERF: This is O(N^2), but will be eliminated once we get smarter.
// Layout the concrete sections and fragments.
MCAssembler &Asm = getAssembler();
uint64_t Address = 0;
for (MCAssembler::iterator it = Asm.begin(), ie = Asm.end(); it != ie; ++it) {
// Skip virtual sections.
if (Asm.getBackend().isVirtualSection(it->getSection()))
continue;
for (iterator it = begin(), ie = end(); it != ie; ++it) {
// Layout the section fragments and its size.
Address = Asm.LayoutSection(*it, *this, Address);
}
// Layout the virtual sections.
for (MCAssembler::iterator it = Asm.begin(), ie = Asm.end(); it != ie; ++it) {
if (!Asm.getBackend().isVirtualSection(it->getSection()))
continue;
// Layout the section fragments and its size.
Address = Asm.LayoutSection(*it, *this, Address);
Address = getAssembler().LayoutSection(**it, *this, Address);
}
}
@ -711,22 +707,10 @@ bool MCAssembler::LayoutOnce(MCAsmLayout &Layout) {
// Layout the concrete sections and fragments.
uint64_t Address = 0;
for (iterator it = begin(), ie = end(); it != ie; ++it) {
// Skip virtual sections.
if (getBackend().isVirtualSection(it->getSection()))
continue;
for (MCAsmLayout::iterator it = Layout.begin(),
ie = Layout.end(); it != ie; ++it) {
// Layout the section fragments and its size.
Address = LayoutSection(*it, Layout, Address);
}
// Layout the virtual sections.
for (iterator it = begin(), ie = end(); it != ie; ++it) {
if (!getBackend().isVirtualSection(it->getSection()))
continue;
// Layout the section fragments and its size.
Address = LayoutSection(*it, Layout, Address);
Address = LayoutSection(**it, Layout, Address);
}
// Scan for fragments that need relaxation.