Layout one section until no relaxations are done and then move to the next

section.

This helps because in practice sections form a dag with debug sections pointing
to text sections. Finishing up the text sections first makes the debug section
relaxation trivial.

llvm-svn: 122314
This commit is contained in:
Rafael Espindola 2010-12-21 04:22:09 +00:00
parent c874f6c9ff
commit 98d93c5294
2 changed files with 43 additions and 34 deletions

View File

@ -711,6 +711,8 @@ private:
/// were adjusted.
bool LayoutOnce(MCAsmLayout &Layout);
bool LayoutSectionOnce(MCAsmLayout &Layout, MCSectionData &SD);
bool RelaxInstruction(MCAsmLayout &Layout, MCInstFragment &IF);
bool RelaxOrg(MCAsmLayout &Layout, MCOrgFragment &OF);

View File

@ -707,46 +707,53 @@ bool MCAssembler::RelaxAlignment(MCAsmLayout &Layout,
return OldSize != Size;
}
bool MCAssembler::LayoutSectionOnce(MCAsmLayout &Layout,
MCSectionData &SD) {
MCFragment *FirstInvalidFragment = NULL;
// Scan for fragments that need relaxation.
for (MCSectionData::iterator it2 = SD.begin(),
ie2 = SD.end(); it2 != ie2; ++it2) {
// Check if this is an fragment that needs relaxation.
bool relaxedFrag = false;
switch(it2->getKind()) {
default:
break;
case MCFragment::FT_Align:
relaxedFrag = RelaxAlignment(Layout, *cast<MCAlignFragment>(it2));
break;
case MCFragment::FT_Inst:
relaxedFrag = RelaxInstruction(Layout, *cast<MCInstFragment>(it2));
break;
case MCFragment::FT_Org:
relaxedFrag = RelaxOrg(Layout, *cast<MCOrgFragment>(it2));
break;
case MCFragment::FT_Dwarf:
relaxedFrag = RelaxDwarfLineAddr(Layout,
*cast<MCDwarfLineAddrFragment>(it2));
break;
case MCFragment::FT_LEB:
relaxedFrag = RelaxLEB(Layout, *cast<MCLEBFragment>(it2));
break;
}
// Update the layout, and remember that we relaxed.
if (relaxedFrag && !FirstInvalidFragment)
FirstInvalidFragment = it2;
}
if (FirstInvalidFragment) {
Layout.Invalidate(FirstInvalidFragment);
return true;
}
return false;
}
bool MCAssembler::LayoutOnce(MCAsmLayout &Layout) {
++stats::RelaxationSteps;
// Scan for fragments that need relaxation.
bool WasRelaxed = false;
for (iterator it = begin(), ie = end(); it != ie; ++it) {
MCSectionData &SD = *it;
MCFragment *FirstInvalidFragment = NULL;
for (MCSectionData::iterator it2 = SD.begin(),
ie2 = SD.end(); it2 != ie2; ++it2) {
// Check if this is an fragment that needs relaxation.
bool relaxedFrag = false;
switch(it2->getKind()) {
default:
break;
case MCFragment::FT_Align:
relaxedFrag = RelaxAlignment(Layout, *cast<MCAlignFragment>(it2));
break;
case MCFragment::FT_Inst:
relaxedFrag = RelaxInstruction(Layout, *cast<MCInstFragment>(it2));
break;
case MCFragment::FT_Org:
relaxedFrag = RelaxOrg(Layout, *cast<MCOrgFragment>(it2));
break;
case MCFragment::FT_Dwarf:
relaxedFrag = RelaxDwarfLineAddr(Layout,
*cast<MCDwarfLineAddrFragment>(it2));
break;
case MCFragment::FT_LEB:
relaxedFrag = RelaxLEB(Layout, *cast<MCLEBFragment>(it2));
break;
}
// Update the layout, and remember that we relaxed.
if (relaxedFrag && !FirstInvalidFragment)
FirstInvalidFragment = it2;
WasRelaxed |= relaxedFrag;
}
if (FirstInvalidFragment)
Layout.Invalidate(FirstInvalidFragment);
while(LayoutSectionOnce(Layout, SD))
WasRelaxed = true;
}
return WasRelaxed;