From: Daniel Dunbar Date: Thu, 25 Mar 2010 19:35:56 +0000 (+0000) Subject: MC: Stop restarting layout on every relaxation. X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=0cc8bd48619b943379f5c2cc11a19fb189342925;p=oota-llvm.git MC: Stop restarting layout on every relaxation. - Still O(N^2), just a faster form, and now its the MCAsmLayout's fault. On the .s I am tuning against (combine.s from 403.gcc): -- ddunbar@lordcrumb:MC$ diff stats-before.txt stats-after.txt 5,10c5,10 < 1728 assembler - Number of assembler layout and relaxation steps < 7707 assembler - Number of emitted assembler fragments < 120588 assembler - Number of emitted object file bytes < 2233448 assembler - Number of evaluated fixups < 1727 assembler - Number of relaxed instructions < 6723845 mcexpr - Number of MCExpr evaluations --- > 3 assembler - Number of assembler layout and relaxation steps > 7707 assembler - Number of emitted assembler fragments > 120588 assembler - Number of emitted object file bytes > 14796 assembler - Number of evaluated fixups > 1727 assembler - Number of relaxed instructions > 67889 mcexpr - Number of MCExpr evaluations -- Feel free to LOL at the -before numbers, if you like. I am a little surprised we make more than 2 relaxation passes. It's pretty trivial for us to do relaxation out-of-order if that would give a speedup. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@99543 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/llvm/MC/MCAsmLayout.h b/include/llvm/MC/MCAsmLayout.h index f7f32aed6ff..ebf0520d091 100644 --- a/include/llvm/MC/MCAsmLayout.h +++ b/include/llvm/MC/MCAsmLayout.h @@ -33,6 +33,11 @@ public: /// Get the assembler object this is a layout for. MCAssembler &getAssembler() const { return Assembler; } + /// \brief Update the layout because a fragment has been resized. The + /// fragments size should have already been updated, the \arg SlideAmount is + /// the delta from the old size. + void UpdateForSlide(MCFragment *F, int SlideAmount); + /// @name Fragment Layout Data /// @{ diff --git a/include/llvm/MC/MCAssembler.h b/include/llvm/MC/MCAssembler.h index bdcc1bf4c14..031ca18d748 100644 --- a/include/llvm/MC/MCAssembler.h +++ b/include/llvm/MC/MCAssembler.h @@ -580,6 +580,8 @@ struct IndirectSymbolData { }; class MCAssembler { + friend class MCAsmLayout; + public: typedef iplist SectionDataListType; typedef iplist SymbolDataListType; diff --git a/lib/MC/MCAssembler.cpp b/lib/MC/MCAssembler.cpp index c3e2ca830de..79a8436bc24 100644 --- a/lib/MC/MCAssembler.cpp +++ b/lib/MC/MCAssembler.cpp @@ -45,6 +45,39 @@ STATISTIC(ObjectBytes, "Number of emitted object file bytes"); /* *** */ +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 are + // can guarantee convergence. + assert(SlideAmount >= 0 && "Negative slides not yet supported"); + + // Update the layout by simply recomputing the layout for the entire + // file. This is trivially correct, but very slow. + // + // 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; + + // 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); + } +} + uint64_t MCAsmLayout::getFragmentAddress(const MCFragment *F) const { assert(F->getParent() && "Missing section()!"); return getSectionAddress(F->getParent()) + getFragmentOffset(F); @@ -716,6 +749,7 @@ bool MCAssembler::LayoutOnce(MCAsmLayout &Layout) { } // Scan for fragments that need relaxation. + bool WasRelaxed = false; for (iterator it = begin(), ie = end(); it != ie; ++it) { MCSectionData &SD = *it; @@ -747,6 +781,7 @@ bool MCAssembler::LayoutOnce(MCAsmLayout &Layout) { VecOS.flush(); // Update the instruction fragment. + int SlideAmount = Code.size() - IF->getInstSize(); IF->setInst(Relaxed); IF->getCode() = Code; IF->getFixups().clear(); @@ -756,15 +791,13 @@ bool MCAssembler::LayoutOnce(MCAsmLayout &Layout) { F.getKind())); } - // Restart layout. - // - // FIXME-PERF: This is O(N^2), but will be eliminated once we have a - // smart MCAsmLayout object. - return true; + // Update the layout, and remember that we relaxed. + Layout.UpdateForSlide(IF, SlideAmount); + WasRelaxed = true; } } - return false; + return WasRelaxed; } void MCAssembler::FinishLayout(MCAsmLayout &Layout) {