mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-02-28 09:31:03 +00: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. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@99543 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
6307dd263f
commit
0cc8bd4861
@ -33,6 +33,11 @@ public:
|
|||||||
/// Get the assembler object this is a layout for.
|
/// Get the assembler object this is a layout for.
|
||||||
MCAssembler &getAssembler() const { return Assembler; }
|
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
|
/// @name Fragment Layout Data
|
||||||
/// @{
|
/// @{
|
||||||
|
|
||||||
|
@ -580,6 +580,8 @@ struct IndirectSymbolData {
|
|||||||
};
|
};
|
||||||
|
|
||||||
class MCAssembler {
|
class MCAssembler {
|
||||||
|
friend class MCAsmLayout;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
typedef iplist<MCSectionData> SectionDataListType;
|
typedef iplist<MCSectionData> SectionDataListType;
|
||||||
typedef iplist<MCSymbolData> SymbolDataListType;
|
typedef iplist<MCSymbolData> SymbolDataListType;
|
||||||
|
@ -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 {
|
uint64_t MCAsmLayout::getFragmentAddress(const MCFragment *F) const {
|
||||||
assert(F->getParent() && "Missing section()!");
|
assert(F->getParent() && "Missing section()!");
|
||||||
return getSectionAddress(F->getParent()) + getFragmentOffset(F);
|
return getSectionAddress(F->getParent()) + getFragmentOffset(F);
|
||||||
@ -716,6 +749,7 @@ bool MCAssembler::LayoutOnce(MCAsmLayout &Layout) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Scan for fragments that need relaxation.
|
// Scan for fragments that need relaxation.
|
||||||
|
bool WasRelaxed = false;
|
||||||
for (iterator it = begin(), ie = end(); it != ie; ++it) {
|
for (iterator it = begin(), ie = end(); it != ie; ++it) {
|
||||||
MCSectionData &SD = *it;
|
MCSectionData &SD = *it;
|
||||||
|
|
||||||
@ -747,6 +781,7 @@ bool MCAssembler::LayoutOnce(MCAsmLayout &Layout) {
|
|||||||
VecOS.flush();
|
VecOS.flush();
|
||||||
|
|
||||||
// Update the instruction fragment.
|
// Update the instruction fragment.
|
||||||
|
int SlideAmount = Code.size() - IF->getInstSize();
|
||||||
IF->setInst(Relaxed);
|
IF->setInst(Relaxed);
|
||||||
IF->getCode() = Code;
|
IF->getCode() = Code;
|
||||||
IF->getFixups().clear();
|
IF->getFixups().clear();
|
||||||
@ -756,15 +791,13 @@ bool MCAssembler::LayoutOnce(MCAsmLayout &Layout) {
|
|||||||
F.getKind()));
|
F.getKind()));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Restart layout.
|
// Update the layout, and remember that we relaxed.
|
||||||
//
|
Layout.UpdateForSlide(IF, SlideAmount);
|
||||||
// FIXME-PERF: This is O(N^2), but will be eliminated once we have a
|
WasRelaxed = true;
|
||||||
// smart MCAsmLayout object.
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return WasRelaxed;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MCAssembler::FinishLayout(MCAsmLayout &Layout) {
|
void MCAssembler::FinishLayout(MCAsmLayout &Layout) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user