1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-24 03:33:20 +01:00

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.

llvm-svn: 99543
This commit is contained in:
Daniel Dunbar 2010-03-25 19:35:56 +00:00
parent aeb4d40a70
commit 21e9834bc1
3 changed files with 46 additions and 6 deletions

View File

@ -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
/// @{

View File

@ -580,6 +580,8 @@ struct IndirectSymbolData {
};
class MCAssembler {
friend class MCAsmLayout;
public:
typedef iplist<MCSectionData> SectionDataListType;
typedef iplist<MCSymbolData> SymbolDataListType;

View File

@ -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) {