Remember the contents of leb and dwarfline fragments when relaxing. This avoids

having to evaluate the expression again when writing.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@120920 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Rafael Espindola 2010-12-04 21:58:52 +00:00
parent 2a7942926b
commit db74aeadcd
4 changed files with 27 additions and 59 deletions

View File

@ -352,13 +352,11 @@ class MCLEBFragment : public MCFragment {
/// IsSigned - True if this is a sleb128, false if uleb128. /// IsSigned - True if this is a sleb128, false if uleb128.
bool IsSigned; bool IsSigned;
/// Size - The current size estimate. SmallString<8> Contents;
uint64_t Size;
public: public:
MCLEBFragment(const MCExpr &Value_, bool IsSigned_, MCSectionData *SD) MCLEBFragment(const MCExpr &Value_, bool IsSigned_, MCSectionData *SD)
: MCFragment(FT_LEB, SD), : MCFragment(FT_LEB, SD),
Value(&Value_), IsSigned(IsSigned_), Size(1) {} Value(&Value_), IsSigned(IsSigned_) { Contents.push_back(0); }
/// @name Accessors /// @name Accessors
/// @{ /// @{
@ -367,9 +365,8 @@ public:
bool isSigned() const { return IsSigned; } bool isSigned() const { return IsSigned; }
uint64_t getSize() const { return Size; } SmallString<8> &getContents() { return Contents; }
const SmallString<8> &getContents() const { return Contents; }
void setSize(uint64_t Size_) { Size = Size_; }
/// @} /// @}
@ -388,14 +385,13 @@ class MCDwarfLineAddrFragment : public MCFragment {
/// make up the address delta between two .loc dwarf directives. /// make up the address delta between two .loc dwarf directives.
const MCExpr *AddrDelta; const MCExpr *AddrDelta;
/// Size - The current size estimate. SmallString<8> Contents;
uint64_t Size;
public: public:
MCDwarfLineAddrFragment(int64_t _LineDelta, const MCExpr &_AddrDelta, MCDwarfLineAddrFragment(int64_t _LineDelta, const MCExpr &_AddrDelta,
MCSectionData *SD = 0) MCSectionData *SD = 0)
: MCFragment(FT_Dwarf, SD), : MCFragment(FT_Dwarf, SD),
LineDelta(_LineDelta), AddrDelta(&_AddrDelta), Size(1) {} LineDelta(_LineDelta), AddrDelta(&_AddrDelta) { Contents.push_back(0); }
/// @name Accessors /// @name Accessors
/// @{ /// @{
@ -404,9 +400,8 @@ public:
const MCExpr &getAddrDelta() const { return *AddrDelta; } const MCExpr &getAddrDelta() const { return *AddrDelta; }
uint64_t getSize() const { return Size; } SmallString<8> &getContents() { return Contents; }
const SmallString<8> &getContents() const { return Contents; }
void setSize(uint64_t Size_) { Size = Size_; }
/// @} /// @}

View File

@ -220,9 +220,6 @@ namespace llvm {
static void Emit(MCStreamer *MCOS, static void Emit(MCStreamer *MCOS,
int64_t LineDelta,uint64_t AddrDelta); int64_t LineDelta,uint64_t AddrDelta);
/// Utility function to compute the size of the encoding.
static uint64_t ComputeSize(int64_t LineDelta, uint64_t AddrDelta);
/// Utility function to write the encoding to an object writer. /// Utility function to write the encoding to an object writer.
static void Write(MCObjectWriter *OW, static void Write(MCObjectWriter *OW,
int64_t LineDelta, uint64_t AddrDelta); int64_t LineDelta, uint64_t AddrDelta);

View File

@ -348,7 +348,7 @@ uint64_t MCAssembler::ComputeFragmentSize(const MCFragment &F,
return cast<MCInstFragment>(F).getInstSize(); return cast<MCInstFragment>(F).getInstSize();
case MCFragment::FT_LEB: case MCFragment::FT_LEB:
return cast<MCLEBFragment>(F).getSize(); return cast<MCLEBFragment>(F).getContents().size();
case MCFragment::FT_Align: { case MCFragment::FT_Align: {
const MCAlignFragment &AF = cast<MCAlignFragment>(F); const MCAlignFragment &AF = cast<MCAlignFragment>(F);
@ -370,7 +370,7 @@ uint64_t MCAssembler::ComputeFragmentSize(const MCFragment &F,
return cast<MCOrgFragment>(F).getSize(); return cast<MCOrgFragment>(F).getSize();
case MCFragment::FT_Dwarf: case MCFragment::FT_Dwarf:
return cast<MCDwarfLineAddrFragment>(F).getSize(); return cast<MCDwarfLineAddrFragment>(F).getContents().size();
} }
assert(0 && "invalid fragment kind"); assert(0 && "invalid fragment kind");
@ -522,20 +522,7 @@ static void WriteFragmentData(const MCAssembler &Asm, const MCAsmLayout &Layout,
case MCFragment::FT_LEB: { case MCFragment::FT_LEB: {
MCLEBFragment &LF = cast<MCLEBFragment>(F); MCLEBFragment &LF = cast<MCLEBFragment>(F);
OW->WriteBytes(LF.getContents().str());
// FIXME: It is probably better if we don't call EvaluateAsAbsolute in
// here.
int64_t Value;
bool IsAbs = LF.getValue().EvaluateAsAbsolute(Value, &Layout);
assert(IsAbs);
(void) IsAbs;
SmallString<32> Tmp;
raw_svector_ostream OSE(Tmp);
if (LF.isSigned())
MCObjectWriter::EncodeSLEB128(Value, OSE);
else
MCObjectWriter::EncodeULEB128(Value, OSE);
OW->WriteBytes(OSE.str());
break; break;
} }
@ -550,15 +537,7 @@ static void WriteFragmentData(const MCAssembler &Asm, const MCAsmLayout &Layout,
case MCFragment::FT_Dwarf: { case MCFragment::FT_Dwarf: {
const MCDwarfLineAddrFragment &OF = cast<MCDwarfLineAddrFragment>(F); const MCDwarfLineAddrFragment &OF = cast<MCDwarfLineAddrFragment>(F);
OW->WriteBytes(OF.getContents().str());
// The AddrDelta is really unsigned and it can only increase.
int64_t AddrDelta;
OF.getAddrDelta().EvaluateAsAbsolute(AddrDelta, &Layout);
int64_t LineDelta;
LineDelta = OF.getLineDelta();
MCDwarfLineAddr::Write(OW, LineDelta, (uint64_t)AddrDelta);
break; break;
} }
} }
@ -830,29 +809,34 @@ bool MCAssembler::RelaxOrg(const MCObjectWriter &Writer,
bool MCAssembler::RelaxLEB(const MCObjectWriter &Writer, bool MCAssembler::RelaxLEB(const MCObjectWriter &Writer,
MCAsmLayout &Layout, MCAsmLayout &Layout,
MCLEBFragment &LF) { MCLEBFragment &LF) {
int64_t Value; int64_t Value = 0;
uint64_t OldSize = LF.getContents().size();
LF.getValue().EvaluateAsAbsolute(Value, &Layout); LF.getValue().EvaluateAsAbsolute(Value, &Layout);
SmallString<32> Tmp; SmallString<8> &Data = LF.getContents();
raw_svector_ostream OSE(Tmp); Data.clear();
raw_svector_ostream OSE(Data);
if (LF.isSigned()) if (LF.isSigned())
MCObjectWriter::EncodeSLEB128(Value, OSE); MCObjectWriter::EncodeSLEB128(Value, OSE);
else else
MCObjectWriter::EncodeULEB128(Value, OSE); MCObjectWriter::EncodeULEB128(Value, OSE);
uint64_t OldSize = LF.getSize(); OSE.flush();
LF.setSize(OSE.GetNumBytesInBuffer()); return OldSize != LF.getContents().size();
return OldSize != LF.getSize();
} }
bool MCAssembler::RelaxDwarfLineAddr(const MCObjectWriter &Writer, bool MCAssembler::RelaxDwarfLineAddr(const MCObjectWriter &Writer,
MCAsmLayout &Layout, MCAsmLayout &Layout,
MCDwarfLineAddrFragment &DF) { MCDwarfLineAddrFragment &DF) {
int64_t AddrDelta; int64_t AddrDelta = 0;
uint64_t OldSize = DF.getContents().size();
DF.getAddrDelta().EvaluateAsAbsolute(AddrDelta, &Layout); DF.getAddrDelta().EvaluateAsAbsolute(AddrDelta, &Layout);
int64_t LineDelta; int64_t LineDelta;
LineDelta = DF.getLineDelta(); LineDelta = DF.getLineDelta();
uint64_t OldSize = DF.getSize(); SmallString<8> &Data = DF.getContents();
DF.setSize(MCDwarfLineAddr::ComputeSize(LineDelta, AddrDelta)); Data.clear();
return OldSize != DF.getSize(); raw_svector_ostream OSE(Data);
MCDwarfLineAddr::Encode(LineDelta, AddrDelta, OSE);
OSE.flush();
return OldSize != Data.size();
} }
bool MCAssembler::LayoutOnce(const MCObjectWriter &Writer, bool MCAssembler::LayoutOnce(const MCObjectWriter &Writer,

View File

@ -320,14 +320,6 @@ void MCDwarfFileTable::Emit(MCStreamer *MCOS,
MCOS->EmitLabel(LineEndSym); MCOS->EmitLabel(LineEndSym);
} }
/// Utility function to compute the size of the encoding.
uint64_t MCDwarfLineAddr::ComputeSize(int64_t LineDelta, uint64_t AddrDelta) {
SmallString<256> Tmp;
raw_svector_ostream OS(Tmp);
MCDwarfLineAddr::Encode(LineDelta, AddrDelta, OS);
return OS.GetNumBytesInBuffer();
}
/// Utility function to write the encoding to an object writer. /// Utility function to write the encoding to an object writer.
void MCDwarfLineAddr::Write(MCObjectWriter *OW, int64_t LineDelta, void MCDwarfLineAddr::Write(MCObjectWriter *OW, int64_t LineDelta,
uint64_t AddrDelta) { uint64_t AddrDelta) {