Don't relax org or align. They change size as the relaxation happens, but they

are not actually relaxed. For example, a section with only alignments will never
needs relaxation.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@122356 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Rafael Espindola 2010-12-21 20:35:18 +00:00
parent a83bf35d16
commit 7a45903bf4
2 changed files with 30 additions and 62 deletions

View File

@ -227,9 +227,6 @@ class MCAlignFragment : public MCFragment {
/// cannot be satisfied in this width then this fragment is ignored.
unsigned MaxBytesToEmit;
/// Size - The current estimate of the size.
unsigned Size;
/// EmitNops - Flag to indicate that (optimal) NOPs should be emitted instead
/// of using the provided value. The exact interpretation of this flag is
/// target dependent.
@ -240,7 +237,7 @@ public:
unsigned _MaxBytesToEmit, MCSectionData *SD = 0)
: MCFragment(FT_Align, SD), Alignment(_Alignment),
Value(_Value),ValueSize(_ValueSize),
MaxBytesToEmit(_MaxBytesToEmit), Size(0), EmitNops(false) {}
MaxBytesToEmit(_MaxBytesToEmit), EmitNops(false) {}
/// @name Accessors
/// @{
@ -251,10 +248,6 @@ public:
unsigned getValueSize() const { return ValueSize; }
unsigned getSize() const { return Size; }
void setSize(unsigned Size_) { Size = Size_; }
unsigned getMaxBytesToEmit() const { return MaxBytesToEmit; }
bool hasEmitNops() const { return EmitNops; }
@ -312,13 +305,10 @@ class MCOrgFragment : public MCFragment {
/// Value - Value to use for filling bytes.
int8_t Value;
/// Size - The current estimate of the size.
unsigned Size;
public:
MCOrgFragment(const MCExpr &_Offset, int8_t _Value, MCSectionData *SD = 0)
: MCFragment(FT_Org, SD),
Offset(&_Offset), Value(_Value), Size(0) {}
Offset(&_Offset), Value(_Value) {}
/// @name Accessors
/// @{
@ -327,9 +317,6 @@ public:
uint8_t getValue() const { return Value; }
unsigned getSize() const { return Size; }
void setSize(unsigned Size_) { Size = Size_; }
/// @}
static bool classof(const MCFragment *F) {
@ -715,14 +702,10 @@ private:
bool RelaxInstruction(MCAsmLayout &Layout, MCInstFragment &IF);
bool RelaxOrg(MCAsmLayout &Layout, MCOrgFragment &OF);
bool RelaxLEB(MCAsmLayout &Layout, MCLEBFragment &IF);
bool RelaxDwarfLineAddr(MCAsmLayout &Layout, MCDwarfLineAddrFragment &DF);
bool RelaxAlignment(MCAsmLayout &Layout, MCAlignFragment &DF);
/// FinishLayout - Finalize a layout, including fragment lowering.
void FinishLayout(MCAsmLayout &Layout);
@ -732,7 +715,7 @@ private:
public:
/// Compute the effective fragment size assuming it is layed out at the given
/// \arg SectionAddress and \arg FragmentOffset.
uint64_t ComputeFragmentSize(const MCFragment &F) const;
uint64_t ComputeFragmentSize(const MCAsmLayout &Layout, const MCFragment &F) const;
/// Find the symbol which defines the atom containing the given symbol, or
/// null if there is no such symbol.

View File

@ -109,7 +109,7 @@ uint64_t MCAsmLayout::getSymbolOffset(const MCSymbolData *SD) const {
uint64_t MCAsmLayout::getSectionAddressSize(const MCSectionData *SD) const {
// The size is the last fragment's end offset.
const MCFragment &F = SD->getFragmentList().back();
return getFragmentOffset(&F) + getAssembler().ComputeFragmentSize(F);
return getFragmentOffset(&F) + getAssembler().ComputeFragmentSize(*this, F);
}
uint64_t MCAsmLayout::getSectionFileSize(const MCSectionData *SD) const {
@ -272,7 +272,8 @@ bool MCAssembler::EvaluateFixup(const MCAsmLayout &Layout,
return IsResolved;
}
uint64_t MCAssembler::ComputeFragmentSize(const MCFragment &F) const {
uint64_t MCAssembler::ComputeFragmentSize(const MCAsmLayout &Layout,
const MCFragment &F) const {
switch (F.getKind()) {
case MCFragment::FT_Data:
return cast<MCDataFragment>(F).getContents().size();
@ -284,11 +285,29 @@ uint64_t MCAssembler::ComputeFragmentSize(const MCFragment &F) const {
case MCFragment::FT_LEB:
return cast<MCLEBFragment>(F).getContents().size();
case MCFragment::FT_Align:
return cast<MCAlignFragment>(F).getSize();
case MCFragment::FT_Align: {
const MCAlignFragment &AF = cast<MCAlignFragment>(F);
unsigned Offset = Layout.getFragmentOffset(&AF);
unsigned Size = OffsetToAlignment(Offset, AF.getAlignment());
if (Size > AF.getMaxBytesToEmit())
return 0;
return Size;
}
case MCFragment::FT_Org:
return cast<MCOrgFragment>(F).getSize();
case MCFragment::FT_Org: {
MCOrgFragment &OF = cast<MCOrgFragment>(F);
int64_t TargetLocation;
if (!OF.getOffset().EvaluateAsAbsolute(TargetLocation, Layout))
report_fatal_error("expected assembly-time absolute expression");
// FIXME: We need a way to communicate this error.
uint64_t FragmentOffset = Layout.getFragmentOffset(&OF);
int64_t Size = TargetLocation - FragmentOffset;
if (Size < 0 || Size >= 0x40000000)
report_fatal_error("invalid .org offset '" + Twine(TargetLocation) +
"' (at offset '" + Twine(FragmentOffset) + "')");
return Size;
}
case MCFragment::FT_Dwarf:
return cast<MCDwarfLineAddrFragment>(F).getContents().size();
@ -313,7 +332,7 @@ void MCAsmLayout::LayoutFragment(MCFragment *F) {
// Compute fragment offset and size.
uint64_t Offset = 0;
if (Prev)
Offset += Prev->Offset + getAssembler().ComputeFragmentSize(*Prev);
Offset += Prev->Offset + getAssembler().ComputeFragmentSize(*this, *Prev);
F->Offset = Offset;
LastValidFragment[F->getParent()] = F;
@ -329,7 +348,7 @@ static void WriteFragmentData(const MCAssembler &Asm, const MCAsmLayout &Layout,
++stats::EmittedFragments;
// FIXME: Embed in fragments instead?
uint64_t FragmentSize = Asm.ComputeFragmentSize(F);
uint64_t FragmentSize = Asm.ComputeFragmentSize(Layout, F);
switch (F.getKind()) {
case MCFragment::FT_Align: {
MCAlignFragment &AF = cast<MCAlignFragment>(F);
@ -649,23 +668,6 @@ bool MCAssembler::RelaxInstruction(MCAsmLayout &Layout,
return true;
}
bool MCAssembler::RelaxOrg(MCAsmLayout &Layout, MCOrgFragment &OF) {
int64_t TargetLocation;
if (!OF.getOffset().EvaluateAsAbsolute(TargetLocation, Layout))
report_fatal_error("expected assembly-time absolute expression");
// FIXME: We need a way to communicate this error.
uint64_t FragmentOffset = Layout.getFragmentOffset(&OF);
int64_t Offset = TargetLocation - FragmentOffset;
if (Offset < 0 || Offset >= 0x40000000)
report_fatal_error("invalid .org offset '" + Twine(TargetLocation) +
"' (at offset '" + Twine(FragmentOffset) + "')");
unsigned OldSize = OF.getSize();
OF.setSize(Offset);
return OldSize != OF.getSize();
}
bool MCAssembler::RelaxLEB(MCAsmLayout &Layout, MCLEBFragment &LF) {
int64_t Value = 0;
uint64_t OldSize = LF.getContents().size();
@ -696,17 +698,6 @@ bool MCAssembler::RelaxDwarfLineAddr(MCAsmLayout &Layout,
return OldSize != Data.size();
}
bool MCAssembler::RelaxAlignment(MCAsmLayout &Layout,
MCAlignFragment &AF) {
unsigned Offset = Layout.getFragmentOffset(&AF);
unsigned Size = OffsetToAlignment(Offset, AF.getAlignment());
if (Size > AF.getMaxBytesToEmit())
Size = 0;
unsigned OldSize = AF.getSize();
AF.setSize(Size);
return OldSize != Size;
}
bool MCAssembler::LayoutSectionOnce(MCAsmLayout &Layout,
MCSectionData &SD) {
MCFragment *FirstInvalidFragment = NULL;
@ -718,15 +709,9 @@ bool MCAssembler::LayoutSectionOnce(MCAsmLayout &Layout,
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));