summaryrefslogtreecommitdiffstats
path: root/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/CodeGen/AsmPrinter/DwarfDebug.cpp')
-rw-r--r--lib/CodeGen/AsmPrinter/DwarfDebug.cpp287
1 files changed, 157 insertions, 130 deletions
diff --git a/lib/CodeGen/AsmPrinter/DwarfDebug.cpp b/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
index 7153fe2..fb91d4f 100644
--- a/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
+++ b/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
@@ -92,11 +92,11 @@ public:
/// addGlobal - Add a new global entity to the compile unit.
///
- void addGlobal(const std::string &Name, DIE *Die) { Globals[Name] = Die; }
+ void addGlobal(StringRef Name, DIE *Die) { Globals[Name] = Die; }
/// addGlobalType - Add a new global type to the compile unit.
///
- void addGlobalType(const std::string &Name, DIE *Die) {
+ void addGlobalType(StringRef Name, DIE *Die) {
GlobalTypes[Name] = Die;
}
@@ -149,20 +149,26 @@ class DbgVariable {
DIVariable Var; // Variable Descriptor.
unsigned FrameIndex; // Variable frame index.
const MachineInstr *DbgValueMInsn; // DBG_VALUE
+ // DbgValueLabel - DBG_VALUE is effective from this label.
+ MCSymbol *DbgValueLabel;
DbgVariable *const AbstractVar; // Abstract variable for this variable.
DIE *TheDIE;
public:
// AbsVar may be NULL.
DbgVariable(DIVariable V, unsigned I, DbgVariable *AbsVar)
- : Var(V), FrameIndex(I), DbgValueMInsn(0), AbstractVar(AbsVar), TheDIE(0) {}
+ : Var(V), FrameIndex(I), DbgValueMInsn(0),
+ DbgValueLabel(0), AbstractVar(AbsVar), TheDIE(0) {}
DbgVariable(DIVariable V, const MachineInstr *MI, DbgVariable *AbsVar)
- : Var(V), FrameIndex(0), DbgValueMInsn(MI), AbstractVar(AbsVar), TheDIE(0)
+ : Var(V), FrameIndex(0), DbgValueMInsn(MI), DbgValueLabel(0),
+ AbstractVar(AbsVar), TheDIE(0)
{}
// Accessors.
DIVariable getVariable() const { return Var; }
unsigned getFrameIndex() const { return FrameIndex; }
const MachineInstr *getDbgValue() const { return DbgValueMInsn; }
+ MCSymbol *getDbgValueLabel() const { return DbgValueLabel; }
+ void setDbgValueLabel(MCSymbol *L) { DbgValueLabel = L; }
DbgVariable *getAbstractVariable() const { return AbstractVar; }
void setDIE(DIE *D) { TheDIE = D; }
DIE *getDIE() const { return TheDIE; }
@@ -224,14 +230,14 @@ public:
void fixInstructionMarkers(DenseMap<const MachineInstr *,
unsigned> &MIIndexMap) {
- assert (getFirstInsn() && "First instruction is missing!");
+ assert(getFirstInsn() && "First instruction is missing!");
// Use the end of last child scope as end of this scope.
const SmallVector<DbgScope *, 4> &Scopes = getScopes();
const MachineInstr *LastInsn = getFirstInsn();
unsigned LIndex = 0;
if (Scopes.empty()) {
- assert (getLastInsn() && "Inner most scope does not have last insn!");
+ assert(getLastInsn() && "Inner most scope does not have last insn!");
return;
}
for (SmallVector<DbgScope *, 4>::const_iterator SI = Scopes.begin(),
@@ -295,15 +301,15 @@ DbgScope::~DbgScope() {
DwarfDebug::DwarfDebug(raw_ostream &OS, AsmPrinter *A, const MCAsmInfo *T)
: DwarfPrinter(OS, A, T), ModuleCU(0),
AbbreviationsSet(InitAbbreviationsSetSize), Abbreviations(),
- DIEValues(), SectionSourceLines(), didInitial(false), shouldEmit(false),
- CurrentFnDbgScope(0), DebugTimer(0) {
+ DIEBlocks(), SectionSourceLines(), didInitial(false), shouldEmit(false),
+ CurrentFnDbgScope(0), PrevDILoc(0), DebugTimer(0) {
NextStringPoolNumber = 0;
if (TimePassesIsEnabled)
DebugTimer = new Timer("Dwarf Debug Writer");
}
DwarfDebug::~DwarfDebug() {
- for (unsigned j = 0, M = DIEValues.size(); j < M; ++j)
- delete DIEValues[j];
+ for (unsigned j = 0, M = DIEBlocks.size(); j < M; ++j)
+ DIEBlocks[j]->~DIEBlock();
delete DebugTimer;
}
@@ -343,8 +349,7 @@ void DwarfDebug::assignAbbrevNumber(DIEAbbrev &Abbrev) {
/// createDIEEntry - Creates a new DIEEntry to be a proxy for a debug
/// information entry.
DIEEntry *DwarfDebug::createDIEEntry(DIE *Entry) {
- DIEEntry *Value = new DIEEntry(Entry);
- DIEValues.push_back(Value);
+ DIEEntry *Value = new (DIEValueAllocator) DIEEntry(Entry);
return Value;
}
@@ -353,8 +358,7 @@ DIEEntry *DwarfDebug::createDIEEntry(DIE *Entry) {
void DwarfDebug::addUInt(DIE *Die, unsigned Attribute,
unsigned Form, uint64_t Integer) {
if (!Form) Form = DIEInteger::BestForm(false, Integer);
- DIEValue *Value = new DIEInteger(Integer);
- DIEValues.push_back(Value);
+ DIEValue *Value = new (DIEValueAllocator) DIEInteger(Integer);
Die->addValue(Attribute, Form, Value);
}
@@ -363,8 +367,7 @@ void DwarfDebug::addUInt(DIE *Die, unsigned Attribute,
void DwarfDebug::addSInt(DIE *Die, unsigned Attribute,
unsigned Form, int64_t Integer) {
if (!Form) Form = DIEInteger::BestForm(true, Integer);
- DIEValue *Value = new DIEInteger(Integer);
- DIEValues.push_back(Value);
+ DIEValue *Value = new (DIEValueAllocator) DIEInteger(Integer);
Die->addValue(Attribute, Form, Value);
}
@@ -372,8 +375,7 @@ void DwarfDebug::addSInt(DIE *Die, unsigned Attribute,
/// keeps string reference.
void DwarfDebug::addString(DIE *Die, unsigned Attribute, unsigned Form,
StringRef String) {
- DIEValue *Value = new DIEString(String);
- DIEValues.push_back(Value);
+ DIEValue *Value = new (DIEValueAllocator) DIEString(String);
Die->addValue(Attribute, Form, Value);
}
@@ -381,18 +383,7 @@ void DwarfDebug::addString(DIE *Die, unsigned Attribute, unsigned Form,
///
void DwarfDebug::addLabel(DIE *Die, unsigned Attribute, unsigned Form,
const MCSymbol *Label) {
- DIEValue *Value = new DIELabel(Label);
- DIEValues.push_back(Value);
- Die->addValue(Attribute, Form, Value);
-}
-
-/// addSectionOffset - Add a section offset label attribute data and value.
-///
-void DwarfDebug::addSectionOffset(DIE *Die, unsigned Attribute, unsigned Form,
- const MCSymbol *Label,const MCSymbol *Section,
- bool isEH) {
- DIEValue *Value = new DIESectionOffset(Label, Section, isEH);
- DIEValues.push_back(Value);
+ DIEValue *Value = new (DIEValueAllocator) DIELabel(Label);
Die->addValue(Attribute, Form, Value);
}
@@ -400,8 +391,7 @@ void DwarfDebug::addSectionOffset(DIE *Die, unsigned Attribute, unsigned Form,
///
void DwarfDebug::addDelta(DIE *Die, unsigned Attribute, unsigned Form,
const MCSymbol *Hi, const MCSymbol *Lo) {
- DIEValue *Value = new DIEDelta(Hi, Lo);
- DIEValues.push_back(Value);
+ DIEValue *Value = new (DIEValueAllocator) DIEDelta(Hi, Lo);
Die->addValue(Attribute, Form, Value);
}
@@ -410,7 +400,7 @@ void DwarfDebug::addDelta(DIE *Die, unsigned Attribute, unsigned Form,
void DwarfDebug::addBlock(DIE *Die, unsigned Attribute, unsigned Form,
DIEBlock *Block) {
Block->ComputeSize(TD);
- DIEValues.push_back(Block);
+ DIEBlocks.push_back(Block); // Memoize so we can call the destructor later on.
Die->addValue(Attribute, Block->BestForm(), Block);
}
@@ -457,8 +447,8 @@ void DwarfDebug::addSourceLine(DIE *Die, const DISubprogram *SP) {
unsigned Line = SP->getLineNumber();
if (!SP->getContext().Verify())
return;
- unsigned FileID = GetOrCreateSourceID(SP->getContext().getDirectory(),
- SP->getContext().getFilename());
+ unsigned FileID = GetOrCreateSourceID(SP->getDirectory(),
+ SP->getFilename());
assert(FileID && "Invalid file id");
addUInt(Die, dwarf::DW_AT_decl_file, 0, FileID);
addUInt(Die, dwarf::DW_AT_decl_line, 0, Line);
@@ -564,7 +554,7 @@ void DwarfDebug::addComplexAddress(DbgVariable *&DV, DIE *Die,
// Decode the original location, and use that as the start of the byref
// variable's location.
unsigned Reg = RI->getDwarfRegNum(Location.getReg(), false);
- DIEBlock *Block = new DIEBlock();
+ DIEBlock *Block = new (DIEValueAllocator) DIEBlock();
if (Location.isReg()) {
if (Reg < 32) {
@@ -696,15 +686,15 @@ void DwarfDebug::addBlockByrefAddress(DbgVariable *&DV, DIE *Die,
}
// Get the offsets for the forwarding field and the variable field.
- unsigned int forwardingFieldOffset =
+ unsigned forwardingFieldOffset =
DIDerivedType(forwardingField.getNode()).getOffsetInBits() >> 3;
- unsigned int varFieldOffset =
+ unsigned varFieldOffset =
DIDerivedType(varField.getNode()).getOffsetInBits() >> 3;
// Decode the original location, and use that as the start of the byref
// variable's location.
unsigned Reg = RI->getDwarfRegNum(Location.getReg(), false);
- DIEBlock *Block = new DIEBlock();
+ DIEBlock *Block = new (DIEValueAllocator) DIEBlock();
if (Location.isReg()) {
if (Reg < 32)
@@ -759,7 +749,7 @@ void DwarfDebug::addBlockByrefAddress(DbgVariable *&DV, DIE *Die,
void DwarfDebug::addAddress(DIE *Die, unsigned Attribute,
const MachineLocation &Location) {
unsigned Reg = RI->getDwarfRegNum(Location.getReg(), false);
- DIEBlock *Block = new DIEBlock();
+ DIEBlock *Block = new (DIEValueAllocator) DIEBlock();
if (Location.isReg()) {
if (Reg < 32) {
@@ -1106,7 +1096,7 @@ DIE *DwarfDebug::createMemberDIE(const DIDerivedType &DT) {
addSourceLine(MemberDie, &DT);
- DIEBlock *MemLocationDie = new DIEBlock();
+ DIEBlock *MemLocationDie = new (DIEValueAllocator) DIEBlock();
addUInt(MemLocationDie, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_plus_uconst);
uint64_t Size = DT.getSizeInBits();
@@ -1142,7 +1132,7 @@ DIE *DwarfDebug::createMemberDIE(const DIDerivedType &DT) {
// expression to extract appropriate offset from vtable.
// BaseAddr = ObAddr + *((*ObAddr) - Offset)
- DIEBlock *VBaseLocationDie = new DIEBlock();
+ DIEBlock *VBaseLocationDie = new (DIEValueAllocator) DIEBlock();
addUInt(VBaseLocationDie, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_dup);
addUInt(VBaseLocationDie, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_deref);
addUInt(VBaseLocationDie, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_constu);
@@ -1208,7 +1198,7 @@ DIE *DwarfDebug::createSubprogramDIE(const DISubprogram &SP, bool MakeDecl) {
unsigned VK = SP.getVirtuality();
if (VK) {
addUInt(SPDie, dwarf::DW_AT_virtuality, dwarf::DW_FORM_flag, VK);
- DIEBlock *Block = new DIEBlock();
+ DIEBlock *Block = new (DIEValueAllocator) DIEBlock();
addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_constu);
addUInt(Block, 0, dwarf::DW_FORM_data1, SP.getVirtualIndex());
addBlock(SPDie, dwarf::DW_AT_vtable_elem_location, 0, Block);
@@ -1244,13 +1234,13 @@ DIE *DwarfDebug::createSubprogramDIE(const DISubprogram &SP, bool MakeDecl) {
return SPDie;
}
-/// getUpdatedDbgScope - Find or create DbgScope assicated with the instruction.
-/// Initialize scope and update scope hierarchy.
+/// getUpdatedDbgScope - Find DbgScope assicated with the instruction.
+/// Update scope hierarchy. Create abstract scope if required.
DbgScope *DwarfDebug::getUpdatedDbgScope(MDNode *N, const MachineInstr *MI,
- MDNode *InlinedAt) {
- assert (N && "Invalid Scope encoding!");
- assert (MI && "Missing machine instruction!");
- bool GetConcreteScope = (MI && InlinedAt);
+ MDNode *InlinedAt) {
+ assert(N && "Invalid Scope encoding!");
+ assert(MI && "Missing machine instruction!");
+ bool isAConcreteScope = InlinedAt != 0;
DbgScope *NScope = NULL;
@@ -1258,17 +1248,17 @@ DbgScope *DwarfDebug::getUpdatedDbgScope(MDNode *N, const MachineInstr *MI,
NScope = DbgScopeMap.lookup(InlinedAt);
else
NScope = DbgScopeMap.lookup(N);
- assert (NScope && "Unable to find working scope!");
+ assert(NScope && "Unable to find working scope!");
if (NScope->getFirstInsn())
return NScope;
DbgScope *Parent = NULL;
- if (GetConcreteScope) {
+ if (isAConcreteScope) {
DILocation IL(InlinedAt);
Parent = getUpdatedDbgScope(IL.getScope().getNode(), MI,
IL.getOrigLocation().getNode());
- assert (Parent && "Unable to find Parent scope!");
+ assert(Parent && "Unable to find Parent scope!");
NScope->setParent(Parent);
Parent->addScope(NScope);
} else if (DIDescriptor(N).isLexicalBlock()) {
@@ -1286,7 +1276,7 @@ DbgScope *DwarfDebug::getUpdatedDbgScope(MDNode *N, const MachineInstr *MI,
CurrentFnDbgScope = NScope;
}
- if (GetConcreteScope) {
+ if (isAConcreteScope) {
ConcreteScopes[InlinedAt] = NScope;
getOrCreateAbstractScope(N);
}
@@ -1295,7 +1285,7 @@ DbgScope *DwarfDebug::getUpdatedDbgScope(MDNode *N, const MachineInstr *MI,
}
DbgScope *DwarfDebug::getOrCreateAbstractScope(MDNode *N) {
- assert (N && "Invalid Scope encoding!");
+ assert(N && "Invalid Scope encoding!");
DbgScope *AScope = AbstractScopes.lookup(N);
if (AScope)
@@ -1377,7 +1367,7 @@ DIE *DwarfDebug::updateSubprogramScopeDIE(MDNode *SPNode) {
DIE *DwarfDebug::constructLexicalScopeDIE(DbgScope *Scope) {
MCSymbol *Start = Scope->getStartLabel();
MCSymbol *End = Scope->getEndLabel();
- if (Start == 0) return 0;
+ if (Start == 0 || End == 0) return 0;
assert(Start->isDefined() && "Invalid starting label for an inlined scope!");
assert(End->isDefined() && "Invalid end label for an inlined scope!");
@@ -1400,7 +1390,7 @@ DIE *DwarfDebug::constructLexicalScopeDIE(DbgScope *Scope) {
DIE *DwarfDebug::constructInlinedScopeDIE(DbgScope *Scope) {
MCSymbol *StartLabel = Scope->getStartLabel();
MCSymbol *EndLabel = Scope->getEndLabel();
- if (StartLabel == 0) return 0;
+ if (StartLabel == 0 || EndLabel == 0) return 0;
assert(StartLabel->isDefined() &&
"Invalid starting label for an inlined scope!");
@@ -1413,7 +1403,7 @@ DIE *DwarfDebug::constructInlinedScopeDIE(DbgScope *Scope) {
DISubprogram InlinedSP = getDISubprogram(DS.getNode());
DIE *OriginDIE = ModuleCU->getDIE(InlinedSP.getNode());
- assert (OriginDIE && "Unable to find Origin DIE!");
+ assert(OriginDIE && "Unable to find Origin DIE!");
addDIEEntry(ScopeDIE, dwarf::DW_AT_abstract_origin,
dwarf::DW_FORM_ref4, OriginDIE);
@@ -1477,9 +1467,9 @@ DIE *DwarfDebug::constructVariableDIE(DbgVariable *DV, DbgScope *Scope) {
DISubprogram InlinedSP = getDISubprogram(DS.getNode());
DIE *OriginSPDIE = ModuleCU->getDIE(InlinedSP.getNode());
(void) OriginSPDIE;
- assert (OriginSPDIE && "Unable to find Origin DIE for the SP!");
+ assert(OriginSPDIE && "Unable to find Origin DIE for the SP!");
DIE *AbsDIE = DV->getAbstractVariable()->getDIE();
- assert (AbsDIE && "Unable to find Origin DIE for the Variable!");
+ assert(AbsDIE && "Unable to find Origin DIE for the Variable!");
addDIEEntry(VariableDie, dwarf::DW_AT_abstract_origin,
dwarf::DW_FORM_ref4, AbsDIE);
}
@@ -1508,12 +1498,18 @@ DIE *DwarfDebug::constructVariableDIE(DbgVariable *DV, DbgScope *Scope) {
MachineLocation Location;
Location.set(DbgValueInsn->getOperand(0).getReg());
addAddress(VariableDie, dwarf::DW_AT_location, Location);
+ if (MCSymbol *VS = DV->getDbgValueLabel())
+ addLabel(VariableDie, dwarf::DW_AT_start_scope, dwarf::DW_FORM_addr,
+ VS);
} else if (DbgValueInsn->getOperand(0).getType() ==
MachineOperand::MO_Immediate) {
- DIEBlock *Block = new DIEBlock();
+ DIEBlock *Block = new (DIEValueAllocator) DIEBlock();
unsigned Imm = DbgValueInsn->getOperand(0).getImm();
addUInt(Block, 0, dwarf::DW_FORM_udata, Imm);
addBlock(VariableDie, dwarf::DW_AT_const_value, 0, Block);
+ if (MCSymbol *VS = DV->getDbgValueLabel())
+ addLabel(VariableDie, dwarf::DW_AT_start_scope, dwarf::DW_FORM_addr,
+ VS);
} else {
//FIXME : Handle other operand types.
delete VariableDie;
@@ -1523,7 +1519,8 @@ DIE *DwarfDebug::constructVariableDIE(DbgVariable *DV, DbgScope *Scope) {
} else {
MachineLocation Location;
unsigned FrameReg;
- int Offset = RI->getFrameIndexReference(*MF, DV->getFrameIndex(), FrameReg);
+ int Offset = RI->getFrameIndexReference(*MF, DV->getFrameIndex(),
+ FrameReg);
Location.set(FrameReg, Offset);
if (VD.hasComplexAddress())
@@ -1576,10 +1573,9 @@ DIE *DwarfDebug::constructScopeDIE(DbgScope *Scope) {
else
ScopeDIE = updateSubprogramScopeDIE(DS.getNode());
}
- else {
+ else
ScopeDIE = constructLexicalScopeDIE(Scope);
- if (!ScopeDIE) return NULL;
- }
+ if (!ScopeDIE) return NULL;
// Add variables to scope.
const SmallVector<DbgVariable *, 8> &Variables = Scope->getVariables();
@@ -1608,7 +1604,7 @@ DIE *DwarfDebug::constructScopeDIE(DbgScope *Scope) {
/// source file names. If none currently exists, create a new id and insert it
/// in the SourceIds map. This can update DirectoryNames and SourceFileNames
/// maps as well.
-unsigned DwarfDebug::GetOrCreateSourceID(StringRef DirName, StringRef FileName) {
+unsigned DwarfDebug::GetOrCreateSourceID(StringRef DirName, StringRef FileName){
unsigned DId;
StringMap<unsigned>::iterator DI = DirectoryIdMap.find(DirName);
if (DI != DirectoryIdMap.end()) {
@@ -1666,15 +1662,19 @@ void DwarfDebug::constructCompileUnit(MDNode *N) {
unsigned ID = GetOrCreateSourceID(Dir, FN);
DIE *Die = new DIE(dwarf::DW_TAG_compile_unit);
- // FIXME: Why getting the delta between two identical labels??
- addSectionOffset(Die, dwarf::DW_AT_stmt_list, dwarf::DW_FORM_data4,
- getTempLabel("section_line"), getTempLabel("section_line"),
- false);
addString(Die, dwarf::DW_AT_producer, dwarf::DW_FORM_string,
DIUnit.getProducer());
addUInt(Die, dwarf::DW_AT_language, dwarf::DW_FORM_data1,
DIUnit.getLanguage());
addString(Die, dwarf::DW_AT_name, dwarf::DW_FORM_string, FN);
+ addLabel(Die, dwarf::DW_AT_low_pc, dwarf::DW_FORM_addr,
+ getTempLabel("text_begin"));
+ addLabel(Die, dwarf::DW_AT_high_pc, dwarf::DW_FORM_addr,
+ getTempLabel("text_end"));
+ // DW_AT_stmt_list is a offset of line number information for this
+ // compile unit in debug_line section. It is always zero when only one
+ // compile unit is emitted in one object file.
+ addUInt(Die, dwarf::DW_AT_stmt_list, dwarf::DW_FORM_data4, 0);
if (!Dir.empty())
addString(Die, dwarf::DW_AT_comp_dir, dwarf::DW_FORM_string, Dir);
@@ -1717,13 +1717,13 @@ void DwarfDebug::constructGlobalVariableDIE(MDNode *N) {
DIDescriptor GVContext = DI_GV.getContext();
// Do not create specification DIE if context is either compile unit
// or a subprogram.
- if (DI_GV.isDefinition() && !GVContext.isCompileUnit()
- && !GVContext.isFile() && !GVContext.isSubprogram()) {
+ if (DI_GV.isDefinition() && !GVContext.isCompileUnit() &&
+ !GVContext.isFile() && !GVContext.isSubprogram()) {
// Create specification DIE.
DIE *VariableSpecDIE = new DIE(dwarf::DW_TAG_variable);
addDIEEntry(VariableSpecDIE, dwarf::DW_AT_specification,
dwarf::DW_FORM_ref4, VariableDie);
- DIEBlock *Block = new DIEBlock();
+ DIEBlock *Block = new (DIEValueAllocator) DIEBlock();
addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_addr);
addLabel(Block, 0, dwarf::DW_FORM_udata,
Asm->Mang->getSymbol(DI_GV.getGlobal()));
@@ -1731,7 +1731,7 @@ void DwarfDebug::constructGlobalVariableDIE(MDNode *N) {
addUInt(VariableDie, dwarf::DW_AT_declaration, dwarf::DW_FORM_flag, 1);
ModuleCU->addDie(VariableSpecDIE);
} else {
- DIEBlock *Block = new DIEBlock();
+ DIEBlock *Block = new (DIEValueAllocator) DIEBlock();
addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_addr);
addLabel(Block, 0, dwarf::DW_FORM_udata,
Asm->Mang->getSymbol(DI_GV.getGlobal()));
@@ -1745,7 +1745,7 @@ void DwarfDebug::constructGlobalVariableDIE(MDNode *N) {
DIType GTy = DI_GV.getType();
if (GTy.isCompositeType() && !GTy.getName().empty()) {
DIEEntry *Entry = ModuleCU->getDIEEntry(GTy.getNode());
- assert (Entry && "Missing global type!");
+ assert(Entry && "Missing global type!");
ModuleCU->addGlobalType(GTy.getName(), Entry->getEntry());
}
return;
@@ -1783,12 +1783,11 @@ void DwarfDebug::constructSubprogramDIE(MDNode *N) {
void DwarfDebug::beginModule(Module *M, MachineModuleInfo *mmi) {
this->M = M;
- if (TimePassesIsEnabled)
- DebugTimer->startTimer();
-
if (!MAI->doesSupportDebugInformation())
return;
+ TimeRegion Timer(DebugTimer);
+
DebugInfoFinder DbgFinder;
DbgFinder.processModule(*M);
@@ -1836,9 +1835,6 @@ void DwarfDebug::beginModule(Module *M, MachineModuleInfo *mmi) {
// Emit initial sections
emitInitial();
-
- if (TimePassesIsEnabled)
- DebugTimer->stopTimer();
}
/// endModule - Emit all Dwarf sections that should come after the content.
@@ -1847,8 +1843,7 @@ void DwarfDebug::endModule() {
if (!ModuleCU)
return;
- if (TimePassesIsEnabled)
- DebugTimer->startTimer();
+ TimeRegion Timer(DebugTimer);
// Attach DW_AT_inline attribute with inlined subprogram DIEs.
for (SmallPtrSet<DIE *, 4>::iterator AI = InlinedSubprogramDIEs.begin(),
@@ -1871,7 +1866,7 @@ void DwarfDebug::endModule() {
if (!NDie) continue;
addDIEEntry(SPDie, dwarf::DW_AT_containing_type, dwarf::DW_FORM_ref4, NDie);
// FIXME - This is not the correct approach.
- // addDIEEntry(NDie, dwarf::DW_AT_containing_type, dwarf::DW_FORM_ref4, NDie);
+ //addDIEEntry(NDie, dwarf::DW_AT_containing_type, dwarf::DW_FORM_ref4, NDie
}
// Standard sections final addresses.
@@ -1932,9 +1927,6 @@ void DwarfDebug::endModule() {
delete ModuleCU;
ModuleCU = NULL; // Reset for the next Module, if any.
-
- if (TimePassesIsEnabled)
- DebugTimer->stopTimer();
}
/// findAbstractVariable - Find abstract variable, if any, associated with Var.
@@ -1971,10 +1963,11 @@ DbgVariable *DwarfDebug::findAbstractVariable(DIVariable &Var,
if (!Scope)
return NULL;
- AbsDbgVariable = new DbgVariable(Var, MI,
+ AbsDbgVariable = new DbgVariable(Var, MI,
NULL /* No more-abstract variable*/);
Scope->addVariable(AbsDbgVariable);
AbstractVariables[Var.getNode()] = AbsDbgVariable;
+ DbgValueStartMap[MI] = AbsDbgVariable;
return AbsDbgVariable;
}
@@ -2010,16 +2003,19 @@ void DwarfDebug::collectVariableInfo() {
for (MachineBasicBlock::const_iterator II = I->begin(), IE = I->end();
II != IE; ++II) {
const MachineInstr *MInsn = II;
- if (MInsn->getOpcode() != TargetOpcode::DBG_VALUE)
+ if (!MInsn->isDebugValue())
continue;
+
// FIXME : Lift this restriction.
if (MInsn->getNumOperands() != 3)
continue;
- DIVariable DV((MDNode*)(MInsn->getOperand(MInsn->getNumOperands() - 1).getMetadata()));
+ DIVariable DV((MDNode*)(MInsn->getOperand(MInsn->getNumOperands()
+ - 1).getMetadata()));
if (DV.getTag() == dwarf::DW_TAG_arg_variable) {
// FIXME Handle inlined subroutine arguments.
DbgVariable *ArgVar = new DbgVariable(DV, MInsn, NULL);
CurrentFnDbgScope->addVariable(ArgVar);
+ DbgValueStartMap[MInsn] = ArgVar;
continue;
}
@@ -2034,19 +2030,54 @@ void DwarfDebug::collectVariableInfo() {
if (!Scope)
continue;
- DbgVariable *AbsDbgVariable = findAbstractVariable(DV, MInsn,
- ScopeLoc);
+ DbgVariable *AbsDbgVariable = findAbstractVariable(DV, MInsn, ScopeLoc);
DbgVariable *RegVar = new DbgVariable(DV, MInsn, AbsDbgVariable);
+ DbgValueStartMap[MInsn] = RegVar;
Scope->addVariable(RegVar);
}
}
}
-/// beginScope - Process beginning of a scope starting at Label.
-void DwarfDebug::beginScope(const MachineInstr *MI, MCSymbol *Label) {
+/// beginScope - Process beginning of a scope.
+void DwarfDebug::beginScope(const MachineInstr *MI) {
+ // Check location.
+ DebugLoc DL = MI->getDebugLoc();
+ if (DL.isUnknown())
+ return;
+ DILocation DILoc = MF->getDILocation(DL);
+ if (!DILoc.getScope().Verify())
+ return;
+
+ // Check and update last known location info.
+ if(DILoc.getNode() == PrevDILoc)
+ return;
+
+ // DBG_VALUE instruction establishes new value.
+ if (MI->isDebugValue()) {
+ DenseMap<const MachineInstr *, DbgVariable *>::iterator DI
+ = DbgValueStartMap.find(MI);
+ if (DI != DbgValueStartMap.end()) {
+ MCSymbol *Label = recordSourceLine(DILoc.getLineNumber(),
+ DILoc.getColumnNumber(),
+ DILoc.getScope().getNode());
+ PrevDILoc = DILoc.getNode();
+ DI->second->setDbgValueLabel(Label);
+ }
+ return;
+ }
+
+ // Emit a label to indicate location change. This is used for line
+ // table even if this instruction does start a new scope.
+ MCSymbol *Label = recordSourceLine(DILoc.getLineNumber(),
+ DILoc.getColumnNumber(),
+ DILoc.getScope().getNode());
+ PrevDILoc = DILoc.getNode();
+
+ // update DbgScope if this instruction starts a new scope.
InsnToDbgScopeMapTy::iterator I = DbgScopeBeginMap.find(MI);
if (I == DbgScopeBeginMap.end())
return;
+
ScopeVector &SD = I->second;
for (ScopeVector::iterator SDI = SD.begin(), SDE = SD.end();
SDI != SDE; ++SDI)
@@ -2055,6 +2086,19 @@ void DwarfDebug::beginScope(const MachineInstr *MI, MCSymbol *Label) {
/// endScope - Process end of a scope.
void DwarfDebug::endScope(const MachineInstr *MI) {
+ // Ignore DBG_VALUE instruction.
+ if (MI->isDebugValue())
+ return;
+
+ // Check location.
+ DebugLoc DL = MI->getDebugLoc();
+ if (DL.isUnknown())
+ return;
+ DILocation DILoc = MF->getDILocation(DL);
+ if (!DILoc.getScope().Verify())
+ return;
+
+ // Emit a label and update DbgScope if this instruction ends a scope.
InsnToDbgScopeMapTy::iterator I = DbgScopeEndMap.find(MI);
if (I == DbgScopeEndMap.end())
return;
@@ -2094,7 +2138,7 @@ void DwarfDebug::createDbgScope(MDNode *Scope, MDNode *InlinedAt) {
}
/// extractScopeInformation - Scan machine instructions in this function
-/// and collect DbgScopes. Return true, if atleast one scope was found.
+/// and collect DbgScopes. Return true, if at least one scope was found.
bool DwarfDebug::extractScopeInformation() {
// If scope information was extracted using .dbg intrinsics then there is not
// any need to extract these information by scanning each instruction.
@@ -2110,12 +2154,13 @@ bool DwarfDebug::extractScopeInformation() {
II != IE; ++II) {
const MachineInstr *MInsn = II;
// FIXME : Remove DBG_VALUE check.
- if (MInsn->getOpcode() == TargetOpcode::DBG_VALUE) continue;
+ if (MInsn->isDebugValue()) continue;
MIIndexMap[MInsn] = MIIndex++;
DebugLoc DL = MInsn->getDebugLoc();
if (DL.isUnknown()) continue;
DILocation DLT = MF->getDILocation(DL);
DIScope DLTScope = DLT.getScope();
+ if (!DLTScope.getNode()) continue;
// There is no need to create another DIE for compile unit. For all
// other scopes, create one DbgScope now. This will be translated
// into a scope DIE at the end.
@@ -2132,11 +2177,12 @@ bool DwarfDebug::extractScopeInformation() {
II != IE; ++II) {
const MachineInstr *MInsn = II;
// FIXME : Remove DBG_VALUE check.
- if (MInsn->getOpcode() == TargetOpcode::DBG_VALUE) continue;
+ if (MInsn->isDebugValue()) continue;
DebugLoc DL = MInsn->getDebugLoc();
if (DL.isUnknown()) continue;
DILocation DLT = MF->getDILocation(DL);
DIScope DLTScope = DLT.getScope();
+ if (!DLTScope.getNode()) continue;
// There is no need to create another DIE for compile unit. For all
// other scopes, create one DbgScope now. This will be translated
// into a scope DIE at the end.
@@ -2159,7 +2205,7 @@ bool DwarfDebug::extractScopeInformation() {
SmallVector<DbgScope *, 4> WorkList;
WorkList.push_back(CurrentFnDbgScope);
while (!WorkList.empty()) {
- DbgScope *S = WorkList.back(); WorkList.pop_back();
+ DbgScope *S = WorkList.pop_back_val();
const SmallVector<DbgScope *, 4> &Children = S->getScopes();
if (!Children.empty())
@@ -2170,7 +2216,7 @@ bool DwarfDebug::extractScopeInformation() {
if (S->isAbstractScope())
continue;
const MachineInstr *MI = S->getFirstInsn();
- assert (MI && "DbgScope does not have first instruction!");
+ assert(MI && "DbgScope does not have first instruction!");
InsnToDbgScopeMapTy::iterator IDI = DbgScopeBeginMap.find(MI);
if (IDI != DbgScopeBeginMap.end())
@@ -2179,7 +2225,7 @@ bool DwarfDebug::extractScopeInformation() {
DbgScopeBeginMap[MI].push_back(S);
MI = S->getLastInsn();
- assert (MI && "DbgScope does not have last instruction!");
+ assert(MI && "DbgScope does not have last instruction!");
IDI = DbgScopeEndMap.find(MI);
if (IDI != DbgScopeEndMap.end())
IDI->second.push_back(S);
@@ -2196,12 +2242,10 @@ void DwarfDebug::beginFunction(const MachineFunction *MF) {
this->MF = MF;
if (!ShouldEmitDwarfDebug()) return;
-
- if (TimePassesIsEnabled)
- DebugTimer->startTimer();
-
if (!extractScopeInformation())
return;
+
+ TimeRegion Timer(DebugTimer);
collectVariableInfo();
@@ -2225,20 +2269,15 @@ void DwarfDebug::beginFunction(const MachineFunction *MF) {
recordSourceLine(Line, Col, DLT.getScope().getNode());
}
- if (TimePassesIsEnabled)
- DebugTimer->stopTimer();
}
/// endFunction - Gather and emit post-function debug information.
///
void DwarfDebug::endFunction(const MachineFunction *MF) {
if (!ShouldEmitDwarfDebug()) return;
-
- if (TimePassesIsEnabled)
- DebugTimer->startTimer();
-
- if (DbgScopeMap.empty())
- return;
+ if (DbgScopeMap.empty()) return;
+
+ TimeRegion Timer(DebugTimer);
if (CurrentFnDbgScope) {
// Define end label for subprogram.
@@ -2271,14 +2310,12 @@ void DwarfDebug::endFunction(const MachineFunction *MF) {
DeleteContainerSeconds(DbgScopeMap);
DbgScopeBeginMap.clear();
DbgScopeEndMap.clear();
+ DbgValueStartMap.clear();
ConcreteScopes.clear();
DeleteContainerSeconds(AbstractScopes);
AbstractScopesList.clear();
AbstractVariables.clear();
Lines.clear();
-
- if (TimePassesIsEnabled)
- DebugTimer->stopTimer();
}
/// recordSourceLine - Register a source line with debug info. Returns the
@@ -2288,8 +2325,7 @@ MCSymbol *DwarfDebug::recordSourceLine(unsigned Line, unsigned Col, MDNode *S) {
if (!MMI)
return 0;
- if (TimePassesIsEnabled)
- DebugTimer->startTimer();
+ TimeRegion Timer(DebugTimer);
StringRef Dir;
StringRef Fn;
@@ -2314,9 +2350,6 @@ MCSymbol *DwarfDebug::recordSourceLine(unsigned Line, unsigned Col, MDNode *S) {
MCSymbol *Label = MMI->getContext().CreateTempSymbol();
Lines.push_back(SrcLineInfo(Line, Col, Src, Label));
- if (TimePassesIsEnabled)
- DebugTimer->stopTimer();
-
Asm->OutStreamer.EmitLabel(Label);
return Label;
}
@@ -2328,15 +2361,8 @@ MCSymbol *DwarfDebug::recordSourceLine(unsigned Line, unsigned Col, MDNode *S) {
/// well.
unsigned DwarfDebug::getOrCreateSourceID(const std::string &DirName,
const std::string &FileName) {
- if (TimePassesIsEnabled)
- DebugTimer->startTimer();
-
- unsigned SrcId = GetOrCreateSourceID(DirName.c_str(), FileName.c_str());
-
- if (TimePassesIsEnabled)
- DebugTimer->stopTimer();
-
- return SrcId;
+ TimeRegion Timer(DebugTimer);
+ return GetOrCreateSourceID(DirName.c_str(), FileName.c_str());
}
//===----------------------------------------------------------------------===//
@@ -2351,7 +2377,8 @@ DwarfDebug::computeSizeAndOffset(DIE *Die, unsigned Offset, bool Last) {
const std::vector<DIE *> &Children = Die->getChildren();
// If not last sibling and has children then add sibling offset attribute.
- if (!Last && !Children.empty()) Die->addSiblingOffset();
+ if (!Last && !Children.empty())
+ Die->addSiblingOffset(DIEValueAllocator);
// Record the abbreviation.
assignAbbrevNumber(Die->getAbbrev());
@@ -2465,7 +2492,7 @@ void DwarfDebug::emitDIE(DIE *Die) {
dwarf::TagString(Abbrev->getTag()));
EmitULEB128(AbbrevNumber);
- SmallVector<DIEValue*, 32> &Values = Die->getValues();
+ const SmallVector<DIEValue*, 32> &Values = Die->getValues();
const SmallVector<DIEAbbrevData, 8> &AbbrevData = Abbrev->getData();
// Emit the DIE attribute values.
OpenPOWER on IntegriCloud