2009-05-15 08:11:17 +08:00
|
|
|
//===--- lib/CodeGen/DIE.cpp - DWARF Info Entries -------------------------===//
|
|
|
|
//
|
|
|
|
// The LLVM Compiler Infrastructure
|
|
|
|
//
|
|
|
|
// This file is distributed under the University of Illinois Open Source
|
|
|
|
// License. See LICENSE.TXT for details.
|
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
//
|
|
|
|
// Data structures for DWARF info entries.
|
2013-01-08 06:40:45 +08:00
|
|
|
//
|
2009-05-15 08:11:17 +08:00
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
2015-01-06 05:29:41 +08:00
|
|
|
#include "llvm/CodeGen/DIE.h"
|
2014-10-04 23:49:50 +08:00
|
|
|
#include "DwarfCompileUnit.h"
|
2013-07-03 07:40:10 +08:00
|
|
|
#include "DwarfDebug.h"
|
2013-12-18 07:32:35 +08:00
|
|
|
#include "DwarfUnit.h"
|
2010-01-17 15:46:39 +08:00
|
|
|
#include "llvm/ADT/Twine.h"
|
2009-05-15 08:11:17 +08:00
|
|
|
#include "llvm/CodeGen/AsmPrinter.h"
|
2013-01-02 19:36:10 +08:00
|
|
|
#include "llvm/IR/DataLayout.h"
|
2009-08-23 04:48:53 +08:00
|
|
|
#include "llvm/MC/MCAsmInfo.h"
|
2014-10-21 08:25:49 +08:00
|
|
|
#include "llvm/MC/MCContext.h"
|
2010-01-20 15:41:15 +08:00
|
|
|
#include "llvm/MC/MCStreamer.h"
|
2010-01-17 02:50:28 +08:00
|
|
|
#include "llvm/MC/MCSymbol.h"
|
2009-12-24 08:27:55 +08:00
|
|
|
#include "llvm/Support/Debug.h"
|
2009-07-12 04:10:48 +08:00
|
|
|
#include "llvm/Support/ErrorHandling.h"
|
2009-08-23 09:01:17 +08:00
|
|
|
#include "llvm/Support/Format.h"
|
2010-01-23 06:09:00 +08:00
|
|
|
#include "llvm/Support/FormattedStream.h"
|
2014-02-22 22:00:39 +08:00
|
|
|
#include "llvm/Support/LEB128.h"
|
2013-07-27 01:02:41 +08:00
|
|
|
#include "llvm/Support/MD5.h"
|
2015-03-24 03:32:43 +08:00
|
|
|
#include "llvm/Support/raw_ostream.h"
|
2009-05-15 08:11:17 +08:00
|
|
|
using namespace llvm;
|
|
|
|
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// DIEAbbrevData Implementation
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
|
|
|
/// Profile - Used to gather unique data for the abbreviation folding set.
|
|
|
|
///
|
|
|
|
void DIEAbbrevData::Profile(FoldingSetNodeID &ID) const {
|
2013-10-22 03:18:31 +08:00
|
|
|
// Explicitly cast to an integer type for which FoldingSetNodeID has
|
|
|
|
// overloads. Otherwise MSVC 2010 thinks this call is ambiguous.
|
|
|
|
ID.AddInteger(unsigned(Attribute));
|
|
|
|
ID.AddInteger(unsigned(Form));
|
2009-05-15 08:11:17 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// DIEAbbrev Implementation
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
|
|
|
/// Profile - Used to gather unique data for the abbreviation folding set.
|
|
|
|
///
|
|
|
|
void DIEAbbrev::Profile(FoldingSetNodeID &ID) const {
|
2013-10-22 03:18:31 +08:00
|
|
|
ID.AddInteger(unsigned(Tag));
|
2014-03-05 09:44:58 +08:00
|
|
|
ID.AddInteger(unsigned(Children));
|
2009-05-15 08:11:17 +08:00
|
|
|
|
|
|
|
// For each attribute description.
|
|
|
|
for (unsigned i = 0, N = Data.size(); i < N; ++i)
|
|
|
|
Data[i].Profile(ID);
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Emit - Print the abbreviation using the specified asm printer.
|
|
|
|
///
|
2015-03-04 10:30:08 +08:00
|
|
|
void DIEAbbrev::Emit(const AsmPrinter *AP) const {
|
2009-05-15 08:11:17 +08:00
|
|
|
// Emit its Dwarf tag type.
|
2010-04-05 08:13:49 +08:00
|
|
|
AP->EmitULEB128(Tag, dwarf::TagString(Tag));
|
2009-05-15 08:11:17 +08:00
|
|
|
|
|
|
|
// Emit whether it has children DIEs.
|
2014-03-05 09:44:58 +08:00
|
|
|
AP->EmitULEB128((unsigned)Children, dwarf::ChildrenString(Children));
|
2009-05-15 08:11:17 +08:00
|
|
|
|
|
|
|
// For each attribute description.
|
|
|
|
for (unsigned i = 0, N = Data.size(); i < N; ++i) {
|
|
|
|
const DIEAbbrevData &AttrData = Data[i];
|
|
|
|
|
|
|
|
// Emit attribute type.
|
2010-04-05 08:13:49 +08:00
|
|
|
AP->EmitULEB128(AttrData.getAttribute(),
|
2011-07-29 11:49:23 +08:00
|
|
|
dwarf::AttributeString(AttrData.getAttribute()));
|
2009-05-15 08:11:17 +08:00
|
|
|
|
|
|
|
// Emit form type.
|
2010-04-05 08:13:49 +08:00
|
|
|
AP->EmitULEB128(AttrData.getForm(),
|
|
|
|
dwarf::FormEncodingString(AttrData.getForm()));
|
2009-05-15 08:11:17 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
// Mark end of abbreviation.
|
2010-04-05 08:13:49 +08:00
|
|
|
AP->EmitULEB128(0, "EOM(1)");
|
|
|
|
AP->EmitULEB128(0, "EOM(2)");
|
2009-05-15 08:11:17 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
#ifndef NDEBUG
|
2009-08-23 09:01:17 +08:00
|
|
|
void DIEAbbrev::print(raw_ostream &O) {
|
2009-05-15 08:11:17 +08:00
|
|
|
O << "Abbreviation @"
|
2009-08-23 09:01:17 +08:00
|
|
|
<< format("0x%lx", (long)(intptr_t)this)
|
2009-05-15 08:11:17 +08:00
|
|
|
<< " "
|
|
|
|
<< dwarf::TagString(Tag)
|
|
|
|
<< " "
|
2014-03-05 09:44:58 +08:00
|
|
|
<< dwarf::ChildrenString(Children)
|
2009-08-23 09:01:17 +08:00
|
|
|
<< '\n';
|
2009-05-15 08:11:17 +08:00
|
|
|
|
|
|
|
for (unsigned i = 0, N = Data.size(); i < N; ++i) {
|
|
|
|
O << " "
|
|
|
|
<< dwarf::AttributeString(Data[i].getAttribute())
|
|
|
|
<< " "
|
|
|
|
<< dwarf::FormEncodingString(Data[i].getForm())
|
2009-08-23 09:01:17 +08:00
|
|
|
<< '\n';
|
2009-05-15 08:11:17 +08:00
|
|
|
}
|
|
|
|
}
|
2009-12-24 08:27:55 +08:00
|
|
|
void DIEAbbrev::dump() { print(dbgs()); }
|
2009-05-15 08:11:17 +08:00
|
|
|
#endif
|
|
|
|
|
2013-11-21 09:01:30 +08:00
|
|
|
/// Climb up the parent chain to get the unit DIE to which this DIE
|
2013-10-30 06:57:10 +08:00
|
|
|
/// belongs.
|
2013-11-20 07:08:21 +08:00
|
|
|
const DIE *DIE::getUnit() const {
|
|
|
|
const DIE *Cu = getUnitOrNull();
|
2013-11-01 01:54:35 +08:00
|
|
|
assert(Cu && "We should not have orphaned DIEs.");
|
|
|
|
return Cu;
|
|
|
|
}
|
|
|
|
|
2013-11-21 09:01:30 +08:00
|
|
|
/// Climb up the parent chain to get the unit DIE this DIE belongs
|
2013-11-01 01:54:35 +08:00
|
|
|
/// to. Return NULL if DIE is not added to an owner yet.
|
2013-11-20 07:08:21 +08:00
|
|
|
const DIE *DIE::getUnitOrNull() const {
|
2013-10-30 06:57:10 +08:00
|
|
|
const DIE *p = this;
|
|
|
|
while (p) {
|
2013-11-20 07:08:21 +08:00
|
|
|
if (p->getTag() == dwarf::DW_TAG_compile_unit ||
|
|
|
|
p->getTag() == dwarf::DW_TAG_type_unit)
|
2013-10-30 06:57:10 +08:00
|
|
|
return p;
|
|
|
|
p = p->getParent();
|
|
|
|
}
|
2014-04-24 14:44:33 +08:00
|
|
|
return nullptr;
|
2013-10-30 06:57:10 +08:00
|
|
|
}
|
|
|
|
|
2015-05-28 03:30:27 +08:00
|
|
|
DIEValue *DIE::findAttribute(dwarf::Attribute Attribute) const {
|
|
|
|
const SmallVectorImpl<DIEValue *> &Values = getValues();
|
2013-08-07 09:18:33 +08:00
|
|
|
const DIEAbbrev &Abbrevs = getAbbrev();
|
|
|
|
|
|
|
|
// Iterate through all the attributes until we find the one we're
|
|
|
|
// looking for, if we can't find it return NULL.
|
|
|
|
for (size_t i = 0; i < Values.size(); ++i)
|
|
|
|
if (Abbrevs.getData()[i].getAttribute() == Attribute)
|
|
|
|
return Values[i];
|
2015-05-28 03:30:27 +08:00
|
|
|
return nullptr;
|
2013-08-07 09:18:33 +08:00
|
|
|
}
|
|
|
|
|
2009-05-15 08:11:17 +08:00
|
|
|
#ifndef NDEBUG
|
2013-05-07 01:50:50 +08:00
|
|
|
void DIE::print(raw_ostream &O, unsigned IndentCount) const {
|
2009-05-15 08:11:17 +08:00
|
|
|
const std::string Indent(IndentCount, ' ');
|
|
|
|
bool isBlock = Abbrev.getTag() == 0;
|
|
|
|
|
|
|
|
if (!isBlock) {
|
|
|
|
O << Indent
|
|
|
|
<< "Die: "
|
2009-08-23 09:01:17 +08:00
|
|
|
<< format("0x%lx", (long)(intptr_t)this)
|
2009-05-15 08:11:17 +08:00
|
|
|
<< ", Offset: " << Offset
|
2010-03-10 07:38:23 +08:00
|
|
|
<< ", Size: " << Size << "\n";
|
2009-05-15 08:11:17 +08:00
|
|
|
|
|
|
|
O << Indent
|
|
|
|
<< dwarf::TagString(Abbrev.getTag())
|
|
|
|
<< " "
|
2014-03-05 09:44:58 +08:00
|
|
|
<< dwarf::ChildrenString(Abbrev.hasChildren()) << "\n";
|
2009-05-15 08:11:17 +08:00
|
|
|
} else {
|
2010-03-10 07:38:23 +08:00
|
|
|
O << "Size: " << Size << "\n";
|
2009-05-15 08:11:17 +08:00
|
|
|
}
|
|
|
|
|
2013-03-30 07:34:06 +08:00
|
|
|
const SmallVectorImpl<DIEAbbrevData> &Data = Abbrev.getData();
|
2009-05-15 08:11:17 +08:00
|
|
|
|
|
|
|
IndentCount += 2;
|
|
|
|
for (unsigned i = 0, N = Data.size(); i < N; ++i) {
|
|
|
|
O << Indent;
|
|
|
|
|
|
|
|
if (!isBlock)
|
|
|
|
O << dwarf::AttributeString(Data[i].getAttribute());
|
|
|
|
else
|
|
|
|
O << "Blk[" << i << "]";
|
|
|
|
|
|
|
|
O << " "
|
|
|
|
<< dwarf::FormEncodingString(Data[i].getForm())
|
|
|
|
<< " ";
|
2015-05-28 03:30:27 +08:00
|
|
|
Values[i]->print(O);
|
2009-05-15 08:11:17 +08:00
|
|
|
O << "\n";
|
|
|
|
}
|
|
|
|
IndentCount -= 2;
|
|
|
|
|
|
|
|
for (unsigned j = 0, M = Children.size(); j < M; ++j) {
|
2013-05-07 01:50:50 +08:00
|
|
|
Children[j]->print(O, IndentCount+4);
|
2009-05-15 08:11:17 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
if (!isBlock) O << "\n";
|
|
|
|
}
|
|
|
|
|
|
|
|
void DIE::dump() {
|
2009-12-24 08:27:55 +08:00
|
|
|
print(dbgs());
|
2009-05-15 08:11:17 +08:00
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2015-05-23 09:45:07 +08:00
|
|
|
void DIEValue::EmitValue(const AsmPrinter *AP, dwarf::Form Form) const {
|
|
|
|
switch (Ty) {
|
2015-05-28 05:15:43 +08:00
|
|
|
#define HANDLE_DIEVALUE(T) \
|
|
|
|
case is##T: \
|
|
|
|
cast<DIE##T>(this)->EmitValueImpl(AP, Form); \
|
2015-05-23 09:45:07 +08:00
|
|
|
break;
|
2015-05-28 05:15:43 +08:00
|
|
|
#include "llvm/CodeGen/DIEValue.def"
|
2015-05-23 09:45:07 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
unsigned DIEValue::SizeOf(const AsmPrinter *AP, dwarf::Form Form) const {
|
|
|
|
switch (Ty) {
|
2015-05-28 05:15:43 +08:00
|
|
|
#define HANDLE_DIEVALUE(T) \
|
|
|
|
case is##T: \
|
|
|
|
return cast<DIE##T>(this)->SizeOfImpl(AP, Form);
|
|
|
|
#include "llvm/CodeGen/DIEValue.def"
|
2015-05-23 09:45:07 +08:00
|
|
|
}
|
2015-05-23 22:46:49 +08:00
|
|
|
llvm_unreachable("Unknown DIE kind");
|
2015-05-23 09:45:07 +08:00
|
|
|
}
|
2009-05-15 08:11:17 +08:00
|
|
|
|
|
|
|
#ifndef NDEBUG
|
2015-05-23 09:45:07 +08:00
|
|
|
void DIEValue::print(raw_ostream &O) const {
|
|
|
|
switch (Ty) {
|
2015-05-28 05:15:43 +08:00
|
|
|
#define HANDLE_DIEVALUE(T) \
|
|
|
|
case is##T: \
|
|
|
|
cast<DIE##T>(this)->printImpl(O); \
|
2015-05-23 09:45:07 +08:00
|
|
|
break;
|
2015-05-28 05:15:43 +08:00
|
|
|
#include "llvm/CodeGen/DIEValue.def"
|
2015-05-23 09:45:07 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-06-01 06:50:40 +08:00
|
|
|
void DIEValue::dump() const {
|
2009-12-24 08:27:55 +08:00
|
|
|
print(dbgs());
|
2009-05-15 08:11:17 +08:00
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// DIEInteger Implementation
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
|
|
|
/// EmitValue - Emit integer of appropriate size.
|
|
|
|
///
|
2015-05-28 03:30:27 +08:00
|
|
|
void DIEInteger::EmitValueImpl(const AsmPrinter *Asm, dwarf::Form Form) const {
|
2010-01-20 15:41:15 +08:00
|
|
|
unsigned Size = ~0U;
|
2009-05-15 08:11:17 +08:00
|
|
|
switch (Form) {
|
2012-08-24 09:14:27 +08:00
|
|
|
case dwarf::DW_FORM_flag_present:
|
|
|
|
// Emit something to keep the lines and comments in sync.
|
|
|
|
// FIXME: Is there a better way to do this?
|
2015-04-25 03:11:51 +08:00
|
|
|
Asm->OutStreamer->AddBlankLine();
|
2012-08-24 09:14:27 +08:00
|
|
|
return;
|
2009-05-15 08:11:17 +08:00
|
|
|
case dwarf::DW_FORM_flag: // Fall thru
|
|
|
|
case dwarf::DW_FORM_ref1: // Fall thru
|
2010-01-20 15:41:15 +08:00
|
|
|
case dwarf::DW_FORM_data1: Size = 1; break;
|
2009-05-15 08:11:17 +08:00
|
|
|
case dwarf::DW_FORM_ref2: // Fall thru
|
2010-01-20 15:41:15 +08:00
|
|
|
case dwarf::DW_FORM_data2: Size = 2; break;
|
2013-01-17 10:59:59 +08:00
|
|
|
case dwarf::DW_FORM_sec_offset: // Fall thru
|
2015-03-05 06:07:36 +08:00
|
|
|
case dwarf::DW_FORM_strp: // Fall thru
|
2009-05-15 08:11:17 +08:00
|
|
|
case dwarf::DW_FORM_ref4: // Fall thru
|
2010-01-20 15:41:15 +08:00
|
|
|
case dwarf::DW_FORM_data4: Size = 4; break;
|
2009-05-15 08:11:17 +08:00
|
|
|
case dwarf::DW_FORM_ref8: // Fall thru
|
2013-11-20 07:08:21 +08:00
|
|
|
case dwarf::DW_FORM_ref_sig8: // Fall thru
|
2010-01-20 15:41:15 +08:00
|
|
|
case dwarf::DW_FORM_data8: Size = 8; break;
|
2013-01-08 03:32:41 +08:00
|
|
|
case dwarf::DW_FORM_GNU_str_index: Asm->EmitULEB128(Integer); return;
|
2013-01-16 07:56:56 +08:00
|
|
|
case dwarf::DW_FORM_GNU_addr_index: Asm->EmitULEB128(Integer); return;
|
2010-04-05 03:09:29 +08:00
|
|
|
case dwarf::DW_FORM_udata: Asm->EmitULEB128(Integer); return;
|
|
|
|
case dwarf::DW_FORM_sdata: Asm->EmitSLEB128(Integer); return;
|
2012-09-11 07:34:03 +08:00
|
|
|
case dwarf::DW_FORM_addr:
|
Revert the majority of the next patch in the address space series:
r165941: Resubmit the changes to llvm core to update the functions to
support different pointer sizes on a per address space basis.
Despite this commit log, this change primarily changed stuff outside of
VMCore, and those changes do not carry any tests for correctness (or
even plausibility), and we have consistently found questionable or flat
out incorrect cases in these changes. Most of them are probably correct,
but we need to devise a system that makes it more clear when we have
handled the address space concerns correctly, and ideally each pass that
gets updated would receive an accompanying test case that exercises that
pass specificaly w.r.t. alternate address spaces.
However, from this commit, I have retained the new C API entry points.
Those were an orthogonal change that probably should have been split
apart, but they seem entirely good.
In several places the changes were very obvious cleanups with no actual
multiple address space code added; these I have not reverted when
I spotted them.
In a few other places there were merge conflicts due to a cleaner
solution being implemented later, often not using address spaces at all.
In those cases, I've preserved the new code which isn't address space
dependent.
This is part of my ongoing effort to clean out the partial address space
code which carries high risk and low test coverage, and not likely to be
finished before the 3.2 release looms closer. Duncan and I would both
like to see the above issues addressed before we return to these
changes.
llvm-svn: 167222
2012-11-01 17:14:31 +08:00
|
|
|
Size = Asm->getDataLayout().getPointerSize(); break;
|
2015-03-05 06:07:36 +08:00
|
|
|
case dwarf::DW_FORM_ref_addr:
|
|
|
|
Size = SizeOf(Asm, dwarf::DW_FORM_ref_addr);
|
|
|
|
break;
|
2009-07-15 00:55:14 +08:00
|
|
|
default: llvm_unreachable("DIE Value form not supported yet");
|
2009-05-15 08:11:17 +08:00
|
|
|
}
|
2015-04-25 03:11:51 +08:00
|
|
|
Asm->OutStreamer->EmitIntValue(Integer, Size);
|
2009-05-15 08:11:17 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
/// SizeOf - Determine size of integer value in bytes.
|
|
|
|
///
|
2015-05-28 03:30:27 +08:00
|
|
|
unsigned DIEInteger::SizeOfImpl(const AsmPrinter *AP, dwarf::Form Form) const {
|
2009-05-15 08:11:17 +08:00
|
|
|
switch (Form) {
|
2012-08-30 01:59:32 +08:00
|
|
|
case dwarf::DW_FORM_flag_present: return 0;
|
2009-05-15 08:11:17 +08:00
|
|
|
case dwarf::DW_FORM_flag: // Fall thru
|
|
|
|
case dwarf::DW_FORM_ref1: // Fall thru
|
|
|
|
case dwarf::DW_FORM_data1: return sizeof(int8_t);
|
|
|
|
case dwarf::DW_FORM_ref2: // Fall thru
|
|
|
|
case dwarf::DW_FORM_data2: return sizeof(int16_t);
|
2013-01-17 10:59:59 +08:00
|
|
|
case dwarf::DW_FORM_sec_offset: // Fall thru
|
2015-03-05 06:07:36 +08:00
|
|
|
case dwarf::DW_FORM_strp: // Fall thru
|
2009-05-15 08:11:17 +08:00
|
|
|
case dwarf::DW_FORM_ref4: // Fall thru
|
|
|
|
case dwarf::DW_FORM_data4: return sizeof(int32_t);
|
|
|
|
case dwarf::DW_FORM_ref8: // Fall thru
|
2013-11-20 07:08:21 +08:00
|
|
|
case dwarf::DW_FORM_ref_sig8: // Fall thru
|
2009-05-15 08:11:17 +08:00
|
|
|
case dwarf::DW_FORM_data8: return sizeof(int64_t);
|
2014-02-22 22:00:39 +08:00
|
|
|
case dwarf::DW_FORM_GNU_str_index: return getULEB128Size(Integer);
|
|
|
|
case dwarf::DW_FORM_GNU_addr_index: return getULEB128Size(Integer);
|
|
|
|
case dwarf::DW_FORM_udata: return getULEB128Size(Integer);
|
|
|
|
case dwarf::DW_FORM_sdata: return getSLEB128Size(Integer);
|
Revert the majority of the next patch in the address space series:
r165941: Resubmit the changes to llvm core to update the functions to
support different pointer sizes on a per address space basis.
Despite this commit log, this change primarily changed stuff outside of
VMCore, and those changes do not carry any tests for correctness (or
even plausibility), and we have consistently found questionable or flat
out incorrect cases in these changes. Most of them are probably correct,
but we need to devise a system that makes it more clear when we have
handled the address space concerns correctly, and ideally each pass that
gets updated would receive an accompanying test case that exercises that
pass specificaly w.r.t. alternate address spaces.
However, from this commit, I have retained the new C API entry points.
Those were an orthogonal change that probably should have been split
apart, but they seem entirely good.
In several places the changes were very obvious cleanups with no actual
multiple address space code added; these I have not reverted when
I spotted them.
In a few other places there were merge conflicts due to a cleaner
solution being implemented later, often not using address spaces at all.
In those cases, I've preserved the new code which isn't address space
dependent.
This is part of my ongoing effort to clean out the partial address space
code which carries high risk and low test coverage, and not likely to be
finished before the 3.2 release looms closer. Duncan and I would both
like to see the above issues addressed before we return to these
changes.
llvm-svn: 167222
2012-11-01 17:14:31 +08:00
|
|
|
case dwarf::DW_FORM_addr: return AP->getDataLayout().getPointerSize();
|
2015-03-05 06:07:36 +08:00
|
|
|
case dwarf::DW_FORM_ref_addr:
|
2015-04-25 03:11:51 +08:00
|
|
|
if (AP->OutStreamer->getContext().getDwarfVersion() == 2)
|
2015-03-05 06:07:36 +08:00
|
|
|
return AP->getDataLayout().getPointerSize();
|
|
|
|
return sizeof(int32_t);
|
2012-01-21 05:51:11 +08:00
|
|
|
default: llvm_unreachable("DIE Value form not supported yet");
|
2009-05-15 08:11:17 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#ifndef NDEBUG
|
2015-05-28 03:30:27 +08:00
|
|
|
void DIEInteger::printImpl(raw_ostream &O) const {
|
2011-11-05 16:57:40 +08:00
|
|
|
O << "Int: " << (int64_t)Integer << " 0x";
|
|
|
|
O.write_hex(Integer);
|
2009-05-15 08:11:17 +08:00
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2013-07-03 02:46:26 +08:00
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// DIEExpr Implementation
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
|
|
|
/// EmitValue - Emit expression value.
|
|
|
|
///
|
2015-05-28 03:30:27 +08:00
|
|
|
void DIEExpr::EmitValueImpl(const AsmPrinter *AP, dwarf::Form Form) const {
|
2015-04-25 03:11:51 +08:00
|
|
|
AP->OutStreamer->EmitValue(Expr, SizeOf(AP, Form));
|
2013-07-03 02:46:26 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
/// SizeOf - Determine size of expression value in bytes.
|
|
|
|
///
|
2015-05-28 03:30:27 +08:00
|
|
|
unsigned DIEExpr::SizeOfImpl(const AsmPrinter *AP, dwarf::Form Form) const {
|
2013-07-03 02:46:26 +08:00
|
|
|
if (Form == dwarf::DW_FORM_data4) return 4;
|
|
|
|
if (Form == dwarf::DW_FORM_sec_offset) return 4;
|
|
|
|
if (Form == dwarf::DW_FORM_strp) return 4;
|
|
|
|
return AP->getDataLayout().getPointerSize();
|
|
|
|
}
|
|
|
|
|
|
|
|
#ifndef NDEBUG
|
2015-05-28 03:30:27 +08:00
|
|
|
void DIEExpr::printImpl(raw_ostream &O) const { O << "Expr: " << *Expr; }
|
2013-07-03 02:46:26 +08:00
|
|
|
#endif
|
|
|
|
|
2009-05-15 08:11:17 +08:00
|
|
|
//===----------------------------------------------------------------------===//
|
2010-03-09 06:31:46 +08:00
|
|
|
// DIELabel Implementation
|
2009-05-15 08:11:17 +08:00
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
|
|
|
/// EmitValue - Emit label value.
|
|
|
|
///
|
2015-05-28 03:30:27 +08:00
|
|
|
void DIELabel::EmitValueImpl(const AsmPrinter *AP, dwarf::Form Form) const {
|
2013-10-22 01:28:37 +08:00
|
|
|
AP->EmitLabelReference(Label, SizeOf(AP, Form),
|
|
|
|
Form == dwarf::DW_FORM_strp ||
|
|
|
|
Form == dwarf::DW_FORM_sec_offset ||
|
|
|
|
Form == dwarf::DW_FORM_ref_addr);
|
2009-05-15 08:11:17 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
/// SizeOf - Determine size of label value in bytes.
|
|
|
|
///
|
2015-05-28 03:30:27 +08:00
|
|
|
unsigned DIELabel::SizeOfImpl(const AsmPrinter *AP, dwarf::Form Form) const {
|
2009-05-15 08:11:17 +08:00
|
|
|
if (Form == dwarf::DW_FORM_data4) return 4;
|
2013-01-17 11:00:04 +08:00
|
|
|
if (Form == dwarf::DW_FORM_sec_offset) return 4;
|
2011-10-27 14:44:11 +08:00
|
|
|
if (Form == dwarf::DW_FORM_strp) return 4;
|
Revert the majority of the next patch in the address space series:
r165941: Resubmit the changes to llvm core to update the functions to
support different pointer sizes on a per address space basis.
Despite this commit log, this change primarily changed stuff outside of
VMCore, and those changes do not carry any tests for correctness (or
even plausibility), and we have consistently found questionable or flat
out incorrect cases in these changes. Most of them are probably correct,
but we need to devise a system that makes it more clear when we have
handled the address space concerns correctly, and ideally each pass that
gets updated would receive an accompanying test case that exercises that
pass specificaly w.r.t. alternate address spaces.
However, from this commit, I have retained the new C API entry points.
Those were an orthogonal change that probably should have been split
apart, but they seem entirely good.
In several places the changes were very obvious cleanups with no actual
multiple address space code added; these I have not reverted when
I spotted them.
In a few other places there were merge conflicts due to a cleaner
solution being implemented later, often not using address spaces at all.
In those cases, I've preserved the new code which isn't address space
dependent.
This is part of my ongoing effort to clean out the partial address space
code which carries high risk and low test coverage, and not likely to be
finished before the 3.2 release looms closer. Duncan and I would both
like to see the above issues addressed before we return to these
changes.
llvm-svn: 167222
2012-11-01 17:14:31 +08:00
|
|
|
return AP->getDataLayout().getPointerSize();
|
2009-05-15 08:11:17 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
#ifndef NDEBUG
|
2015-05-28 03:30:27 +08:00
|
|
|
void DIELabel::printImpl(raw_ostream &O) const {
|
|
|
|
O << "Lbl: " << Label->getName();
|
|
|
|
}
|
2009-05-15 08:11:17 +08:00
|
|
|
#endif
|
|
|
|
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// DIEDelta Implementation
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
|
|
|
/// EmitValue - Emit delta value.
|
|
|
|
///
|
2015-05-28 03:30:27 +08:00
|
|
|
void DIEDelta::EmitValueImpl(const AsmPrinter *AP, dwarf::Form Form) const {
|
2010-04-05 08:18:22 +08:00
|
|
|
AP->EmitLabelDifference(LabelHi, LabelLo, SizeOf(AP, Form));
|
2009-05-15 08:11:17 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
/// SizeOf - Determine size of delta value in bytes.
|
|
|
|
///
|
2015-05-28 03:30:27 +08:00
|
|
|
unsigned DIEDelta::SizeOfImpl(const AsmPrinter *AP, dwarf::Form Form) const {
|
2009-05-15 08:11:17 +08:00
|
|
|
if (Form == dwarf::DW_FORM_data4) return 4;
|
2013-11-22 07:46:41 +08:00
|
|
|
if (Form == dwarf::DW_FORM_sec_offset) return 4;
|
2011-10-27 14:44:11 +08:00
|
|
|
if (Form == dwarf::DW_FORM_strp) return 4;
|
Revert the majority of the next patch in the address space series:
r165941: Resubmit the changes to llvm core to update the functions to
support different pointer sizes on a per address space basis.
Despite this commit log, this change primarily changed stuff outside of
VMCore, and those changes do not carry any tests for correctness (or
even plausibility), and we have consistently found questionable or flat
out incorrect cases in these changes. Most of them are probably correct,
but we need to devise a system that makes it more clear when we have
handled the address space concerns correctly, and ideally each pass that
gets updated would receive an accompanying test case that exercises that
pass specificaly w.r.t. alternate address spaces.
However, from this commit, I have retained the new C API entry points.
Those were an orthogonal change that probably should have been split
apart, but they seem entirely good.
In several places the changes were very obvious cleanups with no actual
multiple address space code added; these I have not reverted when
I spotted them.
In a few other places there were merge conflicts due to a cleaner
solution being implemented later, often not using address spaces at all.
In those cases, I've preserved the new code which isn't address space
dependent.
This is part of my ongoing effort to clean out the partial address space
code which carries high risk and low test coverage, and not likely to be
finished before the 3.2 release looms closer. Duncan and I would both
like to see the above issues addressed before we return to these
changes.
llvm-svn: 167222
2012-11-01 17:14:31 +08:00
|
|
|
return AP->getDataLayout().getPointerSize();
|
2009-05-15 08:11:17 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
#ifndef NDEBUG
|
2015-05-28 03:30:27 +08:00
|
|
|
void DIEDelta::printImpl(raw_ostream &O) const {
|
2010-03-09 06:23:36 +08:00
|
|
|
O << "Del: " << LabelHi->getName() << "-" << LabelLo->getName();
|
2009-05-15 08:11:17 +08:00
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2013-07-27 01:02:41 +08:00
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// DIEString Implementation
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
|
|
|
/// EmitValue - Emit string value.
|
|
|
|
///
|
2015-05-28 03:30:27 +08:00
|
|
|
void DIEString::EmitValueImpl(const AsmPrinter *AP, dwarf::Form Form) const {
|
2015-05-25 00:40:47 +08:00
|
|
|
assert(
|
|
|
|
(Form == dwarf::DW_FORM_strp || Form == dwarf::DW_FORM_GNU_str_index) &&
|
|
|
|
"Expected valid string form");
|
|
|
|
|
|
|
|
// Index of string in symbol table.
|
|
|
|
if (Form == dwarf::DW_FORM_GNU_str_index) {
|
|
|
|
DIEInteger(S.getIndex()).EmitValue(AP, Form);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Relocatable symbol.
|
|
|
|
assert(Form == dwarf::DW_FORM_strp);
|
|
|
|
if (AP->MAI->doesDwarfUseRelocationsAcrossSections()) {
|
|
|
|
DIELabel(S.getSymbol()).EmitValue(AP, Form);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Offset into symbol table.
|
|
|
|
DIEInteger(S.getOffset()).EmitValue(AP, Form);
|
2013-07-27 01:02:41 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
/// SizeOf - Determine size of delta value in bytes.
|
|
|
|
///
|
2015-05-28 03:30:27 +08:00
|
|
|
unsigned DIEString::SizeOfImpl(const AsmPrinter *AP, dwarf::Form Form) const {
|
2015-05-25 00:40:47 +08:00
|
|
|
assert(
|
|
|
|
(Form == dwarf::DW_FORM_strp || Form == dwarf::DW_FORM_GNU_str_index) &&
|
|
|
|
"Expected valid string form");
|
|
|
|
|
|
|
|
// Index of string in symbol table.
|
|
|
|
if (Form == dwarf::DW_FORM_GNU_str_index)
|
|
|
|
return DIEInteger(S.getIndex()).SizeOf(AP, Form);
|
|
|
|
|
|
|
|
// Relocatable symbol.
|
|
|
|
if (AP->MAI->doesDwarfUseRelocationsAcrossSections())
|
|
|
|
return DIELabel(S.getSymbol()).SizeOf(AP, Form);
|
|
|
|
|
|
|
|
// Offset into symbol table.
|
|
|
|
return DIEInteger(S.getOffset()).SizeOf(AP, Form);
|
2013-07-27 01:02:41 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
#ifndef NDEBUG
|
2015-05-28 03:30:27 +08:00
|
|
|
void DIEString::printImpl(raw_ostream &O) const {
|
2015-05-25 00:40:47 +08:00
|
|
|
O << "String: " << S.getString();
|
2013-07-27 01:02:41 +08:00
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2009-05-15 08:11:17 +08:00
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// DIEEntry Implementation
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
|
|
|
/// EmitValue - Emit debug information entry offset.
|
|
|
|
///
|
2015-05-28 03:30:27 +08:00
|
|
|
void DIEEntry::EmitValueImpl(const AsmPrinter *AP, dwarf::Form Form) const {
|
2014-03-06 08:00:56 +08:00
|
|
|
|
|
|
|
if (Form == dwarf::DW_FORM_ref_addr) {
|
|
|
|
const DwarfDebug *DD = AP->getDwarfDebug();
|
2015-05-28 03:30:27 +08:00
|
|
|
unsigned Addr = Entry.getOffset();
|
2014-03-06 08:00:56 +08:00
|
|
|
assert(!DD->useSplitDwarf() && "TODO: dwo files can't have relocations.");
|
|
|
|
// For DW_FORM_ref_addr, output the offset from beginning of debug info
|
|
|
|
// section. Entry->getOffset() returns the offset from start of the
|
|
|
|
// compile unit.
|
2015-05-28 03:30:27 +08:00
|
|
|
DwarfCompileUnit *CU = DD->lookupUnit(Entry.getUnit());
|
2014-03-06 08:00:56 +08:00
|
|
|
assert(CU && "CUDie should belong to a CU.");
|
|
|
|
Addr += CU->getDebugInfoOffset();
|
|
|
|
if (AP->MAI->doesDwarfUseRelocationsAcrossSections())
|
|
|
|
AP->EmitLabelPlusOffset(CU->getSectionSym(), Addr,
|
|
|
|
DIEEntry::getRefAddrSize(AP));
|
|
|
|
else
|
2015-04-25 03:11:51 +08:00
|
|
|
AP->OutStreamer->EmitIntValue(Addr, DIEEntry::getRefAddrSize(AP));
|
2014-03-06 08:00:56 +08:00
|
|
|
} else
|
2015-05-28 03:30:27 +08:00
|
|
|
AP->EmitInt32(Entry.getOffset());
|
2009-05-15 08:11:17 +08:00
|
|
|
}
|
|
|
|
|
2015-03-04 10:30:08 +08:00
|
|
|
unsigned DIEEntry::getRefAddrSize(const AsmPrinter *AP) {
|
2013-07-03 07:40:10 +08:00
|
|
|
// DWARF4: References that use the attribute form DW_FORM_ref_addr are
|
|
|
|
// specified to be four bytes in the DWARF 32-bit format and eight bytes
|
|
|
|
// in the DWARF 64-bit format, while DWARF Version 2 specifies that such
|
|
|
|
// references have the same size as an address on the target system.
|
2013-12-03 23:10:23 +08:00
|
|
|
const DwarfDebug *DD = AP->getDwarfDebug();
|
|
|
|
assert(DD && "Expected Dwarf Debug info to be available");
|
|
|
|
if (DD->getDwarfVersion() == 2)
|
2013-07-03 07:40:10 +08:00
|
|
|
return AP->getDataLayout().getPointerSize();
|
|
|
|
return sizeof(int32_t);
|
|
|
|
}
|
|
|
|
|
2009-05-15 08:11:17 +08:00
|
|
|
#ifndef NDEBUG
|
2015-05-28 03:30:27 +08:00
|
|
|
void DIEEntry::printImpl(raw_ostream &O) const {
|
2014-04-26 03:33:43 +08:00
|
|
|
O << format("Die: 0x%lx", (long)(intptr_t)&Entry);
|
2009-05-15 08:11:17 +08:00
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2013-12-18 07:32:35 +08:00
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// DIETypeSignature Implementation
|
|
|
|
//===----------------------------------------------------------------------===//
|
2015-05-28 03:30:27 +08:00
|
|
|
void DIETypeSignature::EmitValueImpl(const AsmPrinter *Asm, dwarf::Form Form) const {
|
2013-12-18 07:32:35 +08:00
|
|
|
assert(Form == dwarf::DW_FORM_ref_sig8);
|
2015-05-28 03:30:27 +08:00
|
|
|
Asm->OutStreamer->EmitIntValue(Unit.getTypeSignature(), 8);
|
2013-12-18 07:32:35 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
#ifndef NDEBUG
|
2015-05-28 03:30:27 +08:00
|
|
|
void DIETypeSignature::printImpl(raw_ostream &O) const {
|
|
|
|
O << format("Type Unit: 0x%lx", Unit.getTypeSignature());
|
2013-12-18 07:32:35 +08:00
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2014-02-16 16:46:55 +08:00
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// DIELoc Implementation
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
|
|
|
/// ComputeSize - calculate the size of the location expression.
|
|
|
|
///
|
2015-03-04 10:30:08 +08:00
|
|
|
unsigned DIELoc::ComputeSize(const AsmPrinter *AP) const {
|
2014-02-28 02:36:10 +08:00
|
|
|
if (!Size) {
|
|
|
|
const SmallVectorImpl<DIEAbbrevData> &AbbrevData = Abbrev.getData();
|
|
|
|
for (unsigned i = 0, N = Values.size(); i < N; ++i)
|
2015-05-28 03:30:27 +08:00
|
|
|
Size += Values[i]->SizeOf(AP, AbbrevData[i].getForm());
|
2014-02-28 02:36:10 +08:00
|
|
|
}
|
2014-02-16 16:46:55 +08:00
|
|
|
|
2014-02-28 02:36:10 +08:00
|
|
|
return Size;
|
2014-02-16 16:46:55 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
/// EmitValue - Emit location data.
|
|
|
|
///
|
2015-05-28 03:30:27 +08:00
|
|
|
void DIELoc::EmitValueImpl(const AsmPrinter *Asm, dwarf::Form Form) const {
|
2014-02-16 16:46:55 +08:00
|
|
|
switch (Form) {
|
|
|
|
default: llvm_unreachable("Improper form for block");
|
|
|
|
case dwarf::DW_FORM_block1: Asm->EmitInt8(Size); break;
|
|
|
|
case dwarf::DW_FORM_block2: Asm->EmitInt16(Size); break;
|
|
|
|
case dwarf::DW_FORM_block4: Asm->EmitInt32(Size); break;
|
|
|
|
case dwarf::DW_FORM_block:
|
|
|
|
case dwarf::DW_FORM_exprloc:
|
|
|
|
Asm->EmitULEB128(Size); break;
|
|
|
|
}
|
|
|
|
|
|
|
|
const SmallVectorImpl<DIEAbbrevData> &AbbrevData = Abbrev.getData();
|
|
|
|
for (unsigned i = 0, N = Values.size(); i < N; ++i)
|
2015-05-28 03:30:27 +08:00
|
|
|
Values[i]->EmitValue(Asm, AbbrevData[i].getForm());
|
2014-02-16 16:46:55 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
/// SizeOf - Determine size of location data in bytes.
|
|
|
|
///
|
2015-05-28 03:30:27 +08:00
|
|
|
unsigned DIELoc::SizeOfImpl(const AsmPrinter *AP, dwarf::Form Form) const {
|
2014-02-16 16:46:55 +08:00
|
|
|
switch (Form) {
|
|
|
|
case dwarf::DW_FORM_block1: return Size + sizeof(int8_t);
|
|
|
|
case dwarf::DW_FORM_block2: return Size + sizeof(int16_t);
|
|
|
|
case dwarf::DW_FORM_block4: return Size + sizeof(int32_t);
|
|
|
|
case dwarf::DW_FORM_block:
|
|
|
|
case dwarf::DW_FORM_exprloc:
|
2014-02-22 22:00:39 +08:00
|
|
|
return Size + getULEB128Size(Size);
|
2014-02-16 16:46:55 +08:00
|
|
|
default: llvm_unreachable("Improper form for block");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#ifndef NDEBUG
|
2015-05-28 03:30:27 +08:00
|
|
|
void DIELoc::printImpl(raw_ostream &O) const {
|
2014-02-16 16:46:55 +08:00
|
|
|
O << "ExprLoc: ";
|
|
|
|
DIE::print(O, 5);
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2009-05-15 08:11:17 +08:00
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// DIEBlock Implementation
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
|
|
|
/// ComputeSize - calculate the size of the block.
|
|
|
|
///
|
2015-03-04 10:30:08 +08:00
|
|
|
unsigned DIEBlock::ComputeSize(const AsmPrinter *AP) const {
|
2014-02-28 02:36:10 +08:00
|
|
|
if (!Size) {
|
|
|
|
const SmallVectorImpl<DIEAbbrevData> &AbbrevData = Abbrev.getData();
|
|
|
|
for (unsigned i = 0, N = Values.size(); i < N; ++i)
|
2015-05-28 03:30:27 +08:00
|
|
|
Size += Values[i]->SizeOf(AP, AbbrevData[i].getForm());
|
2014-02-28 02:36:10 +08:00
|
|
|
}
|
2009-05-15 08:11:17 +08:00
|
|
|
|
2014-02-28 02:36:10 +08:00
|
|
|
return Size;
|
2009-05-15 08:11:17 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
/// EmitValue - Emit block data.
|
|
|
|
///
|
2015-05-28 03:30:27 +08:00
|
|
|
void DIEBlock::EmitValueImpl(const AsmPrinter *Asm, dwarf::Form Form) const {
|
2009-05-15 08:11:17 +08:00
|
|
|
switch (Form) {
|
2012-02-05 16:31:47 +08:00
|
|
|
default: llvm_unreachable("Improper form for block");
|
2010-04-05 03:09:29 +08:00
|
|
|
case dwarf::DW_FORM_block1: Asm->EmitInt8(Size); break;
|
|
|
|
case dwarf::DW_FORM_block2: Asm->EmitInt16(Size); break;
|
|
|
|
case dwarf::DW_FORM_block4: Asm->EmitInt32(Size); break;
|
|
|
|
case dwarf::DW_FORM_block: Asm->EmitULEB128(Size); break;
|
2009-05-15 08:11:17 +08:00
|
|
|
}
|
|
|
|
|
2013-03-30 07:34:06 +08:00
|
|
|
const SmallVectorImpl<DIEAbbrevData> &AbbrevData = Abbrev.getData();
|
2010-03-10 07:38:23 +08:00
|
|
|
for (unsigned i = 0, N = Values.size(); i < N; ++i)
|
2015-05-28 03:30:27 +08:00
|
|
|
Values[i]->EmitValue(Asm, AbbrevData[i].getForm());
|
2009-05-15 08:11:17 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
/// SizeOf - Determine size of block data in bytes.
|
|
|
|
///
|
2015-05-28 03:30:27 +08:00
|
|
|
unsigned DIEBlock::SizeOfImpl(const AsmPrinter *AP, dwarf::Form Form) const {
|
2009-05-15 08:11:17 +08:00
|
|
|
switch (Form) {
|
|
|
|
case dwarf::DW_FORM_block1: return Size + sizeof(int8_t);
|
|
|
|
case dwarf::DW_FORM_block2: return Size + sizeof(int16_t);
|
|
|
|
case dwarf::DW_FORM_block4: return Size + sizeof(int32_t);
|
2014-02-22 22:00:39 +08:00
|
|
|
case dwarf::DW_FORM_block: return Size + getULEB128Size(Size);
|
2012-01-21 05:51:11 +08:00
|
|
|
default: llvm_unreachable("Improper form for block");
|
2009-05-15 08:11:17 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#ifndef NDEBUG
|
2015-05-28 03:30:27 +08:00
|
|
|
void DIEBlock::printImpl(raw_ostream &O) const {
|
2009-05-15 08:11:17 +08:00
|
|
|
O << "Blk: ";
|
|
|
|
DIE::print(O, 5);
|
|
|
|
}
|
|
|
|
#endif
|
2014-03-06 06:41:20 +08:00
|
|
|
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// DIELocList Implementation
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
2015-05-28 03:30:27 +08:00
|
|
|
unsigned DIELocList::SizeOfImpl(const AsmPrinter *AP, dwarf::Form Form) const {
|
2014-03-06 06:41:20 +08:00
|
|
|
if (Form == dwarf::DW_FORM_data4)
|
|
|
|
return 4;
|
|
|
|
if (Form == dwarf::DW_FORM_sec_offset)
|
|
|
|
return 4;
|
|
|
|
return AP->getDataLayout().getPointerSize();
|
|
|
|
}
|
|
|
|
|
|
|
|
/// EmitValue - Emit label value.
|
|
|
|
///
|
2015-05-28 03:30:27 +08:00
|
|
|
void DIELocList::EmitValueImpl(const AsmPrinter *AP, dwarf::Form Form) const {
|
2014-03-25 09:44:02 +08:00
|
|
|
DwarfDebug *DD = AP->getDwarfDebug();
|
AsmPrinter: Create a unified .debug_loc stream
This commit removes `DebugLocList` and replaces it with
`DebugLocStream`.
- `DebugLocEntry` no longer contains its byte/comment streams.
- The `DebugLocEntry` list for a variable/inlined-at pair is allocated
on the stack, and released right after `DebugLocEntry::finalize()`
(possible because of the refactoring in r231023). Now, only one
list is in memory at a time now.
- There's a single unified stream for the `.debug_loc` section that
persists, stored in the new `DebugLocStream` data structure.
The last point is important: this collapses the nested `SmallVector<>`s
from `DebugLocList` into unified streams. We previously had something
like the following:
vec<tuple<Label, CU,
vec<tuple<BeginSym, EndSym,
vec<Value>,
vec<char>,
vec<string>>>>>
A `SmallVector` can avoid allocations, but is statically fairly large
for a vector: three pointers plus the size of the small storage, which
is the number of elements in small mode times the element size).
Nesting these is expensive, since an inner vector's size contributes to
the element size of an outer one. (Nesting any vector is expensive...)
In the old data structure, the outer vector's *element* size was 632B,
excluding allocation costs for when the middle and inner vectors
exceeded their small sizes. 312B of this was for the "three" pointers
in the vector-tree beneath it. If you assume 1M functions with an
average of 10 variable/inlined-at pairs each (in an LTO scenario),
that's almost 6GB (besides inner allocations), with almost 3GB for the
"three" pointers.
This came up in a heap profile a little while ago of a `clang -flto -g`
bootstrap, with `DwarfDebug::collectVariableInfo()` using something like
10-15% of the total memory.
With this commit, we have:
tuple<vec<tuple<Label, CU, Offset>>,
vec<tuple<BeginSym, EndSym, Offset, Offset>>,
vec<char>,
vec<string>>
The offsets are used to create `ArrayRef` slices of adjacent
`SmallVector`s. This reduces the number of vectors to four (unrelated
to the number of variable/inlined-at pairs), and caps the number of
allocations at the same number.
Besides saving memory and limiting allocations, this is NFC.
I don't know my way around this code very well yet, but I wonder if we
could go further: why stream to a side-table, instead of directly to the
output stream?
llvm-svn: 235229
2015-04-18 05:34:47 +08:00
|
|
|
MCSymbol *Label = DD->getDebugLocs().getList(Index).Label;
|
2014-03-06 06:41:20 +08:00
|
|
|
|
2014-04-02 00:09:49 +08:00
|
|
|
if (AP->MAI->doesDwarfUseRelocationsAcrossSections() && !DD->useSplitDwarf())
|
2015-03-11 00:58:10 +08:00
|
|
|
AP->emitSectionOffset(Label);
|
2014-03-06 06:41:20 +08:00
|
|
|
else
|
2015-03-11 00:58:10 +08:00
|
|
|
AP->EmitLabelDifference(Label, Label->getSection().getBeginSymbol(), 4);
|
2014-03-06 06:41:20 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
#ifndef NDEBUG
|
2015-05-28 03:30:27 +08:00
|
|
|
void DIELocList::printImpl(raw_ostream &O) const {
|
|
|
|
O << "LocList: " << Index;
|
|
|
|
|
|
|
|
}
|
2014-03-06 06:41:20 +08:00
|
|
|
#endif
|