From cb7d743b4242345fa1081223b021b1504dce6fb7 Mon Sep 17 00:00:00 2001 From: Daniel Dunbar Date: Thu, 11 Feb 2010 21:29:46 +0000 Subject: [PATCH] MC: Move assembler-backend's fixup list into the fragment. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@95926 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/MC/MCAssembler.h | 97 +++++++++++++++++++---------------- lib/MC/MCAssembler.cpp | 62 ++++++++-------------- 2 files changed, 74 insertions(+), 85 deletions(-) diff --git a/include/llvm/MC/MCAssembler.h b/include/llvm/MC/MCAssembler.h index 9d3efa7ee65..562a5210ad8 100644 --- a/include/llvm/MC/MCAssembler.h +++ b/include/llvm/MC/MCAssembler.h @@ -31,9 +31,6 @@ class MCSymbol; /// which needs to be rewritten. This region will either be rewritten by the /// assembler or cause a relocation entry to be generated. struct MCAsmFixup { - /// Fragment - The fragment containing the fixup. - MCFragment *Fragment; - /// Offset - The offset inside the fragment which needs to be rewritten. uint64_t Offset; @@ -49,16 +46,18 @@ struct MCAsmFixup { uint64_t FixedValue; public: - MCAsmFixup(MCFragment &_Fragment, uint64_t _Offset, const MCExpr &_Value, - unsigned _Size) - : Fragment(&_Fragment), Offset(_Offset), Value(&_Value), Size(_Size), - FixedValue(0) {} + MCAsmFixup(uint64_t _Offset, const MCExpr &_Value, unsigned _Size) + : Offset(_Offset), Value(&_Value), Size(_Size), FixedValue(0) {} }; class MCFragment : public ilist_node { MCFragment(const MCFragment&); // DO NOT IMPLEMENT void operator=(const MCFragment&); // DO NOT IMPLEMENT +public: + typedef std::vector::const_iterator const_fixup_iterator; + typedef std::vector::iterator fixup_iterator; + public: enum FragmentType { FT_Data, @@ -86,6 +85,11 @@ private: /// FileSize - The file size of this section. This is ~0 until initialized. uint64_t FileSize; + /// Fixups - The list of fixups in this fragment. + // + // FIXME: This should be sunk into MCDataFragment. + std::vector Fixups; + /// @} protected: @@ -107,6 +111,39 @@ public: return 0; } + /// @name Fixup Access + /// @{ + + /// LookupFixup - Look up the fixup for the given \arg Fragment and \arg + /// Offset. + /// + /// If multiple fixups exist for the same fragment and offset it is undefined + /// which one is returned. + // + // FIXME: This isn't horribly slow in practice, but there are much nicer + // solutions to applying the fixups. This will be fixed by sinking fixups into + // data fragments exclusively. + const MCAsmFixup *LookupFixup(uint64_t Offset) const { + for (unsigned i = 0, e = Fixups.size(); i != e; ++i) + if (Fixups[i].Offset == Offset) + return &Fixups[i]; + return 0; + } + + std::vector &getFixups() { + return Fixups; + } + + fixup_iterator fixup_begin() { + return Fixups.begin(); + } + + fixup_iterator fixup_end() { + return Fixups.end(); + } + + size_t fixup_size() const { return Fixups.size(); } + /// @name Assembler Backend Support /// @{ // @@ -313,14 +350,13 @@ class MCSectionData : public ilist_node { void operator=(const MCSectionData&); // DO NOT IMPLEMENT public: - typedef iplist FragmentListType; typedef FragmentListType::const_iterator const_iterator; typedef FragmentListType::iterator iterator; - typedef std::vector::const_iterator const_fixup_iterator; - typedef std::vector::iterator fixup_iterator; + typedef FragmentListType::const_reverse_iterator const_reverse_iterator; + typedef FragmentListType::reverse_iterator reverse_iterator; private: iplist Fragments; @@ -345,12 +381,6 @@ private: /// initialized. uint64_t FileSize; - /// LastFixupLookup - Cache for the last looked up fixup. - mutable unsigned LastFixupLookup; - - /// Fixups - The list of fixups in this section. - std::vector Fixups; - /// HasInstructions - Whether this section has had instructions emitted into /// it. unsigned HasInstructions : 1; @@ -379,45 +409,22 @@ public: iterator end() { return Fragments.end(); } const_iterator end() const { return Fragments.end(); } + reverse_iterator rbegin() { return Fragments.rbegin(); } + const_reverse_iterator rbegin() const { return Fragments.rbegin(); } + + reverse_iterator rend() { return Fragments.rend(); } + const_reverse_iterator rend() const { return Fragments.rend(); } + size_t size() const { return Fragments.size(); } bool empty() const { return Fragments.empty(); } - /// @} - /// @name Fixup Access - /// @{ - - std::vector &getFixups() { - return Fixups; - } - - fixup_iterator fixup_begin() { - return Fixups.begin(); - } - - fixup_iterator fixup_end() { - return Fixups.end(); - } - - size_t fixup_size() const { return Fixups.size(); } - /// @} /// @name Assembler Backend Support /// @{ // // FIXME: This could all be kept private to the assembler implementation. - /// LookupFixup - Look up the fixup for the given \arg Fragment and \arg - /// Offset. - /// - /// If multiple fixups exist for the same fragment and offset it is undefined - /// which one is returned. - // - // FIXME: This isn't horribly slow in practice, but there are much nicer - // solutions to applying the fixups. - const MCAsmFixup *LookupFixup(const MCFragment *Fragment, - uint64_t Offset) const; - uint64_t getAddress() const { assert(Address != ~UINT64_C(0) && "Address not set!"); return Address; diff --git a/lib/MC/MCAssembler.cpp b/lib/MC/MCAssembler.cpp index 682b505e347..9afc169fcf4 100644 --- a/lib/MC/MCAssembler.cpp +++ b/lib/MC/MCAssembler.cpp @@ -402,12 +402,12 @@ public: uint32_t Word0; uint32_t Word1; }; - void ComputeScatteredRelocationInfo(MCAssembler &Asm, + void ComputeScatteredRelocationInfo(MCAssembler &Asm, MCFragment &Fragment, MCAsmFixup &Fixup, const MCValue &Target, DenseMap &SymbolMap, std::vector &Relocs) { - uint32_t Address = Fixup.Fragment->getOffset() + Fixup.Offset; + uint32_t Address = Fragment.getOffset() + Fixup.Offset; unsigned IsPCRel = 0; unsigned Type = RIT_Vanilla; @@ -453,7 +453,7 @@ public: } } - void ComputeRelocationInfo(MCAssembler &Asm, + void ComputeRelocationInfo(MCAssembler &Asm, MCFragment &Fragment, MCAsmFixup &Fixup, DenseMap &SymbolMap, std::vector &Relocs) { @@ -466,11 +466,11 @@ public: if (Target.getSymB() || (Target.getSymA() && !Target.getSymA()->isUndefined() && Target.getConstant())) - return ComputeScatteredRelocationInfo(Asm, Fixup, Target, + return ComputeScatteredRelocationInfo(Asm, Fragment, Fixup, Target, SymbolMap, Relocs); // See . - uint32_t Address = Fixup.Fragment->getOffset() + Fixup.Offset; + uint32_t Address = Fragment.getOffset() + Fixup.Offset; uint32_t Value = 0; unsigned Index = 0; unsigned IsPCRel = 0; @@ -766,17 +766,19 @@ public: // is written. std::vector RelocInfos; uint64_t RelocTableEnd = SectionDataStart + SectionDataFileSize; - for (MCAssembler::iterator it = Asm.begin(), ie = Asm.end(); it != ie; - ++it) { + for (MCAssembler::iterator it = Asm.begin(), + ie = Asm.end(); it != ie; ++it) { MCSectionData &SD = *it; // The assembler writes relocations in the reverse order they were seen. // // FIXME: It is probably more complicated than this. unsigned NumRelocsStart = RelocInfos.size(); - for (unsigned i = 0, e = SD.fixup_size(); i != e; ++i) - ComputeRelocationInfo(Asm, SD.getFixups()[e - i - 1], SymbolMap, - RelocInfos); + for (MCSectionData::reverse_iterator it2 = SD.rbegin(), + ie2 = SD.rend(); it2 != ie2; ++it2) + for (unsigned i = 0, e = it2->fixup_size(); i != e; ++i) + ComputeRelocationInfo(Asm, *it2, it2->getFixups()[e - i - 1], + SymbolMap, RelocInfos); unsigned NumRelocs = RelocInfos.size() - NumRelocsStart; uint64_t SectionStart = SectionDataStart + SD.getAddress(); @@ -905,35 +907,12 @@ MCSectionData::MCSectionData(const MCSection &_Section, MCAssembler *A) Address(~UINT64_C(0)), Size(~UINT64_C(0)), FileSize(~UINT64_C(0)), - LastFixupLookup(~0), HasInstructions(false) { if (A) A->getSectionList().push_back(this); } -const MCAsmFixup *MCSectionData::LookupFixup(const MCFragment *Fragment, - uint64_t Offset) const { - // Use a one level cache to turn the common case of accessing the fixups in - // order into O(1) instead of O(N). - unsigned i = LastFixupLookup, Count = Fixups.size(), End = Fixups.size(); - if (i >= End) - i = 0; - while (Count--) { - const MCAsmFixup &F = Fixups[i]; - if (F.Fragment == Fragment && F.Offset == Offset) { - LastFixupLookup = i; - return &F; - } - - ++i; - if (i == End) - i = 0; - } - - return 0; -} - /* *** */ MCSymbolData::MCSymbolData() : Symbol(0) {} @@ -997,10 +976,13 @@ void MCAssembler::LayoutSection(MCSectionData &SD) { break; // Otherwise, add fixups for the values. - for (uint64_t i = 0, e = FF.getCount(); i != e; ++i) { - MCAsmFixup Fix(F, i*FF.getValueSize(), FF.getValue(),FF.getValueSize()); - SD.getFixups().push_back(Fix); - } + // + // FIXME: What we want to do here is lower this to a data fragment once we + // realize it will need relocations. This means that the only place we + // need to worry about relocations and fixing is on data fragments. + for (uint64_t i = 0, e = FF.getCount(); i != e; ++i) + FF.getFixups().push_back(MCAsmFixup(i*FF.getValueSize(), FF.getValue(), + FF.getValueSize())); break; } @@ -1105,9 +1087,9 @@ static void WriteFileData(raw_ostream &OS, const MCFragment &F, if (!Target.isAbsolute()) { // Find the fixup. // - // FIXME: Find a better way to write in the fixes. - const MCAsmFixup *Fixup = - F.getParent()->LookupFixup(&F, i * FF.getValueSize()); + // FIXME: Find a better way to write in the fixes (move to + // MCDataFragment). + const MCAsmFixup *Fixup = FF.LookupFixup(i * FF.getValueSize()); assert(Fixup && "Missing fixup for fill value!"); Value = Fixup->FixedValue; }